diff options
author | Tejun Heo <tj@kernel.org> | 2011-11-28 09:46:22 -0800 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-11-28 09:46:22 -0800 |
commit | d4bbf7e7759afc172e2bfbc5c416324590049cdd (patch) | |
tree | 7eab5ee5481cd3dcf1162329fec827177640018a /arch/arm/mm | |
parent | a150439c4a97db379f0ed6faa46fbbb6e7bf3cb2 (diff) | |
parent | 401d0069cb344f401bc9d264c31db55876ff78c0 (diff) |
Merge branch 'master' into x86/memblock
Conflicts & resolutions:
* arch/x86/xen/setup.c
dc91c728fd "xen: allow extra memory to be in multiple regions"
24aa07882b "memblock, x86: Replace memblock_x86_reserve/free..."
conflicted on xen_add_extra_mem() updates. The resolution is
trivial as the latter just want to replace
memblock_x86_reserve_range() with memblock_reserve().
* drivers/pci/intel-iommu.c
166e9278a3f "x86/ia64: intel-iommu: move to drivers/iommu/"
5dfe8660a3d "bootmem: Replace work_with_active_regions() with..."
conflicted as the former moved the file under drivers/iommu/.
Resolved by applying the chnages from the latter on the moved
file.
* mm/Kconfig
6661672053a "memblock: add NO_BOOTMEM config symbol"
c378ddd53f9 "memblock, x86: Make ARCH_DISCARD_MEMBLOCK a config option"
conflicted trivially. Both added config options. Just
letting both add their own options resolves the conflict.
* mm/memblock.c
d1f0ece6cdc "mm/memblock.c: small function definition fixes"
ed7b56a799c "memblock: Remove memblock_memory_can_coalesce()"
confliected. The former updates function removed by the
latter. Resolution is trivial.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/arm/mm')
66 files changed, 1392 insertions, 2523 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 0074b8dba79..67f75a0b66d 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -819,9 +819,10 @@ config CACHE_FEROCEON_L2_WRITETHROUGH config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ - REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ + REALVIEW_EB_A9MP || ARCH_IMX_V6_V7 || MACH_REALVIEW_PBX || \ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ - ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE + ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ + ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK default y select OUTER_CACHE select OUTER_CACHE_SYNC diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S index 4f18f9e87ba..54473cd4aba 100644 --- a/arch/arm/mm/abort-ev4.S +++ b/arch/arm/mm/abort-ev4.S @@ -3,14 +3,11 @@ /* * Function: v4_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -21,10 +18,8 @@ ENTRY(v4_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - ldr r3, [r2] @ read aborted ARM instruction + ldr r3, [r4] @ read aborted ARM instruction bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR tst r3, #1 << 20 @ L = 1 -> write? orreq r1, r1, #1 << 11 @ yes. - mov pc, lr - - + b do_DataAbort diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S index b6282548f92..9da704e7b86 100644 --- a/arch/arm/mm/abort-ev4t.S +++ b/arch/arm/mm/abort-ev4t.S @@ -4,14 +4,11 @@ /* * Function: v4t_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -22,9 +19,9 @@ ENTRY(v4t_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - do_thumb_abort - ldreq r3, [r2] @ read aborted ARM instruction + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR tst r3, #1 << 20 @ check write orreq r1, r1, #1 << 11 - mov pc, lr + b do_DataAbort diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S index 02251b526c0..a0908d4653a 100644 --- a/arch/arm/mm/abort-ev5t.S +++ b/arch/arm/mm/abort-ev5t.S @@ -4,14 +4,11 @@ /* * Function: v5t_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -22,10 +19,10 @@ ENTRY(v5t_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - do_thumb_abort - ldreq r3, [r2] @ read aborted ARM instruction + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction bic r1, r1, #1 << 11 @ clear bits 11 of FSR - do_ldrd_abort + do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ check write orreq r1, r1, #1 << 11 - mov pc, lr + b do_DataAbort diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S index bce68d601c8..4006b7a6126 100644 --- a/arch/arm/mm/abort-ev5tj.S +++ b/arch/arm/mm/abort-ev5tj.S @@ -4,14 +4,11 @@ /* * Function: v5tj_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -23,13 +20,11 @@ ENTRY(v5tj_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR - tst r3, #PSR_J_BIT @ Java? - movne pc, lr - do_thumb_abort - ldreq r3, [r2] @ read aborted ARM instruction - do_ldrd_abort + tst r5, #PSR_J_BIT @ Java? + bne do_DataAbort + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction + do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. - mov pc, lr - - + b do_DataAbort diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 1478aa52214..ff1f7cc11f8 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -4,14 +4,11 @@ /* * Function: v6_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -33,16 +30,14 @@ ENTRY(v6_early_abort) * The test below covers all the write situations, including Java bytecodes */ bic r1, r1, #1 << 11 @ clear bit 11 of FSR - tst r3, #PSR_J_BIT @ Java? - movne pc, lr - do_thumb_abort - ldreq r3, [r2] @ read aborted ARM instruction + tst r5, #PSR_J_BIT @ Java? + bne do_DataAbort + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction #ifdef CONFIG_CPU_ENDIAN_BE8 reveq r3, r3 #endif - do_ldrd_abort + do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. - mov pc, lr - - + b do_DataAbort diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index ec88b157d3b..703375277ba 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S @@ -3,14 +3,11 @@ /* * Function: v7_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current aborted instruction. */ @@ -37,18 +34,18 @@ ENTRY(v7_early_abort) ldr r3, =0x40d @ On permission fault and r3, r1, r3 cmp r3, #0x0d - movne pc, lr + bne do_DataAbort mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR isb - mrc p15, 0, r2, c7, c4, 0 @ Read the PAR - and r3, r2, #0x7b @ On translation fault + mrc p15, 0, ip, c7, c4, 0 @ Read the PAR + and r3, ip, #0x7b @ On translation fault cmp r3, #0x0b - movne pc, lr + bne do_DataAbort bic r1, r1, #0xf @ Fix up FSR FS[5:0] - and r2, r2, #0x7e - orr r1, r1, r2, LSR #1 + and ip, ip, #0x7e + orr r1, r1, ip, LSR #1 #endif - mov pc, lr + b do_DataAbort ENDPROC(v7_early_abort) diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index 9fb7b0e25ea..f3982580c27 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S @@ -3,14 +3,11 @@ /* * Function: v4t_late_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = address of abort - * : r1 = FSR, bit 11 = write - * : r2-r8 = corrupted - * : r9 = preserved - * : sp = pointer to registers + * Returns : r4-r5, r10-r11, r13 preserved * * Purpose : obtain information about current aborted instruction. * Note: we read user space. This means we might cause a data @@ -18,7 +15,7 @@ * picture. Unfortunately, this does happen. We live with it. */ ENTRY(v4t_late_abort) - tst r3, #PSR_T_BIT @ check for thumb mode + tst r5, #PSR_T_BIT @ check for thumb mode #ifdef CONFIG_CPU_CP15_MMU mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR @@ -28,7 +25,7 @@ ENTRY(v4t_late_abort) mov r1, #0 #endif bne .data_thumb_abort - ldr r8, [r2] @ read arm instruction + ldr r8, [r4] @ read arm instruction tst r8, #1 << 20 @ L = 1 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 @@ -47,86 +44,84 @@ ENTRY(v4t_late_abort) /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> /* a */ b .data_unknown /* b */ b .data_unknown -/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m -/* d */ mov pc, lr @ ldc rd, [rn, #m] +/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m +/* d */ b do_DataAbort @ ldc rd, [rn, #m] /* e */ b .data_unknown /* f */ .data_unknown: @ Part of jumptable - mov r0, r2 + mov r0, r4 mov r1, r8 - mov r2, sp - bl baddataabort - b ret_from_exception + b baddataabort .data_arm_ldmstm: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup mov r7, #0x11 orr r7, r7, #0x1100 and r6, r8, r7 - and r2, r8, r7, lsl #1 - add r6, r6, r2, lsr #1 - and r2, r8, r7, lsl #2 - add r6, r6, r2, lsr #2 - and r2, r8, r7, lsl #3 - add r6, r6, r2, lsr #3 + and r9, r8, r7, lsl #1 + add r6, r6, r9, lsr #1 + and r9, r8, r7, lsl #2 + add r6, r6, r9, lsr #2 + and r9, r8, r7, lsl #3 + add r6, r6, r9, lsr #3 add r6, r6, r6, lsr #8 add r6, r6, r6, lsr #4 and r6, r6, #15 @ r6 = no. of registers to transfer. - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit subne r7, r7, r6, lsl #2 @ Undo increment addeq r7, r7, r6, lsl #2 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_lateldrhpre: tst r8, #1 << 21 @ Check writeback bit - moveq pc, lr @ No writeback -> no fixup + beq do_DataAbort @ No writeback -> no fixup .data_arm_lateldrhpost: - and r5, r8, #0x00f @ get Rm / low nibble of immediate value + and r9, r8, #0x00f @ get Rm / low nibble of immediate value tst r8, #1 << 22 @ if (immediate offset) andne r6, r8, #0xf00 @ { immediate high nibble - orrne r6, r5, r6, lsr #4 @ combine nibbles } else - ldreq r6, [sp, r5, lsl #2] @ { load Rm value } + orrne r6, r9, r6, lsr #4 @ combine nibbles } else + ldreq r6, [r2, r9, lsl #2] @ { load Rm value } .data_arm_apply_r6_and_rn: - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit subne r7, r7, r6 @ Undo incrmenet addeq r7, r7, r6 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_lateldrpreconst: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup .data_arm_lateldrpostconst: - movs r2, r8, lsl #20 @ Get offset - moveq pc, lr @ zero -> no fixup - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + movs r6, r8, lsl #20 @ Get offset + beq do_DataAbort @ zero -> no fixup + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit - subne r7, r7, r2, lsr #20 @ Undo increment - addeq r7, r7, r2, lsr #20 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + subne r7, r7, r6, lsr #20 @ Undo increment + addeq r7, r7, r6, lsr #20 @ Undo decrement + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_lateldrprereg: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup .data_arm_lateldrpostreg: and r7, r8, #15 @ Extract 'm' from instruction - ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' - mov r5, r8, lsr #7 @ get shift count - ands r5, r5, #31 + ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' + mov r9, r8, lsr #7 @ get shift count + ands r9, r9, #31 and r7, r8, #0x70 @ get shift type orreq r7, r7, #8 @ shift count = 0 add pc, pc, r7 nop - mov r6, r6, lsl r5 @ 0: LSL #!0 + mov r6, r6, lsl r9 @ 0: LSL #!0 b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn @ 1: LSL #0 nop @@ -134,7 +129,7 @@ ENTRY(v4t_late_abort) nop b .data_unknown @ 3: MUL? nop - mov r6, r6, lsr r5 @ 4: LSR #!0 + mov r6, r6, lsr r9 @ 4: LSR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, lsr #32 @ 5: LSR #32 b .data_arm_apply_r6_and_rn @@ -142,7 +137,7 @@ ENTRY(v4t_late_abort) nop b .data_unknown @ 7: MUL? nop - mov r6, r6, asr r5 @ 8: ASR #!0 + mov r6, r6, asr r9 @ 8: ASR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, asr #32 @ 9: ASR #32 b .data_arm_apply_r6_and_rn @@ -150,7 +145,7 @@ ENTRY(v4t_late_abort) nop b .data_unknown @ B: MUL? nop - mov r6, r6, ror r5 @ C: ROR #!0 + mov r6, r6, ror r9 @ C: ROR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, rrx @ D: RRX b .data_arm_apply_r6_and_rn @@ -159,7 +154,7 @@ ENTRY(v4t_late_abort) b .data_unknown @ F: MUL? .data_thumb_abort: - ldrh r8, [r2] @ read instruction + ldrh r8, [r4] @ read instruction tst r8, #1 << 11 @ L = 1 -> write? orreq r1, r1, #1 << 8 @ yes and r7, r8, #15 << 12 @@ -172,10 +167,10 @@ ENTRY(v4t_late_abort) /* 3 */ b .data_unknown /* 4 */ b .data_unknown /* 5 */ b .data_thumb_reg -/* 6 */ mov pc, lr -/* 7 */ mov pc, lr -/* 8 */ mov pc, lr -/* 9 */ mov pc, lr +/* 6 */ b do_DataAbort +/* 7 */ b do_DataAbort +/* 8 */ b do_DataAbort +/* 9 */ b do_DataAbort /* A */ b .data_unknown /* B */ b .data_thumb_pushpop /* C */ b .data_thumb_ldmstm @@ -185,41 +180,41 @@ ENTRY(v4t_late_abort) .data_thumb_reg: tst r8, #1 << 9 - moveq pc, lr + beq do_DataAbort tst r8, #1 << 10 @ If 'S' (signed) bit is set movne r1, #0 @ it must be a load instr - mov pc, lr + b do_DataAbort .data_thumb_pushpop: tst r8, #1 << 10 beq .data_unknown and r6, r8, #0x55 @ hweight8(r8) + R bit - and r2, r8, #0xaa - add r6, r6, r2, lsr #1 - and r2, r6, #0xcc + and r9, r8, #0xaa + add r6, r6, r9, lsr #1 + and r9, r6, #0xcc and r6, r6, #0x33 - add r6, r6, r2, lsr #2 + add r6, r6, r9, lsr #2 movs r7, r8, lsr #9 @ C = r8 bit 8 (R bit) adc r6, r6, r6, lsr #4 @ high + low nibble + R bit and r6, r6, #15 @ number of regs to transfer - ldr r7, [sp, #13 << 2] + ldr r7, [r2, #13 << 2] tst r8, #1 << 11 addeq r7, r7, r6, lsl #2 @ increment SP if PUSH subne r7, r7, r6, lsl #2 @ decrement SP if POP - str r7, [sp, #13 << 2] - mov pc, lr + str r7, [r2, #13 << 2] + b do_DataAbort .data_thumb_ldmstm: and r6, r8, #0x55 @ hweight8(r8) - and r2, r8, #0xaa - add r6, r6, r2, lsr #1 - and r2, r6, #0xcc + and r9, r8, #0xaa + add r6, r6, r9, lsr #1 + and r9, r6, #0xcc and r6, r6, #0x33 - add r6, r6, r2, lsr #2 + add r6, r6, r9, lsr #2 add r6, r6, r6, lsr #4 - and r5, r8, #7 << 8 - ldr r7, [sp, r5, lsr #6] + and r9, r8, #7 << 8 + ldr r7, [r2, r9, lsr #6] and r6, r6, #15 @ number of regs to transfer sub r7, r7, r6, lsl #2 @ always decrement - str r7, [sp, r5, lsr #6] - mov pc, lr + str r7, [r2, r9, lsr #6] + b do_DataAbort diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index d7cb1bfa51a..2cbf68ef0e8 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S @@ -9,34 +9,32 @@ * */ - .macro do_thumb_abort - tst r3, #PSR_T_BIT + .macro do_thumb_abort, fsr, pc, psr, tmp + tst \psr, #PSR_T_BIT beq not_thumb - ldrh r3, [r2] @ Read aborted Thumb instruction - and r3, r3, # 0xfe00 @ Mask opcode field - cmp r3, # 0x5600 @ Is it ldrsb? - orreq r3, r3, #1 << 11 @ Set L-bit if yes - tst r3, #1 << 11 @ L = 0 -> write - orreq r1, r1, #1 << 11 @ yes. - mov pc, lr + ldrh \tmp, [\pc] @ Read aborted Thumb instruction + and \tmp, \tmp, # 0xfe00 @ Mask opcode field + cmp \tmp, # 0x5600 @ Is it ldrsb? + orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes + tst \tmp, #1 << 11 @ L = 0 -> write + orreq \fsr, \fsr, #1 << 11 @ yes. + b do_DataAbort not_thumb: .endm /* - * We check for the following insturction encoding for LDRD. + * We check for the following instruction encoding for LDRD. * - * [27:25] == 0 + * [27:25] == 000 * [7:4] == 1101 * [20] == 0 */ - .macro do_ldrd_abort - tst r3, #0x0e000000 @ [27:25] == 0 + .macro do_ldrd_abort, tmp, insn + tst \insn, #0x0e100000 @ [27:25,20] == 0 bne not_ldrd - and r2, r3, #0x000000f0 @ [7:4] == 1101 - cmp r2, #0x000000d0 - bne not_ldrd - tst r3, #1 << 20 @ [20] == 0 - moveq pc, lr + and \tmp, \insn, #0x000000f0 @ [7:4] == 1101 + cmp \tmp, #0x000000d0 + beq do_DataAbort not_ldrd: .endm diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S index 625e580945b..119cb479c2a 100644 --- a/arch/arm/mm/abort-nommu.S +++ b/arch/arm/mm/abort-nommu.S @@ -3,11 +3,11 @@ /* * Function: nommu_early_abort * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * - * Returns : r0 = 0 (abort address) - * : r1 = 0 (FSR) + * Returns : r4 - r11, r13 preserved * * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. * Just fill zero into the registers. @@ -16,5 +16,5 @@ ENTRY(nommu_early_abort) mov r0, #0 @ clear r0, r1 (no FSR/FAR) mov r1, #0 - mov pc, lr + b do_DataAbort ENDPROC(nommu_early_abort) diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 724ba3bce72..c335c76e0d8 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -22,6 +22,7 @@ #include <linux/sched.h> #include <linux/uaccess.h> +#include <asm/system.h> #include <asm/unaligned.h> #include "fault.h" @@ -85,6 +86,33 @@ core_param(alignment, ai_usermode, int, 0600); #define UM_FIXUP (1 << 1) #define UM_SIGNAL (1 << 2) +/* Return true if and only if the ARMv6 unaligned access model is in use. */ +static bool cpu_is_v6_unaligned(void) +{ + return cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U); +} + +static int safe_usermode(int new_usermode, bool warn) +{ + /* + * ARMv6 and later CPUs can perform unaligned accesses for + * most single load and store instructions up to word size. + * LDM, STM, LDRD and STRD still need to be handled. + * + * Ignoring the alignment fault is not an option on these + * CPUs since we spin re-faulting the instruction without + * making any progress. + */ + if (cpu_is_v6_unaligned() && !(new_usermode & (UM_FIXUP | UM_SIGNAL))) { + new_usermode |= UM_FIXUP; + + if (warn) + printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); + } + + return new_usermode; +} + #ifdef CONFIG_PROC_FS static const char *usermode_action[] = { "ignored", @@ -125,7 +153,7 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer if (get_user(mode, buffer)) return -EFAULT; if (mode >= '0' && mode <= '5') - ai_usermode = mode - '0'; + ai_usermode = safe_usermode(mode - '0', true); } return count; } @@ -727,6 +755,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) int isize = 4; int thumb2_32b = 0; + if (interrupts_enabled(regs)) + local_irq_enable(); + instrptr = instruction_pointer(regs); fs = get_fs(); @@ -883,9 +914,16 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (ai_usermode & UM_FIXUP) goto fixup; - if (ai_usermode & UM_SIGNAL) - force_sig(SIGBUS, current); - else { + if (ai_usermode & UM_SIGNAL) { + siginfo_t si; + + si.si_signo = SIGBUS; + si.si_errno = 0; + si.si_code = BUS_ADRALN; + si.si_addr = (void __user *)addr; + + force_sig_info(si.si_signo, &si, current); + } else { /* * We're about to disable the alignment trap and return to * user space. But if an interrupt occurs before actually @@ -923,20 +961,11 @@ static int __init alignment_init(void) return -ENOMEM; #endif - /* - * ARMv6 and later CPUs can perform unaligned accesses for - * most single load and store instructions up to word size. - * LDM, STM, LDRD and STRD still need to be handled. - * - * Ignoring the alignment fault is not an option on these - * CPUs since we spin re-faulting the instruction without - * making any progress. - */ - if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) { + if (cpu_is_v6_unaligned()) { cr_alignment &= ~CR_A; cr_no_alignment &= ~CR_A; set_cr(cr_alignment); - ai_usermode = UM_FIXUP; + ai_usermode = safe_usermode(ai_usermode, false); } hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN, diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S index 1fa6f71470d..07201637109 100644 --- a/arch/arm/mm/cache-fa.S +++ b/arch/arm/mm/cache-fa.S @@ -242,16 +242,5 @@ ENDPROC(fa_dma_unmap_area) __INITDATA - .type fa_cache_fns, #object -ENTRY(fa_cache_fns) - .long fa_flush_icache_all - .long fa_flush_kern_cache_all - .long fa_flush_user_cache_all - .long fa_flush_user_cache_range - .long fa_coherent_kern_range - .long fa_coherent_user_range - .long fa_flush_kern_dcache_area - .long fa_dma_map_area - .long fa_dma_unmap_area - .long fa_dma_flush_range - .size fa_cache_fns, . - fa_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions fa diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 44c086710d2..8ac9e9f8479 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -16,9 +16,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/err.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> @@ -26,15 +29,23 @@ #define CACHE_LINE_SIZE 32 static void __iomem *l2x0_base; -static DEFINE_SPINLOCK(l2x0_lock); +static DEFINE_RAW_SPINLOCK(l2x0_lock); static uint32_t l2x0_way_mask; /* Bitmask of active ways */ static uint32_t l2x0_size; +struct l2x0_regs l2x0_saved_regs; + +struct l2x0_of_data { + void (*setup)(const struct device_node *, __u32 *, __u32 *); + void (*save)(void); + void (*resume)(void); +}; + static inline void cache_wait_way(void __iomem *reg, unsigned long mask) { /* wait for cache operation by line or way to complete */ while (readl_relaxed(reg) & mask) - ; + cpu_relax(); } #ifdef CONFIG_CACHE_PL310 @@ -115,9 +126,9 @@ static void l2x0_cache_sync(void) { unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void __l2x0_flush_all(void) @@ -134,9 +145,9 @@ static void l2x0_flush_all(void) unsigned long flags; /* clean all ways */ - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); __l2x0_flush_all(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_all(void) @@ -144,11 +155,11 @@ static void l2x0_clean_all(void) unsigned long flags; /* clean all ways */ - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY); cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_all(void) @@ -156,13 +167,13 @@ static void l2x0_inv_all(void) unsigned long flags; /* invalidate all ways */ - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); /* Invalidating when L2 is enabled is a nono */ BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1); writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) @@ -170,7 +181,7 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); debug_writel(0x03); @@ -195,13 +206,13 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) } if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) @@ -214,7 +225,7 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) return; } - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { unsigned long blk_end = start + min(end - start, 4096UL); @@ -225,13 +236,13 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) } if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) @@ -244,7 +255,7 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) return; } - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { unsigned long blk_end = start + min(end - start, 4096UL); @@ -257,24 +268,43 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) debug_writel(0x00); if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_disable(void) { unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + raw_spin_lock_irqsave(&l2x0_lock, flags); __l2x0_flush_all(); writel_relaxed(0, l2x0_base + L2X0_CTRL); dsb(); - spin_unlock_irqrestore(&l2x0_lock, flags); + raw_spin_unlock_irqrestore(&l2x0_lock, flags); +} + +static void l2x0_unlock(__u32 cache_id) +{ + int lockregs; + int i; + + if (cache_id == L2X0_CACHE_ID_PART_L310) + lockregs = 8; + else + /* L210 and unknown types */ + lockregs = 1; + + for (i = 0; i < lockregs; i++) { + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE + + i * L2X0_LOCKDOWN_STRIDE); + writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE + + i * L2X0_LOCKDOWN_STRIDE); + } } void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) @@ -328,10 +358,14 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) * accessing the below registers will fault. */ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* Make sure that I&D is not locked down when starting */ + l2x0_unlock(cache_id); /* l2x0 controller is disabled */ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); + l2x0_saved_regs.aux_ctrl = aux; + l2x0_inv_all(); /* enable L2X0 */ @@ -351,3 +385,202 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", ways, cache_id, aux, l2x0_size); } + +#ifdef CONFIG_OF +static void __init l2x0_of_setup(const struct device_node *np, + __u32 *aux_val, __u32 *aux_mask) +{ + u32 data[2] = { 0, 0 }; + u32 tag = 0; + u32 dirty = 0; + u32 val = 0, mask = 0; + + of_property_read_u32(np, "arm,tag-latency", &tag); + if (tag) { + mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK; + val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT; + } + + of_property_read_u32_array(np, "arm,data-latency", + data, ARRAY_SIZE(data)); + if (data[0] && data[1]) { + mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK | + L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK; + val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) | + ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT); + } + + of_property_read_u32(np, "arm,dirty-latency", &dirty); + if (dirty) { + mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK; + val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT; + } + + *aux_val &= ~mask; + *aux_val |= val; + *aux_mask &= ~mask; +} + +static void __init pl310_of_setup(const struct device_node *np, + __u32 *aux_val, __u32 *aux_mask) +{ + u32 data[3] = { 0, 0, 0 }; + u32 tag[3] = { 0, 0, 0 }; + u32 filter[2] = { 0, 0 }; + + of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag)); + if (tag[0] && tag[1] && tag[2]) + writel_relaxed( + ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) | + ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) | + ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT), + l2x0_base + L2X0_TAG_LATENCY_CTRL); + + of_property_read_u32_array(np, "arm,data-latency", + data, ARRAY_SIZE(data)); + if (data[0] && data[1] && data[2]) + writel_relaxed( + ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) | + ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) | + ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT), + l2x0_base + L2X0_DATA_LATENCY_CTRL); + + of_property_read_u32_array(np, "arm,filter-ranges", + filter, ARRAY_SIZE(filter)); + if (filter[1]) { + writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M), + l2x0_base + L2X0_ADDR_FILTER_END); + writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN, + l2x0_base + L2X0_ADDR_FILTER_START); + } +} + +static void __init pl310_save(void) +{ + u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & + L2X0_CACHE_ID_RTL_MASK; + + l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base + + L2X0_TAG_LATENCY_CTRL); + l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base + + L2X0_DATA_LATENCY_CTRL); + l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base + + L2X0_ADDR_FILTER_END); + l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base + + L2X0_ADDR_FILTER_START); + + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { + /* + * From r2p0, there is Prefetch offset/control register + */ + l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base + + L2X0_PREFETCH_CTRL); + /* + * From r3p0, there is Power control register + */ + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0) + l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base + + L2X0_POWER_CTRL); + } +} + +static void l2x0_resume(void) +{ + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* restore aux ctrl and enable l2 */ + l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID)); + + writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base + + L2X0_AUX_CTRL); + + l2x0_inv_all(); + + writel_relaxed(1, l2x0_base + L2X0_CTRL); + } +} + +static void pl310_resume(void) +{ + u32 l2x0_revision; + + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* restore pl310 setup */ + writel_relaxed(l2x0_saved_regs.tag_latency, + l2x0_base + L2X0_TAG_LATENCY_CTRL); + writel_relaxed(l2x0_saved_regs.data_latency, + l2x0_base + L2X0_DATA_LATENCY_CTRL); + writel_relaxed(l2x0_saved_regs.filter_end, + l2x0_base + L2X0_ADDR_FILTER_END); + writel_relaxed(l2x0_saved_regs.filter_start, + l2x0_base + L2X0_ADDR_FILTER_START); + + l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & + L2X0_CACHE_ID_RTL_MASK; + + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { + writel_relaxed(l2x0_saved_regs.prefetch_ctrl, + l2x0_base + L2X0_PREFETCH_CTRL); + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0) + writel_relaxed(l2x0_saved_regs.pwr_ctrl, + l2x0_base + L2X0_POWER_CTRL); + } + } + + l2x0_resume(); +} + +static const struct l2x0_of_data pl310_data = { + pl310_of_setup, + pl310_save, + pl310_resume, +}; + +static const struct l2x0_of_data l2x0_data = { + l2x0_of_setup, + NULL, + l2x0_resume, +}; + +static const struct of_device_id l2x0_ids[] __initconst = { + { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data }, + { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data }, + { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data }, + {} +}; + +int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) +{ + struct device_node *np; + struct l2x0_of_data *data; + struct resource res; + + np = of_find_matching_node(NULL, l2x0_ids); + if (!np) + return -ENODEV; + + if (of_address_to_resource(np, 0, &res)) + return -ENODEV; + + l2x0_base = ioremap(res.start, resource_size(&res)); + if (!l2x0_base) + return -ENOMEM; + + l2x0_saved_regs.phy_base = res.start; + + data = of_match_node(l2x0_ids, np)->data; + + /* L2 configuration can only be changed if the cache is disabled */ + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + if (data->setup) + data->setup(np, &aux_val, &aux_mask); + } + + if (data->save) + data->save(); + + l2x0_init(l2x0_base, aux_val, aux_mask); + + outer_cache.resume = data->resume; + return 0; +} +#endif diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S index 2e2bc406a18..c2301f22610 100644 --- a/arch/arm/mm/cache-v3.S +++ b/arch/arm/mm/cache-v3.S @@ -129,16 +129,5 @@ ENDPROC(v3_dma_map_area) __INITDATA - .type v3_cache_fns, #object -ENTRY(v3_cache_fns) - .long v3_flush_icache_all - .long v3_flush_kern_cache_all - .long v3_flush_user_cache_all - .long v3_flush_user_cache_range - .long v3_coherent_kern_range - .long v3_coherent_user_range - .long v3_flush_kern_dcache_area - .long v3_dma_map_area - .long v3_dma_unmap_area - .long v3_dma_flush_range - .size v3_cache_fns, . - v3_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v3 diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index a8fefb523f1..fd9bb7addc8 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -141,16 +141,5 @@ ENDPROC(v4_dma_map_area) __INITDATA - .type v4_cache_fns, #object -ENTRY(v4_cache_fns) - .long v4_flush_icache_all - .long v4_flush_kern_cache_all - .long v4_flush_user_cache_all - .long v4_flush_user_cache_range - .long v4_coherent_kern_range - .long v4_coherent_user_range - .long v4_flush_kern_dcache_area - .long v4_dma_map_area - .long v4_dma_unmap_area - .long v4_dma_flush_range - .size v4_cache_fns, . - v4_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v4 diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index f40c69656d8..4f2c14151cc 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -253,16 +253,5 @@ ENDPROC(v4wb_dma_unmap_area) __INITDATA - .type v4wb_cache_fns, #object -ENTRY(v4wb_cache_fns) - .long v4wb_flush_icache_all - .long v4wb_flush_kern_cache_all - .long v4wb_flush_user_cache_all - .long v4wb_flush_user_cache_range - .long v4wb_coherent_kern_range - .long v4wb_coherent_user_range - .long v4wb_flush_kern_dcache_area - .long v4wb_dma_map_area - .long v4wb_dma_unmap_area - .long v4wb_dma_flush_range - .size v4wb_cache_fns, . - v4wb_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v4wb diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S index a7b276dbda1..4d7b467631c 100644 --- a/arch/arm/mm/cache-v4wt.S +++ b/arch/arm/mm/cache-v4wt.S @@ -197,16 +197,5 @@ ENDPROC(v4wt_dma_map_area) __INITDATA - .type v4wt_cache_fns, #object -ENTRY(v4wt_cache_fns) - .long v4wt_flush_icache_all - .long v4wt_flush_kern_cache_all - .long v4wt_flush_user_cache_all - .long v4wt_flush_user_cache_range - .long v4wt_coherent_kern_range - .long v4wt_coherent_user_range - .long v4wt_flush_kern_dcache_area - .long v4wt_dma_map_area - .long v4wt_dma_unmap_area - .long v4wt_dma_flush_range - .size v4wt_cache_fns, . - v4wt_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v4wt diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 73b4a8b66a5..74c2e5a33a4 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -330,16 +330,5 @@ ENDPROC(v6_dma_unmap_area) __INITDATA - .type v6_cache_fns, #object -ENTRY(v6_cache_fns) - .long v6_flush_icache_all - .long v6_flush_kern_cache_all - .long v6_flush_user_cache_all - .long v6_flush_user_cache_range - .long v6_coherent_kern_range - .long v6_coherent_user_range - .long v6_flush_kern_dcache_area - .long v6_dma_map_area - .long v6_dma_unmap_area - .long v6_dma_flush_range - .size v6_cache_fns, . - v6_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v6 diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index d32f02b6186..07c4bc8ea0a 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -174,6 +174,10 @@ ENTRY(v7_coherent_user_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r12, r0, r3 +#ifdef CONFIG_ARM_ERRATA_764369 + ALT_SMP(W(dsb)) + ALT_UP(W(nop)) +#endif 1: USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification add r12, r12, r2 @@ -223,6 +227,10 @@ ENTRY(v7_flush_kern_dcache_area) add r1, r0, r1 sub r3, r2, #1 bic r0, r0, r3 +#ifdef CONFIG_ARM_ERRATA_764369 + ALT_SMP(W(dsb)) + ALT_UP(W(nop)) +#endif 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line add r0, r0, r2 @@ -247,6 +255,10 @@ v7_dma_inv_range: sub r3, r2, #1 tst r0, r3 bic r0, r0, r3 +#ifdef CONFIG_ARM_ERRATA_764369 + ALT_SMP(W(dsb)) + ALT_UP(W(nop)) +#endif mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line tst r1, r3 @@ -270,6 +282,10 @@ v7_dma_clean_range: dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 +#ifdef CONFIG_ARM_ERRATA_764369 + ALT_SMP(W(dsb)) + ALT_UP(W(nop)) +#endif 1: mcr p15, 0, r0, c7, c10, 1 @ clean D / U line add r0, r0, r2 @@ -288,6 +304,10 @@ ENTRY(v7_dma_flush_range) dcache_line_size r2, r3 sub r3, r2, #1 bic r0, r0, r3 +#ifdef CONFIG_ARM_ERRATA_764369 + ALT_SMP(W(dsb)) + ALT_UP(W(nop)) +#endif 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line add r0, r0, r2 @@ -325,16 +345,5 @@ ENDPROC(v7_dma_unmap_area) __INITDATA - .type v7_cache_fns, #object -ENTRY(v7_cache_fns) - .long v7_flush_icache_all - .long v7_flush_kern_cache_all - .long v7_flush_user_cache_all - .long v7_flush_user_cache_range - .long v7_coherent_kern_range - .long v7_coherent_user_range - .long v7_flush_kern_dcache_area - .long v7_dma_map_area - .long v7_dma_unmap_area - .long v7_dma_flush_range - .size v7_cache_fns, . - v7_cache_fns + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions v7 diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index b0ee9ba3cfa..93aac068da9 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -16,7 +16,7 @@ #include <asm/mmu_context.h> #include <asm/tlbflush.h> -static DEFINE_SPINLOCK(cpu_asid_lock); +static DEFINE_RAW_SPINLOCK(cpu_asid_lock); unsigned int cpu_last_asid = ASID_FIRST_VERSION; #ifdef CONFIG_SMP DEFINE_PER_CPU(struct mm_struct *, current_mm); @@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct mm_struct *, current_mm); void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { mm->context.id = 0; - spin_lock_init(&mm->context.id_lock); + raw_spin_lock_init(&mm->context.id_lock); } static void flush_context(void) @@ -58,7 +58,7 @@ static void set_mm_context(struct mm_struct *mm, unsigned int asid) * the broadcast. This function is also called via IPI so the * mm->context.id_lock has to be IRQ-safe. */ - spin_lock_irqsave(&mm->context.id_lock, flags); + raw_spin_lock_irqsave(&mm->context.id_lock, flags); if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) { /* * Old version of ASID found. Set the new one and @@ -67,7 +67,7 @@ static void set_mm_context(struct mm_struct *mm, unsigned int asid) mm->context.id = asid; cpumask_clear(mm_cpumask(mm)); } - spin_unlock_irqrestore(&mm->context.id_lock, flags); + raw_spin_unlock_irqrestore(&mm->context.id_lock, flags); /* * Set the mm_cpumask(mm) bit for the current CPU. @@ -117,7 +117,7 @@ void __new_context(struct mm_struct *mm) { unsigned int asid; - spin_lock(&cpu_asid_lock); + raw_spin_lock(&cpu_asid_lock); #ifdef CONFIG_SMP /* * Check the ASID again, in case the change was broadcast from @@ -125,7 +125,7 @@ void __new_context(struct mm_struct *mm) */ if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) { cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); - spin_unlock(&cpu_asid_lock); + raw_spin_unlock(&cpu_asid_lock); return; } #endif @@ -153,5 +153,5 @@ void __new_context(struct mm_struct *mm) } set_mm_context(mm, asid); - spin_unlock(&cpu_asid_lock); + raw_spin_unlock(&cpu_asid_lock); } diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index b8061519ce7..7d0a8c23034 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -30,7 +30,7 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) -static DEFINE_SPINLOCK(minicache_lock); +static DEFINE_RAW_SPINLOCK(minicache_lock); /* * ARMv4 mini-dcache optimised copy_user_highpage @@ -76,14 +76,14 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, if (!test_and_set_bit(PG_dcache_clean, &from->flags)) __flush_dcache_page(page_mapping(from), from); - spin_lock(&minicache_lock); + raw_spin_lock(&minicache_lock); set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); flush_tlb_kernel_page(0xffff8000); mc_copy_user_page((void *)0xffff8000, kto); - spin_unlock(&minicache_lock); + raw_spin_unlock(&minicache_lock); kunmap_atomic(kto, KM_USER1); } diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index bdba6c65c90..3d9a1552cef 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -27,7 +27,7 @@ #define from_address (0xffff8000) #define to_address (0xffffc000) -static DEFINE_SPINLOCK(v6_lock); +static DEFINE_RAW_SPINLOCK(v6_lock); /* * Copy the user page. No aliasing to deal with so we can just @@ -41,7 +41,6 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, kfrom = kmap_atomic(from, KM_USER0); kto = kmap_atomic(to, KM_USER1); copy_page(kto, kfrom); - __cpuc_flush_dcache_area(kto, PAGE_SIZE); kunmap_atomic(kto, KM_USER1); kunmap_atomic(kfrom, KM_USER0); } @@ -89,7 +88,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to, * Now copy the page using the same cache colour as the * pages ultimate destination. */ - spin_lock(&v6_lock); + raw_spin_lock(&v6_lock); set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); @@ -102,7 +101,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to, copy_page((void *)kto, (void *)kfrom); - spin_unlock(&v6_lock); + raw_spin_unlock(&v6_lock); } /* @@ -122,13 +121,13 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad * Now clear the page using the same cache colour as * the pages ultimate destination. */ - spin_lock(&v6_lock); + raw_spin_lock(&v6_lock); set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); flush_tlb_kernel_page(to); clear_page((void *)to); - spin_unlock(&v6_lock); + raw_spin_unlock(&v6_lock); } struct cpu_user_fns v6_user_fns __initdata = { diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 649bbcd325b..610c24ced31 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -32,7 +32,7 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) -static DEFINE_SPINLOCK(minicache_lock); +static DEFINE_RAW_SPINLOCK(minicache_lock); /* * XScale mini-dcache optimised copy_user_highpage @@ -98,14 +98,14 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from, if (!test_and_set_bit(PG_dcache_clean, &from->flags)) __flush_dcache_page(page_mapping(from), from); - spin_lock(&minicache_lock); + raw_spin_lock(&minicache_lock); set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); flush_tlb_kernel_page(COPYPAGE_MINICACHE); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); - spin_unlock(&minicache_lock); + raw_spin_unlock(&minicache_lock); kunmap_atomic(kto, KM_USER1); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 82a093cee09..e4e7f6cba1a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -18,16 +18,20 @@ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/highmem.h> +#include <linux/slab.h> #include <asm/memory.h> #include <asm/highmem.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/sizes.h> +#include <asm/mach/arch.h> + +#include "mm.h" static u64 get_coherent_dma_mask(struct device *dev) { - u64 mask = ISA_DMA_THRESHOLD; + u64 mask = (u64)arm_dma_limit; if (dev) { mask = dev->coherent_dma_mask; @@ -41,10 +45,10 @@ static u64 get_coherent_dma_mask(struct device *dev) return 0; } - if ((~mask) & ISA_DMA_THRESHOLD) { + if ((~mask) & (u64)arm_dma_limit) { dev_warn(dev, "coherent DMA mask %#llx is smaller " "than system GFP_DMA mask %#llx\n", - mask, (unsigned long long)ISA_DMA_THRESHOLD); + mask, (u64)arm_dma_limit); return 0; } } @@ -115,26 +119,36 @@ static void __dma_free_buffer(struct page *page, size_t size) } #ifdef CONFIG_MMU -/* Sanity check size */ -#if (CONSISTENT_DMA_SIZE % SZ_2M) -#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB" -#endif -#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) -#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) -#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) +#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT) +#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT) /* * These are the page tables (2MB each) covering uncached, DMA consistent allocations */ -static pte_t *consistent_pte[NUM_CONSISTENT_PTES]; +static pte_t **consistent_pte; + +#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M + +unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; + +void __init init_consistent_dma_size(unsigned long size) +{ + unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M); + + BUG_ON(consistent_pte); /* Check we're called before DMA region init */ + BUG_ON(base < VMALLOC_END); + + /* Grow region to accommodate specified size */ + if (base < consistent_base) + consistent_base = base; +} #include "vmregion.h" static struct arm_vmregion_head consistent_head = { .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock), .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), - .vm_start = CONSISTENT_BASE, .vm_end = CONSISTENT_END, }; @@ -153,7 +167,17 @@ static int __init consistent_init(void) pmd_t *pmd; pte_t *pte; int i = 0; - u32 base = CONSISTENT_BASE; + unsigned long base = consistent_base; + unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT; + + consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); + if (!consistent_pte) { + pr_err("%s: no memory\n", __func__); + return -ENOMEM; + } + + pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END); + consistent_head.vm_start = base; do { pgd = pgd_offset(&init_mm, base); @@ -181,7 +205,7 @@ static int __init consistent_init(void) } consistent_pte[i++] = pte; - base += (1 << PGDIR_SHIFT); + base += PMD_SIZE; } while (base < CONSISTENT_END); return ret; @@ -196,7 +220,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) size_t align; int bit; - if (!consistent_pte[0]) { + if (!consistent_pte) { printk(KERN_ERR "%s: not initialised\n", __func__); dump_stack(); return NULL; @@ -322,6 +346,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, if (addr) *handle = pfn_to_dma(dev, page_to_pfn(page)); + else + __dma_free_buffer(page, size); return addr; } @@ -657,6 +683,33 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } EXPORT_SYMBOL(dma_sync_sg_for_device); +/* + * Return whether the given device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits + * during bus mastering, then you would pass 0x00ffffff as the mask + * to this function. + */ +int dma_supported(struct device *dev, u64 mask) +{ + if (mask < (u64)arm_dma_limit) + return 0; + return 1; +} +EXPORT_SYMBOL(dma_supported); + +int dma_set_mask(struct device *dev, u64 dma_mask) +{ + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + +#ifndef CONFIG_DMABOUNCE + *dev->dma_mask = dma_mask; +#endif + + return 0; +} +EXPORT_SYMBOL(dma_set_mask); + #define PREALLOC_DMA_DEBUG_ENTRIES 4096 static int __init dma_debug_do_init(void) diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 7cab7917942..7599e2625c7 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -8,7 +8,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index bc0e1d88fd3..aa33949fef6 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -20,6 +20,7 @@ #include <linux/highmem.h> #include <linux/perf_event.h> +#include <asm/exception.h> #include <asm/system.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -94,7 +95,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr) pud = pud_offset(pgd, addr); if (PTRS_PER_PUD != 1) - printk(", *pud=%08lx", pud_val(*pud)); + printk(", *pud=%08llx", (long long)pud_val(*pud)); if (pud_none(*pud)) break; @@ -285,6 +286,10 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) tsk = current; mm = tsk->mm; + /* Enable interrupts if they were enabled in the parent context. */ + if (interrupts_enabled(regs)) + local_irq_enable(); + /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -318,11 +323,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) fault = __do_page_fault(mm, addr, fsr, tsk); up_read(&mm->mmap_sem); - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, addr); + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); if (fault & VM_FAULT_MAJOR) - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, regs, addr); + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, addr); else if (fault & VM_FAULT_MINOR) - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, regs, addr); + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, addr); /* * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c19571c40a2..fbdd12ea3a5 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/bootmem.h> #include <linux/mman.h> +#include <linux/export.h> #include <linux/nodemask.h> #include <linux/initrd.h> #include <linux/of_fdt.h> @@ -212,6 +213,18 @@ static void __init arm_bootmem_init(unsigned long start_pfn, } #ifdef CONFIG_ZONE_DMA + +unsigned long arm_dma_zone_size __read_mostly; +EXPORT_SYMBOL(arm_dma_zone_size); + +/* + * The DMA mask corresponding to the maximum bus address allocatable + * using GFP_DMA. The default here places no restriction on DMA + * allocations. This must be the smallest DMA mask in the system, + * so a successful GFP_DMA allocation will always satisfy this. + */ +u32 arm_dma_limit; + static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, unsigned long dma_size) { @@ -267,17 +280,17 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, #endif } -#ifdef ARM_DMA_ZONE_SIZE -#ifndef CONFIG_ZONE_DMA -#error ARM_DMA_ZONE_SIZE set but no DMA zone to limit allocations -#endif - +#ifdef CONFIG_ZONE_DMA /* * Adjust the sizes according to any special requirements for * this machine type. */ - arm_adjust_dma_zone(zone_size, zhole_size, - ARM_DMA_ZONE_SIZE >> PAGE_SHIFT); + if (arm_dma_zone_size) { + arm_adjust_dma_zone(zone_size, zhole_size, + arm_dma_zone_size >> PAGE_SHIFT); + arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1; + } else + arm_dma_limit = 0xffffffff; #endif free_area_init_node(0, zone_size, min, zhole_size); @@ -286,7 +299,7 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid(unsigned long pfn) { - return memblock_is_memory(pfn << PAGE_SHIFT); + return memblock_is_memory(__pfn_to_phys(pfn)); } EXPORT_SYMBOL(pfn_valid); #endif @@ -422,6 +435,17 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) return pages; } +/* + * Poison init memory with an undefined instruction (ARM) or a branch to an + * undefined instruction (Thumb). + */ +static inline void poison_init_mem(void *s, size_t count) +{ + u32 *p = (u32 *)s; + for (; count != 0; count -= 4) + *p++ = 0xe7fddef0; +} + static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn) { @@ -473,6 +497,13 @@ static void __init free_unused_memmap(struct meminfo *mi) */ bank_start = min(bank_start, ALIGN(prev_bank_end, PAGES_PER_SECTION)); +#else + /* + * Align down here since the VM subsystem insists that the + * memmap entries are valid from the bank start aligned to + * MAX_ORDER_NR_PAGES. + */ + bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES); #endif /* * If we had a previous bank, and there is a space @@ -630,17 +661,14 @@ void __init mem_init(void) " ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n" #endif " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" -#ifdef CONFIG_MMU - " DMA : 0x%08lx - 0x%08lx (%4ld MB)\n" -#endif " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" #ifdef CONFIG_HIGHMEM " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" #endif " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" - " .init : 0x%p" " - 0x%p" " (%4d kB)\n" " .text : 0x%p" " - 0x%p" " (%4d kB)\n" + " .init : 0x%p" " - 0x%p" " (%4d kB)\n" " .data : 0x%p" " - 0x%p" " (%4d kB)\n" " .bss : 0x%p" " - 0x%p" " (%4d kB)\n", @@ -651,9 +679,6 @@ void __init mem_init(void) MLK(ITCM_OFFSET, (unsigned long) itcm_end), #endif MLK(FIXADDR_START, FIXADDR_TOP), -#ifdef CONFIG_MMU - MLM(CONSISTENT_BASE, CONSISTENT_END), -#endif MLM(VMALLOC_START, VMALLOC_END), MLM(PAGE_OFFSET, (unsigned long)high_memory), #ifdef CONFIG_HIGHMEM @@ -662,8 +687,8 @@ void __init mem_init(void) #endif MLM(MODULES_VADDR, MODULES_END), - MLK_ROUNDUP(__init_begin, __init_end), MLK_ROUNDUP(_text, _etext), + MLK_ROUNDUP(__init_begin, __init_end), MLK_ROUNDUP(_sdata, _edata), MLK_ROUNDUP(__bss_start, __bss_stop)); @@ -676,9 +701,6 @@ void __init mem_init(void) * be detected at build time already. */ #ifdef CONFIG_MMU - BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE); - BUG_ON(VMALLOC_END > CONSISTENT_BASE); - BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR); BUG_ON(TASK_SIZE > MODULES_VADDR); #endif @@ -704,11 +726,13 @@ void free_initmem(void) #ifdef CONFIG_HAVE_TCM extern char __tcm_start, __tcm_end; + poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), __phys_to_pfn(__pa(&__tcm_end)), "TCM link"); #endif + poison_init_mem(__init_begin, __init_end - __init_begin); if (!machine_is_integrator() && !machine_is_cintegrator()) totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), __phys_to_pfn(__pa(__init_end)), @@ -721,10 +745,12 @@ static int keep_initrd; void free_initrd_mem(unsigned long start, unsigned long end) { - if (!keep_initrd) + if (!keep_initrd) { + poison_init_mem((void *)start, PAGE_ALIGN(end) - start); totalram_pages += free_area(__phys_to_pfn(__pa(start)), __phys_to_pfn(__pa(end)), "initrd"); + } } static int __init keepinitrd_setup(char *__unused) diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index ffad039cbb7..430df1a5978 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -9,6 +9,9 @@ #include <linux/ioport.h> #include <linux/io.h> +unsigned long vga_base; +EXPORT_SYMBOL(vga_base); + #ifdef __io void __iomem *ioport_map(unsigned long port, unsigned int nr) { @@ -23,6 +26,15 @@ EXPORT_SYMBOL(ioport_unmap); #endif #ifdef CONFIG_PCI +unsigned long pcibios_min_io = 0x1000; +EXPORT_SYMBOL(pcibios_min_io); + +unsigned long pcibios_min_mem = 0x01000000; +EXPORT_SYMBOL(pcibios_min_mem); + +unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; +EXPORT_SYMBOL(pci_flags); + void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { resource_size_t start = pci_resource_start(dev, bar); diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index ab506272b2d..bdb248c4f55 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -289,6 +289,27 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) } EXPORT_SYMBOL(__arm_ioremap); +/* + * Remap an arbitrary physical address space into the kernel virtual + * address space as memory. Needed when the kernel wants to execute + * code in external memory. This is needed for reprogramming source + * clocks that would affect normal memory for example. Please see + * CONFIG_GENERIC_ALLOCATOR for allocating external memory. + */ +void __iomem * +__arm_ioremap_exec(unsigned long phys_addr, size_t size, bool cached) +{ + unsigned int mtype; + + if (cached) + mtype = MT_MEMORY; + else + mtype = MT_MEMORY_NONCACHED; + + return __arm_ioremap_caller(phys_addr, size, mtype, + __builtin_return_address(0)); +} + void __iounmap(volatile void __iomem *io_addr) { void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 5b3d7d54365..ad7cce3bc43 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -12,8 +12,8 @@ static inline pmd_t *pmd_off_k(unsigned long virt) struct mem_type { pteval_t prot_pte; - unsigned int prot_l1; - unsigned int prot_sect; + pmdval_t prot_l1; + pmdval_t prot_sect; unsigned int domain; }; @@ -23,5 +23,11 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page #endif +#ifdef CONFIG_ZONE_DMA +extern u32 arm_dma_limit; +#else +#define arm_dma_limit ((u32)~0) +#endif + void __init bootmem_init(void); void arm_mm_memblock_reserve(void); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 594d677b92c..dc8c550e6cb 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -60,7 +60,7 @@ EXPORT_SYMBOL(pgprot_kernel); struct cachepolicy { const char policy[16]; unsigned int cr_mask; - unsigned int pmd; + pmdval_t pmd; pteval_t pte; }; @@ -273,6 +273,14 @@ static struct mem_type mem_types[] = { .prot_l1 = PMD_TYPE_TABLE, .domain = DOMAIN_KERNEL, }, + [MT_MEMORY_SO] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_MT_UNCACHED, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S | + PMD_SECT_UNCACHED | PMD_SECT_XN, + .domain = DOMAIN_KERNEL, + }, }; const struct mem_type *get_mem_type(unsigned int type) @@ -288,7 +296,7 @@ static void __init build_mem_type_table(void) { struct cachepolicy *cp; unsigned int cr = get_cr(); - unsigned int user_pgprot, kern_pgprot, vecs_pgprot; + pteval_t user_pgprot, kern_pgprot, vecs_pgprot; int cpu_arch = cpu_architecture(); int i; @@ -863,14 +871,14 @@ static inline void prepare_page_table(void) /* * Clear out all the mappings below the kernel image. */ - for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE) + for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); #ifdef CONFIG_XIP_KERNEL /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK; + addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK; #endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); /* @@ -885,10 +893,12 @@ static inline void prepare_page_table(void) * memory bank, up to the end of the vmalloc region. */ for (addr = __phys_to_virt(end); - addr < VMALLOC_END; addr += PGDIR_SIZE) + addr < VMALLOC_END; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); } +#define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) + /* * Reserve the special regions of memory */ @@ -898,7 +908,7 @@ void __init arm_mm_memblock_reserve(void) * Reserve the page tables. These are already in use, * and can only be in node 0. */ - memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t)); + memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE); #ifdef CONFIG_SA1111 /* @@ -926,7 +936,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) */ vectors_page = early_alloc(PAGE_SIZE); - for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + for (addr = VMALLOC_END; addr; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); /* diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S index 87970eba88e..8bbff025269 100644 --- a/arch/arm/mm/pabort-legacy.S +++ b/arch/arm/mm/pabort-legacy.S @@ -4,16 +4,18 @@ /* * Function: legacy_pabort * - * Params : r0 = address of aborted instruction + * Params : r2 = pt_regs + * : r4 = address of aborted instruction + * : r5 = psr for parent context * - * Returns : r0 = address of abort - * : r1 = Simulated IFSR with section translation fault status + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current prefetch abort. */ .align 5 ENTRY(legacy_pabort) + mov r0, r4 mov r1, #5 - mov pc, lr + b do_PrefetchAbort ENDPROC(legacy_pabort) diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S index 06e3d1ef211..9627646ce78 100644 --- a/arch/arm/mm/pabort-v6.S +++ b/arch/arm/mm/pabort-v6.S @@ -4,16 +4,18 @@ /* * Function: v6_pabort * - * Params : r0 = address of aborted instruction + * Params : r2 = pt_regs + * : r4 = address of aborted instruction + * : r5 = psr for parent context * - * Returns : r0 = address of abort - * : r1 = IFSR + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current prefetch abort. */ .align 5 ENTRY(v6_pabort) + mov r0, r4 mrc p15, 0, r1, c5, c0, 1 @ get IFSR - mov pc, lr + b do_PrefetchAbort ENDPROC(v6_pabort) diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S index a8b3b300a18..875761f44f3 100644 --- a/arch/arm/mm/pabort-v7.S +++ b/arch/arm/mm/pabort-v7.S @@ -2,12 +2,13 @@ #include <asm/assembler.h> /* - * Function: v6_pabort + * Function: v7_pabort * - * Params : r0 = address of aborted instruction + * Params : r2 = pt_regs + * : r4 = address of aborted instruction + * : r5 = psr for parent context * - * Returns : r0 = address of abort - * : r1 = IFSR + * Returns : r4 - r11, r13 preserved * * Purpose : obtain information about current prefetch abort. */ @@ -16,5 +17,5 @@ ENTRY(v7_pabort) mrc p15, 0, r0, c6, c0, 2 @ get IFAR mrc p15, 0, r1, c5, c0, 1 @ get IFSR - mov pc, lr + b do_PrefetchAbort ENDPROC(v7_pabort) diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 6c4e7fd6c8a..67469665d47 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -364,17 +364,8 @@ ENTRY(arm1020_dma_unmap_area) mov pc, lr ENDPROC(arm1020_dma_unmap_area) -ENTRY(arm1020_cache_fns) - .long arm1020_flush_icache_all - .long arm1020_flush_kern_cache_all - .long arm1020_flush_user_cache_all - .long arm1020_flush_user_cache_range - .long arm1020_coherent_kern_range - .long arm1020_coherent_user_range - .long arm1020_flush_kern_dcache_area - .long arm1020_dma_map_area - .long arm1020_dma_unmap_area - .long arm1020_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm1020 .align 5 ENTRY(cpu_arm1020_dcache_clean_area) @@ -477,38 +468,14 @@ arm1020_crval: crval clear=0x0000593f, mmuset=0x00003935, ucset=0x00001930 __INITDATA + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm1020, dabort=v4t_early_abort, pabort=legacy_pabort -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm1020_processor_functions, #object -arm1020_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm1020_proc_init - .word cpu_arm1020_proc_fin - .word cpu_arm1020_reset - .word cpu_arm1020_do_idle - .word cpu_arm1020_dcache_clean_area - .word cpu_arm1020_switch_mm - .word cpu_arm1020_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm1020_processor_functions, . - arm1020_processor_functions .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name + string cpu_arch_name, "armv5t" + string cpu_elf_name, "v5" .type cpu_arm1020_name, #object cpu_arm1020_name: diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 4ce947c1962..4251421c0ed 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -350,17 +350,8 @@ ENTRY(arm1020e_dma_unmap_area) mov pc, lr ENDPROC(arm1020e_dma_unmap_area) -ENTRY(arm1020e_cache_fns) - .long arm1020e_flush_icache_all - .long arm1020e_flush_kern_cache_all - .long arm1020e_flush_user_cache_all - .long arm1020e_flush_user_cache_range - .long arm1020e_coherent_kern_range - .long arm1020e_coherent_user_range - .long arm1020e_flush_kern_dcache_area - .long arm1020e_dma_map_area - .long arm1020e_dma_unmap_area - .long arm1020e_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm1020e .align 5 ENTRY(cpu_arm1020e_dcache_clean_area) @@ -458,43 +449,14 @@ arm1020e_crval: crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm1020e_processor_functions, #object -arm1020e_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm1020e_proc_init - .word cpu_arm1020e_proc_fin - .word cpu_arm1020e_reset - .word cpu_arm1020e_do_idle - .word cpu_arm1020e_dcache_clean_area - .word cpu_arm1020e_switch_mm - .word cpu_arm1020e_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm1020e_processor_functions, . - arm1020e_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm1020e, dabort=v4t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm1020e_name, #object -cpu_arm1020e_name: - .asciz "ARM1020E" - .size cpu_arm1020e_name, . - cpu_arm1020e_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + string cpu_arm1020e_name, "ARM1020E" .align diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index c8884c5413a..d283cf3d06e 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -339,17 +339,8 @@ ENTRY(arm1022_dma_unmap_area) mov pc, lr ENDPROC(arm1022_dma_unmap_area) -ENTRY(arm1022_cache_fns) - .long arm1022_flush_icache_all - .long arm1022_flush_kern_cache_all - .long arm1022_flush_user_cache_all - .long arm1022_flush_user_cache_range - .long arm1022_coherent_kern_range - .long arm1022_coherent_user_range - .long arm1022_flush_kern_dcache_area - .long arm1022_dma_map_area - .long arm1022_dma_unmap_area - .long arm1022_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm1022 .align 5 ENTRY(cpu_arm1022_dcache_clean_area) @@ -441,43 +432,14 @@ arm1022_crval: crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm1022_processor_functions, #object -arm1022_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm1022_proc_init - .word cpu_arm1022_proc_fin - .word cpu_arm1022_reset - .word cpu_arm1022_do_idle - .word cpu_arm1022_dcache_clean_area - .word cpu_arm1022_switch_mm - .word cpu_arm1022_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm1022_processor_functions, . - arm1022_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm1022, dabort=v4t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm1022_name, #object -cpu_arm1022_name: - .asciz "ARM1022" - .size cpu_arm1022_name, . - cpu_arm1022_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + string cpu_arm1022_name, "ARM1022" .align diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index 413684660aa..678a1ceafed 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -333,17 +333,8 @@ ENTRY(arm1026_dma_unmap_area) mov pc, lr ENDPROC(arm1026_dma_unmap_area) -ENTRY(arm1026_cache_fns) - .long arm1026_flush_icache_all - .long arm1026_flush_kern_cache_all - .long arm1026_flush_user_cache_all - .long arm1026_flush_user_cache_range - .long arm1026_coherent_kern_range - .long arm1026_coherent_user_range - .long arm1026_flush_kern_dcache_area - .long arm1026_dma_map_area - .long arm1026_dma_unmap_area - .long arm1026_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm1026 .align 5 ENTRY(cpu_arm1026_dcache_clean_area) @@ -436,45 +427,15 @@ arm1026_crval: crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm1026_processor_functions, #object -arm1026_processor_functions: - .word v5t_early_abort - .word legacy_pabort - .word cpu_arm1026_proc_init - .word cpu_arm1026_proc_fin - .word cpu_arm1026_reset - .word cpu_arm1026_do_idle - .word cpu_arm1026_dcache_clean_area - .word cpu_arm1026_switch_mm - .word cpu_arm1026_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm1026_processor_functions, . - arm1026_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort .section .rodata - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5tej" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name + string cpu_arch_name, "armv5tej" + string cpu_elf_name, "v5" .align - - .type cpu_arm1026_name, #object -cpu_arm1026_name: - .asciz "ARM1026EJ-S" - .size cpu_arm1026_name, . - cpu_arm1026_name - + string cpu_arm1026_name, "ARM1026EJ-S" .align .section ".proc.info.init", #alloc, #execinstr diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 5f79dc4ce3f..e5b974cddac 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S @@ -29,19 +29,19 @@ ENTRY(cpu_arm7_dcache_clean_area) /* * Function: arm6_7_data_abort () * - * Params : r2 = address of aborted instruction - * : sp = pointer to registers + * Params : r2 = pt_regs + * : r4 = aborted context pc + * : r5 = aborted context psr * * Purpose : obtain information about current aborted instruction * - * Returns : r0 = address of abort - * : r1 = FSR + * Returns : r4-r5, r10-r11, r13 preserved */ ENTRY(cpu_arm7_data_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - ldr r8, [r2] @ read arm instruction + ldr r8, [r4] @ read arm instruction tst r8, #1 << 20 @ L = 0 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 @@ -49,7 +49,7 @@ ENTRY(cpu_arm7_data_abort) nop /* 0 */ b .data_unknown -/* 1 */ mov pc, lr @ swp +/* 1 */ b do_DataAbort @ swp /* 2 */ b .data_unknown /* 3 */ b .data_unknown /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m @@ -60,87 +60,85 @@ ENTRY(cpu_arm7_data_abort) /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> /* a */ b .data_unknown /* b */ b .data_unknown -/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m -/* d */ mov pc, lr @ ldc rd, [rn, #m] +/* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m +/* d */ b do_DataAbort @ ldc rd, [rn, #m] /* e */ b .data_unknown /* f */ .data_unknown: @ Part of jumptable - mov r0, r2 + mov r0, r4 mov r1, r8 - mov r2, sp - bl baddataabort - b ret_from_exception + b baddataabort ENTRY(cpu_arm6_data_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - ldr r8, [r2] @ read arm instruction + ldr r8, [r4] @ read arm instruction tst r8, #1 << 20 @ L = 0 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #14 << 24 teq r7, #8 << 24 @ was it ldm/stm - movne pc, lr + bne do_DataAbort .data_arm_ldmstm: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup mov r7, #0x11 orr r7, r7, #0x1100 and r6, r8, r7 - and r2, r8, r7, lsl #1 - add r6, r6, r2, lsr #1 - and r2, r8, r7, lsl #2 - add r6, r6, r2, lsr #2 - and r2, r8, r7, lsl #3 - add r6, r6, r2, lsr #3 + and r9, r8, r7, lsl #1 + add r6, r6, r9, lsr #1 + and r9, r8, r7, lsl #2 + add r6, r6, r9, lsr #2 + and r9, r8, r7, lsl #3 + add r6, r6, r9, lsr #3 add r6, r6, r6, lsr #8 add r6, r6, r6, lsr #4 and r6, r6, #15 @ r6 = no. of registers to transfer. - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit subne r7, r7, r6, lsl #2 @ Undo increment addeq r7, r7, r6, lsl #2 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_apply_r6_and_rn: - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit subne r7, r7, r6 @ Undo incrmenet addeq r7, r7, r6 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_lateldrpreconst: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup .data_arm_lateldrpostconst: - movs r2, r8, lsl #20 @ Get offset - moveq pc, lr @ zero -> no fixup - and r5, r8, #15 << 16 @ Extract 'n' from instruction - ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + movs r6, r8, lsl #20 @ Get offset + beq do_DataAbort @ zero -> no fixup + and r9, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' tst r8, #1 << 23 @ Check U bit - subne r7, r7, r2, lsr #20 @ Undo increment - addeq r7, r7, r2, lsr #20 @ Undo decrement - str r7, [sp, r5, lsr #14] @ Put register 'Rn' - mov pc, lr + subne r7, r7, r6, lsr #20 @ Undo increment + addeq r7, r7, r6, lsr #20 @ Undo decrement + str r7, [r2, r9, lsr #14] @ Put register 'Rn' + b do_DataAbort .data_arm_lateldrprereg: tst r8, #1 << 21 @ check writeback bit - moveq pc, lr @ no writeback -> no fixup + beq do_DataAbort @ no writeback -> no fixup .data_arm_lateldrpostreg: and r7, r8, #15 @ Extract 'm' from instruction - ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' - mov r5, r8, lsr #7 @ get shift count - ands r5, r5, #31 + ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' + mov r9, r8, lsr #7 @ get shift count + ands r9, r9, #31 and r7, r8, #0x70 @ get shift type orreq r7, r7, #8 @ shift count = 0 add pc, pc, r7 nop - mov r6, r6, lsl r5 @ 0: LSL #!0 + mov r6, r6, lsl r9 @ 0: LSL #!0 b .data_arm_apply_r6_and_rn b .data_arm_apply_r6_and_rn @ 1: LSL #0 nop @@ -148,7 +146,7 @@ ENTRY(cpu_arm6_data_abort) nop b .data_unknown @ 3: MUL? nop - mov r6, r6, lsr r5 @ 4: LSR #!0 + mov r6, r6, lsr r9 @ 4: LSR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, lsr #32 @ 5: LSR #32 b .data_arm_apply_r6_and_rn @@ -156,7 +154,7 @@ ENTRY(cpu_arm6_data_abort) nop b .data_unknown @ 7: MUL? nop - mov r6, r6, asr r5 @ 8: ASR #!0 + mov r6, r6, asr r9 @ 8: ASR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, asr #32 @ 9: ASR #32 b .data_arm_apply_r6_and_rn @@ -164,7 +162,7 @@ ENTRY(cpu_arm6_data_abort) nop b .data_unknown @ B: MUL? nop - mov r6, r6, ror r5 @ C: ROR #!0 + mov r6, r6, ror r9 @ C: ROR #!0 b .data_arm_apply_r6_and_rn mov r6, r6, rrx @ D: RRX b .data_arm_apply_r6_and_rn @@ -269,159 +267,57 @@ __arm7_setup: mov r0, #0 __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm6_processor_functions, #object -ENTRY(arm6_processor_functions) - .word cpu_arm6_data_abort - .word legacy_pabort - .word cpu_arm6_proc_init - .word cpu_arm6_proc_fin - .word cpu_arm6_reset - .word cpu_arm6_do_idle - .word cpu_arm6_dcache_clean_area - .word cpu_arm6_switch_mm - .word cpu_arm6_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm6_processor_functions, . - arm6_processor_functions - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm7_processor_functions, #object -ENTRY(arm7_processor_functions) - .word cpu_arm7_data_abort - .word legacy_pabort - .word cpu_arm7_proc_init - .word cpu_arm7_proc_fin - .word cpu_arm7_reset - .word cpu_arm7_do_idle - .word cpu_arm7_dcache_clean_area - .word cpu_arm7_switch_mm - .word cpu_arm7_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm7_processor_functions, . - arm7_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm6, dabort=cpu_arm6_data_abort, pabort=legacy_pabort + define_processor_functions arm7, dabort=cpu_arm7_data_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: .asciz "armv3" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: .asciz "v3" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm6_name, #object -cpu_arm6_name: .asciz "ARM6" - .size cpu_arm6_name, . - cpu_arm6_name - - .type cpu_arm610_name, #object -cpu_arm610_name: - .asciz "ARM610" - .size cpu_arm610_name, . - cpu_arm610_name - - .type cpu_arm7_name, #object -cpu_arm7_name: .asciz "ARM7" - .size cpu_arm7_name, . - cpu_arm7_name - - .type cpu_arm710_name, #object -cpu_arm710_name: - .asciz "ARM710" - .size cpu_arm710_name, . - cpu_arm710_name + string cpu_arch_name, "armv3" + string cpu_elf_name, "v3" + string cpu_arm6_name, "ARM6" + string cpu_arm610_name, "ARM610" + string cpu_arm7_name, "ARM7" + string cpu_arm710_name, "ARM710" .align .section ".proc.info.init", #alloc, #execinstr - .type __arm6_proc_info, #object -__arm6_proc_info: - .long 0x41560600 - .long 0xfffffff0 - .long 0x00000c1e - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __arm6_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm6_name - .long arm6_processor_functions - .long v3_tlb_fns - .long v3_user_fns - .long v3_cache_fns - .size __arm6_proc_info, . - __arm6_proc_info - - .type __arm610_proc_info, #object -__arm610_proc_info: - .long 0x41560610 - .long 0xfffffff0 - .long 0x00000c1e +.macro arm67_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \ + cpu_mm_mmu_flags:req, cpu_flush:req, cpu_proc_funcs:req + .type __\name\()_proc_info, #object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask + .long \cpu_mm_mmu_flags .long PMD_TYPE_SECT | \ PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ - b __arm6_setup + b \cpu_flush .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm610_name - .long arm6_processor_functions + .long \cpu_name + .long \cpu_proc_funcs .long v3_tlb_fns .long v3_user_fns .long v3_cache_fns - .size __arm610_proc_info, . - __arm610_proc_info - - .type __arm7_proc_info, #object -__arm7_proc_info: - .long 0x41007000 - .long 0xffffff00 - .long 0x00000c1e - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __arm7_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm7_name - .long arm7_processor_functions - .long v3_tlb_fns - .long v3_user_fns - .long v3_cache_fns - .size __arm7_proc_info, . - __arm7_proc_info - - .type __arm710_proc_info, #object -__arm710_proc_info: - .long 0x41007100 - .long 0xfff8ff00 - .long PMD_TYPE_SECT | \ + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm + + arm67_proc_info arm6, 0x41560600, 0xfffffff0, cpu_arm6_name, \ + 0x00000c1e, __arm6_setup, arm6_processor_functions + arm67_proc_info arm610, 0x41560610, 0xfffffff0, cpu_arm610_name, \ + 0x00000c1e, __arm6_setup, arm6_processor_functions + arm67_proc_info arm7, 0x41007000, 0xffffff00, cpu_arm7_name, \ + 0x00000c1e, __arm7_setup, arm7_processor_functions + arm67_proc_info arm710, 0x41007100, 0xfff8ff00, cpu_arm710_name, \ + PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __arm7_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm710_name - .long arm7_processor_functions - .long v3_tlb_fns - .long v3_user_fns - .long v3_cache_fns - .size __arm710_proc_info, . - __arm710_proc_info + PMD_SECT_AP_READ, \ + __arm7_setup, arm7_processor_functions diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 7a06e5964f5..55f4e290665 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -169,46 +169,15 @@ arm720_crval: crval clear=0x00002f3f, mmuset=0x0000213d, ucset=0x00000130 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm720_processor_functions, #object -ENTRY(arm720_processor_functions) - .word v4t_late_abort - .word legacy_pabort - .word cpu_arm720_proc_init - .word cpu_arm720_proc_fin - .word cpu_arm720_reset - .word cpu_arm720_do_idle - .word cpu_arm720_dcache_clean_area - .word cpu_arm720_switch_mm - .word cpu_arm720_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm720_processor_functions, . - arm720_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm720, dabort=v4t_late_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm710_name, #object -cpu_arm710_name: - .asciz "ARM710T" - .size cpu_arm710_name, . - cpu_arm710_name - - .type cpu_arm720_name, #object -cpu_arm720_name: - .asciz "ARM720T" - .size cpu_arm720_name, . - cpu_arm720_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm710_name, "ARM710T" + string cpu_arm720_name, "ARM720T" .align @@ -218,10 +187,11 @@ cpu_arm720_name: .section ".proc.info.init", #alloc, #execinstr - .type __arm710_proc_info, #object -__arm710_proc_info: - .long 0x41807100 @ cpu_val - .long 0xffffff00 @ cpu_mask +.macro arm720_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cpu_flush:req + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ @@ -232,38 +202,17 @@ __arm710_proc_info: PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ - b __arm710_setup @ cpu_flush + b \cpu_flush @ cpu_flush .long cpu_arch_name @ arch_name .long cpu_elf_name @ elf_name .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap - .long cpu_arm710_name @ name + .long \cpu_name .long arm720_processor_functions .long v4_tlb_fns .long v4wt_user_fns .long v4_cache_fns - .size __arm710_proc_info, . - __arm710_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm - .type __arm720_proc_info, #object -__arm720_proc_info: - .long 0x41807200 @ cpu_val - .long 0xffffff00 @ cpu_mask - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __arm720_setup @ cpu_flush - .long cpu_arch_name @ arch_name - .long cpu_elf_name @ elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap - .long cpu_arm720_name @ name - .long arm720_processor_functions - .long v4_tlb_fns - .long v4wt_user_fns - .long v4_cache_fns - .size __arm720_proc_info, . - __arm720_proc_info + arm720_proc_info arm710, 0x41807100, 0xffffff00, cpu_arm710_name, __arm710_setup + arm720_proc_info arm720, 0x41807200, 0xffffff00, cpu_arm720_name, __arm720_setup diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S index 6f9d12effee..4506be3adda 100644 --- a/arch/arm/mm/proc-arm740.S +++ b/arch/arm/mm/proc-arm740.S @@ -17,6 +17,8 @@ #include <asm/pgtable.h> #include <asm/ptrace.h> +#include "proc-macros.S" + .text /* * cpu_arm740_proc_init() @@ -115,42 +117,14 @@ __arm740_setup: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm740_processor_functions, #object -ENTRY(arm740_processor_functions) - .word v4t_late_abort - .word legacy_pabort - .word cpu_arm740_proc_init - .word cpu_arm740_proc_fin - .word cpu_arm740_reset - .word cpu_arm740_do_idle - .word cpu_arm740_dcache_clean_area - .word cpu_arm740_switch_mm - .word 0 @ cpu_*_set_pte - .word 0 - .word 0 - .word 0 - .size arm740_processor_functions, . - arm740_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm740, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm740_name, #object -cpu_arm740_name: - .ascii "ARM740T" - .size cpu_arm740_name, . - cpu_arm740_name + string cpu_arch_name, "armv4" + string cpu_elf_name, "v4" + string cpu_arm740_name, "ARM740T" .align @@ -170,5 +144,3 @@ __arm740_proc_info: .long 0 .long v3_cache_fns @ cache model .size __arm740_proc_info, . - __arm740_proc_info - - diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S index 537ffcb0646..7e0e1fe4ed4 100644 --- a/arch/arm/mm/proc-arm7tdmi.S +++ b/arch/arm/mm/proc-arm7tdmi.S @@ -17,6 +17,8 @@ #include <asm/pgtable.h> #include <asm/ptrace.h> +#include "proc-macros.S" + .text /* * cpu_arm7tdmi_proc_init() @@ -55,197 +57,57 @@ __arm7tdmi_setup: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm7tdmi_processor_functions, #object -ENTRY(arm7tdmi_processor_functions) - .word v4t_late_abort - .word legacy_pabort - .word cpu_arm7tdmi_proc_init - .word cpu_arm7tdmi_proc_fin - .word cpu_arm7tdmi_reset - .word cpu_arm7tdmi_do_idle - .word cpu_arm7tdmi_dcache_clean_area - .word cpu_arm7tdmi_switch_mm - .word 0 @ cpu_*_set_pte - .word 0 - .word 0 - .word 0 - .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm7tdmi, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm7tdmi_name, #object -cpu_arm7tdmi_name: - .asciz "ARM7TDMI" - .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name - - .type cpu_triscenda7_name, #object -cpu_triscenda7_name: - .asciz "Triscend-A7x" - .size cpu_triscenda7_name, . - cpu_triscenda7_name - - .type cpu_at91_name, #object -cpu_at91_name: - .asciz "Atmel-AT91M40xxx" - .size cpu_at91_name, . - cpu_at91_name - - .type cpu_s3c3410_name, #object -cpu_s3c3410_name: - .asciz "Samsung-S3C3410" - .size cpu_s3c3410_name, . - cpu_s3c3410_name - - .type cpu_s3c44b0x_name, #object -cpu_s3c44b0x_name: - .asciz "Samsung-S3C44B0x" - .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name - - .type cpu_s3c4510b, #object -cpu_s3c4510b_name: - .asciz "Samsung-S3C4510B" - .size cpu_s3c4510b_name, . - cpu_s3c4510b_name - - .type cpu_s3c4530_name, #object -cpu_s3c4530_name: - .asciz "Samsung-S3C4530" - .size cpu_s3c4530_name, . - cpu_s3c4530_name - - .type cpu_netarm_name, #object -cpu_netarm_name: - .asciz "NETARM" - .size cpu_netarm_name, . - cpu_netarm_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm7tdmi_name, "ARM7TDMI" + string cpu_triscenda7_name, "Triscend-A7x" + string cpu_at91_name, "Atmel-AT91M40xxx" + string cpu_s3c3410_name, "Samsung-S3C3410" + string cpu_s3c44b0x_name, "Samsung-S3C44B0x" + string cpu_s3c4510b_name, "Samsung-S3C4510B" + string cpu_s3c4530_name, "Samsung-S3C4530" + string cpu_netarm_name, "NETARM" .align .section ".proc.info.init", #alloc, #execinstr - .type __arm7tdmi_proc_info, #object -__arm7tdmi_proc_info: - .long 0x41007700 - .long 0xfff8ff00 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm7tdmi_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __arm7tdmi_proc_info, . - __arm7tdmi_proc_info - - .type __triscenda7_proc_info, #object -__triscenda7_proc_info: - .long 0x0001d2ff - .long 0x0001ffff - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_triscenda7_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __triscenda7_proc_info, . - __triscenda7_proc_info - - .type __at91_proc_info, #object -__at91_proc_info: - .long 0x14000040 - .long 0xfff000e0 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_at91_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __at91_proc_info, . - __at91_proc_info - - .type __s3c4510b_proc_info, #object -__s3c4510b_proc_info: - .long 0x36365000 - .long 0xfffff000 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c4510b_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c4510b_proc_info, . - __s3c4510b_proc_info - - .type __s3c4530_proc_info, #object -__s3c4530_proc_info: - .long 0x4c000000 - .long 0xfff000e0 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c4530_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c4530_proc_info, . - __s3c4530_proc_info - - .type __s3c3410_proc_info, #object -__s3c3410_proc_info: - .long 0x34100000 - .long 0xffff0000 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c3410_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c3410_proc_info, . - __s3c3410_proc_info - - .type __s3c44b0x_proc_info, #object -__s3c44b0x_proc_info: - .long 0x44b00000 - .long 0xffff0000 +.macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \ + extra_hwcaps=0 + .type __\name\()_proc_info, #object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long 0 .long 0 b __arm7tdmi_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c44b0x_name + .long HWCAP_SWP | HWCAP_26BIT | ( \extra_hwcaps ) + .long \cpu_name .long arm7tdmi_processor_functions .long 0 .long 0 .long v4_cache_fns - .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm + + arm7tdmi_proc_info arm7tdmi, 0x41007700, 0xfff8ff00, \ + cpu_arm7tdmi_name + arm7tdmi_proc_info triscenda7, 0x0001d2ff, 0x0001ffff, \ + cpu_triscenda7_name, extra_hwcaps=HWCAP_THUMB + arm7tdmi_proc_info at91, 0x14000040, 0xfff000e0, \ + cpu_at91_name, extra_hwcaps=HWCAP_THUMB + arm7tdmi_proc_info s3c4510b, 0x36365000, 0xfffff000, \ + cpu_s3c4510b_name, extra_hwcaps=HWCAP_THUMB + arm7tdmi_proc_info s3c4530, 0x4c000000, 0xfff000e0, \ + cpu_s3c4530_name, extra_hwcaps=HWCAP_THUMB + arm7tdmi_proc_info s3c3410, 0x34100000, 0xffff0000, \ + cpu_s3c3410_name, extra_hwcaps=HWCAP_THUMB + arm7tdmi_proc_info s3c44b0x, 0x44b00000, 0xffff0000, \ + cpu_s3c44b0x_name, extra_hwcaps=HWCAP_THUMB diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index bf8a1d1cccb..88fb3d9e064 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -315,18 +315,8 @@ ENTRY(arm920_dma_unmap_area) mov pc, lr ENDPROC(arm920_dma_unmap_area) -ENTRY(arm920_cache_fns) - .long arm920_flush_icache_all - .long arm920_flush_kern_cache_all - .long arm920_flush_user_cache_all - .long arm920_flush_user_cache_range - .long arm920_coherent_kern_range - .long arm920_coherent_user_range - .long arm920_flush_kern_dcache_area - .long arm920_dma_map_area - .long arm920_dma_unmap_area - .long arm920_dma_flush_range - + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm920 #endif @@ -392,33 +382,25 @@ ENTRY(cpu_arm920_set_pte_ext) .equ cpu_arm920_suspend_size, 4 * 3 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm920_do_suspend) - stmfd sp!, {r4 - r7, lr} + stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ TTB address - mrc p15, 0, r7, c1, c0, 0 @ Control register - stmia r0, {r4 - r7} - ldmfd sp!, {r4 - r7, pc} + mrc p15, 0, r6, c1, c0, 0 @ Control register + stmia r0, {r4 - r6} + ldmfd sp!, {r4 - r6, pc} ENDPROC(cpu_arm920_do_suspend) ENTRY(cpu_arm920_do_resume) mov ip, #0 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches - ldmia r0, {r4 - r7} + ldmia r0, {r4 - r6} mcr p15, 0, r4, c13, c0, 0 @ PID mcr p15, 0, r5, c3, c0, 0 @ Domain ID - mcr p15, 0, r6, c2, c0, 0 @ TTB address - mov r0, r7 @ control register - mov r2, r6, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE + mcr p15, 0, r1, c2, c0, 0 @ TTB address + mov r0, r6 @ control register b cpu_resume_mmu ENDPROC(cpu_arm920_do_resume) -#else -#define cpu_arm920_do_suspend 0 -#define cpu_arm920_do_resume 0 #endif __CPUINIT @@ -450,43 +432,14 @@ arm920_crval: crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm920_processor_functions, #object -arm920_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm920_proc_init - .word cpu_arm920_proc_fin - .word cpu_arm920_reset - .word cpu_arm920_do_idle - .word cpu_arm920_dcache_clean_area - .word cpu_arm920_switch_mm - .word cpu_arm920_set_pte_ext - .word cpu_arm920_suspend_size - .word cpu_arm920_do_suspend - .word cpu_arm920_do_resume - .size arm920_processor_functions, . - arm920_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm920, dabort=v4t_early_abort, pabort=legacy_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm920_name, #object -cpu_arm920_name: - .asciz "ARM920T" - .size cpu_arm920_name, . - cpu_arm920_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm920_name, "ARM920T" .align diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index 95ba1fc56e4..490e1883385 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -317,18 +317,8 @@ ENTRY(arm922_dma_unmap_area) mov pc, lr ENDPROC(arm922_dma_unmap_area) -ENTRY(arm922_cache_fns) - .long arm922_flush_icache_all - .long arm922_flush_kern_cache_all - .long arm922_flush_user_cache_all - .long arm922_flush_user_cache_range - .long arm922_coherent_kern_range - .long arm922_coherent_user_range - .long arm922_flush_kern_dcache_area - .long arm922_dma_map_area - .long arm922_dma_unmap_area - .long arm922_dma_flush_range - + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm922 #endif @@ -420,43 +410,14 @@ arm922_crval: crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm922_processor_functions, #object -arm922_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm922_proc_init - .word cpu_arm922_proc_fin - .word cpu_arm922_reset - .word cpu_arm922_do_idle - .word cpu_arm922_dcache_clean_area - .word cpu_arm922_switch_mm - .word cpu_arm922_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm922_processor_functions, . - arm922_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm922, dabort=v4t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm922_name, #object -cpu_arm922_name: - .asciz "ARM922T" - .size cpu_arm922_name, . - cpu_arm922_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm922_name, "ARM922T" .align diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 541e4774eea..51d494be057 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -372,17 +372,8 @@ ENTRY(arm925_dma_unmap_area) mov pc, lr ENDPROC(arm925_dma_unmap_area) -ENTRY(arm925_cache_fns) - .long arm925_flush_icache_all - .long arm925_flush_kern_cache_all - .long arm925_flush_user_cache_all - .long arm925_flush_user_cache_range - .long arm925_coherent_kern_range - .long arm925_coherent_user_range - .long arm925_flush_kern_dcache_area - .long arm925_dma_map_area - .long arm925_dma_unmap_area - .long arm925_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm925 ENTRY(cpu_arm925_dcache_clean_area) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH @@ -487,52 +478,24 @@ arm925_crval: crval clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130 __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm925_processor_functions, #object -arm925_processor_functions: - .word v4t_early_abort - .word legacy_pabort - .word cpu_arm925_proc_init - .word cpu_arm925_proc_fin - .word cpu_arm925_reset - .word cpu_arm925_do_idle - .word cpu_arm925_dcache_clean_area - .word cpu_arm925_switch_mm - .word cpu_arm925_set_pte_ext - .word 0 - .word 0 - .word 0 - .size arm925_processor_functions, . - arm925_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm925, dabort=v4t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm925_name, #object -cpu_arm925_name: - .asciz "ARM925T" - .size cpu_arm925_name, . - cpu_arm925_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm925_name, "ARM925T" .align .section ".proc.info.init", #alloc, #execinstr - .type __arm925_proc_info,#object -__arm925_proc_info: - .long 0x54029250 - .long 0xfffffff0 +.macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long PMD_TYPE_SECT | \ PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ @@ -550,27 +513,8 @@ __arm925_proc_info: .long v4wbi_tlb_fns .long v4wb_user_fns .long arm925_cache_fns - .size __arm925_proc_info, . - __arm925_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm - .type __arm915_proc_info,#object -__arm915_proc_info: - .long 0x54029150 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __arm925_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB - .long cpu_arm925_name - .long arm925_processor_functions - .long v4wbi_tlb_fns - .long v4wb_user_fns - .long arm925_cache_fns - .size __arm925_proc_info, . - __arm925_proc_info + arm925_proc_info arm925, 0x54029250, 0xfffffff0, cpu_arm925_name + arm925_proc_info arm915, 0x54029150, 0xfffffff0, cpu_arm925_name diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 0ed85d930c0..9f8fd91f918 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -335,17 +335,8 @@ ENTRY(arm926_dma_unmap_area) mov pc, lr ENDPROC(arm926_dma_unmap_area) -ENTRY(arm926_cache_fns) - .long arm926_flush_icache_all - .long arm926_flush_kern_cache_all - .long arm926_flush_user_cache_all - .long arm926_flush_user_cache_range - .long arm926_coherent_kern_range - .long arm926_coherent_user_range - .long arm926_flush_kern_dcache_area - .long arm926_dma_map_area - .long arm926_dma_unmap_area - .long arm926_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm926 ENTRY(cpu_arm926_dcache_clean_area) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH @@ -406,33 +397,25 @@ ENTRY(cpu_arm926_set_pte_ext) .equ cpu_arm926_suspend_size, 4 * 3 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm926_do_suspend) - stmfd sp!, {r4 - r7, lr} + stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID mrc p15, 0, r5, c3, c0, 0 @ Domain ID - mrc p15, 0, r6, c2, c0, 0 @ TTB address - mrc p15, 0, r7, c1, c0, 0 @ Control register - stmia r0, {r4 - r7} - ldmfd sp!, {r4 - r7, pc} + mrc p15, 0, r6, c1, c0, 0 @ Control register + stmia r0, {r4 - r6} + ldmfd sp!, {r4 - r6, pc} ENDPROC(cpu_arm926_do_suspend) ENTRY(cpu_arm926_do_resume) mov ip, #0 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches - ldmia r0, {r4 - r7} + ldmia r0, {r4 - r6} mcr p15, 0, r4, c13, c0, 0 @ PID mcr p15, 0, r5, c3, c0, 0 @ Domain ID - mcr p15, 0, r6, c2, c0, 0 @ TTB address - mov r0, r7 @ control register - mov r2, r6, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE + mcr p15, 0, r1, c2, c0, 0 @ TTB address + mov r0, r6 @ control register b cpu_resume_mmu ENDPROC(cpu_arm926_do_resume) -#else -#define cpu_arm926_do_suspend 0 -#define cpu_arm926_do_resume 0 #endif __CPUINIT @@ -475,42 +458,14 @@ arm926_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm926_processor_functions, #object -arm926_processor_functions: - .word v5tj_early_abort - .word legacy_pabort - .word cpu_arm926_proc_init - .word cpu_arm926_proc_fin - .word cpu_arm926_reset - .word cpu_arm926_do_idle - .word cpu_arm926_dcache_clean_area - .word cpu_arm926_switch_mm - .word cpu_arm926_set_pte_ext - .word cpu_arm926_suspend_size - .word cpu_arm926_do_suspend - .word cpu_arm926_do_resume - .size arm926_processor_functions, . - arm926_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm926, dabort=v5tj_early_abort, pabort=legacy_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5tej" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm926_name, #object -cpu_arm926_name: - .asciz "ARM926EJ-S" - .size cpu_arm926_name, . - cpu_arm926_name + string cpu_arch_name, "armv5tej" + string cpu_elf_name, "v5" + string cpu_arm926_name, "ARM926EJ-S" .align diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 26aea3f71c2..ac750d50615 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -264,17 +264,8 @@ ENTRY(arm940_dma_unmap_area) mov pc, lr ENDPROC(arm940_dma_unmap_area) -ENTRY(arm940_cache_fns) - .long arm940_flush_icache_all - .long arm940_flush_kern_cache_all - .long arm940_flush_user_cache_all - .long arm940_flush_user_cache_range - .long arm940_coherent_kern_range - .long arm940_coherent_user_range - .long arm940_flush_kern_dcache_area - .long arm940_dma_map_area - .long arm940_dma_unmap_area - .long arm940_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm940 __CPUINIT @@ -348,42 +339,14 @@ __arm940_setup: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm940_processor_functions, #object -ENTRY(arm940_processor_functions) - .word nommu_early_abort - .word legacy_pabort - .word cpu_arm940_proc_init - .word cpu_arm940_proc_fin - .word cpu_arm940_reset - .word cpu_arm940_do_idle - .word cpu_arm940_dcache_clean_area - .word cpu_arm940_switch_mm - .word 0 @ cpu_*_set_pte - .word 0 - .word 0 - .word 0 - .size arm940_processor_functions, . - arm940_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm940, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" -.type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm940_name, #object -cpu_arm940_name: - .ascii "ARM940T" - .size cpu_arm940_name, . - cpu_arm940_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm940_name, "ARM940T" .align diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index 8063345406f..683af3a182b 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -306,18 +306,8 @@ ENTRY(arm946_dma_unmap_area) mov pc, lr ENDPROC(arm946_dma_unmap_area) -ENTRY(arm946_cache_fns) - .long arm946_flush_icache_all - .long arm946_flush_kern_cache_all - .long arm946_flush_user_cache_all - .long arm946_flush_user_cache_range - .long arm946_coherent_kern_range - .long arm946_coherent_user_range - .long arm946_flush_kern_dcache_area - .long arm946_dma_map_area - .long arm946_dma_unmap_area - .long arm946_dma_flush_range - + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions arm946 ENTRY(cpu_arm946_dcache_clean_area) #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH @@ -403,43 +393,14 @@ __arm946_setup: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm946_processor_functions, #object -ENTRY(arm946_processor_functions) - .word nommu_early_abort - .word legacy_pabort - .word cpu_arm946_proc_init - .word cpu_arm946_proc_fin - .word cpu_arm946_reset - .word cpu_arm946_do_idle - - .word cpu_arm946_dcache_clean_area - .word cpu_arm946_switch_mm - .word 0 @ cpu_*_set_pte - .word 0 - .word 0 - .word 0 - .size arm946_processor_functions, . - arm946_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm946, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5t" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm946_name, #object -cpu_arm946_name: - .ascii "ARM946E-S" - .size cpu_arm946_name, . - cpu_arm946_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5t" + string cpu_arm946_name, "ARM946E-S" .align @@ -449,6 +410,7 @@ __arm946_proc_info: .long 0x41009460 .long 0xff00fff0 .long 0 + .long 0 b __arm946_setup .long cpu_arch_name .long cpu_elf_name @@ -457,6 +419,6 @@ __arm946_proc_info: .long arm946_processor_functions .long 0 .long 0 - .long arm940_cache_fns + .long arm946_cache_fns .size __arm946_proc_info, . - __arm946_proc_info diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S index 546b54da100..2120f9e2af7 100644 --- a/arch/arm/mm/proc-arm9tdmi.S +++ b/arch/arm/mm/proc-arm9tdmi.S @@ -17,6 +17,8 @@ #include <asm/pgtable.h> #include <asm/ptrace.h> +#include "proc-macros.S" + .text /* * cpu_arm9tdmi_proc_init() @@ -55,82 +57,38 @@ __arm9tdmi_setup: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm9tdmi_processor_functions, #object -ENTRY(arm9tdmi_processor_functions) - .word nommu_early_abort - .word legacy_pabort - .word cpu_arm9tdmi_proc_init - .word cpu_arm9tdmi_proc_fin - .word cpu_arm9tdmi_reset - .word cpu_arm9tdmi_do_idle - .word cpu_arm9tdmi_dcache_clean_area - .word cpu_arm9tdmi_switch_mm - .word 0 @ cpu_*_set_pte - .word 0 - .word 0 - .word 0 - .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions arm9tdmi, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm9tdmi_name, #object -cpu_arm9tdmi_name: - .asciz "ARM9TDMI" - .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name - - .type cpu_p2001_name, #object -cpu_p2001_name: - .asciz "P2001" - .size cpu_p2001_name, . - cpu_p2001_name + string cpu_arch_name, "armv4t" + string cpu_elf_name, "v4" + string cpu_arm9tdmi_name, "ARM9TDMI" + string cpu_p2001_name, "P2001" .align .section ".proc.info.init", #alloc, #execinstr - .type __arm9tdmi_proc_info, #object -__arm9tdmi_proc_info: - .long 0x41009900 - .long 0xfff8ff00 +.macro arm9tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req + .type __\name\()_proc_info, #object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long 0 .long 0 b __arm9tdmi_setup .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_arm9tdmi_name + .long \cpu_name .long arm9tdmi_processor_functions .long 0 .long 0 .long v4_cache_fns - .size __arm9tdmi_proc_info, . - __arm9tdmi_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm - .type __p2001_proc_info, #object -__p2001_proc_info: - .long 0x41029000 - .long 0xffffffff - .long 0 - .long 0 - b __arm9tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_p2001_name - .long arm9tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __p2001_proc_info, . - __p2001_proc_info + arm9tdmi_proc_info arm9tdmi, 0x41009900, 0xfff8ff00, cpu_arm9tdmi_name + arm9tdmi_proc_info p2001, 0x41029000, 0xffffffff, cpu_p2001_name diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S index fc2a4ae15cf..4c7a5710472 100644 --- a/arch/arm/mm/proc-fa526.S +++ b/arch/arm/mm/proc-fa526.S @@ -180,42 +180,14 @@ fa526_cr1_set: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type fa526_processor_functions, #object -fa526_processor_functions: - .word v4_early_abort - .word legacy_pabort - .word cpu_fa526_proc_init - .word cpu_fa526_proc_fin - .word cpu_fa526_reset - .word cpu_fa526_do_idle - .word cpu_fa526_dcache_clean_area - .word cpu_fa526_switch_mm - .word cpu_fa526_set_pte_ext - .word 0 - .word 0 - .word 0 - .size fa526_processor_functions, . - fa526_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions fa526, dabort=v4_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_fa526_name, #object -cpu_fa526_name: - .asciz "FA526" - .size cpu_fa526_name, . - cpu_fa526_name + string cpu_arch_name, "armv4" + string cpu_elf_name, "v4" + string cpu_fa526_name, "FA526" .align diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index d3883eed7a4..8a6c2f78c1c 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -411,29 +411,28 @@ ENTRY(feroceon_dma_unmap_area) mov pc, lr ENDPROC(feroceon_dma_unmap_area) -ENTRY(feroceon_cache_fns) - .long feroceon_flush_icache_all - .long feroceon_flush_kern_cache_all - .long feroceon_flush_user_cache_all - .long feroceon_flush_user_cache_range - .long feroceon_coherent_kern_range - .long feroceon_coherent_user_range - .long feroceon_flush_kern_dcache_area - .long feroceon_dma_map_area - .long feroceon_dma_unmap_area - .long feroceon_dma_flush_range - -ENTRY(feroceon_range_cache_fns) - .long feroceon_flush_icache_all - .long feroceon_flush_kern_cache_all - .long feroceon_flush_user_cache_all - .long feroceon_flush_user_cache_range - .long feroceon_coherent_kern_range - .long feroceon_coherent_user_range - .long feroceon_range_flush_kern_dcache_area - .long feroceon_range_dma_map_area - .long feroceon_dma_unmap_area - .long feroceon_range_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions feroceon + +.macro range_alias basename + .globl feroceon_range_\basename + .type feroceon_range_\basename , %function + .equ feroceon_range_\basename , feroceon_\basename +.endm + +/* + * Most of the cache functions are unchanged for this case. + * Export suitable alias symbols for the unchanged functions: + */ + range_alias flush_icache_all + range_alias flush_user_cache_all + range_alias flush_kern_cache_all + range_alias flush_user_cache_range + range_alias coherent_kern_range + range_alias coherent_user_range + range_alias dma_unmap_area + + define_cache_functions feroceon_range .align 5 ENTRY(cpu_feroceon_dcache_clean_area) @@ -539,93 +538,27 @@ feroceon_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type feroceon_processor_functions, #object -feroceon_processor_functions: - .word v5t_early_abort - .word legacy_pabort - .word cpu_feroceon_proc_init - .word cpu_feroceon_proc_fin - .word cpu_feroceon_reset - .word cpu_feroceon_do_idle - .word cpu_feroceon_dcache_clean_area - .word cpu_feroceon_switch_mm - .word cpu_feroceon_set_pte_ext - .word 0 - .word 0 - .word 0 - .size feroceon_processor_functions, . - feroceon_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions feroceon, dabort=v5t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_feroceon_name, #object -cpu_feroceon_name: - .asciz "Feroceon" - .size cpu_feroceon_name, . - cpu_feroceon_name - - .type cpu_88fr531_name, #object -cpu_88fr531_name: - .asciz "Feroceon 88FR531-vd" - .size cpu_88fr531_name, . - cpu_88fr531_name - - .type cpu_88fr571_name, #object -cpu_88fr571_name: - .asciz "Feroceon 88FR571-vd" - .size cpu_88fr571_name, . - cpu_88fr571_name - - .type cpu_88fr131_name, #object -cpu_88fr131_name: - .asciz "Feroceon 88FR131" - .size cpu_88fr131_name, . - cpu_88fr131_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + string cpu_feroceon_name, "Feroceon" + string cpu_88fr531_name, "Feroceon 88FR531-vd" + string cpu_88fr571_name, "Feroceon 88FR571-vd" + string cpu_88fr131_name, "Feroceon 88FR131" .align .section ".proc.info.init", #alloc, #execinstr -#ifdef CONFIG_CPU_FEROCEON_OLD_ID - .type __feroceon_old_id_proc_info,#object -__feroceon_old_id_proc_info: - .long 0x41009260 - .long 0xff00fff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __feroceon_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_feroceon_name - .long feroceon_processor_functions - .long v4wbi_tlb_fns - .long feroceon_user_fns - .long feroceon_cache_fns - .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info -#endif - - .type __88fr531_proc_info,#object -__88fr531_proc_info: - .long 0x56055310 - .long 0xfffffff0 +.macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ @@ -640,59 +573,22 @@ __88fr531_proc_info: .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_88fr531_name + .long \cpu_name .long feroceon_processor_functions .long v4wbi_tlb_fns .long feroceon_user_fns - .long feroceon_cache_fns - .size __88fr531_proc_info, . - __88fr531_proc_info + .long \cache + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm - .type __88fr571_proc_info,#object -__88fr571_proc_info: - .long 0x56155710 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __feroceon_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_88fr571_name - .long feroceon_processor_functions - .long v4wbi_tlb_fns - .long feroceon_user_fns - .long feroceon_range_cache_fns - .size __88fr571_proc_info, . - __88fr571_proc_info +#ifdef CONFIG_CPU_FEROCEON_OLD_ID + feroceon_proc_info feroceon_old_id, 0x41009260, 0xff00fff0, \ + cpu_name=cpu_feroceon_name, cache=feroceon_cache_fns +#endif - .type __88fr131_proc_info,#object -__88fr131_proc_info: - .long 0x56251310 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_BIT4 | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __feroceon_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_88fr131_name - .long feroceon_processor_functions - .long v4wbi_tlb_fns - .long feroceon_user_fns - .long feroceon_range_cache_fns - .size __88fr131_proc_info, . - __88fr131_proc_info + feroceon_proc_info 88fr531, 0x56055310, 0xfffffff0, cpu_88fr531_name, \ + cache=feroceon_cache_fns + feroceon_proc_info 88fr571, 0x56155710, 0xfffffff0, cpu_88fr571_name, \ + cache=feroceon_range_cache_fns + feroceon_proc_info 88fr131, 0x56251310, 0xfffffff0, cpu_88fr131_name, \ + cache=feroceon_range_cache_fns diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 34261f9486b..307a4def8d3 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -254,3 +254,71 @@ mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line mcr p15, 0, ip, c7, c10, 4 @ data write barrier .endm + +.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0 + .type \name\()_processor_functions, #object + .align 2 +ENTRY(\name\()_processor_functions) + .word \dabort + .word \pabort + .word cpu_\name\()_proc_init + .word cpu_\name\()_proc_fin + .word cpu_\name\()_reset + .word cpu_\name\()_do_idle + .word cpu_\name\()_dcache_clean_area + .word cpu_\name\()_switch_mm + + .if \nommu + .word 0 + .else + .word cpu_\name\()_set_pte_ext + .endif + + .if \suspend + .word cpu_\name\()_suspend_size +#ifdef CONFIG_PM_SLEEP + .word cpu_\name\()_do_suspend + .word cpu_\name\()_do_resume +#else + .word 0 + .word 0 +#endif + .else + .word 0 + .word 0 + .word 0 + .endif + + .size \name\()_processor_functions, . - \name\()_processor_functions +.endm + +.macro define_cache_functions name:req + .align 2 + .type \name\()_cache_fns, #object +ENTRY(\name\()_cache_fns) + .long \name\()_flush_icache_all + .long \name\()_flush_kern_cache_all + .long \name\()_flush_user_cache_all + .long \name\()_flush_user_cache_range + .long \name\()_coherent_kern_range + .long \name\()_coherent_user_range + .long \name\()_flush_kern_dcache_area + .long \name\()_dma_map_area + .long \name\()_dma_unmap_area + .long \name\()_dma_flush_range + .size \name\()_cache_fns, . - \name\()_cache_fns +.endm + +.macro define_tlb_functions name:req, flags_up:req, flags_smp + .type \name\()_tlb_fns, #object +ENTRY(\name\()_tlb_fns) + .long \name\()_flush_user_tlb_range + .long \name\()_flush_kern_tlb_range + .ifnb \flags_smp + ALT_SMP(.long \flags_smp ) + ALT_UP(.long \flags_up ) + .else + .long \flags_up + .endif + .size \name\()_tlb_fns, . - \name\()_tlb_fns +.endm diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S index 9d4f2ae6337..db52b0fb14a 100644 --- a/arch/arm/mm/proc-mohawk.S +++ b/arch/arm/mm/proc-mohawk.S @@ -93,6 +93,17 @@ ENTRY(cpu_mohawk_do_idle) mov pc, lr /* + * flush_icache_all() + * + * Unconditionally clean and invalidate the entire icache. + */ +ENTRY(mohawk_flush_icache_all) + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr +ENDPROC(mohawk_flush_icache_all) + +/* * flush_user_cache_all() * * Clean and invalidate all cache entries in a particular @@ -288,16 +299,8 @@ ENTRY(mohawk_dma_unmap_area) mov pc, lr ENDPROC(mohawk_dma_unmap_area) -ENTRY(mohawk_cache_fns) - .long mohawk_flush_kern_cache_all - .long mohawk_flush_user_cache_all - .long mohawk_flush_user_cache_range - .long mohawk_coherent_kern_range - .long mohawk_coherent_user_range - .long mohawk_flush_kern_dcache_area - .long mohawk_dma_map_area - .long mohawk_dma_unmap_area - .long mohawk_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions mohawk ENTRY(cpu_mohawk_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry @@ -373,42 +376,14 @@ mohawk_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type mohawk_processor_functions, #object -mohawk_processor_functions: - .word v5t_early_abort - .word legacy_pabort - .word cpu_mohawk_proc_init - .word cpu_mohawk_proc_fin - .word cpu_mohawk_reset - .word cpu_mohawk_do_idle - .word cpu_mohawk_dcache_clean_area - .word cpu_mohawk_switch_mm - .word cpu_mohawk_set_pte_ext - .word 0 - .word 0 - .word 0 - .size mohawk_processor_functions, . - mohawk_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions mohawk, dabort=v5t_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_mohawk_name, #object -cpu_mohawk_name: - .asciz "Marvell 88SV331x" - .size cpu_mohawk_name, . - cpu_mohawk_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + string cpu_mohawk_name, "Marvell 88SV331x" .align diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 46f09ed16b9..d50ada26edd 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -187,43 +187,14 @@ sa110_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - - .type sa110_processor_functions, #object -ENTRY(sa110_processor_functions) - .word v4_early_abort - .word legacy_pabort - .word cpu_sa110_proc_init - .word cpu_sa110_proc_fin - .word cpu_sa110_reset - .word cpu_sa110_do_idle - .word cpu_sa110_dcache_clean_area - .word cpu_sa110_switch_mm - .word cpu_sa110_set_pte_ext - .word 0 - .word 0 - .word 0 - .size sa110_processor_functions, . - sa110_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions sa110, dabort=v4_early_abort, pabort=legacy_pabort .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_sa110_name, #object -cpu_sa110_name: - .asciz "StrongARM-110" - .size cpu_sa110_name, . - cpu_sa110_name + string cpu_arch_name, "armv4" + string cpu_elf_name, "v4" + string cpu_sa110_name, "StrongARM-110" .align diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 184a9c997e3..7d91545d089 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -34,7 +34,7 @@ */ #define DCACHELINESIZE 32 - __INIT + .section .text /* * cpu_sa1100_proc_init() @@ -45,8 +45,6 @@ ENTRY(cpu_sa1100_proc_init) mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland mov pc, lr - .section .text - /* * cpu_sa1100_proc_fin() * @@ -170,39 +168,31 @@ ENTRY(cpu_sa1100_set_pte_ext) mov pc, lr .globl cpu_sa1100_suspend_size -.equ cpu_sa1100_suspend_size, 4*4 +.equ cpu_sa1100_suspend_size, 4 * 3 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_sa1100_do_suspend) - stmfd sp!, {r4 - r7, lr} + stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c3, c0, 0 @ domain ID - mrc p15, 0, r5, c2, c0, 0 @ translation table base addr - mrc p15, 0, r6, c13, c0, 0 @ PID - mrc p15, 0, r7, c1, c0, 0 @ control reg - stmia r0, {r4 - r7} @ store cp regs - ldmfd sp!, {r4 - r7, pc} + mrc p15, 0, r5, c13, c0, 0 @ PID + mrc p15, 0, r6, c1, c0, 0 @ control reg + stmia r0, {r4 - r6} @ store cp regs + ldmfd sp!, {r4 - r6, pc} ENDPROC(cpu_sa1100_do_suspend) ENTRY(cpu_sa1100_do_resume) - ldmia r0, {r4 - r7} @ load cp regs - mov r1, #0 - mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs - mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache - mcr p15, 0, r1, c9, c0, 0 @ invalidate RB - mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB + ldmia r0, {r4 - r6} @ load cp regs + mov ip, #0 + mcr p15, 0, ip, c8, c7, 0 @ flush I+D TLBs + mcr p15, 0, ip, c7, c7, 0 @ flush I&D cache + mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c9, c0, 5 @ allow user space to use RB mcr p15, 0, r4, c3, c0, 0 @ domain ID - mcr p15, 0, r5, c2, c0, 0 @ translation table base addr - mcr p15, 0, r6, c13, c0, 0 @ PID - mov r0, r7 @ control register - mov r2, r5, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE + mcr p15, 0, r1, c2, c0, 0 @ translation table base addr + mcr p15, 0, r5, c13, c0, 0 @ PID + mov r0, r6 @ control register b cpu_resume_mmu ENDPROC(cpu_sa1100_do_resume) -#else -#define cpu_sa1100_do_suspend 0 -#define cpu_sa1100_do_resume 0 #endif __CPUINIT @@ -236,59 +226,28 @@ sa1100_crval: __INITDATA /* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - -/* * SA1100 and SA1110 share the same function calls */ - .type sa1100_processor_functions, #object -ENTRY(sa1100_processor_functions) - .word v4_early_abort - .word legacy_pabort - .word cpu_sa1100_proc_init - .word cpu_sa1100_proc_fin - .word cpu_sa1100_reset - .word cpu_sa1100_do_idle - .word cpu_sa1100_dcache_clean_area - .word cpu_sa1100_switch_mm - .word cpu_sa1100_set_pte_ext - .word cpu_sa1100_suspend_size - .word cpu_sa1100_do_suspend - .word cpu_sa1100_do_resume - .size sa1100_processor_functions, . - sa1100_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1 - .type cpu_sa1100_name, #object -cpu_sa1100_name: - .asciz "StrongARM-1100" - .size cpu_sa1100_name, . - cpu_sa1100_name + .section ".rodata" - .type cpu_sa1110_name, #object -cpu_sa1110_name: - .asciz "StrongARM-1110" - .size cpu_sa1110_name, . - cpu_sa1110_name + string cpu_arch_name, "armv4" + string cpu_elf_name, "v4" + string cpu_sa1100_name, "StrongARM-1100" + string cpu_sa1110_name, "StrongARM-1110" .align .section ".proc.info.init", #alloc, #execinstr - .type __sa1100_proc_info,#object -__sa1100_proc_info: - .long 0x4401a110 - .long 0xfffffff0 +.macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ @@ -301,32 +260,13 @@ __sa1100_proc_info: .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT - .long cpu_sa1100_name + .long \cpu_name .long sa1100_processor_functions .long v4wb_tlb_fns .long v4_mc_user_fns .long v4wb_cache_fns - .size __sa1100_proc_info, . - __sa1100_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm - .type __sa1110_proc_info,#object -__sa1110_proc_info: - .long 0x6901b110 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __sa1100_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT - .long cpu_sa1110_name - .long sa1100_processor_functions - .long v4wb_tlb_fns - .long v4_mc_user_fns - .long v4wb_cache_fns - .size __sa1110_proc_info, . - __sa1110_proc_info + sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name + sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 1d2b8451bf2..d061d2fa550 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -56,6 +56,11 @@ ENTRY(cpu_v6_proc_fin) */ .align 5 ENTRY(cpu_v6_reset) + mrc p15, 0, r1, c1, c0, 0 @ ctrl register + bic r1, r1, #0x1 @ ...............m + mcr p15, 0, r1, c1, c0, 0 @ disable MMU + mov r1, #0 + mcr p15, 0, r1, c7, c5, 4 @ ISB mov pc, r0 /* @@ -123,20 +128,18 @@ ENTRY(cpu_v6_set_pte_ext) /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ .globl cpu_v6_suspend_size -.equ cpu_v6_suspend_size, 4 * 8 +.equ cpu_v6_suspend_size, 4 * 6 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_v6_do_suspend) - stmfd sp!, {r4 - r11, lr} + stmfd sp!, {r4 - r9, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID - mrc p15, 0, r5, c13, c0, 1 @ Context ID - mrc p15, 0, r6, c3, c0, 0 @ Domain ID - mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0 - mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1 - mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register - mrc p15, 0, r10, c1, c0, 2 @ co-processor access control - mrc p15, 0, r11, c1, c0, 0 @ control register - stmia r0, {r4 - r11} - ldmfd sp!, {r4- r11, pc} + mrc p15, 0, r5, c3, c0, 0 @ Domain ID + mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1 + mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register + mrc p15, 0, r8, c1, c0, 2 @ co-processor access control + mrc p15, 0, r9, c1, c0, 0 @ control register + stmia r0, {r4 - r9} + ldmfd sp!, {r4- r9, pc} ENDPROC(cpu_v6_do_suspend) ENTRY(cpu_v6_do_resume) @@ -145,35 +148,24 @@ ENTRY(cpu_v6_do_resume) mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache mcr p15, 0, ip, c7, c10, 4 @ drain write buffer - ldmia r0, {r4 - r11} + mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID + ldmia r0, {r4 - r9} mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID - mcr p15, 0, r5, c13, c0, 1 @ Context ID - mcr p15, 0, r6, c3, c0, 0 @ Domain ID - mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0 - mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1 - mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register - mcr p15, 0, r10, c1, c0, 2 @ co-processor access control + mcr p15, 0, r5, c3, c0, 0 @ Domain ID + ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) + ALT_UP(orr r1, r1, #TTB_FLAGS_UP) + mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0 + mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1 + mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register + mcr p15, 0, r8, c1, c0, 2 @ co-processor access control mcr p15, 0, ip, c2, c0, 2 @ TTB control register mcr p15, 0, ip, c7, c5, 4 @ ISB - mov r0, r11 @ control register - mov r2, r7, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, cpu_resume_l1_flags + mov r0, r9 @ control register b cpu_resume_mmu ENDPROC(cpu_v6_do_resume) -cpu_resume_l1_flags: - ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) - ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP) -#else -#define cpu_v6_do_suspend 0 -#define cpu_v6_do_resume 0 #endif - - .type cpu_v6_name, #object -cpu_v6_name: - .asciz "ARMv6-compatible processor" - .size cpu_v6_name, . - cpu_v6_name + string cpu_v6_name, "ARMv6-compatible processor" .align @@ -225,6 +217,22 @@ __v6_setup: mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them +#ifdef CONFIG_ARM_ERRATA_364296 + /* + * Workaround for the 364296 ARM1136 r0p2 erratum (possible cache data + * corruption with hit-under-miss enabled). The conditional code below + * (setting the undocumented bit 31 in the auxiliary control register + * and the FI bit in the control register) disables hit-under-miss + * without putting the processor into full low interrupt latency mode. + */ + ldr r6, =0x4107b362 @ id for ARM1136 r0p2 + mrc p15, 0, r5, c0, c0, 0 @ get processor id + teq r5, r6 @ check for the faulty core + mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg + orreq r5, r5, #(1 << 31) @ set the undocumented bit 31 + mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg + orreq r0, r0, #(1 << 21) @ low interrupt latency configuration +#endif mov pc, lr @ return to head.S:__ret /* @@ -239,33 +247,13 @@ v6_crval: __INITDATA - .type v6_processor_functions, #object -ENTRY(v6_processor_functions) - .word v6_early_abort - .word v6_pabort - .word cpu_v6_proc_init - .word cpu_v6_proc_fin - .word cpu_v6_reset - .word cpu_v6_do_idle - .word cpu_v6_dcache_clean_area - .word cpu_v6_switch_mm - .word cpu_v6_set_pte_ext - .word cpu_v6_suspend_size - .word cpu_v6_do_suspend - .word cpu_v6_do_resume - .size v6_processor_functions, . - v6_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions v6, dabort=v6_early_abort, pabort=v6_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv6" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v6" - .size cpu_elf_name, . - cpu_elf_name + string cpu_arch_name, "armv6" + string cpu_elf_name, "v6" .align .section ".proc.info.init", #alloc, #execinstr diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 089c0b5e454..2c559ac3814 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -58,9 +58,17 @@ ENDPROC(cpu_v7_proc_fin) * to what would be the reset vector. * * - loc - location to jump to for soft reset + * + * This code must be executed using a flat identity mapping with + * caches disabled. */ .align 5 ENTRY(cpu_v7_reset) + mrc p15, 0, r1, c1, c0, 0 @ ctrl register + bic r1, r1, #0x1 @ ...............m + THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions) + mcr p15, 0, r1, c1, c0, 0 @ disable MMU + isb mov pc, r0 ENDPROC(cpu_v7_reset) @@ -173,8 +181,7 @@ ENTRY(cpu_v7_set_pte_ext) mov pc, lr ENDPROC(cpu_v7_set_pte_ext) -cpu_v7_name: - .ascii "ARMv7 Processor" + string cpu_v7_name, "ARMv7 Processor" .align /* @@ -210,56 +217,50 @@ cpu_v7_name: /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ .globl cpu_v7_suspend_size -.equ cpu_v7_suspend_size, 4 * 9 -#ifdef CONFIG_PM_SLEEP +.equ cpu_v7_suspend_size, 4 * 7 +#ifdef CONFIG_ARM_CPU_SUSPEND ENTRY(cpu_v7_do_suspend) - stmfd sp!, {r4 - r11, lr} + stmfd sp!, {r4 - r10, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID - mrc p15, 0, r5, c13, c0, 1 @ Context ID - mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID - stmia r0!, {r4 - r6} + mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID + stmia r0!, {r4 - r5} mrc p15, 0, r6, c3, c0, 0 @ Domain ID - mrc p15, 0, r7, c2, c0, 0 @ TTB 0 - mrc p15, 0, r8, c2, c0, 1 @ TTB 1 - mrc p15, 0, r9, c1, c0, 0 @ Control register - mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register - mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control - stmia r0, {r6 - r11} - ldmfd sp!, {r4 - r11, pc} + mrc p15, 0, r7, c2, c0, 1 @ TTB 1 + mrc p15, 0, r8, c1, c0, 0 @ Control register + mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register + mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control + stmia r0, {r6 - r10} + ldmfd sp!, {r4 - r10, pc} ENDPROC(cpu_v7_do_suspend) ENTRY(cpu_v7_do_resume) mov ip, #0 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache - ldmia r0!, {r4 - r6} + mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID + ldmia r0!, {r4 - r5} mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID - mcr p15, 0, r5, c13, c0, 1 @ Context ID - mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID - ldmia r0, {r6 - r11} + mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID + ldmia r0, {r6 - r10} mcr p15, 0, r6, c3, c0, 0 @ Domain ID - mcr p15, 0, r7, c2, c0, 0 @ TTB 0 - mcr p15, 0, r8, c2, c0, 1 @ TTB 1 + ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) + ALT_UP(orr r1, r1, #TTB_FLAGS_UP) + mcr p15, 0, r1, c2, c0, 0 @ TTB 0 + mcr p15, 0, r7, c2, c0, 1 @ TTB 1 mcr p15, 0, ip, c2, c0, 2 @ TTB control register - mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register - mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control + mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register + teq r4, r9 @ Is it already set? + mcrne p15, 0, r9, c1, c0, 1 @ No, so write it + mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control ldr r4, =PRRR @ PRRR ldr r5, =NMRR @ NMRR mcr p15, 0, r4, c10, c2, 0 @ write PRRR mcr p15, 0, r5, c10, c2, 1 @ write NMRR isb - mov r0, r9 @ control register - mov r2, r7, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, cpu_resume_l1_flags + dsb + mov r0, r8 @ control register b cpu_resume_mmu ENDPROC(cpu_v7_do_resume) -cpu_resume_l1_flags: - ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) - ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP) -#else -#define cpu_v7_do_suspend 0 -#define cpu_v7_do_resume 0 #endif __CPUINIT @@ -279,13 +280,20 @@ cpu_resume_l1_flags: * It is assumed that: * - cache type register is implemented */ +__v7_ca5mp_setup: __v7_ca9mp_setup: + mov r10, #(1 << 0) @ TLB ops broadcasting + b 1f +__v7_ca15mp_setup: + mov r10, #0 +1: #ifdef CONFIG_SMP ALT_SMP(mrc p15, 0, r0, c1, c0, 1) ALT_UP(mov r0, #(1 << 6)) @ fake it for UP tst r0, #(1 << 6) @ SMP/nAMP mode enabled? - orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and - mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting + orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode + orreq r0, r0, r10 @ Enable CPU-specific SMP bits + mcreq p15, 0, r0, c1, c0, 1 #endif __v7_setup: adr r12, __v7_setup_stack @ the local stack @@ -411,94 +419,75 @@ __v7_setup_stack: __INITDATA - .type v7_processor_functions, #object -ENTRY(v7_processor_functions) - .word v7_early_abort - .word v7_pabort - .word cpu_v7_proc_init - .word cpu_v7_proc_fin - .word cpu_v7_reset - .word cpu_v7_do_idle - .word cpu_v7_dcache_clean_area - .word cpu_v7_switch_mm - .word cpu_v7_set_pte_ext - .word cpu_v7_suspend_size - .word cpu_v7_do_suspend - .word cpu_v7_do_resume - .size v7_processor_functions, . - v7_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv7" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v7" - .size cpu_elf_name, . - cpu_elf_name + string cpu_arch_name, "armv7" + string cpu_elf_name, "v7" .align .section ".proc.info.init", #alloc, #execinstr - .type __v7_ca9mp_proc_info, #object -__v7_ca9mp_proc_info: - .long 0x410fc090 @ Required ID value - .long 0xff0ffff0 @ Mask for ID - ALT_SMP(.long \ - PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS_SMP) - ALT_UP(.long \ - PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS_UP) - .long PMD_TYPE_SECT | \ - PMD_SECT_XN | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - W(b) __v7_ca9mp_setup + /* + * Standard v7 proc info content + */ +.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 + ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ + PMD_FLAGS_SMP | \mm_mmuflags) + ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ + PMD_FLAGS_UP | \mm_mmuflags) + .long PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ | \io_mmuflags + W(b) \initfunc .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \ + HWCAP_EDSP | HWCAP_TLS | \hwcaps .long cpu_v7_name .long v7_processor_functions .long v7wbi_tlb_fns .long v6_user_fns .long v7_cache_fns +.endm + + /* + * ARM Ltd. Cortex A5 processor. + */ + .type __v7_ca5mp_proc_info, #object +__v7_ca5mp_proc_info: + .long 0x410fc050 + .long 0xff0ffff0 + __v7_proc __v7_ca5mp_setup + .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info + + /* + * ARM Ltd. Cortex A9 processor. + */ + .type __v7_ca9mp_proc_info, #object +__v7_ca9mp_proc_info: + .long 0x410fc090 + .long 0xff0ffff0 + __v7_proc __v7_ca9mp_setup .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info /* + * ARM Ltd. Cortex A15 processor. + */ + .type __v7_ca15mp_proc_info, #object +__v7_ca15mp_proc_info: + .long 0x410fc0f0 + .long 0xff0ffff0 + __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV + .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info + + /* * Match any ARMv7 processor core. */ .type __v7_proc_info, #object __v7_proc_info: .long 0x000f0000 @ Required ID value .long 0x000f0000 @ Mask for ID - ALT_SMP(.long \ - PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS_SMP) - ALT_UP(.long \ - PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS_UP) - .long PMD_TYPE_SECT | \ - PMD_SECT_XN | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - W(b) __v7_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS - .long cpu_v7_name - .long v7_processor_functions - .long v7wbi_tlb_fns - .long v6_user_fns - .long v7_cache_fns + __v7_proc __v7_setup .size __v7_proc_info, . - __v7_proc_info diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 596213699f3..abf0507a08a 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -28,7 +28,6 @@ #include <linux/init.h> #include <asm/assembler.h> #include <asm/hwcap.h> -#include <mach/hardware.h> #include <asm/pgtable.h> #include <asm/pgtable-hwdef.h> #include <asm/page.h> @@ -335,17 +334,8 @@ ENTRY(xsc3_dma_unmap_area) mov pc, lr ENDPROC(xsc3_dma_unmap_area) -ENTRY(xsc3_cache_fns) - .long xsc3_flush_icache_all - .long xsc3_flush_kern_cache_all - .long xsc3_flush_user_cache_all - .long xsc3_flush_user_cache_range - .long xsc3_coherent_kern_range - .long xsc3_coherent_user_range - .long xsc3_flush_kern_dcache_area - .long xsc3_dma_map_area - .long xsc3_dma_unmap_area - .long xsc3_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions xsc3 ENTRY(cpu_xsc3_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line @@ -416,24 +406,23 @@ ENTRY(cpu_xsc3_set_pte_ext) .align .globl cpu_xsc3_suspend_size -.equ cpu_xsc3_suspend_size, 4 * 8 +.equ cpu_xsc3_suspend_size, 4 * 6 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_xsc3_do_suspend) - stmfd sp!, {r4 - r10, lr} + stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode mrc p15, 0, r5, c15, c1, 0 @ CP access reg mrc p15, 0, r6, c13, c0, 0 @ PID mrc p15, 0, r7, c3, c0, 0 @ domain ID - mrc p15, 0, r8, c2, c0, 0 @ translation table base addr - mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg - mrc p15, 0, r10, c1, c0, 0 @ control reg + mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg + mrc p15, 0, r9, c1, c0, 0 @ control reg bic r4, r4, #2 @ clear frequency change bit - stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs - ldmia sp!, {r4 - r10, pc} + stmia r0, {r4 - r9} @ store cp regs + ldmia sp!, {r4 - r9, pc} ENDPROC(cpu_xsc3_do_suspend) ENTRY(cpu_xsc3_do_resume) - ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs + ldmia r0, {r4 - r9} @ load cp regs mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer @@ -443,20 +432,12 @@ ENTRY(cpu_xsc3_do_resume) mcr p15, 0, r5, c15, c1, 0 @ CP access reg mcr p15, 0, r6, c13, c0, 0 @ PID mcr p15, 0, r7, c3, c0, 0 @ domain ID - mcr p15, 0, r8, c2, c0, 0 @ translation table base addr - mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg - - @ temporarily map resume_turn_on_mmu into the page table, - @ otherwise prefetch abort occurs after MMU is turned on - mov r0, r10 @ control register - mov r2, r8, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, =0x542e @ section flags + orr r1, r1, #0x18 @ cache the page table in L2 + mcr p15, 0, r1, c2, c0, 0 @ translation table base addr + mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg + mov r0, r9 @ control register b cpu_resume_mmu ENDPROC(cpu_xsc3_do_resume) -#else -#define cpu_xsc3_do_suspend 0 -#define cpu_xsc3_do_resume 0 #endif __CPUINIT @@ -503,52 +484,24 @@ xsc3_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - - .type xsc3_processor_functions, #object -ENTRY(xsc3_processor_functions) - .word v5t_early_abort - .word legacy_pabort - .word cpu_xsc3_proc_init - .word cpu_xsc3_proc_fin - .word cpu_xsc3_reset - .word cpu_xsc3_do_idle - .word cpu_xsc3_dcache_clean_area - .word cpu_xsc3_switch_mm - .word cpu_xsc3_set_pte_ext - .word cpu_xsc3_suspend_size - .word cpu_xsc3_do_suspend - .word cpu_xsc3_do_resume - .size xsc3_processor_functions, . - xsc3_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions xsc3, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_xsc3_name, #object -cpu_xsc3_name: - .asciz "XScale-V3 based processor" - .size cpu_xsc3_name, . - cpu_xsc3_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + string cpu_xsc3_name, "XScale-V3 based processor" .align .section ".proc.info.init", #alloc, #execinstr - .type __xsc3_proc_info,#object -__xsc3_proc_info: - .long 0x69056000 - .long 0xffffe000 +.macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask .long PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ @@ -566,29 +519,10 @@ __xsc3_proc_info: .long v4wbi_tlb_fns .long xsc3_mc_user_fns .long xsc3_cache_fns - .size __xsc3_proc_info, . - __xsc3_proc_info + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm -/* Note: PXA935 changed its implementor ID from Intel to Marvell */ + xsc3_proc_info xsc3, 0x69056000, 0xffffe000 - .type __xsc3_pxa935_proc_info,#object -__xsc3_pxa935_proc_info: - .long 0x56056000 - .long 0xffffe000 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xsc3_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_xsc3_name - .long xsc3_processor_functions - .long v4wbi_tlb_fns - .long xsc3_mc_user_fns - .long xsc3_cache_fns - .size __xsc3_pxa935_proc_info, . - __xsc3_pxa935_proc_info +/* Note: PXA935 changed its implementor ID from Intel to Marvell */ + xsc3_proc_info xsc3_pxa935, 0x56056000, 0xffffe000 diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 42af97664c9..3277904beba 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -390,12 +390,12 @@ ENDPROC(xscale_dma_map_area) * - size - size of region * - dir - DMA direction */ -ENTRY(xscale_dma_a0_map_area) +ENTRY(xscale_80200_A0_A1_dma_map_area) add r1, r1, r0 teq r2, #DMA_TO_DEVICE beq xscale_dma_clean_range b xscale_dma_flush_range -ENDPROC(xscale_dma_a0_map_area) +ENDPROC(xscale_80200_A0_A1_dma_map_area) /* * dma_unmap_area(start, size, dir) @@ -407,17 +407,8 @@ ENTRY(xscale_dma_unmap_area) mov pc, lr ENDPROC(xscale_dma_unmap_area) -ENTRY(xscale_cache_fns) - .long xscale_flush_icache_all - .long xscale_flush_kern_cache_all - .long xscale_flush_user_cache_all - .long xscale_flush_user_cache_range - .long xscale_coherent_kern_range - .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_area - .long xscale_dma_map_area - .long xscale_dma_unmap_area - .long xscale_dma_flush_range + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions xscale /* * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't @@ -432,16 +423,28 @@ ENTRY(xscale_cache_fns) * revision January 22, 2003, available at: * http://www.intel.com/design/iio/specupdt/273415.htm */ -ENTRY(xscale_80200_A0_A1_cache_fns) - .long xscale_flush_kern_cache_all - .long xscale_flush_user_cache_all - .long xscale_flush_user_cache_range - .long xscale_coherent_kern_range - .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_area - .long xscale_dma_a0_map_area - .long xscale_dma_unmap_area - .long xscale_dma_flush_range +.macro a0_alias basename + .globl xscale_80200_A0_A1_\basename + .type xscale_80200_A0_A1_\basename , %function + .equ xscale_80200_A0_A1_\basename , xscale_\basename +.endm + +/* + * Most of the cache functions are unchanged for these processor revisions. + * Export suitable alias symbols for the unchanged functions: + */ + a0_alias flush_icache_all + a0_alias flush_user_cache_all + a0_alias flush_kern_cache_all + a0_alias flush_user_cache_range + a0_alias coherent_kern_range + a0_alias coherent_user_range + a0_alias flush_kern_dcache_area + a0_alias dma_flush_range + a0_alias dma_unmap_area + + @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) + define_cache_functions xscale_80200_A0_A1 ENTRY(cpu_xscale_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry @@ -517,24 +520,23 @@ ENTRY(cpu_xscale_set_pte_ext) .align .globl cpu_xscale_suspend_size -.equ cpu_xscale_suspend_size, 4 * 7 +.equ cpu_xscale_suspend_size, 4 * 6 #ifdef CONFIG_PM_SLEEP ENTRY(cpu_xscale_do_suspend) - stmfd sp!, {r4 - r10, lr} + stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode mrc p15, 0, r5, c15, c1, 0 @ CP access reg mrc p15, 0, r6, c13, c0, 0 @ PID mrc p15, 0, r7, c3, c0, 0 @ domain ID - mrc p15, 0, r8, c2, c0, 0 @ translation table base addr - mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg - mrc p15, 0, r10, c1, c0, 0 @ control reg + mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg + mrc p15, 0, r9, c1, c0, 0 @ control reg bic r4, r4, #2 @ clear frequency change bit - stmia r0, {r4 - r10} @ store cp regs - ldmfd sp!, {r4 - r10, pc} + stmia r0, {r4 - r9} @ store cp regs + ldmfd sp!, {r4 - r9, pc} ENDPROC(cpu_xscale_do_suspend) ENTRY(cpu_xscale_do_resume) - ldmia r0, {r4 - r10} @ load cp regs + ldmia r0, {r4 - r9} @ load cp regs mov ip, #0 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB @@ -542,18 +544,11 @@ ENTRY(cpu_xscale_do_resume) mcr p15, 0, r5, c15, c1, 0 @ CP access reg mcr p15, 0, r6, c13, c0, 0 @ PID mcr p15, 0, r7, c3, c0, 0 @ domain ID - mcr p15, 0, r8, c2, c0, 0 @ translation table base addr - mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg - mov r0, r10 @ control register - mov r2, r8, lsr #14 @ get TTB0 base - mov r2, r2, lsl #14 - ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE + mcr p15, 0, r1, c2, c0, 0 @ translation table base addr + mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg + mov r0, r9 @ control register b cpu_resume_mmu ENDPROC(cpu_xscale_do_resume) -#else -#define cpu_xscale_do_suspend 0 -#define cpu_xscale_do_resume 0 #endif __CPUINIT @@ -587,432 +582,74 @@ xscale_crval: __INITDATA -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - - .type xscale_processor_functions, #object -ENTRY(xscale_processor_functions) - .word v5t_early_abort - .word legacy_pabort - .word cpu_xscale_proc_init - .word cpu_xscale_proc_fin - .word cpu_xscale_reset - .word cpu_xscale_do_idle - .word cpu_xscale_dcache_clean_area - .word cpu_xscale_switch_mm - .word cpu_xscale_set_pte_ext - .word cpu_xscale_suspend_size - .word cpu_xscale_do_suspend - .word cpu_xscale_do_resume - .size xscale_processor_functions, . - xscale_processor_functions + @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) + define_processor_functions xscale, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1 .section ".rodata" - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_80200_A0_A1_name, #object -cpu_80200_A0_A1_name: - .asciz "XScale-80200 A0/A1" - .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name - - .type cpu_80200_name, #object -cpu_80200_name: - .asciz "XScale-80200" - .size cpu_80200_name, . - cpu_80200_name - - .type cpu_80219_name, #object -cpu_80219_name: - .asciz "XScale-80219" - .size cpu_80219_name, . - cpu_80219_name - - .type cpu_8032x_name, #object -cpu_8032x_name: - .asciz "XScale-IOP8032x Family" - .size cpu_8032x_name, . - cpu_8032x_name - - .type cpu_8033x_name, #object -cpu_8033x_name: - .asciz "XScale-IOP8033x Family" - .size cpu_8033x_name, . - cpu_8033x_name - - .type cpu_pxa250_name, #object -cpu_pxa250_name: - .asciz "XScale-PXA250" - .size cpu_pxa250_name, . - cpu_pxa250_name - - .type cpu_pxa210_name, #object -cpu_pxa210_name: - .asciz "XScale-PXA210" - .size cpu_pxa210_name, . - cpu_pxa210_name - - .type cpu_ixp42x_name, #object -cpu_ixp42x_name: - .asciz "XScale-IXP42x Family" - .size cpu_ixp42x_name, . - cpu_ixp42x_name - - .type cpu_ixp43x_name, #object -cpu_ixp43x_name: - .asciz "XScale-IXP43x Family" - .size cpu_ixp43x_name, . - cpu_ixp43x_name - - .type cpu_ixp46x_name, #object -cpu_ixp46x_name: - .asciz "XScale-IXP46x Family" - .size cpu_ixp46x_name, . - cpu_ixp46x_name - - .type cpu_ixp2400_name, #object -cpu_ixp2400_name: - .asciz "XScale-IXP2400" - .size cpu_ixp2400_name, . - cpu_ixp2400_name - - .type cpu_ixp2800_name, #object -cpu_ixp2800_name: - .asciz "XScale-IXP2800" - .size cpu_ixp2800_name, . - cpu_ixp2800_name - - .type cpu_pxa255_name, #object -cpu_pxa255_name: - .asciz "XScale-PXA255" - .size cpu_pxa255_name, . - cpu_pxa255_name - - .type cpu_pxa270_name, #object -cpu_pxa270_name: - .asciz "XScale-PXA270" - .size cpu_pxa270_name, . - cpu_pxa270_name + string cpu_arch_name, "armv5te" + string cpu_elf_name, "v5" + + string cpu_80200_A0_A1_name, "XScale-80200 A0/A1" + string cpu_80200_name, "XScale-80200" + string cpu_80219_name, "XScale-80219" + string cpu_8032x_name, "XScale-IOP8032x Family" + string cpu_8033x_name, "XScale-IOP8033x Family" + string cpu_pxa250_name, "XScale-PXA250" + string cpu_pxa210_name, "XScale-PXA210" + string cpu_ixp42x_name, "XScale-IXP42x Family" + string cpu_ixp43x_name, "XScale-IXP43x Family" + string cpu_ixp46x_name, "XScale-IXP46x Family" + string cpu_ixp2400_name, "XScale-IXP2400" + string cpu_ixp2800_name, "XScale-IXP2800" + string cpu_pxa255_name, "XScale-PXA255" + string cpu_pxa270_name, "XScale-PXA270" .align .section ".proc.info.init", #alloc, #execinstr - .type __80200_A0_A1_proc_info,#object -__80200_A0_A1_proc_info: - .long 0x69052000 - .long 0xfffffffe - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_80200_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_80200_A0_A1_cache_fns - .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info - - .type __80200_proc_info,#object -__80200_proc_info: - .long 0x69052000 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ +.macro xscale_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache + .type __\name\()_proc_info,#object +__\name\()_proc_info: + .long \cpu_val + .long \cpu_mask + .long PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ + .long PMD_TYPE_SECT | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ b __xscale_setup .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_80200_name + .long \cpu_name .long xscale_processor_functions .long v4wbi_tlb_fns .long xscale_mc_user_fns - .long xscale_cache_fns - .size __80200_proc_info, . - __80200_proc_info - - .type __80219_proc_info,#object -__80219_proc_info: - .long 0x69052e20 - .long 0xffffffe0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_80219_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __80219_proc_info, . - __80219_proc_info - - .type __8032x_proc_info,#object -__8032x_proc_info: - .long 0x69052420 - .long 0xfffff7e0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_8032x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __8032x_proc_info, . - __8032x_proc_info - - .type __8033x_proc_info,#object -__8033x_proc_info: - .long 0x69054010 - .long 0xfffffd30 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_8033x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __8033x_proc_info, . - __8033x_proc_info - - .type __pxa250_proc_info,#object -__pxa250_proc_info: - .long 0x69052100 - .long 0xfffff7f0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_pxa250_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __pxa250_proc_info, . - __pxa250_proc_info - - .type __pxa210_proc_info,#object -__pxa210_proc_info: - .long 0x69052120 - .long 0xfffff3f0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_pxa210_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __pxa210_proc_info, . - __pxa210_proc_info - - .type __ixp2400_proc_info, #object -__ixp2400_proc_info: - .long 0x69054190 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp2400_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp2400_proc_info, . - __ixp2400_proc_info - - .type __ixp2800_proc_info, #object -__ixp2800_proc_info: - .long 0x690541a0 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp2800_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp2800_proc_info, . - __ixp2800_proc_info - - .type __ixp42x_proc_info, #object -__ixp42x_proc_info: - .long 0x690541c0 - .long 0xffffffc0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp42x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp42x_proc_info, . - __ixp42x_proc_info - - .type __ixp43x_proc_info, #object -__ixp43x_proc_info: - .long 0x69054040 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp43x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp43x_proc_info, . - __ixp43x_proc_info - - .type __ixp46x_proc_info, #object -__ixp46x_proc_info: - .long 0x69054200 - .long 0xffffff00 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp46x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp46x_proc_info, . - __ixp46x_proc_info - - .type __pxa255_proc_info,#object -__pxa255_proc_info: - .long 0x69052d00 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_pxa255_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __pxa255_proc_info, . - __pxa255_proc_info - - .type __pxa270_proc_info,#object -__pxa270_proc_info: - .long 0x69054110 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_pxa270_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __pxa270_proc_info, . - __pxa270_proc_info - + .ifb \cache + .long xscale_cache_fns + .else + .long \cache + .endif + .size __\name\()_proc_info, . - __\name\()_proc_info +.endm + + xscale_proc_info 80200_A0_A1, 0x69052000, 0xfffffffe, cpu_80200_name, \ + cache=xscale_80200_A0_A1_cache_fns + xscale_proc_info 80200, 0x69052000, 0xfffffff0, cpu_80200_name + xscale_proc_info 80219, 0x69052e20, 0xffffffe0, cpu_80219_name + xscale_proc_info 8032x, 0x69052420, 0xfffff7e0, cpu_8032x_name + xscale_proc_info 8033x, 0x69054010, 0xfffffd30, cpu_8033x_name + xscale_proc_info pxa250, 0x69052100, 0xfffff7f0, cpu_pxa250_name + xscale_proc_info pxa210, 0x69052120, 0xfffff3f0, cpu_pxa210_name + xscale_proc_info ixp2400, 0x69054190, 0xfffffff0, cpu_ixp2400_name + xscale_proc_info ixp2800, 0x690541a0, 0xfffffff0, cpu_ixp2800_name + xscale_proc_info ixp42x, 0x690541c0, 0xffffffc0, cpu_ixp42x_name + xscale_proc_info ixp43x, 0x69054040, 0xfffffff0, cpu_ixp43x_name + xscale_proc_info ixp46x, 0x69054200, 0xffffff00, cpu_ixp46x_name + xscale_proc_info pxa255, 0x69052d00, 0xfffffff0, cpu_pxa255_name + xscale_proc_info pxa270, 0x69054110, 0xfffffff0, cpu_pxa270_name diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S index 9694f1f6f48..d3ddcf9a76c 100644 --- a/arch/arm/mm/tlb-fa.S +++ b/arch/arm/mm/tlb-fa.S @@ -46,7 +46,6 @@ ENTRY(fa_flush_user_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB mcr p15, 0, r3, c7, c10, 4 @ data write barrier mov pc, lr @@ -60,16 +59,11 @@ ENTRY(fa_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB mcr p15, 0, r3, c7, c10, 4 @ data write barrier - mcr p15, 0, r3, c7, c5, 4 @ prefetch flush + mcr p15, 0, r3, c7, c5, 4 @ prefetch flush (isb) mov pc, lr __INITDATA - .type fa_tlb_fns, #object -ENTRY(fa_tlb_fns) - .long fa_flush_user_tlb_range - .long fa_flush_kern_tlb_range - .long fa_tlb_flags - .size fa_tlb_fns, . - fa_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions fa, fa_tlb_flags diff --git a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S index c10786ec8e0..d253995ec4c 100644 --- a/arch/arm/mm/tlb-v3.S +++ b/arch/arm/mm/tlb-v3.S @@ -44,9 +44,5 @@ ENTRY(v3_flush_kern_tlb_range) __INITDATA - .type v3_tlb_fns, #object -ENTRY(v3_tlb_fns) - .long v3_flush_user_tlb_range - .long v3_flush_kern_tlb_range - .long v3_tlb_flags - .size v3_tlb_fns, . - v3_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v3, v3_tlb_flags diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S index d6c94457c2b..17a025ade57 100644 --- a/arch/arm/mm/tlb-v4.S +++ b/arch/arm/mm/tlb-v4.S @@ -57,9 +57,5 @@ ENTRY(v4_flush_user_tlb_range) __INITDATA - .type v4_tlb_fns, #object -ENTRY(v4_tlb_fns) - .long v4_flush_user_tlb_range - .long v4_flush_kern_tlb_range - .long v4_tlb_flags - .size v4_tlb_fns, . - v4_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v4, v4_tlb_flags diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S index cb829ca7845..c04598fa4d4 100644 --- a/arch/arm/mm/tlb-v4wb.S +++ b/arch/arm/mm/tlb-v4wb.S @@ -69,9 +69,5 @@ ENTRY(v4wb_flush_kern_tlb_range) __INITDATA - .type v4wb_tlb_fns, #object -ENTRY(v4wb_tlb_fns) - .long v4wb_flush_user_tlb_range - .long v4wb_flush_kern_tlb_range - .long v4wb_tlb_flags - .size v4wb_tlb_fns, . - v4wb_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v4wb, v4wb_tlb_flags diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S index 60cfc4a25dd..1f6062b6c1c 100644 --- a/arch/arm/mm/tlb-v4wbi.S +++ b/arch/arm/mm/tlb-v4wbi.S @@ -60,9 +60,5 @@ ENTRY(v4wbi_flush_kern_tlb_range) __INITDATA - .type v4wbi_tlb_fns, #object -ENTRY(v4wbi_tlb_fns) - .long v4wbi_flush_user_tlb_range - .long v4wbi_flush_kern_tlb_range - .long v4wbi_tlb_flags - .size v4wbi_tlb_fns, . - v4wbi_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v4wbi, v4wbi_tlb_flags diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index 73d7d89b04c..eca07f550a0 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S @@ -54,7 +54,6 @@ ENTRY(v6wbi_flush_user_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier mov pc, lr @@ -83,16 +82,11 @@ ENTRY(v6wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier - mcr p15, 0, r2, c7, c5, 4 @ prefetch flush + mcr p15, 0, r2, c7, c5, 4 @ prefetch flush (isb) mov pc, lr __INIT - .type v6wbi_tlb_fns, #object -ENTRY(v6wbi_tlb_fns) - .long v6wbi_flush_user_tlb_range - .long v6wbi_flush_kern_tlb_range - .long v6wbi_tlb_flags - .size v6wbi_tlb_fns, . - v6wbi_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v6wbi, v6wbi_tlb_flags diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index 53cd5b45467..845f461f8ec 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -48,9 +48,6 @@ ENTRY(v7wbi_flush_user_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mov ip, #0 - ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable - ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB dsb mov pc, lr ENDPROC(v7wbi_flush_user_tlb_range) @@ -75,9 +72,6 @@ ENTRY(v7wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mov r2, #0 - ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable - ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB dsb isb mov pc, lr @@ -85,10 +79,5 @@ ENDPROC(v7wbi_flush_kern_tlb_range) __INIT - .type v7wbi_tlb_fns, #object -ENTRY(v7wbi_tlb_fns) - .long v7wbi_flush_user_tlb_range - .long v7wbi_flush_kern_tlb_range - ALT_SMP(.long v7wbi_tlb_flags_smp) - ALT_UP(.long v7wbi_tlb_flags_up) - .size v7wbi_tlb_fns, . - v7wbi_tlb_fns + /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ + define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp |