diff options
author | Patrick McHardy <kaber@trash.net> | 2011-01-19 23:51:37 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-01-19 23:51:37 +0100 |
commit | 14f0290ba44de6ed435fea24bba26e7868421c66 (patch) | |
tree | 449d32e4848007e3edbcab14fa8e09fdc66608ed /arch/m68k | |
parent | f5c88f56b35599ab9ff2d3398e0153e4cd4a4c82 (diff) | |
parent | a5db219f4cf9f67995eabd53b81a1232c82f5852 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Diffstat (limited to 'arch/m68k')
31 files changed, 660 insertions, 592 deletions
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S index 73613b5f1ee..26e85e2b7a5 100644 --- a/arch/m68k/ifpsp060/src/fpsp.S +++ b/arch/m68k/ifpsp060/src/fpsp.S @@ -3881,7 +3881,7 @@ _fpsp_fline: # FP Unimplemented Instruction stack frame and jump to that entry # point. # -# but, if the FPU is disabled, then we need to jump to the FPU diabled +# but, if the FPU is disabled, then we need to jump to the FPU disabled # entry point. movc %pcr,%d0 btst &0x1,%d0 diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h index 7085bd51668..cb88aa96c4f 100644 --- a/arch/m68k/include/asm/cacheflush_no.h +++ b/arch/m68k/include/asm/cacheflush_no.h @@ -2,21 +2,22 @@ #define _M68KNOMMU_CACHEFLUSH_H /* - * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com> + * (C) Copyright 2000-2010, Greg Ungerer <gerg@snapgear.com> */ #include <linux/mm.h> +#include <asm/mcfsim.h> #define flush_cache_all() __flush_cache_all() #define flush_cache_mm(mm) do { } while (0) #define flush_cache_dup_mm(mm) do { } while (0) -#define flush_cache_range(vma, start, end) __flush_cache_all() +#define flush_cache_range(vma, start, end) do { } while (0) #define flush_cache_page(vma, vmaddr) do { } while (0) -#define flush_dcache_range(start,len) __flush_cache_all() +#define flush_dcache_range(start, len) __flush_dcache_all() #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -#define flush_icache_range(start,len) __flush_cache_all() +#define flush_icache_range(start, len) __flush_icache_all() #define flush_icache_page(vma,pg) do { } while (0) #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) #define flush_cache_vmap(start, end) do { } while (0) @@ -27,66 +28,52 @@ #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ memcpy(dst, src, len) +void mcf_cache_push(void); + static inline void __flush_cache_all(void) { -#if defined(CONFIG_M5407) || defined(CONFIG_M548x) - /* - * Use cpushl to push and invalidate all cache lines. - * Gas doesn't seem to know how to generate the ColdFire - * cpushl instruction... Oh well, bit stuff it for now. - */ - __asm__ __volatile__ ( - "nop\n\t" - "clrl %%d0\n\t" - "1:\n\t" - "movel %%d0,%%a0\n\t" - "2:\n\t" - ".word 0xf468\n\t" - "addl #0x10,%%a0\n\t" - "cmpl #0x00000800,%%a0\n\t" - "blt 2b\n\t" - "addql #1,%%d0\n\t" - "cmpil #4,%%d0\n\t" - "bne 1b\n\t" - "movel #0xb6088500,%%d0\n\t" - "movec %%d0,%%CACR\n\t" - : : : "d0", "a0" ); -#endif /* CONFIG_M5407 */ -#if defined(CONFIG_M523x) || defined(CONFIG_M527x) - __asm__ __volatile__ ( - "movel #0x81400100, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M523x || CONFIG_M527x */ -#if defined(CONFIG_M528x) - __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M528x */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) +#ifdef CACHE_PUSH + mcf_cache_push(); +#endif +#ifdef CACHE_INVALIDATE __asm__ __volatile__ ( - "movel #0x81000100, %%d0\n\t" + "movel %0, %%d0\n\t" "movec %%d0, %%CACR\n\t" "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ -#ifdef CONFIG_M5249 + : : "i" (CACHE_INVALIDATE) : "d0" ); +#endif +} + +/* + * Some ColdFire parts implement separate instruction and data caches, + * on those we should just flush the appropriate cache. If we don't need + * to do any specific flushing then this will be optimized away. + */ +static inline void __flush_icache_all(void) +{ +#ifdef CACHE_INVALIDATEI __asm__ __volatile__ ( - "movel #0xa1000200, %%d0\n\t" + "movel %0, %%d0\n\t" "movec %%d0, %%CACR\n\t" "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M5249 */ -#ifdef CONFIG_M532x + : : "i" (CACHE_INVALIDATEI) : "d0" ); +#endif +} + +static inline void __flush_dcache_all(void) +{ +#ifdef CACHE_PUSH + mcf_cache_push(); +#endif +#ifdef CACHE_INVALIDATED __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" + "movel %0, %%d0\n\t" "movec %%d0, %%CACR\n\t" "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M532x */ + : : "i" (CACHE_INVALIDATED) : "d0" ); +#else + /* Flush the wrtite buffer */ + __asm__ __volatile__ ( "nop" ); +#endif } - #endif /* _M68KNOMMU_CACHEFLUSH_H */ diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h index 3b0a34d0fe3..213028cbe11 100644 --- a/arch/m68k/include/asm/coldfire.h +++ b/arch/m68k/include/asm/coldfire.h @@ -32,7 +32,7 @@ */ #define MCF_MBAR 0x10000000 #define MCF_MBAR2 0x80000000 -#if defined(CONFIG_M548x) +#if defined(CONFIG_M54xx) #define MCF_IPSBAR MCF_MBAR #elif defined(CONFIG_M520x) #define MCF_IPSBAR 0xFC000000 diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h index 26be277394f..627d69bacc5 100644 --- a/arch/m68k/include/asm/entry_no.h +++ b/arch/m68k/include/asm/entry_no.h @@ -42,12 +42,16 @@ */ #ifdef CONFIG_COLDFIRE +#ifdef CONFIG_COLDFIRE_SW_A7 /* - * This is made a little more tricky on the ColdFire. There is no - * separate kernel and user stack pointers. Need to artificially + * This is made a little more tricky on older ColdFires. There is no + * separate supervisor and user stack pointers. Need to artificially * construct a usp in software... When doing this we need to disable - * interrupts, otherwise bad things could happen. + * interrupts, otherwise bad things will happen. */ +.globl sw_usp +.globl sw_ksp + .macro SAVE_ALL move #0x2700,%sr /* disable intrs */ btst #5,%sp@(2) /* from user? */ @@ -74,9 +78,7 @@ 7: .endm -.macro RESTORE_ALL - btst #5,%sp@(PT_SR) /* going user? */ - bnes 8f /* no, skip */ +.macro RESTORE_USER move #0x2700,%sr /* disable intrs */ movel sw_usp,%a0 /* get usp */ movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ @@ -91,19 +93,22 @@ subql #8,sw_usp /* set exception */ movel sw_usp,%sp /* restore usp */ rte - 8: - moveml %sp@,%d1-%d5/%a0-%a2 - lea %sp@(32),%sp /* space for 8 regs */ - movel %sp@+,%d0 - addql #4,%sp /* orig d0 */ - addl %sp@+,%sp /* stkadj */ - rte .endm +.macro RDUSP + movel sw_usp,%a2 +.endm + +.macro WRUSP + movel %a0,sw_usp +.endm + +#else /* !CONFIG_COLDFIRE_SW_A7 */ /* - * Quick exception save, use current stack only. + * Modern ColdFire parts have separate supervisor and user stack + * pointers. Simple load and restore macros for this case. */ -.macro SAVE_LOCAL +.macro SAVE_ALL move #0x2700,%sr /* disable intrs */ clrl %sp@- /* stkadj */ movel %d0,%sp@- /* orig d0 */ @@ -112,7 +117,7 @@ moveml %d1-%d5/%a0-%a2,%sp@ .endm -.macro RESTORE_LOCAL +.macro RESTORE_USER moveml %sp@,%d1-%d5/%a0-%a2 lea %sp@(32),%sp /* space for 8 regs */ movel %sp@+,%d0 @@ -121,6 +126,18 @@ rte .endm +.macro RDUSP + /*move %usp,%a2*/ + .word 0x4e6a +.endm + +.macro WRUSP + /*move %a0,%usp*/ + .word 0x4e60 +.endm + +#endif /* !CONFIG_COLDFIRE_SW_A7 */ + .macro SAVE_SWITCH_STACK lea %sp@(-24),%sp /* 6 regs */ moveml %a3-%a6/%d6-%d7,%sp@ @@ -131,14 +148,6 @@ lea %sp@(24),%sp /* 6 regs */ .endm -/* - * Software copy of the user and kernel stack pointers... Ugh... - * Need these to get around ColdFire not having separate kernel - * and user stack pointers. - */ -.globl sw_usp -.globl sw_ksp - #else /* !CONFIG_COLDFIRE */ /* @@ -167,6 +176,6 @@ moveml %sp@+,%a3-%a6/%d6-%d7 .endm -#endif /* !CONFIG_COLDFIRE */ +#endif /* !COLDFIRE_SW_A7 */ #endif /* __ASSEMBLY__ */ #endif /* __M68KNOMMU_ENTRY_H */ diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index 1b57adbafad..c64c7b74cf8 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -37,7 +37,7 @@ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M532x) || defined(CONFIG_M548x) + defined(CONFIG_M532x) || defined(CONFIG_M54xx) /* These parts have GPIO organized by 8 bit ports */ diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 6e2413e518c..cf20f3097af 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -145,7 +145,6 @@ static inline void io_insl(unsigned int addr, void *buf, int len) #define IOMAP_WRITETHROUGH 3 extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); -extern void __iounmap(void *addr, unsigned long size); static inline void *ioremap(unsigned long physaddr, unsigned long size) { diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index 9c384e294af..561b03b5ddf 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -12,6 +12,10 @@ #define m5206sim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m5206)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> /* * Define the 5206 SIM register set addresses. @@ -88,6 +92,14 @@ #define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */ #define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */ +#if defined(CONFIG_NETtel) +#define MCFUART_BASE1 0x180 /* Base address of UART1 */ +#define MCFUART_BASE2 0x140 /* Base address of UART2 */ +#else +#define MCFUART_BASE1 0x140 /* Base address of UART1 */ +#define MCFUART_BASE2 0x180 /* Base address of UART2 */ +#endif + /* * Define system peripheral IRQ usage. */ @@ -95,7 +107,7 @@ #define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ /* - * Generic GPIO + * Generic GPIO */ #define MCFGPIO_PIN_MAX 8 #define MCFGPIO_IRQ_VECBASE -1 diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index db824a4b136..88ed8239fe4 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -11,6 +11,11 @@ #define m520xsim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m520x)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> + /* * Define the 520x SIM register set addresses. */ @@ -54,6 +59,9 @@ #define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */ #define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */ +/* + * EPORT and GPIO registers. + */ #define MCFEPORT_EPDDR 0xFC088002 #define MCFEPORT_EPDR 0xFC088004 #define MCFEPORT_EPPDR 0xFC088005 @@ -97,6 +105,7 @@ #define MCFGPIO_PCLRR_UART 0xFC0A402A #define MCFGPIO_PCLRR_FECH 0xFC0A402B #define MCFGPIO_PCLRR_FECL 0xFC0A402C + /* * Generic GPIO support */ @@ -109,7 +118,6 @@ #define MCFGPIO_PIN_MAX 80 #define MCFGPIO_IRQ_MAX 8 #define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE -/****************************************************************************/ #define MCF_GPIO_PAR_UART (0xA4036) #define MCF_GPIO_PAR_FECI2C (0xA4033) @@ -126,6 +134,13 @@ #define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) /* + * UART module. + */ +#define MCFUART_BASE1 0x60000 /* Base address of UART1 */ +#define MCFUART_BASE2 0x64000 /* Base address of UART2 */ +#define MCFUART_BASE3 0x68000 /* Base address of UART2 */ + +/* * Reset Controll Unit. */ #define MCF_RCR 0xFC0A0000 diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index e8d06b24a48..4ad7a00257a 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -11,6 +11,10 @@ #define m523xsim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m523x)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> /* * Define the 523x SIM register set addresses. @@ -50,6 +54,13 @@ #define MCF_RCR_SWRESET 0x80 /* Software reset bit */ #define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ +/* + * UART module. + */ +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x240 /* Base address of UART2 */ +#define MCFUART_BASE3 0x280 /* Base address of UART3 */ + #define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) #define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001) #define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002) diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h index 79b7b402f3c..4908b118f2f 100644 --- a/arch/m68k/include/asm/m5249sim.h +++ b/arch/m68k/include/asm/m5249sim.h @@ -11,6 +11,11 @@ #define m5249sim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m5249)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> + /* * Define the 5249 SIM register set addresses. */ @@ -56,6 +61,11 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ +/* + * UART module. + */ +#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ +#define MCFUART_BASE2 0x200 /* Base address of UART2 */ /* * Some symbol defines for the above... diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index df3332c2317..b7cc50abc83 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -12,6 +12,11 @@ #define m5272sim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m5272)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> + /* * Define the 5272 SIM register set addresses. */ @@ -62,6 +67,9 @@ #define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */ #define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */ +#define MCFUART_BASE1 0x100 /* Base address of UART1 */ +#define MCFUART_BASE2 0x140 /* Base address of UART2 */ + #define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */ #define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */ #define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */ diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 1feb46f108c..e8042e8bc00 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -11,6 +11,10 @@ #define m527xsim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m527x)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> /* * Define the 5270/5271 SIM register set addresses. @@ -55,6 +59,12 @@ #define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */ #endif +/* + * UART module. + */ +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x240 /* Base address of UART2 */ +#define MCFUART_BASE3 0x280 /* Base address of UART3 */ #ifdef CONFIG_M5271 #define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000) diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index 891cbedad97..a6d2f4d9aaa 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -11,6 +11,10 @@ #define m528xsim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m528x)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m52xxacr.h> /* * Define the 5280/5282 SIM register set addresses. @@ -42,6 +46,13 @@ #define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ /* + * UART module. + */ +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x240 /* Base address of UART2 */ +#define MCFUART_BASE3 0x280 /* Base address of UART3 */ + +/* * GPIO registers */ #define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000) diff --git a/arch/m68k/include/asm/m52xxacr.h b/arch/m68k/include/asm/m52xxacr.h new file mode 100644 index 00000000000..abc391a9ae8 --- /dev/null +++ b/arch/m68k/include/asm/m52xxacr.h @@ -0,0 +1,94 @@ +/****************************************************************************/ + +/* + * m52xxacr.h -- ColdFire version 2 core cache support + * + * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com> + */ + +/****************************************************************************/ +#ifndef m52xxacr_h +#define m52xxacr_h +/****************************************************************************/ + +/* + * All varients of the ColdFire using version 2 cores have a similar + * cache setup. Although not absolutely identical the cache register + * definitions are compatible for all of them. Mostly they support a + * configurable cache memory that can be instruction only, data only, + * or split instruction and data. The exception is the very old version 2 + * core based parts, like the 5206(e), 5249 and 5272, which are instruction + * cache only. Cache size varies from 2k up to 16k. + */ + +/* + * Define the Cache Control register flags. + */ +#define CACR_CENB 0x80000000 /* Enable cache */ +#define CACR_CDPI 0x10000000 /* Disable invalidation by CPUSHL */ +#define CACR_CFRZ 0x08000000 /* Cache freeze mode */ +#define CACR_CINV 0x01000000 /* Invalidate cache */ +#define CACR_DISI 0x00800000 /* Disable instruction cache */ +#define CACR_DISD 0x00400000 /* Disable data cache */ +#define CACR_INVI 0x00200000 /* Invalidate instruction cache */ +#define CACR_INVD 0x00100000 /* Invalidate data cache */ +#define CACR_CEIB 0x00000400 /* Non-cachable instruction burst */ +#define CACR_DCM 0x00000200 /* Default cache mode */ +#define CACR_DBWE 0x00000100 /* Buffered write enable */ +#define CACR_DWP 0x00000020 /* Write protection */ +#define CACR_EUSP 0x00000010 /* Enable separate user a7 */ + +/* + * Define the Access Control register flags. + */ +#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */ +#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */ +#define ACR_ENABLE 0x00008000 /* Enable this ACR */ +#define ACR_USER 0x00000000 /* Allow only user accesses */ +#define ACR_SUPER 0x00002000 /* Allow supervisor access only */ +#define ACR_ANY 0x00004000 /* Allow any access type */ +#define ACR_CENB 0x00000000 /* Caching of region enabled */ +#define ACR_CDIS 0x00000040 /* Caching of region disabled */ +#define ACR_BWE 0x00000020 /* Write buffer enabled */ +#define ACR_WPROTECT 0x00000004 /* Write protect region */ + +/* + * Set the cache controller settings we will use. On the cores that support + * a split cache configuration we allow all the combinations at Kconfig + * time. For those cores that only have an instruction cache we just set + * that as on. + */ +#if defined(CONFIG_CACHE_I) +#define CACHE_TYPE (CACR_DISD + CACR_EUSP) +#define CACHE_INVTYPEI 0 +#elif defined(CONFIG_CACHE_D) +#define CACHE_TYPE (CACR_DISI + CACR_EUSP) +#define CACHE_INVTYPED 0 +#elif defined(CONFIG_CACHE_BOTH) +#define CACHE_TYPE CACR_EUSP +#define CACHE_INVTYPEI CACR_INVI +#define CACHE_INVTYPED CACR_INVD +#else +/* This is the instruction cache only devices (no split cache, no eusp) */ +#define CACHE_TYPE 0 +#define CACHE_INVTYPEI 0 +#endif + +#define CACHE_INIT (CACR_CINV + CACHE_TYPE) +#define CACHE_MODE (CACR_CENB + CACHE_TYPE + CACR_DCM) + +#define CACHE_INVALIDATE (CACHE_MODE + CACR_CINV) +#if defined(CACHE_INVTYPEI) +#define CACHE_INVALIDATEI (CACHE_MODE + CACR_CINV + CACHE_INVTYPEI) +#endif +#if defined(CACHE_INVTYPED) +#define CACHE_INVALIDATED (CACHE_MODE + CACR_CINV + CACHE_INVTYPED) +#endif + +#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \ + (0x000f0000) + \ + (ACR_ENABLE + ACR_ANY + ACR_CENB + ACR_BWE)) +#define ACR1_MODE 0 + +/****************************************************************************/ +#endif /* m52xxsim_h */ diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index c6830e5b54c..0bf57397e7a 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -14,6 +14,11 @@ #define m5307sim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m5307)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m53xxacr.h> + /* * Define the 5307 SIM register set addresses. */ @@ -94,6 +99,17 @@ #define MCFSIM_PADAT (MCF_MBAR + 0x248) /* + * UART module. + */ +#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */ +#else +#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ +#define MCFUART_BASE2 0x200 /* Base address of UART2 */ +#endif + +/* * Generic GPIO support */ #define MCFGPIO_PIN_MAX 16 @@ -146,32 +162,5 @@ #define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ #define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ -/* - * Define the Cache register flags. - */ -#define CACR_EC (1<<31) -#define CACR_ESB (1<<29) -#define CACR_DPI (1<<28) -#define CACR_HLCK (1<<27) -#define CACR_CINVA (1<<24) -#define CACR_DNFB (1<<10) -#define CACR_DCM_WTHRU (0<<8) -#define CACR_DCM_WBACK (1<<8) -#define CACR_DCM_OFF_PRE (2<<8) -#define CACR_DCM_OFF_IMP (3<<8) -#define CACR_DW (1<<5) - -#define ACR_BASE_POS 24 -#define ACR_MASK_POS 16 -#define ACR_ENABLE (1<<15) -#define ACR_USER (0<<13) -#define ACR_SUPER (1<<13) -#define ACR_ANY (2<<13) -#define ACR_CM_WTHRU (0<<5) -#define ACR_CM_WBACK (1<<5) -#define ACR_CM_OFF_PRE (2<<5) -#define ACR_CM_OFF_IMP (3<<5) -#define ACR_WPROTECT (1<<2) - /****************************************************************************/ #endif /* m5307sim_h */ diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index c4bf1c81e3c..e6470f8ca32 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -9,6 +9,11 @@ #define m532xsim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m532x)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m53xxacr.h> + #define MCF_REG32(x) (*(volatile unsigned long *)(x)) #define MCF_REG16(x) (*(volatile unsigned short *)(x)) #define MCF_REG08(x) (*(volatile unsigned char *)(x)) @@ -74,31 +79,11 @@ #define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */ /* - * Define the Cache register flags. + * UART module. */ -#define CACR_EC (1<<31) -#define CACR_ESB (1<<29) -#define CACR_DPI (1<<28) -#define CACR_HLCK (1<<27) -#define CACR_CINVA (1<<24) -#define CACR_DNFB (1<<10) -#define CACR_DCM_WTHRU (0<<8) -#define CACR_DCM_WBACK (1<<8) -#define CACR_DCM_OFF_PRE (2<<8) -#define CACR_DCM_OFF_IMP (3<<8) -#define CACR_DW (1<<5) - -#define ACR_BASE_POS 24 -#define ACR_MASK_POS 16 -#define ACR_ENABLE (1<<15) -#define ACR_USER (0<<13) -#define ACR_SUPER (1<<13) -#define ACR_ANY (2<<13) -#define ACR_CM_WTHRU (0<<5) -#define ACR_CM_WBACK (1<<5) -#define ACR_CM_OFF_PRE (2<<5) -#define ACR_CM_OFF_IMP (3<<5) -#define ACR_WPROTECT (1<<2) +#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */ +#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */ +#define MCFUART_BASE3 0xFC068000 /* Base address of UART3 */ /********************************************************************* * diff --git a/arch/m68k/include/asm/m53xxacr.h b/arch/m68k/include/asm/m53xxacr.h new file mode 100644 index 00000000000..cd952b0a8bd --- /dev/null +++ b/arch/m68k/include/asm/m53xxacr.h @@ -0,0 +1,101 @@ +/****************************************************************************/ + +/* + * m53xxacr.h -- ColdFire version 3 core cache support + * + * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com> + */ + +/****************************************************************************/ +#ifndef m53xxacr_h +#define m53xxacr_h +/****************************************************************************/ + +/* + * All varients of the ColdFire using version 3 cores have a similar + * cache setup. They have a unified instruction and data cache, with + * configurable write-through or copy-back operation. + */ + +/* + * Define the Cache Control register flags. + */ +#define CACR_EC 0x80000000 /* Enable cache */ +#define CACR_ESB 0x20000000 /* Enable store buffer */ +#define CACR_DPI 0x10000000 /* Disable invalidation by CPUSHL */ +#define CACR_HLCK 0x08000000 /* Half cache lock mode */ +#define CACR_CINVA 0x01000000 /* Invalidate cache */ +#define CACR_DNFB 0x00000400 /* Inhibited fill buffer */ +#define CACR_DCM_WT 0x00000000 /* Cacheable write-through */ +#define CACR_DCM_CB 0x00000100 /* Cacheable copy-back */ +#define CACR_DCM_PRE 0x00000200 /* Cache inhibited, precise */ +#define CACR_DCM_IMPRE 0x00000300 /* Cache inhibited, imprecise */ +#define CACR_WPROTECT 0x00000020 /* Write protect*/ +#define CACR_EUSP 0x00000010 /* Eanble separate user a7 */ + +/* + * Define the Access Control register flags. + */ +#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */ +#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */ +#define ACR_ENABLE 0x00008000 /* Enable this ACR */ +#define ACR_USER 0x00000000 /* Allow only user accesses */ +#define ACR_SUPER 0x00002000 /* Allow supervisor access only */ +#define ACR_ANY 0x00004000 /* Allow any access type */ +#define ACR_CM_WT 0x00000000 /* Cacheable, write-through */ +#define ACR_CM_CB 0x00000020 /* Cacheable, copy-back */ +#define ACR_CM_PRE 0x00000040 /* Cache inhibited, precise */ +#define ACR_CM_IMPRE 0x00000060 /* Cache inhibited, imprecise */ +#define ACR_WPROTECT 0x00000004 /* Write protect region */ + +/* + * Define the cache type and arrangement (needed for pushes). + */ +#if defined(CONFIG_M5307) +#define CACHE_SIZE 0x2000 /* 8k of unified cache */ +#define ICACHE_SIZE CACHE_SIZE +#define DCACHE_SIZE CACHE_SIZE +#elif defined(CONFIG_M532x) +#define CACHE_SIZE 0x4000 /* 32k of unified cache */ +#define ICACHE_SIZE CACHE_SIZE +#define DCACHE_SIZE CACHE_SIZE +#endif + +#define CACHE_LINE_SIZE 16 /* 16 byte line size */ +#define CACHE_WAYS 4 /* 4 ways - set associative */ + +/* + * Set the cache controller settings we will use. This default in the + * CACR is cache inhibited, we use the ACR register to set cacheing + * enabled on the regions we want (eg RAM). + */ +#if defined(CONFIG_CACHE_COPYBACK) +#define CACHE_TYPE ACR_CM_CB +#define CACHE_PUSH +#else +#define CACHE_TYPE ACR_CM_WT +#endif + +#ifdef CONFIG_COLDFIRE_SW_A7 +#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE) +#else +#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE + CACR_EUSP) +#endif + +/* + * Unified cache means we will never need to flush for coherency of + * instruction fetch. We will need to flush to maintain memory/DMA + * coherency though in all cases. And for copyback caches we will need + * to push cached data as well. + */ +#define CACHE_INIT CACR_CINVA +#define CACHE_INVALIDATE CACR_CINVA +#define CACHE_INVALIDATED CACR_CINVA + +#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \ + (0x000f0000) + \ + (ACR_ENABLE + ACR_ANY + CACHE_TYPE)) +#define ACR1_MODE 0 + +/****************************************************************************/ +#endif /* m53xxsim_h */ diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index c399abbf953..75f5c28a551 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -14,6 +14,11 @@ #define m5407sim_h /****************************************************************************/ +#define CPU_NAME "COLDFIRE(m5407)" +#define CPU_INSTR_PER_JIFFY 3 + +#include <asm/m54xxacr.h> + /* * Define the 5407 SIM register set addresses. */ @@ -73,6 +78,9 @@ #define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ #define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ +#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ +#define MCFUART_BASE2 0x200 /* Base address of UART2 */ + #define MCFSIM_PADDR (MCF_MBAR + 0x244) #define MCFSIM_PADAT (MCF_MBAR + 0x248) @@ -117,39 +125,5 @@ #define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ #define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ -/* - * Define the Cache register flags. - */ -#define CACR_DEC 0x80000000 /* Enable data cache */ -#define CACR_DWP 0x40000000 /* Data write protection */ -#define CACR_DESB 0x20000000 /* Enable data store buffer */ -#define CACR_DDPI 0x10000000 /* Disable CPUSHL */ -#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */ -#define CACR_DDCM_WT 0x00000000 /* Write through cache*/ -#define CACR_DDCM_CP 0x02000000 /* Copyback cache */ -#define CACR_DDCM_P 0x04000000 /* No cache, precise */ -#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */ -#define CACR_DCINVA 0x01000000 /* Invalidate data cache */ -#define CACR_BEC 0x00080000 /* Enable branch cache */ -#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */ -#define CACR_IEC 0x00008000 /* Enable instruction cache */ -#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */ -#define CACR_IDPI 0x00001000 /* Disable CPUSHL */ -#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */ -#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */ -#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */ - -#define ACR_BASE_POS 24 /* Address Base */ -#define ACR_MASK_POS 16 /* Address Mask */ -#define ACR_ENABLE 0x00008000 /* Enable address */ -#define ACR_USER 0x00000000 /* User mode access only */ -#define ACR_SUPER 0x00002000 /* Supervisor mode only */ -#define ACR_ANY 0x00004000 /* Match any access mode */ -#define ACR_CM_WT 0x00000000 /* Write through mode */ -#define ACR_CM_CP 0x00000020 /* Copyback mode */ -#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */ -#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */ -#define ACR_WPROTECT 0x00000004 /* Write protect */ - /****************************************************************************/ #endif /* m5407sim_h */ diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h new file mode 100644 index 00000000000..16a1835f9b2 --- /dev/null +++ b/arch/m68k/include/asm/m54xxacr.h @@ -0,0 +1,97 @@ +/* + * Bit definitions for the MCF54xx ACR and CACR registers. + */ + +#ifndef m54xxacr_h +#define m54xxacr_h + +/* + * Define the Cache register flags. + */ +#define CACR_DEC 0x80000000 /* Enable data cache */ +#define CACR_DWP 0x40000000 /* Data write protection */ +#define CACR_DESB 0x20000000 /* Enable data store buffer */ +#define CACR_DDPI 0x10000000 /* Disable invalidation by CPUSHL */ +#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */ +#define CACR_DDCM_WT 0x00000000 /* Write through cache*/ +#define CACR_DDCM_CP 0x02000000 /* Copyback cache */ +#define CACR_DDCM_P 0x04000000 /* No cache, precise */ +#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */ +#define CACR_DCINVA 0x01000000 /* Invalidate data cache */ +#define CACR_BEC 0x00080000 /* Enable branch cache */ +#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */ +#define CACR_IEC 0x00008000 /* Enable instruction cache */ +#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */ +#define CACR_IDPI 0x00001000 /* Disable CPUSHL */ +#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */ +#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */ +#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */ +#define CACR_EUSP 0x00000020 /* Enable separate user a7 */ + +#define ACR_BASE_POS 24 /* Address Base */ +#define ACR_MASK_POS 16 /* Address Mask */ +#define ACR_ENABLE 0x00008000 /* Enable address */ +#define ACR_USER 0x00000000 /* User mode access only */ +#define ACR_SUPER 0x00002000 /* Supervisor mode only */ +#define ACR_ANY 0x00004000 /* Match any access mode */ +#define ACR_CM_WT 0x00000000 /* Write through mode */ +#define ACR_CM_CP 0x00000020 /* Copyback mode */ +#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */ +#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */ +#define ACR_CM 0x00000060 /* Cache mode mask */ +#define ACR_WPROTECT 0x00000004 /* Write protect */ + +#if defined(CONFIG_M5407) + +#define ICACHE_SIZE 0x4000 /* instruction - 16k */ +#define DCACHE_SIZE 0x2000 /* data - 8k */ + +#elif defined(CONFIG_M54xx) + +#define ICACHE_SIZE 0x8000 /* instruction - 32k */ +#define DCACHE_SIZE 0x8000 /* data - 32k */ + +#endif + +#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */ +#define CACHE_WAYS 4 /* 4 ways */ + +/* + * Version 4 cores have a true harvard style separate instruction + * and data cache. Enable data and instruction caches, also enable write + * buffers and branch accelerator. + */ +/* attention : enabling CACR_DESB requires a "nop" to flush the store buffer */ +/* use '+' instead of '|' for assembler's sake */ + + /* Enable data cache */ + /* Enable data store buffer */ + /* outside ACRs : No cache, precise */ + /* Enable instruction+branch caches */ +#if defined(CONFIG_M5407) +#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC) +#else +#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC+CACR_EUSP) +#endif +#if defined(CONFIG_CACHE_COPYBACK) +#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_CP) +#else +#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_WT) +#endif +#define INSN_CACHE_MODE (ACR_ENABLE+ACR_ANY) + +#define CACHE_INIT (CACR_DCINVA+CACR_BCINVA+CACR_ICINVA) +#define CACHE_INVALIDATE (CACHE_MODE+CACR_DCINVA+CACR_BCINVA+CACR_ICINVA) +#define CACHE_INVALIDATEI (CACHE_MODE+CACR_BCINVA+CACR_ICINVA) +#define CACHE_INVALIDATED (CACHE_MODE+CACR_DCINVA) +#define ACR0_MODE (0x000f0000+DATA_CACHE_MODE) +#define ACR1_MODE 0 +#define ACR2_MODE (0x000f0000+INSN_CACHE_MODE) +#define ACR3_MODE 0 + +#if ((DATA_CACHE_MODE & ACR_CM) == ACR_CM_CP) +/* Copyback cache mode must push dirty cache lines first */ +#define CACHE_PUSH +#endif + +#endif /* m54xxacr_h */ diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m54xxgpt.h index c8ef158a1c4..df75dd87ae7 100644 --- a/arch/m68k/include/asm/m548xgpt.h +++ b/arch/m68k/include/asm/m54xxgpt.h @@ -1,13 +1,13 @@ /* - * File: m548xgpt.h - * Purpose: Register and bit definitions for the MCF548X + * File: m54xxgpt.h + * Purpose: Register and bit definitions for the MCF54XX * * Notes: * */ -#ifndef m548xgpt_h -#define m548xgpt_h +#ifndef m54xxgpt_h +#define m54xxgpt_h /********************************************************************* * @@ -59,11 +59,13 @@ #define MCF_GPT_GMS_GPIO_INPUT (0x00000000) #define MCF_GPT_GMS_GPIO_OUTLO (0x00000020) #define MCF_GPT_GMS_GPIO_OUTHI (0x00000030) +#define MCF_GPT_GMS_GPIO_MASK (0x00000030) #define MCF_GPT_GMS_TMS_DISABLE (0x00000000) #define MCF_GPT_GMS_TMS_INCAPT (0x00000001) #define MCF_GPT_GMS_TMS_OUTCAPT (0x00000002) #define MCF_GPT_GMS_TMS_PWM (0x00000003) #define MCF_GPT_GMS_TMS_GPIO (0x00000004) +#define MCF_GPT_GMS_TMS_MASK (0x00000007) /* Bit definitions and macros for MCF_GPT_GCIR */ #define MCF_GPT_GCIR_CNT(x) (((x)&0x0000FFFF)<<0) @@ -85,4 +87,4 @@ /********************************************************************/ -#endif /* m548xgpt_h */ +#endif /* m54xxgpt_h */ diff --git a/arch/m68k/include/asm/m548xsim.h b/arch/m68k/include/asm/m54xxsim.h index 149135ef30d..462ae532844 100644 --- a/arch/m68k/include/asm/m548xsim.h +++ b/arch/m68k/include/asm/m54xxsim.h @@ -1,11 +1,16 @@ /* - * m548xsim.h -- ColdFire 547x/548x System Integration Unit support. + * m54xxsim.h -- ColdFire 547x/548x System Integration Unit support. */ -#ifndef m548xsim_h -#define m548xsim_h +#ifndef m54xxsim_h +#define m54xxsim_h -#define MCFINT_VECBASE 64 +#define CPU_NAME "COLDFIRE(m54xx)" +#define CPU_INSTR_PER_JIFFY 2 + +#include <asm/m54xxacr.h> + +#define MCFINT_VECBASE 64 /* * Interrupt Controller Registers @@ -22,6 +27,14 @@ #define MCFINTC_ICR0 0x40 /* Base ICR register */ /* + * UART module. + */ +#define MCFUART_BASE1 0x8600 /* Base address of UART1 */ +#define MCFUART_BASE2 0x8700 /* Base address of UART2 */ +#define MCFUART_BASE3 0x8800 /* Base address of UART3 */ +#define MCFUART_BASE4 0x8900 /* Base address of UART4 */ + +/* * Define system peripheral IRQ usage. */ #define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */ @@ -52,4 +65,4 @@ #define MCF_PAR_PSC_RTS_RTS (0x30) #define MCF_PAR_PSC_CANRX (0x40) -#endif /* m548xsim_h */ +#endif /* m54xxsim_h */ diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h deleted file mode 100644 index f49dfc09f70..00000000000 --- a/arch/m68k/include/asm/mcfcache.h +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************/ - -/* - * mcfcache.h -- ColdFire CPU cache support code - * - * (C) Copyright 2004, Greg Ungerer <gerg@snapgear.com> - */ - -/****************************************************************************/ -#ifndef __M68KNOMMU_MCFCACHE_H -#define __M68KNOMMU_MCFCACHE_H -/****************************************************************************/ - - -/* - * The different ColdFire families have different cache arrangments. - * Everything from a small instruction only cache, to configurable - * data and/or instruction cache, to unified instruction/data, to - * harvard style separate instruction and data caches. - */ - -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) -/* - * Simple version 2 core cache. These have instruction cache only, - * we just need to invalidate it and enable it. - */ -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate cache cmd */ - movec %d0,%CACR /* do invalidate cache */ - movel #0x80000100,%d0 /* setup cache mask */ - movec %d0,%CACR /* enable cache */ -.endm -#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ - -#if defined(CONFIG_M523x) || defined(CONFIG_M527x) -/* - * New version 2 cores have a configurable split cache arrangement. - * For now I am just enabling instruction cache - but ultimately I - * think a split instruction/data cache would be better. - */ -.macro CACHE_ENABLE - movel #0x01400000,%d0 - movec %d0,%CACR /* invalidate cache */ - nop - movel #0x0000c000,%d0 /* set SDRAM cached only */ - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0x80400100,%d0 /* configure cache */ - movec %d0,%CACR /* enable cache */ - nop -.endm -#endif /* CONFIG_M523x || CONFIG_M527x */ - -#if defined(CONFIG_M528x) -.macro CACHE_ENABLE - nop - movel #0x01000000, %d0 - movec %d0, %CACR /* Invalidate cache */ - nop - movel #0x0000c020, %d0 /* Set SDRAM cached only */ - movec %d0, %ACR0 - movel #0x00000000, %d0 /* No other regions cached */ - movec %d0, %ACR1 - movel #0x80000200, %d0 /* Setup cache mask */ - movec %d0, %CACR /* Enable cache */ - nop -.endm -#endif /* CONFIG_M528x */ - -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) -/* - * The version 3 core cache. Oddly enough the version 2 core 5249 - * has the same SDRAM and cache setup as the version 3 cores. - * This is a single unified instruction/data cache. - */ -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop -#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3) - movel #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ -#else - movel #0x0000c020,%d0 /* set SDRAM cached (copyback) */ -#endif - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0xa0000200,%d0 /* enable cache */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M5249 || CONFIG_M5307 */ - -#if defined(CONFIG_M532x) -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate cache cmd */ - movec %d0,%CACR /* do invalidate cache */ - nop - movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */ - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0x80000200,%d0 /* setup cache mask */ - movec %d0,%CACR /* enable cache */ - nop -.endm -#endif /* CONFIG_M532x */ - -#if defined(CONFIG_M5407) || defined(CONFIG_M548x) -/* - * Version 4 cores have a true harvard style separate instruction - * and data cache. Invalidate and enable cache, also enable write - * buffers and branch accelerator. - */ -.macro CACHE_ENABLE - movel #0x01040100,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop - movel #0x000fc000,%d0 /* set SDRAM cached only */ - movec %d0, %ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0, %ACR1 - movel #0x000fc000,%d0 /* set SDRAM cached only */ - movec %d0, %ACR2 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0, %ACR3 - movel #0xb6088400,%d0 /* enable caches */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M5407 */ - -#if defined(CONFIG_M520x) -.macro CACHE_ENABLE - move.l #0x01000000,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop - move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ - movec %d0,%ACR0 - move.l #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - move.l #0x80400000,%d0 /* enable 8K instruction cache */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M520x */ - -/****************************************************************************/ -#endif /* __M68KNOMMU_MCFCACHE_H */ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index 6901fd68165..ebd0304054a 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -41,8 +41,8 @@ #elif defined(CONFIG_M5407) #include <asm/m5407sim.h> #include <asm/mcfintc.h> -#elif defined(CONFIG_M548x) -#include <asm/m548xsim.h> +#elif defined(CONFIG_M54xx) +#include <asm/m54xxsim.h> #endif /****************************************************************************/ diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h index db72e2b889c..2abedff0a69 100644 --- a/arch/m68k/include/asm/mcfuart.h +++ b/arch/m68k/include/asm/mcfuart.h @@ -12,49 +12,6 @@ #define mcfuart_h /****************************************************************************/ -/* - * Define the base address of the UARTS within the MBAR address - * space. - */ -#if defined(CONFIG_M5272) -#define MCFUART_BASE1 0x100 /* Base address of UART1 */ -#define MCFUART_BASE2 0x140 /* Base address of UART2 */ -#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) -#if defined(CONFIG_NETtel) -#define MCFUART_BASE1 0x180 /* Base address of UART1 */ -#define MCFUART_BASE2 0x140 /* Base address of UART2 */ -#else -#define MCFUART_BASE1 0x140 /* Base address of UART1 */ -#define MCFUART_BASE2 0x180 /* Base address of UART2 */ -#endif -#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -#define MCFUART_BASE1 0x200 /* Base address of UART1 */ -#define MCFUART_BASE2 0x240 /* Base address of UART2 */ -#define MCFUART_BASE3 0x280 /* Base address of UART3 */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) -#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) -#define MCFUART_BASE1 0x200 /* Base address of UART1 */ -#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */ -#else -#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ -#define MCFUART_BASE2 0x200 /* Base address of UART2 */ -#endif -#elif defined(CONFIG_M520x) -#define MCFUART_BASE1 0x60000 /* Base address of UART1 */ -#define MCFUART_BASE2 0x64000 /* Base address of UART2 */ -#define MCFUART_BASE3 0x68000 /* Base address of UART2 */ -#elif defined(CONFIG_M532x) -#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */ -#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */ -#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */ -#elif defined(CONFIG_M548x) -#define MCFUART_BASE1 0x8600 /* on M548x */ -#define MCFUART_BASE2 0x8700 /* on M548x */ -#define MCFUART_BASE3 0x8800 /* on M548x */ -#define MCFUART_BASE4 0x8900 /* on M548x */ -#endif - - #include <linux/serial_core.h> #include <linux/platform_device.h> @@ -217,7 +174,7 @@ struct mcf_platform_uart { #define MCFUART_URF_RXS 0xc0 /* Receiver status */ #endif -#if defined(CONFIG_M548x) +#if defined(CONFIG_M54xx) #define MCFUART_TXFIFOSIZE 512 #elif defined(CONFIG_M5272) #define MCFUART_TXFIFOSIZE 25 diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index 7a6a7590cc0..278c69bad57 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -20,23 +20,26 @@ static inline unsigned long rdusp(void) { -#ifdef CONFIG_COLDFIRE +#ifdef CONFIG_COLDFIRE_SW_A7 extern unsigned int sw_usp; return sw_usp; #else - unsigned long usp; - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + register unsigned long usp __asm__("a0"); + /* move %usp,%a0 */ + __asm__ __volatile__(".word 0x4e68" : "=a" (usp)); return usp; #endif } static inline void wrusp(unsigned long usp) { -#ifdef CONFIG_COLDFIRE +#ifdef CONFIG_COLDFIRE_SW_A7 extern unsigned int sw_usp; sw_usp = usp; #else - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); + register unsigned long a0 __asm__("a0") = usp; + /* move %a0,%usp */ + __asm__ __volatile__(".word 0x4e60" : : "a" (a0) ); #endif } diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h index cf5fad9b525..f55aa04161e 100644 --- a/arch/m68k/include/asm/sun3_pgtable.h +++ b/arch/m68k/include/asm/sun3_pgtable.h @@ -217,9 +217,8 @@ static inline pte_t pgoff_to_pte(unsigned off) /* Find an entry in the third-level pagetable. */ #define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) #define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) -/* FIXME: should we bother with kmap() here? */ -#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address)) -#define pte_unmap(pte) kunmap(pte) +#define pte_offset_map(pmd, address) ((pte_t *)page_address(pmd_page(*pmd)) + pte_index(address)) +#define pte_unmap(pte) do { } while (0) /* Macros to (de)construct the fake PTEs representing swap pages. */ #define __swp_type(x) ((x).val & 0x7F) diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index 1da5d53a00e..790988967ba 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -104,5 +104,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_TRACE 15 /* syscall trace active */ #define TIF_MEMDIE 16 /* is terminating due to OOM killer */ #define TIF_FREEZE 17 /* thread is freezing for suspend */ +#define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal */ #endif /* _ASM_M68K_THREAD_INFO_H */ diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index b43b36beafe..26d851d385b 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -373,6 +373,7 @@ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND /* * "Conditional" syscalls diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 6360c437dcf..1559dea36e5 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -99,7 +99,10 @@ do_trace_exit: jra .Lret_from_exception ENTRY(ret_from_signal) - RESTORE_SWITCH_STACK + tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) + jge 1f + jbsr syscall_trace +1: RESTORE_SWITCH_STACK addql #4,%sp /* on 68040 complete pending writebacks if any */ #ifdef CONFIG_M68040 @@ -174,16 +177,11 @@ do_signal_return: subql #4,%sp | dummy return address SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) - clrl %sp@- bsrl do_signal - addql #8,%sp + addql #4,%sp RESTORE_SWITCH_STACK addql #4,%sp - tstl %d0 - jeq resume_userspace - | when single stepping into handler stop at the first insn - btst #6,%curptr@(TASK_INFO+TINFO_FLAGS+2) - jeq resume_userspace + jbra resume_userspace do_delayed_trace: bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR @@ -290,22 +288,6 @@ ENTRY(sys_vfork) RESTORE_SWITCH_STACK rts -ENTRY(sys_sigsuspend) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr do_sigsuspend - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_rt_sigsuspend) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr do_rt_sigsuspend - addql #4,%sp - RESTORE_SWITCH_STACK - rts - ENTRY(sys_sigreturn) SAVE_SWITCH_STACK jbsr do_sigreturn diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 4b387538706..d12c3b0d9e4 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -51,8 +51,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); - const int frame_extra_sizes[16] = { [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ [2] = sizeof(((struct frame *)0)->un.fmt2), @@ -74,51 +72,21 @@ const int frame_extra_sizes[16] = { /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int do_sigsuspend(struct pt_regs *regs) +asmlinkage int +sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) { - old_sigset_t mask = regs->d3; - sigset_t saveset; - mask &= _BLOCKABLE; - saveset = current->blocked; + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); - regs->d0 = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - return -EINTR; - } -} - -asmlinkage int -do_rt_sigsuspend(struct pt_regs *regs) -{ - sigset_t __user *unewset = (sigset_t __user *)regs->d1; - size_t sigsetsize = (size_t)regs->d2; - sigset_t saveset, newset; - - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) - return -EINVAL; + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_restore_sigmask(); - if (copy_from_user(&newset, unewset, sizeof(newset))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - - regs->d0 = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - return -EINTR; - } + return -ERESTARTNOHAND; } asmlinkage int @@ -132,10 +100,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -144,10 +112,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; @@ -318,36 +286,10 @@ out: return err; } -static inline int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp, - int *pd0) +static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, + void __user *fp) { - int fsize, formatvec; - struct sigcontext context; - int err; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - /* get previous context */ - if (copy_from_user(&context, usc, sizeof(context))) - goto badframe; - - /* restore passed registers */ - regs->d1 = context.sc_d1; - regs->a0 = context.sc_a0; - regs->a1 = context.sc_a1; - regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); - regs->pc = context.sc_pc; - regs->orig_d0 = -1; /* disable syscall checks */ - wrusp(context.sc_usp); - formatvec = context.sc_formatvec; - regs->format = formatvec >> 12; - regs->vector = formatvec & 0xfff; - - err = restore_fpu_state(&context); - - fsize = frame_extra_sizes[regs->format]; + int fsize = frame_extra_sizes[formatvec >> 12]; if (fsize < 0) { /* * user process trying to return with weird frame format @@ -355,16 +297,22 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u #ifdef DEBUG printk("user process returning with weird frame format\n"); #endif - goto badframe; + return 1; } + if (!fsize) { + regs->format = formatvec >> 12; + regs->vector = formatvec & 0xfff; + } else { + struct switch_stack *sw = (struct switch_stack *)regs - 1; + unsigned long buf[fsize / 2]; /* yes, twice as much */ - /* OK. Make room on the supervisor stack for the extra junk, - * if necessary. - */ + /* that'll make sure that expansion won't crap over data */ + if (copy_from_user(buf + fsize / 4, fp, fsize)) + return 1; - if (fsize) { - struct switch_stack *sw = (struct switch_stack *)regs - 1; - regs->d0 = context.sc_d0; + /* point of no return */ + regs->format = formatvec >> 12; + regs->vector = formatvec & 0xfff; #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) __asm__ __volatile__ (" movel %0,%/a0\n\t" @@ -376,30 +324,50 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ " lsrl #2,%1\n\t" " subql #1,%1\n\t" - "2: movesl %4@+,%2\n\t" - "3: movel %2,%/a0@+\n\t" + /* copy to the gap we'd made */ + "2: movel %4@+,%/a0@+\n\t" " dbra %1,2b\n\t" " bral ret_from_signal\n" - "4:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 2b,4b\n" - " .long 3b,4b\n" - ".previous" : /* no outputs, it doesn't ever return */ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), - "n" (frame_offset), "a" (fp) + "n" (frame_offset), "a" (buf + fsize/4) : "a0"); #undef frame_offset - /* - * If we ever get here an exception occurred while - * building the above stack-frame. - */ - goto badframe; } + return 0; +} - *pd0 = context.sc_d0; - return err; +static inline int +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) +{ + int formatvec; + struct sigcontext context; + int err; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + /* get previous context */ + if (copy_from_user(&context, usc, sizeof(context))) + goto badframe; + + /* restore passed registers */ + regs->d0 = context.sc_d0; + regs->d1 = context.sc_d1; + regs->a0 = context.sc_a0; + regs->a1 = context.sc_a1; + regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); + regs->pc = context.sc_pc; + regs->orig_d0 = -1; /* disable syscall checks */ + wrusp(context.sc_usp); + formatvec = context.sc_formatvec; + + err = restore_fpu_state(&context); + + if (err || mangle_kernel_stack(regs, formatvec, fp)) + goto badframe; + + return 0; badframe: return 1; @@ -407,9 +375,9 @@ badframe: static inline int rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, - struct ucontext __user *uc, int *pd0) + struct ucontext __user *uc) { - int fsize, temp; + int temp; greg_t __user *gregs = uc->uc_mcontext.gregs; unsigned long usp; int err; @@ -443,65 +411,16 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, regs->sr = (regs->sr & 0xff00) | (temp & 0xff); regs->orig_d0 = -1; /* disable syscall checks */ err |= __get_user(temp, &uc->uc_formatvec); - regs->format = temp >> 12; - regs->vector = temp & 0xfff; err |= rt_restore_fpu_state(uc); - if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) + if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) goto badframe; - fsize = frame_extra_sizes[regs->format]; - if (fsize < 0) { - /* - * user process trying to return with weird frame format - */ -#ifdef DEBUG - printk("user process returning with weird frame format\n"); -#endif + if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) goto badframe; - } - - /* OK. Make room on the supervisor stack for the extra junk, - * if necessary. - */ - if (fsize) { -#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) - __asm__ __volatile__ - (" movel %0,%/a0\n\t" - " subl %1,%/a0\n\t" /* make room on stack */ - " movel %/a0,%/sp\n\t" /* set stack pointer */ - /* move switch_stack and pt_regs */ - "1: movel %0@+,%/a0@+\n\t" - " dbra %2,1b\n\t" - " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ - " lsrl #2,%1\n\t" - " subql #1,%1\n\t" - "2: movesl %4@+,%2\n\t" - "3: movel %2,%/a0@+\n\t" - " dbra %1,2b\n\t" - " bral ret_from_signal\n" - "4:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 2b,4b\n" - " .long 3b,4b\n" - ".previous" - : /* no outputs, it doesn't ever return */ - : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), - "n" (frame_offset), "a" (&uc->uc_extra) - : "a0"); -#undef frame_offset - /* - * If we ever get here an exception occurred while - * building the above stack-frame. - */ - goto badframe; - } - - *pd0 = regs->d0; - return err; + return 0; badframe: return 1; @@ -514,7 +433,6 @@ asmlinkage int do_sigreturn(unsigned long __unused) unsigned long usp = rdusp(); struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); sigset_t set; - int d0; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; @@ -528,9 +446,9 @@ asmlinkage int do_sigreturn(unsigned long __unused) current->blocked = set; recalc_sigpending(); - if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) + if (restore_sigcontext(regs, &frame->sc, frame + 1)) goto badframe; - return d0; + return regs->d0; badframe: force_sig(SIGSEGV, current); @@ -544,7 +462,6 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused) unsigned long usp = rdusp(); struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); sigset_t set; - int d0; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; @@ -555,9 +472,9 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused) current->blocked = set; recalc_sigpending(); - if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) + if (rt_restore_ucontext(regs, sw, &frame->uc)) goto badframe; - return d0; + return regs->d0; badframe: force_sig(SIGSEGV, current); @@ -775,7 +692,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) return (void __user *)((usp - frame_size) & -8UL); } -static void setup_frame (int sig, struct k_sigaction *ka, +static int setup_frame (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; @@ -793,10 +710,8 @@ static void setup_frame (int sig, struct k_sigaction *ka, frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); - if (fsize) { + if (fsize) err |= copy_to_user (frame + 1, regs + 1, fsize); - regs->stkadj = fsize; - } err |= __put_user((current_thread_info()->exec_domain && current_thread_info()->exec_domain->signal_invmap @@ -826,11 +741,21 @@ static void setup_frame (int sig, struct k_sigaction *ka, push_cache ((unsigned long) &frame->retcode); - /* Set up registers for signal handler */ + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ wrusp ((unsigned long) frame); regs->pc = (unsigned long) ka->sa.sa_handler; -adjust_stack: + /* + * This is subtle; if we build more than one sigframe, all but the + * first one will see frame format 0 and have fsize == 0, so we won't + * screw stkadj. + */ + if (fsize) + regs->stkadj = fsize; + /* Prepare to skip over the extra stuff in the exception frame. */ if (regs->stkadj) { struct pt_regs *tregs = @@ -845,14 +770,14 @@ adjust_stack: tregs->pc = regs->pc; tregs->sr = regs->sr; } - return; + return 0; give_sigsegv: force_sigsegv(sig, current); - goto adjust_stack; + return err; } -static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, +static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -869,10 +794,8 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, frame = get_sigframe(ka, regs, sizeof(*frame)); - if (fsize) { + if (fsize) err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); - regs->stkadj = fsize; - } err |= __put_user((current_thread_info()->exec_domain && current_thread_info()->exec_domain->signal_invmap @@ -914,11 +837,21 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, push_cache ((unsigned long) &frame->retcode); - /* Set up registers for signal handler */ + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ wrusp ((unsigned long) frame); regs->pc = (unsigned long) ka->sa.sa_handler; -adjust_stack: + /* + * This is subtle; if we build more than one sigframe, all but the + * first one will see frame format 0 and have fsize == 0, so we won't + * screw stkadj. + */ + if (fsize) + regs->stkadj = fsize; + /* Prepare to skip over the extra stuff in the exception frame. */ if (regs->stkadj) { struct pt_regs *tregs = @@ -933,11 +866,11 @@ adjust_stack: tregs->pc = regs->pc; tregs->sr = regs->sr; } - return; + return 0; give_sigsegv: force_sigsegv(sig, current); - goto adjust_stack; + return err; } static inline void @@ -995,6 +928,7 @@ static void handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { + int err; /* are we from a system call? */ if (regs->orig_d0 >= 0) /* If so, check system call restarting.. */ @@ -1002,17 +936,24 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, /* set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(sig, ka, info, oldset, regs); + err = setup_rt_frame(sig, ka, info, oldset, regs); else - setup_frame(sig, ka, oldset, regs); + err = setup_frame(sig, ka, oldset, regs); - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; + if (err) + return; sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked,sig); recalc_sigpending(); + + if (test_thread_flag(TIF_DELAYED_TRACE)) { + regs->sr &= ~0x8000; + send_sig(SIGTRAP, current, 1); + } + + clear_thread_flag(TIF_RESTORE_SIGMASK); } /* @@ -1020,22 +961,25 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) +asmlinkage void do_signal(struct pt_regs *regs) { siginfo_t info; struct k_sigaction ka; int signr; + sigset_t *oldset; current->thread.esp0 = (unsigned long) regs; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &ka, &info, oldset, regs); - return 1; + return; } /* Did we come from a system call? */ @@ -1043,5 +987,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* Restart the system call - no handlers present */ handle_restart(regs, NULL, 0); - return 0; + /* If there's no signal to deliver, we just restore the saved mask. */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } } diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index ba6ccab6401..a4c3eb60706 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -88,7 +88,7 @@ void __init psc_init(void) /* * The PSC is always at the same spot, but using psc - * keeps things consisant with the psc_xxxx functions. + * keeps things consistent with the psc_xxxx functions. */ psc = (void *) PSC_BASE; |