Commit 9b651cc2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arc-v3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull ARC updates from Vineet Gupta:
 "Nothing too exciting here, just minor fixes/cleanup.  Only noteworthy
  ones are:

   - Moving cache disabling to early boot
   - ARC UART enabled only if earlyprintk setup in cmdline"

* tag 'arc-v3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: Disable caches in early boot if so configured
  ARC: [arcfpga] Early ARC UART to be only activated by cmdline
  ARC: [arcfpga] Get rid of legacy BVCI latency unit support
  ARC: remove duplicate header exports
  ARC: arc_local_timer_setup() need not pass own cpu id
  ARC: Fixed spelling errors within comments
  ARC: make start_thread() out-of-line
  ARC: fix mmuv2 warning
  ARC: [SMP] ISS SMP extension bitrot
parents 214b9313 ef680cdc
......@@ -17,7 +17,7 @@ / {
interrupt-parent = <&intc>;
chosen {
bootargs = "console=ttyARC0,115200n8";
bootargs = "console=ttyARC0,115200n8 earlyprintk=ttyARC0";
};
aliases {
......
......@@ -55,4 +55,31 @@ extern void read_decode_cache_bcr(void);
#endif /* !__ASSEMBLY__ */
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72 /* Build Config reg */
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
#endif /* _ASM_CACHE_H */
......@@ -19,8 +19,6 @@
#include <asm-generic/irq.h>
extern void arc_init_IRQ(void);
extern int get_hw_config_num_irq(void);
void arc_local_timer_setup(unsigned int cpu);
void arc_local_timer_setup(void);
#endif
......@@ -18,7 +18,6 @@
#ifndef __ASSEMBLY__
#include <asm/arcregs.h> /* for STATUS_E1_MASK et all */
#include <asm/ptrace.h>
/* Arch specific stuff which needs to be saved per task.
......@@ -41,15 +40,13 @@ struct thread_struct {
/* Forward declaration, a strange C thing */
struct task_struct;
/*
* Return saved PC of a blocked thread.
*/
/* Return saved PC of a blocked thread */
unsigned long thread_saved_pc(struct task_struct *t);
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
/* Free all resources held by a thread. */
/* Free all resources held by a thread */
#define release_thread(thread) do { } while (0)
/* Prepare to copy thread state - unlazy all lazy status */
......@@ -82,26 +79,8 @@ unsigned long thread_saved_pc(struct task_struct *t);
#define KSTK_BLINK(tsk) KSTK_REG(tsk, 4)
#define KSTK_FP(tsk) KSTK_REG(tsk, 0)
/*
* Do necessary setup to start up a newly executed thread.
*
* E1,E2 so that Interrupts are enabled in user mode
* L set, so Loop inhibited to begin with
* lp_start and lp_end seeded with bogus non-zero values so to easily catch
* the ARC700 sr to lp_start hardware bug
*/
#define start_thread(_regs, _pc, _usp) \
do { \
set_fs(USER_DS); /* reads from user space */ \
(_regs)->ret = (_pc); \
/* Interrupts enabled in User Mode */ \
(_regs)->status32 = STATUS_U_MASK | STATUS_L_MASK \
| STATUS_E1_MASK | STATUS_E2_MASK; \
(_regs)->sp = (_usp); \
/* bogus seed values for debugging */ \
(_regs)->lp_start = 0x10; \
(_regs)->lp_end = 0x80; \
} while (0)
extern void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long usp);
extern unsigned int get_wchan(struct task_struct *p);
......
......@@ -2,11 +2,4 @@
include include/uapi/asm-generic/Kbuild.asm
header-y += elf.h
header-y += page.h
header-y += setup.h
header-y += byteorder.h
header-y += cachectl.h
header-y += ptrace.h
header-y += sigcontext.h
header-y += signal.h
header-y += swab.h
header-y += unistd.h
......@@ -156,7 +156,7 @@ ARCFP_DATA int1_saved_reg
int1_saved_reg:
.zero 4
/* Each Interrupt level needs it's own scratch */
/* Each Interrupt level needs its own scratch */
#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
ARCFP_DATA int2_saved_reg
......@@ -473,7 +473,7 @@ trap_with_param:
lr r0, [efa]
mov r1, sp
; Now that we have read EFA, its safe to do "fake" rtie
; Now that we have read EFA, it is safe to do "fake" rtie
; and get out of CPU exception mode
FAKE_RET_FROM_EXCPN r11
......@@ -678,9 +678,9 @@ not_exception:
brne r9, event_IRQ2, 149f
;------------------------------------------------------------------
; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier
; so that sched doesnt move to new task, causing L1 to be delayed
; undeterministically. Now that we've achieved that, lets reset
; if L2 IRQ interrupted an L1 ISR, we'd disabled preemption earlier
; so that sched doesn't move to new task, causing L1 to be delayed
; undeterministically. Now that we've achieved that, let's reset
; things to what they were, before returning from L2 context
;----------------------------------------------------------------
......@@ -736,7 +736,7 @@ ENTRY(ret_from_fork)
; put last task in scheduler queue
bl @schedule_tail
; If kernel thread, jump to it's entry-point
; If kernel thread, jump to its entry-point
ld r9, [sp, PT_status32]
brne r9, 0, 1f
......
......@@ -12,10 +12,42 @@
* to skip certain things during boot on simulator
*/
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/entry.h>
#include <linux/linkage.h>
#include <asm/arcregs.h>
#include <asm/cache.h>
.macro CPU_EARLY_SETUP
; Setting up Vectror Table (in case exception happens in early boot
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
; Disable I-cache/D-cache if kernel so configured
lr r5, [ARC_REG_IC_BCR]
breq r5, 0, 1f ; I$ doesn't exist
lr r5, [ARC_REG_IC_CTRL]
#ifdef CONFIG_ARC_HAS_ICACHE
bclr r5, r5, 0 ; 0 - Enable, 1 is Disable
#else
bset r5, r5, 0 ; I$ exists, but is not used
#endif
sr r5, [ARC_REG_IC_CTRL]
1:
lr r5, [ARC_REG_DC_BCR]
breq r5, 0, 1f ; D$ doesn't exist
lr r5, [ARC_REG_DC_CTRL]
bclr r5, r5, 6 ; Invalidate (discard w/o wback)
#ifdef CONFIG_ARC_HAS_DCACHE
bclr r5, r5, 0 ; Enable (+Inv)
#else
bset r5, r5, 0 ; Disable (+Inv)
#endif
sr r5, [ARC_REG_DC_CTRL]
1:
.endm
.cpu A7
......@@ -27,7 +59,7 @@ stext:
; Don't clobber r0-r2 yet. It might have bootloader provided info
;-------------------------------------------------------------------
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
CPU_EARLY_SETUP
#ifdef CONFIG_SMP
; Ensure Boot (Master) proceeds. Others wait in platform dependent way
......@@ -90,7 +122,7 @@ stext:
first_lines_of_secondary:
sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
CPU_EARLY_SETUP
; setup per-cpu idle task as "current" on this CPU
ld r0, [@secondary_idle_tsk]
......
......@@ -150,24 +150,6 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs);
}
int get_hw_config_num_irq(void)
{
uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR);
switch (val & 0x03) {
case 0:
return 16;
case 1:
return 32;
case 2:
return 8;
default:
return 0;
}
return 0;
}
/*
* arch_local_irq_enable - Enable interrupts.
*
......
......@@ -150,6 +150,29 @@ int copy_thread(unsigned long clone_flags,
return 0;
}
/*
* Do necessary setup to start up a new user task
*/
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp)
{
set_fs(USER_DS); /* user space */
regs->sp = usp;
regs->ret = pc;
/*
* [U]ser Mode bit set
* [L] ZOL loop inhibited to begin with - cleared by a LP insn
* Interrupts enabled
*/
regs->status32 = STATUS_U_MASK | STATUS_L_MASK |
STATUS_E1_MASK | STATUS_E2_MASK;
/* bogus seed values for debugging */
regs->lp_start = 0x10;
regs->lp_end = 0x80;
}
/*
* Some archs flush debug and FPU info here
*/
......
......@@ -138,7 +138,7 @@ void start_kernel_secondary(void)
if (machine_desc->init_smp)
machine_desc->init_smp(smp_processor_id());
arc_local_timer_setup(cpu);
arc_local_timer_setup();
local_irq_enable();
preempt_disable();
......
......@@ -219,12 +219,13 @@ static struct irqaction arc_timer_irq = {
/*
* Setup the local event timer for @cpu
*/
void arc_local_timer_setup(unsigned int cpu)
void arc_local_timer_setup()
{
struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu);
struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
int cpu = smp_processor_id();
clk->cpumask = cpumask_of(cpu);
clockevents_config_and_register(clk, arc_get_core_freq(),
evt->cpumask = cpumask_of(cpu);
clockevents_config_and_register(evt, arc_get_core_freq(),
0, ARC_TIMER_MAX);
/*
......@@ -261,7 +262,7 @@ void __init time_init(void)
clocksource_register_hz(&arc_counter, arc_get_core_freq());
/* sets up the periodic event timer */
arc_local_timer_setup(smp_processor_id());
arc_local_timer_setup();
if (machine_desc->init_time)
machine_desc->init_time();
......
......@@ -73,33 +73,6 @@
#include <asm/cachectl.h>
#include <asm/setup.h>
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72 /* Build Config reg */
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
char *arc_cache_mumbojumbo(int c, char *buf, int len)
{
int n = 0;
......@@ -168,72 +141,43 @@ void read_decode_cache_bcr(void)
*/
void arc_cache_init(void)
{
unsigned int cpu = smp_processor_id();
struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
unsigned int dcache_does_alias, temp;
unsigned int __maybe_unused cpu = smp_processor_id();
struct cpuinfo_arc_cache __maybe_unused *ic, __maybe_unused *dc;
char str[256];
printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
if (!ic->ver)
goto chk_dc;
#ifdef CONFIG_ARC_HAS_ICACHE
/* 1. Confirm some of I-cache params which Linux assumes */
if (ic->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config");
if (ic->ver != CONFIG_ARC_MMU_VER)
panic("Cache ver doesn't match MMU ver\n");
#endif
/* Enable/disable I-Cache */
temp = read_aux_reg(ARC_REG_IC_CTRL);
#ifdef CONFIG_ARC_HAS_ICACHE
temp &= ~IC_CTRL_CACHE_DISABLE;
#else
temp |= IC_CTRL_CACHE_DISABLE;
ic = &cpuinfo_arc700[cpu].icache;
if (ic->ver) {
if (ic->line_len != L1_CACHE_BYTES)
panic("ICache line [%d] != kernel Config [%d]",
ic->line_len, L1_CACHE_BYTES);
if (ic->ver != CONFIG_ARC_MMU_VER)
panic("Cache ver [%d] doesn't match MMU ver [%d]\n",
ic->ver, CONFIG_ARC_MMU_VER);
}
#endif
write_aux_reg(ARC_REG_IC_CTRL, temp);
chk_dc:
if (!dc->ver)
return;
#ifdef CONFIG_ARC_HAS_DCACHE
if (dc->line_len != L1_CACHE_BYTES)
panic("Cache H/W doesn't match kernel Config");
dc = &cpuinfo_arc700[cpu].dcache;
if (dc->ver) {
unsigned int dcache_does_alias;
/* check for D-Cache aliasing */
dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
if (dc->line_len != L1_CACHE_BYTES)
panic("DCache line [%d] != kernel Config [%d]",
dc->line_len, L1_CACHE_BYTES);
if (dcache_does_alias && !cache_is_vipt_aliasing())
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
else if (!dcache_does_alias && cache_is_vipt_aliasing())
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
#endif
/* Set the default Invalidate Mode to "simpy discard dirty lines"
* as this is more frequent then flush before invalidate
* Ofcourse we toggle this default behviour when desired
*/
temp = read_aux_reg(ARC_REG_DC_CTRL);
temp &= ~DC_CTRL_INV_MODE_FLUSH;
/* check for D-Cache aliasing */
dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
#ifdef CONFIG_ARC_HAS_DCACHE
/* Enable D-Cache: Clear Bit 0 */
write_aux_reg(ARC_REG_DC_CTRL, temp & ~IC_CTRL_CACHE_DISABLE);
#else
/* Flush D cache */
write_aux_reg(ARC_REG_DC_FLSH, 0x1);
/* Disable D cache */
write_aux_reg(ARC_REG_DC_CTRL, temp | IC_CTRL_CACHE_DISABLE);
if (dcache_does_alias && !cache_is_vipt_aliasing())
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
else if (!dcache_does_alias && cache_is_vipt_aliasing())
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
}
#endif
return;
}
#define OP_INV 0x1
......@@ -253,12 +197,16 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr,
if (cacheop == OP_INV_IC) {
aux_cmd = ARC_REG_IC_IVIL;
#if (CONFIG_ARC_MMU_VER > 2)
aux_tag = ARC_REG_IC_PTAG;
#endif
}
else {
/* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
aux_cmd = cacheop & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL;
#if (CONFIG_ARC_MMU_VER > 2)
aux_tag = ARC_REG_DC_PTAG;
#endif
}
/* Ensure we properly floor/ceil the non-line aligned/sized requests
......
......@@ -48,36 +48,4 @@ config ARC_SERIAL_BAUD
help
Baud rate for the ARC UART
menuconfig ARC_HAS_BVCI_LAT_UNIT
bool "BVCI Bus Latency Unit"
depends on ARC_BOARD_ML509 || ARC_BOARD_ANGEL4
help
IP to add artificial latency to BVCI Bus Based FPGA builds.
The default latency (even worst case) for FPGA is non-realistic
(~10 SDRAM, ~5 SSRAM).
config BVCI_LAT_UNITS
hex "Latency Unit(s) Bitmap"
default "0x0"
depends on ARC_HAS_BVCI_LAT_UNIT
help
There are multiple Latency Units corresponding to the many
interfaces of the system bus arbiter (both CPU side as well as
the peripheral side).
To add latency to ALL memory transaction, choose Unit 0, otherwise
for finer grainer - interface wise latency, specify a bitmap (1 bit
per unit) of all units. e.g. 1,2,12 will be 0x1003
Unit 0 - System Arb and Mem Controller
Unit 1 - I$ and System Bus
Unit 2 - D$ and System Bus
..
Unit 12 - IDE Disk controller and System Bus
config BVCI_LAT_CYCLES
int "Latency Value in cycles"
range 0 63
default "30"
depends on ARC_HAS_BVCI_LAT_UNIT
endif
......@@ -9,4 +9,4 @@
KBUILD_CFLAGS += -Iarch/arc/plat-arcfpga/include
obj-y := platform.o irq.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_ISS_SMP_EXTN) += smp.o
......@@ -22,59 +22,6 @@
#include <plat/smp.h>
#include <plat/irq.h>
/*-----------------------BVCI Latency Unit -----------------------------*/
#ifdef CONFIG_ARC_HAS_BVCI_LAT_UNIT
int lat_cycles = CONFIG_BVCI_LAT_CYCLES;
/* BVCI Bus Profiler: Latency Unit */
static void __init setup_bvci_lat_unit(void)
{
#define MAX_BVCI_UNITS 12
unsigned int i;
unsigned int *base = (unsigned int *)BVCI_LAT_UNIT_BASE;
const unsigned long units_req = CONFIG_BVCI_LAT_UNITS;
const unsigned int REG_UNIT = 21;
const unsigned int REG_VAL = 22;
/*
* There are multiple Latency Units corresponding to the many
* interfaces of the system bus arbiter (both CPU side as well as
* the peripheral side).
*
* Unit 0 - System Arb and Mem Controller - adds latency to all
* memory trasactions
* Unit 1 - I$ and System Bus
* Unit 2 - D$ and System Bus
* ..
* Unit 12 - IDE Disk controller and System Bus
*
* The programmers model requires writing to lat_unit reg first
* and then the latency value (cycles) to lat_value reg
*/
if (CONFIG_BVCI_LAT_UNITS == 0) {
writel(0, base + REG_UNIT);
writel(lat_cycles, base + REG_VAL);
pr_info("BVCI Latency for all Memory Transactions %d cycles\n",
lat_cycles);
} else {
for_each_set_bit(i, &units_req, MAX_BVCI_UNITS) {
writel(i + 1, base + REG_UNIT); /* loop is 0 based */
writel(lat_cycles, base + REG_VAL);
pr_info("BVCI Latency for Unit[%d] = %d cycles\n",
(i + 1), lat_cycles);
}
}
}
#else
static void __init setup_bvci_lat_unit(void)
{
}
#endif
/*----------------------- Platform Devices -----------------------------*/
#if IS_ENABLED(CONFIG_SERIAL_ARC)
......@@ -132,16 +79,11 @@ static void arc_fpga_serial_init(void)
ARRAY_SIZE(fpga_early_devs));
/*
* ARC console driver registers itself as an early platform driver
* of class "earlyprintk".
* Install it here, followed by probe of devices.
* The installation here doesn't require earlyprintk in command line
* To do so however, replace the lines below with
* parse_early_param();
* early_platform_driver_probe("earlyprintk", 1, 1);
* ^^
* ARC console driver registers (build time) as an early platform driver
* of class "earlyprintk". However it needs explicit cmdline toggle
* "earlyprintk=ttyARC0" to be successfuly runtime registered.
* Otherwise the early probe below fails to find the driver
*/
early_platform_driver_register_all("earlyprintk");
early_platform_driver_probe("earlyprintk", 1, 0);
/*
......@@ -165,11 +107,9 @@ static void __init plat_fpga_early_init(void)
{
pr_info("[plat-arcfpga]: registering early dev resources\n");
setup_bvci_lat_unit();
arc_fpga_serial_init();
#ifdef CONFIG_SMP
#ifdef CONFIG_ISS_SMP_EXTN
iss_model_init_early_smp();
#endif
}
......@@ -211,7 +151,7 @@ MACHINE_START(ANGEL4, "angel4")
.init_early = plat_fpga_early_init,
.init_machine = plat_fpga_populate_dev,
.init_irq = plat_fpga_init_IRQ,
#ifdef CONFIG_SMP
#ifdef CONFIG_ISS_SMP_EXTN
.init_smp = iss_model_init_smp,
#endif
MACHINE_END
......
......@@ -42,6 +42,24 @@ static void iss_model_smp_wakeup_cpu(int cpu, unsigned long pc)
}
static inline int get_hw_config_num_irq(void)
{
uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR);
switch (val & 0x03) {
case 0:
return 16;
case 1:
return 32;
case 2:
return 8;
default:
return 0;
}
return 0;
}
/*
* Any SMP specific init any CPU does when it comes up.
* Here we setup the CPU to enable Inter-Processor-Interrupts
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment