diff options
author | Akira Takeuchi <takeuchi.akr@jp.panasonic.com> | 2010-10-27 17:28:55 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2010-10-27 17:28:55 +0100 |
commit | 368dd5acd154b09c043cc4392a74da01599b37d5 (patch) | |
tree | dd94ae3d044f6e774dec2437613515bd6b46dacb /arch | |
parent | 04157a6e7df99fd5ed64955233d6e00ab6613614 (diff) |
MN10300: And Panasonic AM34 subarch and implement SMP
Implement the Panasonic MN10300 AM34 CPU subarch and implement SMP support for
MN10300. Also implement support for the MN2WS0060 processor and the ASB2364
evaluation board which are AM34 based.
Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com>
Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch')
79 files changed, 4494 insertions, 481 deletions
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index a0a16e6e4a4e..81e27816aaf8 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -48,7 +48,7 @@ config GENERIC_CALIBRATE_DELAY def_bool y config GENERIC_CMOS_UPDATE - def_bool y + def_bool n config GENERIC_FIND_NEXT_BIT def_bool y @@ -72,10 +72,6 @@ config GENERIC_HARDIRQS config HOTPLUG_CPU def_bool n -config HZ - int - default 1000 - mainmenu "Matsushita MN10300/AM33 Kernel Configuration" source "init/Kconfig" @@ -98,6 +94,9 @@ config MN10300_UNIT_ASB2303 config MN10300_UNIT_ASB2305 bool "ASB2305" +config MN10300_UNIT_ASB2364 + bool "ASB2364" + endchoice choice @@ -115,17 +114,13 @@ config MN10300_PROC_MN103E010 select MN10300_PROC_HAS_TTYSM1 select MN10300_PROC_HAS_TTYSM2 -endchoice - -choice - prompt "Processor core support" - default MN10300_CPU_AM33V2 - help - This option specifies the processor core for which the kernel will be - compiled. It affects the instruction set used. - -config MN10300_CPU_AM33V2 - bool "AM33v2" +config MN10300_PROC_MN2WS0050 + bool "MN2WS0050" + depends on MN10300_UNIT_ASB2364 + select AM34_2 + select MN10300_PROC_HAS_TTYSM0 + select MN10300_PROC_HAS_TTYSM1 + select MN10300_PROC_HAS_TTYSM2 endchoice @@ -138,7 +133,7 @@ config MN10300_HAS_ATOMIC_OPS_UNIT config FPU bool "FPU present" default y - depends on MN10300_PROC_MN103E010 + depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 config LAZY_SAVE_FPU bool "Save FPU state lazily" @@ -179,24 +174,55 @@ config KERNEL_TEXT_ADDRESS config KERNEL_ZIMAGE_BASE_ADDRESS hex "Base address of compressed vmlinux image" - default "0x90700000" + default "0x50700000" + +config BOOT_STACK_OFFSET + hex + default "0xF00" if SMP + default "0xFF0" if !SMP +config BOOT_STACK_SIZE + hex + depends on SMP + default "0x100" endmenu -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. +config SMP + bool "Symmetric multi-processing support" + default y + depends on MN10300_PROC_MN2WS0038 || MN10300_PROC_MN2WS0050 + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + See also <file:Documentation/i386/IO-APIC.txt>, + <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at + <http://www.tldp.org/docs.html#howto>. - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. + If you don't know what to do here, say N. + +config NR_CPUS + int + depends on SMP + default "2" + +config USE_GENERIC_SMP_HELPERS + bool + depends on SMP + default y + +source "kernel/Kconfig.preempt" config MN10300_CURRENT_IN_E2 bool "Hold current task address in E2 register" + depends on !SMP default y help This option removes the E2/R2 register from the set available to gcc @@ -218,12 +244,14 @@ config MN10300_USING_JTAG suppresses the use of certain hardware debugging features, such as single-stepping, which are taken over completely by the JTAG unit. +source "kernel/Kconfig.hz" + config MN10300_RTC bool "Using MN10300 RTC" - depends on MN10300_PROC_MN103E010 + depends on MN10300_PROC_MN103E010 || MN10300_PROC_MN2WS0050 + select GENERIC_CMOS_UPDATE default n help - This option enables support for the RTC, thus enabling time to be tracked, even when system is powered down. This is available on-chip on the MN103E010. @@ -315,14 +343,23 @@ config MN10300_TTYSM1 choice prompt "Select the timer to supply the clock for SIF1" - default MN10300_TTYSM0_TIMER9 + default MN10300_TTYSM1_TIMER12 \ + if !(AM33_2 || AM33_3) + default MN10300_TTYSM1_TIMER9 \ + if AM33_2 || AM33_3 depends on MN10300_TTYSM1 +config MN10300_TTYSM1_TIMER12 + bool "Use timer 12 (16-bit)" + depends on !(AM33_2 || AM33_3) + config MN10300_TTYSM1_TIMER9 bool "Use timer 9 (16-bit)" + depends on AM33_2 || AM33_3 config MN10300_TTYSM1_TIMER3 bool "Use timer 3 (8-bit)" + depends on AM33_2 || AM33_3 endchoice @@ -337,17 +374,33 @@ config MN10300_TTYSM2 choice prompt "Select the timer to supply the clock for SIF2" - default MN10300_TTYSM0_TIMER10 + default MN10300_TTYSM2_TIMER3 \ + if !(AM33_2 || AM33_3) + default MN10300_TTYSM2_TIMER10 \ + if AM33_2 || AM33_3 depends on MN10300_TTYSM2 +config MN10300_TTYSM2_TIMER9 + bool "Use timer 9 (16-bit)" + depends on !(AM33_2 || AM33_3) + +config MN10300_TTYSM2_TIMER1 + bool "Use timer 1 (8-bit)" + depends on !(AM33_2 || AM33_3) + +config MN10300_TTYSM2_TIMER3 + bool "Use timer 3 (8-bit)" + depends on !(AM33_2 || AM33_3) + config MN10300_TTYSM2_TIMER10 bool "Use timer 10 (16-bit)" + depends on AM33_2 || AM33_3 endchoice config MN10300_TTYSM2_CTS bool "Enable the use of the CTS line /dev/ttySM2" - depends on MN10300_TTYSM2 + depends on MN10300_TTYSM2 && AM33_2 endmenu diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index ac5c6bdb2f05..7120282bf0d8 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile @@ -36,6 +36,9 @@ endif ifeq ($(CONFIG_MN10300_PROC_MN103E010),y) PROCESSOR := mn103e010 endif +ifeq ($(CONFIG_MN10300_PROC_MN2WS0050),y) +PROCESSOR := mn2ws0050 +endif ifeq ($(CONFIG_MN10300_UNIT_ASB2303),y) UNIT := asb2303 @@ -43,6 +46,9 @@ endif ifeq ($(CONFIG_MN10300_UNIT_ASB2305),y) UNIT := asb2305 endif +ifeq ($(CONFIG_MN10300_UNIT_ASB2364),y) +UNIT := asb2364 +endif head-y := arch/mn10300/kernel/head.o arch/mn10300/kernel/init_task.o diff --git a/arch/mn10300/boot/compressed/head.S b/arch/mn10300/boot/compressed/head.S index 4ef608a62416..7b50345b9e84 100644 --- a/arch/mn10300/boot/compressed/head.S +++ b/arch/mn10300/boot/compressed/head.S @@ -15,10 +15,28 @@ #include <linux/linkage.h> #include <asm/cpu-regs.h> #include <asm/cache.h> +#ifdef CONFIG_SMP +#include <proc/smp-regs.h> +#endif .globl startup_32 startup_32: - # first save off parameters from bootloader +#ifdef CONFIG_SMP + # + # Secondary CPUs jump directly to the kernel entry point + # + # Must save primary CPU's D0-D2 registers as they hold boot parameters + # + mov (CPUID), d3 + and CPUID_MASK,d3 + beq startup_primary + mov CONFIG_KERNEL_TEXT_ADDRESS,a0 + jmp (a0) + +startup_primary: +#endif /* CONFIG_SMP */ + + # first save parameters from bootloader mov param_save_area,a0 mov d0,(a0) mov d1,(4,a0) diff --git a/arch/mn10300/include/asm/exceptions.h b/arch/mn10300/include/asm/exceptions.h index 7d8080bc6590..ca3e20508c77 100644 --- a/arch/mn10300/include/asm/exceptions.h +++ b/arch/mn10300/include/asm/exceptions.h @@ -114,6 +114,8 @@ extern void die(const char *, struct pt_regs *, enum exception_code) extern int die_if_no_fixup(const char *, struct pt_regs *, enum exception_code); +#define NUM2EXCEP_IRQ_LEVEL(num) (EXCEP_IRQ_LEVEL0 + (num) * 8) + #endif /* __ASSEMBLY__ */ #endif /* _ASM_EXCEPTIONS_H */ diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc index 5b1949bdf039..406060e5e1c0 100644 --- a/arch/mn10300/include/asm/frame.inc +++ b/arch/mn10300/include/asm/frame.inc @@ -18,6 +18,9 @@ #ifndef __ASM_OFFSETS_H__ #include <asm/asm-offsets.h> #endif +#ifdef CONFIG_SMP +#include <proc/smp-regs.h> +#endif #define pi break @@ -37,9 +40,25 @@ movm [d2,d3,a2,a3,exreg0,exreg1,exother],(sp) mov sp,fp # FRAME pointer in A3 add -12,sp # allow for calls to be made +#ifdef CONFIG_SMP +#ifdef CONFIG_PREEMPT /* FIXME */ + mov epsw,d2 + and ~EPSW_IE,epsw +#endif + mov (CPUID),a0 + add a0,a0 + add a0,a0 + mov (___frame,a0),a1 + mov a1,(REG_NEXT,fp) + mov fp,(___frame,a0) +#ifdef CONFIG_PREEMPT /* FIXME */ + mov d2,epsw +#endif +#else /* CONFIG_SMP */ mov (__frame),a1 mov a1,(REG_NEXT,fp) mov fp,(__frame) +#endif /* CONFIG_SMP */ and ~EPSW_FE,epsw # disable the FPU inside the kernel @@ -57,10 +76,27 @@ .macro RESTORE_ALL # peel back the stack to the calling frame # - this permits execve() to discard extra frames due to kernel syscalls +#ifdef CONFIG_SMP +#ifdef CONFIG_PREEMPT /* FIXME */ + mov epsw,d2 + and ~EPSW_IE,epsw +#endif + mov (CPUID),a0 + add a0,a0 + add a0,a0 + mov (___frame,a0),fp + mov fp,sp + mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 + mov d0,(___frame,a0) +#ifdef CONFIG_PREEMPT /* FIXME */ + mov d2,epsw +#endif +#else /* CONFIG_SMP */ mov (__frame),fp mov fp,sp mov (REG_NEXT,fp),d0 # userspace has regs->next == 0 mov d0,(__frame) +#endif /* CONFIG_SMP */ #ifndef CONFIG_MN10300_USING_JTAG mov (REG_EPSW,fp),d0 diff --git a/arch/mn10300/include/asm/hardirq.h b/arch/mn10300/include/asm/hardirq.h index 7bd9b7cc2451..0000d650b55f 100644 --- a/arch/mn10300/include/asm/hardirq.h +++ b/arch/mn10300/include/asm/hardirq.h @@ -19,8 +19,10 @@ /* assembly code in softirq.h is sensitive to the offsets of these fields */ typedef struct { unsigned int __softirq_pending; +#ifdef CONFIG_MN10300_WD_TIMER unsigned int __nmi_count; /* arch dependent */ unsigned int __irq_count; /* arch dependent */ +#endif } ____cacheline_aligned irq_cpustat_t; #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ diff --git a/arch/mn10300/include/asm/intctl-regs.h b/arch/mn10300/include/asm/intctl-regs.h index ba544c796c5a..585b708c2bc0 100644 --- a/arch/mn10300/include/asm/intctl-regs.h +++ b/arch/mn10300/include/asm/intctl-regs.h @@ -15,24 +15,19 @@ #ifdef __KERNEL__ -/* interrupt controller registers */ -#define GxICR(X) __SYSREG(0xd4000000 + (X) * 4, u16) /* group irq ctrl regs */ - -#define IAGR __SYSREG(0xd4000100, u16) /* intr acceptance group reg */ -#define IAGR_GN 0x00fc /* group number register - * (documentation _has_ to be wrong) - */ +/* + * Interrupt controller registers + * - Registers 64-191 are at addresses offset from the main array + */ +#define GxICR(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u16) -#define EXTMD __SYSREG(0xd4000200, u16) /* external pin intr spec reg */ -#define GET_XIRQ_TRIGGER(X) ((EXTMD >> ((X) * 2)) & 3) +#define GxICR_u8(X) \ + __SYSREG(0xd4000000 + (X) * 4 + \ + (((X) >= 64) && ((X) < 192)) * 0xf00, u8) -#define SET_XIRQ_TRIGGER(X,Y) \ -do { \ - u16 x = EXTMD; \ - x &= ~(3 << ((X) * 2)); \ - x |= ((Y) & 3) << ((X) * 2); \ - EXTMD = x; \ -} while (0) +#include <proc/intctl-regs.h> #define XIRQ_TRIGGER_LOWLEVEL 0 #define XIRQ_TRIGGER_HILEVEL 1 @@ -59,10 +54,18 @@ do { \ #define GxICR_LEVEL_5 0x5000 /* - level 5 */ #define GxICR_LEVEL_6 0x6000 /* - level 6 */ #define GxICR_LEVEL_SHIFT 12 +#define GxICR_NMI 0x8000 /* nmi request flag */ + +#define NUM2GxICR_LEVEL(num) ((num) << GxICR_LEVEL_SHIFT) #ifndef __ASSEMBLY__ extern void set_intr_level(int irq, u16 level); -extern void set_intr_postackable(int irq); +extern void mn10300_intc_set_level(unsigned int irq, unsigned int level); +extern void mn10300_intc_clear(unsigned int irq); +extern void mn10300_intc_set(unsigned int irq); +extern void mn10300_intc_enable(unsigned int irq); +extern void mn10300_intc_disable(unsigned int irq); +extern void mn10300_set_lateack_irq_type(int irq); #endif /* external interrupts */ diff --git a/arch/mn10300/include/asm/irq.h b/arch/mn10300/include/asm/irq.h index 25c045d16d1c..b7b8e175b167 100644 --- a/arch/mn10300/include/asm/irq.h +++ b/arch/mn10300/include/asm/irq.h @@ -22,7 +22,11 @@ #define NO_IRQ INT_MAX /* hardware irq numbers */ +#ifdef CONFIG_SMP +#define NR_IRQS GxICR_NUM_EXT_IRQS +#else #define NR_IRQS GxICR_NUM_IRQS +#endif /* external hardware irq numbers */ #define NR_XIRQS GxICR_NUM_XIRQS diff --git a/arch/mn10300/include/asm/irqflags.h b/arch/mn10300/include/asm/irqflags.h index b3ab2071354d..7a7ae12c7119 100644 --- a/arch/mn10300/include/asm/irqflags.h +++ b/arch/mn10300/include/asm/irqflags.h @@ -13,6 +13,9 @@ #define _ASM_IRQFLAGS_H #include <asm/cpu-regs.h> +#ifndef __ASSEMBLY__ +#include <linux/smp.h> +#endif /* * interrupt control @@ -60,11 +63,12 @@ static inline unsigned long arch_local_irq_save(void) /* * we make sure arch_irq_enable() doesn't cause priority inversion */ -extern unsigned long __mn10300_irq_enabled_epsw; +extern unsigned long __mn10300_irq_enabled_epsw[]; static inline void arch_local_irq_enable(void) { unsigned long tmp; + int cpu = raw_smp_processor_id(); asm volatile( " mov epsw,%0 \n" @@ -72,8 +76,8 @@ static inline void arch_local_irq_enable(void) " or %2,%0 \n" " mov %0,epsw \n" : "=&d"(tmp) - : "i"(~EPSW_IM), "r |