Commit 441b91ac authored by Catalin Marinas's avatar Catalin Marinas

Thumb-2: Implement the unified arch/arm/mm support

This patch adds the ARM/Thumb-2 unified support to the arch/arm/mm/*
files.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent c0ac5dc4
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Purpose : obtain information about current aborted instruction. * Purpose : obtain information about current aborted instruction.
*/ */
.align 5 .align 5
.type v7_early_abort, %function
ENTRY(v7_early_abort) ENTRY(v7_early_abort)
/* /*
* The effect of data aborts on on the exclusive access monitor are * The effect of data aborts on on the exclusive access monitor are
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* Just fill zero into the registers. * Just fill zero into the registers.
*/ */
.align 5 .align 5
.type nommu_early_abort, %function
ENTRY(nommu_early_abort) ENTRY(nommu_early_abort)
mov r0, #0 @ clear r0, r1 (no FSR/FAR) mov r0, #0 @ clear r0, r1 (no FSR/FAR)
mov r1, #0 mov r1, #0
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/unified.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -149,7 +150,9 @@ union offset_union { ...@@ -149,7 +150,9 @@ union offset_union {
#define __get8_unaligned_check(ins,val,addr,err) \ #define __get8_unaligned_check(ins,val,addr,err) \
__asm__( \ __asm__( \
"1: "ins" %1, [%2], #1\n" \ ARM( "1: "ins" %1, [%2], #1\n" ) \
THUMB( "1: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
"2:\n" \ "2:\n" \
" .section .fixup,\"ax\"\n" \ " .section .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
...@@ -205,7 +208,9 @@ union offset_union { ...@@ -205,7 +208,9 @@ union offset_union {
do { \ do { \
unsigned int err = 0, v = val, a = addr; \ unsigned int err = 0, v = val, a = addr; \
__asm__( FIRST_BYTE_16 \ __asm__( FIRST_BYTE_16 \
"1: "ins" %1, [%2], #1\n" \ ARM( "1: "ins" %1, [%2], #1\n" ) \
THUMB( "1: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
" mov %1, %1, "NEXT_BYTE"\n" \ " mov %1, %1, "NEXT_BYTE"\n" \
"2: "ins" %1, [%2]\n" \ "2: "ins" %1, [%2]\n" \
"3:\n" \ "3:\n" \
...@@ -235,11 +240,17 @@ union offset_union { ...@@ -235,11 +240,17 @@ union offset_union {
do { \ do { \
unsigned int err = 0, v = val, a = addr; \ unsigned int err = 0, v = val, a = addr; \
__asm__( FIRST_BYTE_32 \ __asm__( FIRST_BYTE_32 \
"1: "ins" %1, [%2], #1\n" \ ARM( "1: "ins" %1, [%2], #1\n" ) \
THUMB( "1: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
" mov %1, %1, "NEXT_BYTE"\n" \ " mov %1, %1, "NEXT_BYTE"\n" \
"2: "ins" %1, [%2], #1\n" \ ARM( "2: "ins" %1, [%2], #1\n" ) \
THUMB( "2: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
" mov %1, %1, "NEXT_BYTE"\n" \ " mov %1, %1, "NEXT_BYTE"\n" \
"3: "ins" %1, [%2], #1\n" \ ARM( "3: "ins" %1, [%2], #1\n" ) \
THUMB( "3: "ins" %1, [%2]\n" ) \
THUMB( " add %2, %2, #1\n" ) \
" mov %1, %1, "NEXT_BYTE"\n" \ " mov %1, %1, "NEXT_BYTE"\n" \
"4: "ins" %1, [%2]\n" \ "4: "ins" %1, [%2]\n" \
"5:\n" \ "5:\n" \
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* *
* This is the "shell" of the ARMv7 processor support. * This is the "shell" of the ARMv7 processor support.
*/ */
#include <asm/unified.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/assembler.h> #include <asm/assembler.h>
...@@ -21,10 +23,11 @@ ...@@ -21,10 +23,11 @@
* *
* Flush the whole D-cache. * Flush the whole D-cache.
* *
* Corrupted registers: r0-r5, r7, r9-r11 * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
* *
* - mm - mm_struct describing address space * - mm - mm_struct describing address space
*/ */
.type v7_flush_dcache_all, %function
ENTRY(v7_flush_dcache_all) ENTRY(v7_flush_dcache_all)
mrc p15, 1, r0, c0, c0, 1 @ read clidr mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr ands r3, r0, #0x7000000 @ extract loc from clidr
...@@ -50,8 +53,12 @@ loop1: ...@@ -50,8 +53,12 @@ loop1:
loop2: loop2:
mov r9, r4 @ create working copy of max way size mov r9, r4 @ create working copy of max way size
loop3: loop3:
orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11 THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way subs r9, r9, #1 @ decrement the way
bge loop3 bge loop3
...@@ -78,12 +85,15 @@ finished: ...@@ -78,12 +85,15 @@ finished:
* unification in a single instruction. * unification in a single instruction.
* *
*/ */
.type v7_flush_kern_cache_all, %function
ENTRY(v7_flush_kern_cache_all) ENTRY(v7_flush_kern_cache_all)
stmfd sp!, {r4-r5, r7, r9-r11, lr} ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
bl v7_flush_dcache_all bl v7_flush_dcache_all
mov r0, #0 mov r0, #0
mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
ldmfd sp!, {r4-r5, r7, r9-r11, lr} ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
mov pc, lr mov pc, lr
/* /*
...@@ -93,6 +103,7 @@ ENTRY(v7_flush_kern_cache_all) ...@@ -93,6 +103,7 @@ ENTRY(v7_flush_kern_cache_all)
* *
* - mm - mm_struct describing address space * - mm - mm_struct describing address space
*/ */
.type v7_flush_user_cache_all, %function
ENTRY(v7_flush_user_cache_all) ENTRY(v7_flush_user_cache_all)
/*FALLTHROUGH*/ /*FALLTHROUGH*/
...@@ -108,6 +119,7 @@ ENTRY(v7_flush_user_cache_all) ...@@ -108,6 +119,7 @@ ENTRY(v7_flush_user_cache_all)
* It is assumed that: * It is assumed that:
* - we have a VIPT cache. * - we have a VIPT cache.
*/ */
.type v7_flush_user_cache_range, %function
ENTRY(v7_flush_user_cache_range) ENTRY(v7_flush_user_cache_range)
mov pc, lr mov pc, lr
...@@ -124,6 +136,7 @@ ENTRY(v7_flush_user_cache_range) ...@@ -124,6 +136,7 @@ ENTRY(v7_flush_user_cache_range)
* It is assumed that: * It is assumed that:
* - the Icache does not read data from the write buffer * - the Icache does not read data from the write buffer
*/ */
.type v7_coherent_kern_range, %function
ENTRY(v7_coherent_kern_range) ENTRY(v7_coherent_kern_range)
/* FALLTHROUGH */ /* FALLTHROUGH */
...@@ -140,6 +153,7 @@ ENTRY(v7_coherent_kern_range) ...@@ -140,6 +153,7 @@ ENTRY(v7_coherent_kern_range)
* It is assumed that: * It is assumed that:
* - the Icache does not read data from the write buffer * - the Icache does not read data from the write buffer
*/ */
.type v7_coherent_user_range, %function
ENTRY(v7_coherent_user_range) ENTRY(v7_coherent_user_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
...@@ -164,6 +178,7 @@ ENTRY(v7_coherent_user_range) ...@@ -164,6 +178,7 @@ ENTRY(v7_coherent_user_range)
* *
* - kaddr - kernel address (guaranteed to be page aligned) * - kaddr - kernel address (guaranteed to be page aligned)
*/ */
.type v7_flush_kern_dcache_page, %function
ENTRY(v7_flush_kern_dcache_page) ENTRY(v7_flush_kern_dcache_page)
dcache_line_size r2, r3 dcache_line_size r2, r3
add r1, r0, #PAGE_SZ add r1, r0, #PAGE_SZ
...@@ -185,15 +200,18 @@ ENTRY(v7_flush_kern_dcache_page) ...@@ -185,15 +200,18 @@ ENTRY(v7_flush_kern_dcache_page)
* - start - virtual start address of region * - start - virtual start address of region
* - end - virtual end address of region * - end - virtual end address of region
*/ */
.type v7_dma_inv_range, %function
ENTRY(v7_dma_inv_range) ENTRY(v7_dma_inv_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
tst r0, r3 tst r0, r3
bic r0, r0, r3 bic r0, r0, r3
it ne
mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
tst r1, r3 tst r1, r3
bic r1, r1, r3 bic r1, r1, r3
it ne
mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line
1: 1:
mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line
...@@ -208,6 +226,7 @@ ENTRY(v7_dma_inv_range) ...@@ -208,6 +226,7 @@ ENTRY(v7_dma_inv_range)
* - start - virtual start address of region * - start - virtual start address of region
* - end - virtual end address of region * - end - virtual end address of region
*/ */
.type v7_dma_clean_range, %function
ENTRY(v7_dma_clean_range) ENTRY(v7_dma_clean_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
...@@ -225,6 +244,7 @@ ENTRY(v7_dma_clean_range) ...@@ -225,6 +244,7 @@ ENTRY(v7_dma_clean_range)
* - start - virtual start address of region * - start - virtual start address of region
* - end - virtual end address of region * - end - virtual end address of region
*/ */
.type v7_dma_flush_range, %function
ENTRY(v7_dma_flush_range) ENTRY(v7_dma_flush_range)
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* VMA_VM_FLAGS * VMA_VM_FLAGS
* VM_EXEC * VM_EXEC
*/ */
#include <asm/unified.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
* *
* This is the "shell" of the ARMv7 processor support. * This is the "shell" of the ARMv7 processor support.
*/ */
#include <asm/unified.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
...@@ -23,9 +25,11 @@ ...@@ -23,9 +25,11 @@
#define TTB_RGN_OC_WT (2 << 3) #define TTB_RGN_OC_WT (2 << 3)
#define TTB_RGN_OC_WB (3 << 3) #define TTB_RGN_OC_WB (3 << 3)
.type cpu_v7_proc_init, %function
ENTRY(cpu_v7_proc_init) ENTRY(cpu_v7_proc_init)
mov pc, lr mov pc, lr
.type cpu_v7_proc_fin, %function
ENTRY(cpu_v7_proc_fin) ENTRY(cpu_v7_proc_fin)
mov pc, lr mov pc, lr
...@@ -41,6 +45,7 @@ ENTRY(cpu_v7_proc_fin) ...@@ -41,6 +45,7 @@ ENTRY(cpu_v7_proc_fin)
* It is assumed that: * It is assumed that:
*/ */
.align 5 .align 5
.type cpu_v7_reset, %function
ENTRY(cpu_v7_reset) ENTRY(cpu_v7_reset)
mov pc, r0 mov pc, r0
...@@ -51,10 +56,12 @@ ENTRY(cpu_v7_reset) ...@@ -51,10 +56,12 @@ ENTRY(cpu_v7_reset)
* *
* IRQs are already disabled. * IRQs are already disabled.
*/ */
.type cpu_v7_do_idle, %function
ENTRY(cpu_v7_do_idle) ENTRY(cpu_v7_do_idle)
.long 0xe320f003 @ ARM V7 WFI instruction wfi
mov pc, lr mov pc, lr
.type cpu_v7_dcache_clean_area, %function
ENTRY(cpu_v7_dcache_clean_area) ENTRY(cpu_v7_dcache_clean_area)
#ifndef TLB_CAN_READ_FROM_L1_CACHE #ifndef TLB_CAN_READ_FROM_L1_CACHE
dcache_line_size r2, r3 dcache_line_size r2, r3
...@@ -76,6 +83,7 @@ ENTRY(cpu_v7_dcache_clean_area) ...@@ -76,6 +83,7 @@ ENTRY(cpu_v7_dcache_clean_area)
* It is assumed that: * It is assumed that:
* - we are not using split page tables * - we are not using split page tables
*/ */
.type cpu_v7_switch_mm, %function
ENTRY(cpu_v7_switch_mm) ENTRY(cpu_v7_switch_mm)
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
mov r2, #0 mov r2, #0
...@@ -110,9 +118,12 @@ ENTRY(cpu_v7_switch_mm) ...@@ -110,9 +118,12 @@ ENTRY(cpu_v7_switch_mm)
* 11x0 0 1 0 r/w r/o * 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w * 1111 0 1 1 r/w r/w
*/ */
.type cpu_v7_set_pte_ext, %function
ENTRY(cpu_v7_set_pte_ext) ENTRY(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version ARM( str r1, [r0], #-2048 ) @ linux version
THUMB( str r1, [r0] ) @ linux version
THUMB( sub r0, r0, #2048 )
bic r3, r1, #0x000003f0 bic r3, r1, #0x000003f0
bic r3, r3, #0x00000003 bic r3, r3, #0x00000003
...@@ -120,21 +131,26 @@ ENTRY(cpu_v7_set_pte_ext) ...@@ -120,21 +131,26 @@ ENTRY(cpu_v7_set_pte_ext)
orr r3, r3, #PTE_EXT_AP0 | 2 orr r3, r3, #PTE_EXT_AP0 | 2
tst r1, #L_PTE_WRITE tst r1, #L_PTE_WRITE
ite ne
tstne r1, #L_PTE_DIRTY tstne r1, #L_PTE_DIRTY
orreq r3, r3, #PTE_EXT_APX orreq r3, r3, #PTE_EXT_APX
tst r1, #L_PTE_USER tst r1, #L_PTE_USER
ittt ne
orrne r3, r3, #PTE_EXT_AP1 orrne r3, r3, #PTE_EXT_AP1
tstne r3, #PTE_EXT_APX tstne r3, #PTE_EXT_APX
bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
tst r1, #L_PTE_YOUNG tst r1, #L_PTE_YOUNG
it eq
biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
tst r1, #L_PTE_EXEC tst r1, #L_PTE_EXEC
it eq
orreq r3, r3, #PTE_EXT_XN orreq r3, r3, #PTE_EXT_XN
tst r1, #L_PTE_PRESENT tst r1, #L_PTE_PRESENT
it eq
moveq r3, #0 moveq r3, #0
str r3, [r0] str r3, [r0]
...@@ -163,6 +179,7 @@ cpu_v7_name: ...@@ -163,6 +179,7 @@ cpu_v7_name:
* It is assumed that: * It is assumed that:
* - cache type register is implemented * - cache type register is implemented
*/ */
.type __v7_setup, #function
__v7_setup: __v7_setup:
adr r12, __v7_setup_stack @ the local stack adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr} stmia r12, {r0-r5, r7, r9, r11, lr}
...@@ -189,15 +206,17 @@ __v7_setup: ...@@ -189,15 +206,17 @@ __v7_setup:
orr r0, r0, r6 @ set them orr r0, r0, r6 @ set them
mov pc, lr @ return to head.S:__ret mov pc, lr @ return to head.S:__ret
.align 2
/* /*
* V X F I D LR * T V X F I D LR
* .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM * .E.. ...E PUI. .T.T 4RVI ZFRS BLDP WCAM
* rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
* 0 110 0011 1.00 .111 1101 < we want * 0 110 0011 1.00 .111 1101 < we want
*/ */
.type v7_crval, #object .type v7_crval, #object
v7_crval: v7_crval:
crval clear=0x0120c302, mmuset=0x00c0387d, ucset=0x00c0187c ARM( crval clear=0x0120c302, mmuset=0x00c0387d, ucset=0x00c0187c )
THUMB( crval clear=0x0120c302, mmuset=0x40c0387d, ucset=0x00c0187c )
__v7_setup_stack: __v7_setup_stack:
.space 4 * 11 @ 11 registers .space 4 * 11 @ 11 registers
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* ARM architecture version 6 TLB handling functions. * ARM architecture version 6 TLB handling functions.
* These assume a split I/D TLB. * These assume a split I/D TLB.
*/ */
#include <asm/unified.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -30,6 +32,7 @@ ...@@ -30,6 +32,7 @@
* - the "Invalidate single entry" instruction will invalidate * - the "Invalidate single entry" instruction will invalidate
* both the I and the D TLBs on Harvard-style TLBs * both the I and the D TLBs on Harvard-style TLBs
*/ */
.type v7wbi_flush_user_tlb_range, %function
ENTRY(v7wbi_flush_user_tlb_range) ENTRY(v7wbi_flush_user_tlb_range)
vma_vm_mm r3, r2 @ get vma->vm_mm vma_vm_mm r3, r2 @ get vma->vm_mm
mmid r3, r3 @ get vm_mm->context.id mmid r3, r3 @ get vm_mm->context.id
...@@ -43,6 +46,7 @@ ENTRY(v7wbi_flush_user_tlb_range) ...@@ -43,6 +46,7 @@ ENTRY(v7wbi_flush_user_tlb_range)
1: 1:
mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1) mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1)
tst r2, #VM_EXEC @ Executable area ? tst r2, #VM_EXEC @ Executable area ?
it ne
mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1) mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1)
add r0, r0, #PAGE_SZ add r0, r0, #PAGE_SZ
cmp r0, r1 cmp r0, r1
...@@ -60,6 +64,7 @@ ENTRY(v7wbi_flush_user_tlb_range) ...@@ -60,6 +64,7 @@ ENTRY(v7wbi_flush_user_tlb_range)
* - start - start address (may not be aligned) * - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned) * - end - end address (exclusive, may not be aligned)
*/ */
.type v7wbi_flush_kern_tlb_range, %function
ENTRY(v7wbi_flush_kern_tlb_range) ENTRY(v7wbi_flush_kern_tlb_range)
dsb dsb
mov r0, r0, lsr #PAGE_SHIFT @ align address mov r0, r0, lsr #PAGE_SHIFT @ align address
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment