summaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/Makefile26
-rw-r--r--arch/arm/mm/fault-armv.c54
-rw-r--r--arch/arm/mm/fault-common.c15
-rw-r--r--arch/arm/mm/init.c6
-rw-r--r--arch/arm/mm/ioremap.c2
-rw-r--r--arch/arm/mm/mm-armv.c2
-rw-r--r--arch/arm/mm/mm-rpc.c6
-rw-r--r--arch/arm/mm/proc-arm2,3.S71
-rw-r--r--arch/arm/mm/proc-arm6,7.S281
-rw-r--r--arch/arm/mm/proc-sa110.S220
10 files changed, 432 insertions, 251 deletions
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 665c7c0b1..42a92201f 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -7,17 +7,24 @@
#
# Note 2! The CFLAGS definition is now in the main makefile...
-all: lib first_rule
+O_TARGET := mm.o
+O_OBJS := init.o extable.o fault-$(PROCESSOR).o small_page.o
-O_TARGET := mm.o
-O_OBJS := init.o extable.o fault-$(PROCESSOR).o small_page.o
-
-ifeq ($(PROCESSOR),armo)
- O_OBJS += proc-arm2,3.o
+ifeq ($(CONFIG_CPU_26),y)
+ O_OBJS += proc-arm2,3.o
endif
-ifeq ($(PROCESSOR),armv)
- O_OBJS += mm-$(MACHINE).o proc-arm6,7.o proc-sa110.o ioremap.o
+ifeq ($(CONFIG_CPU_32),y)
+ ifeq ($(CONFIG_CPU_ARM6),y)
+ P_OBJS += proc-arm6,7.o
+ endif
+ ifeq ($(CONFIG_CPU_ARM7),y)
+ P_OBJS += proc-arm6,7.o
+ endif
+ ifeq ($(CONFIG_CPU_SA110),y)
+ P_OBJS += proc-sa110.o
+ endif
+ O_OBJS += mm-$(MACHINE).o ioremap.o $(sort $(P_OBJS))
endif
include $(TOPDIR)/Rules.make
@@ -25,9 +32,6 @@ include $(TOPDIR)/Rules.make
%.o: %.S
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
-.PHONY: lib
-lib:; @$(MAKE) -C ../lib constants.h
-
# Special dependencies
fault-armv.o: fault-common.c
fault-armo.o: fault-common.c
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index d57d4fb20..0c5582fb7 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -32,13 +32,14 @@
#include "fault-common.c"
+/*
+ * need to get a 16k page for level 1
+ */
pgd_t *get_pgd_slow(void)
{
- /*
- * need to get a 16k page for level 1
- */
pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,2);
pgd_t *init;
+ pmd_t *new_pmd;
if (pgd) {
init = pgd_offset(&init_mm, 0);
@@ -46,8 +47,32 @@ pgd_t *get_pgd_slow(void)
memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
+
+ /*
+ * On ARM, first page must always be allocated
+ */
+ if (!pmd_alloc(pgd, 0))
+ goto nomem;
+ else {
+ pmd_t *old_pmd = pmd_offset(init, 0);
+ new_pmd = pmd_offset(pgd, 0);
+
+ if (!pte_alloc(new_pmd, 0))
+ goto nomem_pmd;
+ else {
+ pte_t *new_pte = pte_offset(new_pmd, 0);
+ pte_t *old_pte = pte_offset(old_pmd, 0);
+
+ set_pte (new_pte, *old_pte);
+ }
+ }
}
return pgd;
+
+nomem_pmd:
+ pmd_free(new_pmd);
+nomem:
+ return NULL;
}
pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
@@ -180,6 +205,7 @@ static int proc_alignment_read(char *page, char **start, off_t off,
return len;
}
+#ifdef CONFIG_SYSCTL
/*
* This needs to be done after sysctl_init, otherwise sys/
* will be overwritten.
@@ -194,6 +220,9 @@ void __init alignment_init(void)
e->read_proc = proc_alignment_read;
}
+__initcall(alignment_init);
+#endif
+
static int
do_alignment_exception(struct pt_regs *regs)
{
@@ -380,8 +409,25 @@ do_alignment_exception(struct pt_regs *regs)
asmlinkage void
do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
{
- if (user_mode(regs))
+ if (user_mode(regs)) {
+ if (addr == regs->ARM_pc) {
+ static int first = 1;
+ if (first) {
+ /*
+ * I want statistical information on this problem!
+ */
+ printk(KERN_ERR "Buggy processor (%08X), "
+ "trying to continue.\n"
+ "Please send contents of /proc/cpuinfo "
+ "and this message to linux@arm.linux.org.uk",
+ fsr);
+ first = 0;
+ }
+ return;
+ }
+
error_code |= FAULT_CODE_USER;
+ }
#define DIE(signr,nam)\
force_sig(signr, current);\
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index 1251525da..a536515af 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -85,7 +85,10 @@ kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
reason, addr);
- printk(KERN_ALERT "memmap = %08lX, pgd = %p\n", tsk->tss.memmap, mm->pgd);
+ if (!mm)
+ mm = &init_mm;
+
+ printk(KERN_ALERT "pgd = %p\n", mm->pgd);
show_pte(mm, addr);
die("Oops", regs, mode);
@@ -106,7 +109,7 @@ static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || mm == &init_mm)
+ if (in_interrupt() || !mm)
goto no_context;
down(&mm->mmap_sem);
@@ -151,8 +154,8 @@ bad_area:
/* User mode accesses just cause a SIGSEGV */
if (mode & FAULT_CODE_USER) {
- tsk->tss.error_code = mode;
- tsk->tss.trap_no = 14;
+ tsk->thread.error_code = mode;
+ tsk->thread.trap_no = 14;
#ifdef CONFIG_DEBUG_USER
printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
@@ -186,8 +189,8 @@ do_sigbus:
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
- tsk->tss.error_code = mode;
- tsk->tss.trap_no = 14;
+ tsk->thread.error_code = mode;
+ tsk->thread.trap_no = 14;
force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8db4e7923..4fa1ca498 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -123,7 +123,7 @@ void show_mem(void)
/*
* paging_init() sets up the page tables...
*/
-__initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem))
+unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
{
extern unsigned long free_area_init(unsigned long, unsigned long);
@@ -156,7 +156,7 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
* memory is free. This is done after various parts of the system have
* claimed their memory after the kernel image.
*/
-__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+void __init mem_init(unsigned long start_mem, unsigned long end_mem)
{
extern void sound_init(void);
int codepages = 0;
@@ -247,7 +247,7 @@ void free_initmem (void)
(unsigned long)(&__netwinder_end),
"netwinder");
- if (!machine_is_ebsa285() && !machine_is_cats())
+ if (!machine_is_ebsa285() && !machine_is_cats() && !machine_is_co285())
free_area((unsigned long)(&__ebsa285_begin),
(unsigned long)(&__ebsa285_end),
"ebsa285/cats");
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 48e34214e..e4c84fa71 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -143,7 +143,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
return (void *) (offset + (char *)addr);
}
-void iounmap(void *addr)
+void __iounmap(void *addr)
{
return vfree((void *) (PAGE_MASK & (unsigned long) addr));
}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 4481fc32b..02890c55b 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -25,7 +25,7 @@ static const struct mapping {
#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-__initfunc(unsigned long setup_io_pagetables(unsigned long start_mem))
+unsigned long __init setup_io_pagetables(unsigned long start_mem)
{
const struct mapping *mp;
int i;
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 1c755faaf..80f821245 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -68,8 +68,8 @@ unsigned long __phys_to_virt(unsigned long phys)
return phys + rambank[bank].phys_offset;
}
-__initfunc(void
-init_dram_banks(struct param_struct *params))
+void __init
+init_dram_banks(struct param_struct *params)
{
unsigned int bank;
unsigned int bytes = 0;
@@ -85,8 +85,6 @@ init_dram_banks(struct param_struct *params))
rambank[FIRST_VRAM_BANK].phys_offset = 0xd6000000;
rambank[FIRST_VRAM_BANK].virt_addr = 0xd8000000;
-
- current->tss.memmap = __virt_to_phys((unsigned long)swapper_pg_dir);
}
#define MAPPING \
diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index 7e4871fe2..6ec34b612 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -1,14 +1,14 @@
/*
- * linux/arch/arm/mm/arm2,3.S: MMU functions for ARM2,3
+ * linux/arch/arm/mm/proc-arm2,3.S: MMU functions for ARM2,3
*
- * (C) 1997 Russell King
+ * (C) 1997-1999 Russell King
*
* These are the low level assembler for performing cache
* and memory functions on ARM2, ARM250 and ARM3 processors.
*/
#include <linux/linkage.h>
-
#include <asm/assembler.h>
+#include <asm/procinfo.h>
#include "../lib/constants.h"
/*
@@ -424,17 +424,18 @@ _arm3_xchg_4: swp r0, r0, [r1]
movs pc, lr
+armvlsi_name: .asciz "ARM/VLSI"
+_arm2_name: .asciz "arm2"
+_arm250_name: .asciz "arm250"
+_arm3_name: .asciz "arm3"
+
+ .section ".text.init", #alloc, #execinstr
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
-_arm2_name:
- .ascii "arm2\0"
- .align
-
.globl SYMBOL_NAME(arm2_processor_functions)
SYMBOL_NAME(arm2_processor_functions):
- .word _arm2_name @ 0
.word _arm2_switch_to @ 4
.word _arm2_3_data_abort @ 8
.word _arm2_3_check_bugs @ 12
@@ -448,13 +449,8 @@ SYMBOL_NAME(arm2_processor_functions):
.word SYMBOL_NAME(abort) @ 40
.word _arm2_xchg_4 @ 44
-_arm250_name:
- .ascii "arm250\0"
- .align
-
.globl SYMBOL_NAME(arm250_processor_functions)
SYMBOL_NAME(arm250_processor_functions):
- .word _arm250_name @ 0
.word _arm2_switch_to @ 4
.word _arm2_3_data_abort @ 8
.word _arm2_3_check_bugs @ 12
@@ -468,13 +464,8 @@ SYMBOL_NAME(arm250_processor_functions):
.word SYMBOL_NAME(abort) @ 40
.word _arm3_xchg_4 @ 44
-_arm3_name:
- .ascii "arm3\0"
- .align
-
.globl SYMBOL_NAME(arm3_processor_functions)
SYMBOL_NAME(arm3_processor_functions):
- .word _arm3_name @ 0
.word _arm3_switch_to @ 4
.word _arm2_3_data_abort @ 8
.word _arm2_3_check_bugs @ 12
@@ -488,3 +479,47 @@ SYMBOL_NAME(arm3_processor_functions):
.word SYMBOL_NAME(abort) @ 40
.word _arm3_xchg_4 @ 44
+cpu_arm2_info:
+ .long armvlsi_name
+ .long _arm2_name
+
+cpu_arm250_info:
+ .long armvlsi_name
+ .long _arm250_name
+
+cpu_arm3_info:
+ .long armvlsi_name
+ .long _arm3_name
+
+arm2_arch_name: .asciz "armv1"
+arm3_arch_name: .asciz "armv2"
+arm2_elf_name: .asciz "v1"
+arm3_elf_name: .asciz "v2"
+ .align
+
+ .section ".proc.info", #alloc
+
+ .long 0x41560200
+ .long 0xfffffff0
+ .long arm2_arch_name
+ .long arm2_elf_name
+ .long 0
+ .long cpu_arm2_info
+ .long SYMBOL_NAME(arm2_processor_functions)
+
+ .long 0x41560250
+ .long 0xfffffff0
+ .long arm3_arch_name
+ .long arm3_elf_name
+ .long 0
+ .long cpu_arm250_info
+ .long SYMBOL_NAME(arm250_processor_functions)
+
+ .long 0x41560300
+ .long 0xfffffff0
+ .long arm3_arch_name
+ .long arm3_elf_name
+ .long 0
+ .long cpu_arm3_info
+ .long SYMBOL_NAME(arm3_processor_functions)
+
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index d1f31e35d..67fb0aa8b 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -1,13 +1,14 @@
/*
- * linux/arch/arm/mm/arm6.S: MMU functions for ARM6
+ * linux/arch/arm/mm/proc-arm6,7.S: MMU functions for ARM6
*
- * (C) 1997 Russell King
+ * (C) 1997-1999 Russell King
*
* These are the low level assembler for performing cache and TLB
* functions on the ARM6 & ARM7.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/procinfo.h>
#include "../lib/constants.h"
/*
@@ -20,10 +21,24 @@
*
* Purpose : Flush all cache lines
*/
-_arm6_7_flush_cache:
+ENTRY(cpu_arm6_flush_cache_all)
+ENTRY(cpu_arm7_flush_cache_all)
+ENTRY(cpu_arm6_flush_cache_area)
+ENTRY(cpu_arm7_flush_cache_area)
+ENTRY(cpu_arm6_flush_cache_entry)
+ENTRY(cpu_arm7_flush_cache_entry)
+ENTRY(cpu_arm6_flush_icache_area)
+ENTRY(cpu_arm7_flush_icache_area)
+ENTRY(cpu_arm6_cache_wback_area)
+ENTRY(cpu_arm7_cache_wback_area)
+ENTRY(cpu_arm6_cache_purge_area)
+ENTRY(cpu_arm7_cache_purge_area)
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ flush cache
-_arm6_7_null:
+ENTRY(cpu_arm6_clean_cache_area)
+ENTRY(cpu_arm7_clean_cache_area)
+ENTRY(cpu_arm6_flush_ram_page)
+ENTRY(cpu_arm7_flush_ram_page)
mov pc, lr
/*
@@ -31,7 +46,8 @@ _arm6_7_null:
*
* Purpose : flush all TLB entries in all caches
*/
-_arm6_7_flush_tlb_all:
+ENTRY(cpu_arm6_flush_tlb_all)
+ENTRY(cpu_arm7_flush_tlb_all)
mov r0, #0
mcr p15, 0, r0, c5, c0, 0 @ flush TLB
mov pc, lr
@@ -45,7 +61,8 @@ _arm6_7_flush_tlb_all:
*
* Purpose : flush a TLB entry
*/
-_arm6_7_flush_tlb_area:
+ENTRY(cpu_arm6_flush_tlb_area)
+ENTRY(cpu_arm7_flush_tlb_area)
1: mcr p15, 0, r0, c6, c0, 0 @ flush TLB
add r0, r0, #4096
cmp r0, r1
@@ -53,41 +70,6 @@ _arm6_7_flush_tlb_area:
mov pc, lr
/*
- * Function: arm6_7_switch_to (struct task_struct *prev, struct task_struct *next)
- *
- * Params : prev Old task structure
- * : next New task structure for process to run
- *
- * Returns : prev
- *
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- * the new.
- *
- * Notes : We don't fiddle with the FP registers here - we postpone this until
- * the new task actually uses FP. This way, we don't swap FP for tasks
- * that do not require it.
- */
-_arm6_7_switch_to:
- stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
- mrs ip, cpsr
- stmfd sp!, {ip} @ Save cpsr_SVC
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldr r2, [r1, #TSK_ADDR_LIMIT]
- ldr r3, [r1, #TSS_MEMMAP] @ Page table pointer
- teq r2, #0
- moveq r2, #DOM_KERNELDOMAIN
- movne r2, #DOM_USERDOMAIN
- mcr p15, 0, r2, c3, c0 @ Set domain reg
- mov r1, #0
- mcr p15, 0, r1, c7, c0, 0 @ flush cache
- mcr p15, 0, r3, c2, c0, 0 @ update page table ptr
- mcr p15, 0, r1, c5, c0, 0 @ flush TLBs
- ldmfd sp!, {ip}
- msr spsr, ip @ Save tasks CPSR into SPSR for this return
- ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
-
-/*
* Function: arm6_7_data_abort ()
*
* Params : r0 = address of aborted instruction
@@ -106,7 +88,7 @@ Lukabttxt: .ascii "Unknown data abort code %d [pc=%p, *pc=%p] LR=%p\0"
msg: .ascii "DA*%p=%p\n\0"
.align
-_arm6_data_abort:
+ENTRY(cpu_arm6_data_abort)
ldr r4, [r0] @ read instruction causing problem
mov r2, r4, lsr #19 @ r2 b1 = L
and r1, r4, #15 << 24
@@ -137,7 +119,7 @@ Ldata_unknown: @ Part of jumptable
bl SYMBOL_NAME(panic)
Lstop: b Lstop
-_arm7_data_abort:
+ENTRY(cpu_arm7_data_abort)
ldr r4, [r0] @ read instruction causing problem
mov r2, r4, lsr #19 @ r2 b1 = L
and r1, r4, #15 << 24
@@ -332,12 +314,29 @@ Ldata_lateldrprereg:
*
* Notes : This processor does not require these
*/
-_arm6_7_check_bugs:
+ENTRY(cpu_arm6_check_bugs)
+ENTRY(cpu_arm7_check_bugs)
mrs ip, cpsr
bic ip, ip, #F_BIT
msr cpsr, ip
-_arm6_7_proc_init:
-_arm6_7_proc_fin:
+ENTRY(cpu_arm6_proc_init)
+ENTRY(cpu_arm7_proc_init)
+ENTRY(cpu_arm6_proc_fin)
+ENTRY(cpu_arm7_proc_fin)
+ mov pc, lr
+
+/*
+ * Function: arm6_7_set_pgd(unsigned long pgd_phys)
+ * Params : pgd_phys Physical address of page table
+ * Purpose : Perform a task switch, saving the old processes state, and restoring
+ * the new.
+ */
+ENTRY(cpu_arm6_set_pgd)
+ENTRY(cpu_arm7_set_pgd)
+ mov r1, #0
+ mcr p15, 0, r1, c7, c0, 0 @ flush cache
+ mcr p15, 0, r0, c2, c0, 0 @ update page table ptr
+ mcr p15, 0, r1, c5, c0, 0 @ flush TLBs
mov pc, lr
/*
@@ -348,7 +347,8 @@ _arm6_7_proc_fin:
*
* Purpose : Set a PMD and flush it out of any WB cache
*/
-_arm6_set_pmd: and r2, r1, #11
+ENTRY(cpu_arm6_set_pmd)
+ and r2, r1, #11
teq r2, #1
teqne r2, #9
teqne r2, #10
@@ -364,7 +364,8 @@ _arm6_set_pmd: and r2, r1, #11
*
* Purpose : Set a PMD and flush it out of any WB cache
*/
-_arm7_set_pmd: tst r1, #3
+ENTRY(cpu_arm7_set_pmd)
+ tst r1, #3
orrne r1, r1, #16 @ Updatable bit is always set on ARM7
str r1, [r0]
mov pc, lr
@@ -376,7 +377,8 @@ _arm7_set_pmd: tst r1, #3
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-_arm6_7_set_pte:
+ENTRY(cpu_arm6_set_pte)
+ENTRY(cpu_arm7_set_pte)
str r1, [r0], #-1024 @ linux version
bic r2, r1, #0xff0
@@ -403,7 +405,9 @@ _arm6_7_set_pte:
*
* Notes : This sets up everything for a reset
*/
-_arm6_7_reset: mrs r1, cpsr
+ENTRY(cpu_arm6_reset)
+ENTRY(cpu_arm7_reset)
+ mrs r1, cpsr
orr r1, r1, #F_BIT|I_BIT
msr cpsr, r1
mov r0, #0
@@ -412,62 +416,145 @@ _arm6_7_reset: mrs r1, cpsr
mov r1, #F_BIT | I_BIT | 3
mov pc, lr
+cpu_armvlsi_name:
+ .asciz "ARM/VLSI"
+cpu_arm6_name: .asciz "arm6"
+cpu_arm610_name:
+ .asciz "arm610"
+cpu_arm7_name: .asciz "arm7"
+cpu_arm710_name:
+ .asciz "arm710"
+ .align
+
+ .section ".text.init", #alloc, #execinstr
+
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
-_arm6_name: .ascii "arm6\0"
- .align
-
+ .type arm6_processor_functions, #object
ENTRY(arm6_processor_functions)
- .word _arm6_name @ 0
- .word _arm6_7_switch_to @ 4
- .word _arm6_data_abort @ 8
- .word _arm6_7_check_bugs @ 12
- .word _arm6_7_proc_init @ 16
- .word _arm6_7_proc_fin @ 20
-
- .word _arm6_7_flush_cache @ 24
- .word _arm6_7_flush_cache @ 28
- .word _arm6_7_flush_cache @ 32
- .word _arm6_7_null @ 36
- .word _arm6_7_flush_cache @ 40
- .word _arm6_7_flush_tlb_all @ 44
- .word _arm6_7_flush_tlb_area @ 48
- .word _arm6_set_pmd @ 52
- .word _arm6_7_set_pte @ 56
- .word _arm6_7_reset @ 60
- .word _arm6_7_flush_cache @ 64
-
- .word _arm6_7_flush_cache @ 68
- .word _arm6_7_flush_cache @ 72
+ .word cpu_arm6_data_abort
+ .word cpu_arm6_check_bugs
+ .word cpu_arm6_proc_init
+ .word cpu_arm6_proc_fin
+ .word cpu_arm6_flush_cache_all
+ .word cpu_arm6_flush_cache_area
+ .word cpu_arm6_flush_cache_entry
+ .word cpu_arm6_clean_cache_area
+ .word cpu_arm6_flush_ram_page
+ .word cpu_arm6_flush_tlb_all
+ .word cpu_arm6_flush_tlb_area
+ .word cpu_arm6_set_pgd
+ .word cpu_arm6_set_pmd
+ .word cpu_arm6_set_pte
+ .word cpu_arm6_reset
+ .word cpu_arm6_flush_icache_area
+ .word cpu_arm6_cache_wback_area
+ .word cpu_arm6_cache_purge_area
+ .size arm6_processor_functions, . - arm6_processor_functions
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
-_arm7_name: .ascii "arm7\0"
+ .type arm7_processor_functions, #object
+ENTRY(arm7_processor_functions)
+ .word cpu_arm7_data_abort
+ .word cpu_arm7_check_bugs
+ .word cpu_arm7_proc_init
+ .word cpu_arm7_proc_fin
+ .word cpu_arm7_flush_cache_all
+ .word cpu_arm7_flush_cache_area
+ .word cpu_arm7_flush_cache_entry
+ .word cpu_arm7_clean_cache_area
+ .word cpu_arm7_flush_ram_page
+ .word cpu_arm7_flush_tlb_all
+ .word cpu_arm7_flush_tlb_area
+ .word cpu_arm7_set_pgd
+ .word cpu_arm7_set_pmd
+ .word cpu_arm7_set_pte
+ .word cpu_arm7_reset
+ .word cpu_arm7_flush_icache_area
+ .word cpu_arm7_cache_wback_area
+ .word cpu_arm7_cache_purge_area
+ .size arm7_processor_functions, . - arm7_processor_functions
+
+ .type cpu_arm6_info, #object
+cpu_arm6_info:
+ .long cpu_armvlsi_name
+ .long cpu_arm6_name
+ .size cpu_arm6_info, . - cpu_arm6_info
+
+ .type cpu_arm610_info, #object
+cpu_arm610_info:
+ .long cpu_armvlsi_name
+ .long cpu_arm610_name
+ .size cpu_arm610_info, . - cpu_Arm610_info
+
+ .type cpu_arm7_info, #object
+cpu_arm7_info:
+ .long cpu_armvlsi_name
+ .long cpu_arm7_name
+ .size cpu_arm7_info, . - cpu_arm7_info
+
+ .type cpu_arm710_info, #object
+cpu_arm710_info:
+ .long cpu_armvlsi_name
+ .long cpu_arm710_name
+ .size cpu_arm710_info, . - cpu_arm710_info
+
+ .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
.align
-ENTRY(arm7_processor_functions)
- .word _arm7_name @ 0
- .word _arm6_7_switch_to @ 4
- .word _arm7_data_abort @ 8
- .word _arm6_7_check_bugs @ 12
- .word _arm6_7_proc_init @ 16
- .word _arm6_7_proc_fin @ 20
-
- .word _arm6_7_flush_cache @ 24
- .word _arm6_7_flush_cache @ 28
- .word _arm6_7_flush_cache @ 32
- .word _arm6_7_null @ 36
- .word _arm6_7_flush_cache @ 40
- .word _arm6_7_flush_tlb_all @ 44
- .word _arm6_7_flush_tlb_area @ 48
- .word _arm7_set_pmd @ 52
- .word _arm6_7_set_pte @ 56
- .word _arm6_7_reset @ 60
- .word _arm6_7_flush_cache @ 64
-
- .word _arm6_7_flush_cache @ 68
- .word _arm6_7_flush_cache @ 72
+ .section ".proc.info", #alloc
+
+ .type __arm6_proc_info, #object
+__arm6_proc_info:
+ .long 0x41560600
+ .long 0xfffffff0
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP
+ .long cpu_arm6_info
+ .long arm6_processor_functions
+ .size __arm6_proc_info, . - __arm6_proc_info
+
+ .type __arm610_proc_info, #object
+__arm610_proc_info:
+ .long 0x41560610
+ .long 0xfffffff0
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP
+ .long cpu_arm610_info
+ .long arm6_processor_functions
+ .size __arm610_proc_info, . - __arm610_proc_info
+
+ .type __arm7_proc_info, #object
+__arm7_proc_info:
+ .long 0x41007000
+ .long 0xffffff00
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP
+ .long cpu_arm7_info
+ .long arm7_processor_functions
+ .size __arm7_proc_info, . - __arm7_proc_info
+
+ .type __arm710_proc_info, #object
+__arm710_proc_info:
+ .long 0x41007100
+ .long 0xfff8ff00
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP
+ .long cpu_arm710_info
+ .long arm7_processor_functions
+ .size __arm710_proc_info, . - __arm710_proc_info
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index be9fad45e..aecc223af 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -1,13 +1,14 @@
/*
- * linux/arch/arm/mm/sa110.S: MMU functions for SA110
+ * linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110
*
- * (C) 1997 Russell King
+ * (C) 1997-1999 Russell King
*
* These are the low level assembler for performing cache and TLB
* functions on the sa110.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include <asm/procinfo.h>
#include <asm/hardware.h>
#include "../lib/constants.h"
@@ -25,9 +26,9 @@ Lclean_switch: .long 0
* Purpose : Flush all cache lines
*/
.align 5
-_sa110_flush_cache_all: @ preserves r0
+ENTRY(cpu_sa110_flush_cache_all) @ preserves r0
mov r2, #1
-_sa110_flush_cache_all_r2:
+cpu_sa110_flush_cache_all_r2:
ldr r3, =Lclean_switch
ldr ip, =FLUSH_BASE
ldr r1, [r3]
@@ -53,10 +54,10 @@ _sa110_flush_cache_all_r2:
* Purpose : clean & flush all cache lines associated with this area of memory
*/
.align 5
-_sa110_flush_cache_area:
+ENTRY(cpu_sa110_flush_cache_area)
sub r3, r1, r0
cmp r3, #MAX_AREA_SIZE
- bgt _sa110_flush_cache_all_r2
+ bgt cpu_sa110_flush_cache_all_r2
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c6, 1 @ flush D entry
add r0, r0, #32
@@ -78,11 +79,11 @@ _sa110_flush_cache_area:
* written out to memory (for DMA)
*/
.align 5
-_sa110_cache_wback_area:
+ENTRY(cpu_sa110_cache_wback_area)
sub r3, r1, r0
cmp r3, #MAX_AREA_SIZE
mov r2, #0
- bgt _sa110_flush_cache_all_r2
+ bgt cpu_sa110_flush_cache_all_r2
bic r0, r0, #31
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
add r0, r0, #32
@@ -103,7 +104,7 @@ _sa110_cache_wback_area:
* start and/or end address are not cache aligned.
*/
.align 5
-_sa110_cache_purge_area:
+ENTRY(cpu_sa110_cache_purge_area)
tst r0, #31
bic r0, r0, #31
mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -121,7 +122,7 @@ _sa110_cache_purge_area:
* Purpose : clean & flush an entry
*/
.align 5
-_sa110_flush_cache_entry:
+ENTRY(cpu_sa110_flush_cache_entry)
mov r1, #0
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r1, c7, c10, 4 @ drain WB
@@ -134,7 +135,7 @@ _sa110_flush_cache_entry:
* Purpose : Ensure that physical memory reflects cache at this location
* for page table purposes.
*/
-_sa110_clean_cache_area:
+ENTRY(cpu_sa110_clean_cache_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
add r0, r0, #32
subs r1, r1, #32
@@ -143,25 +144,24 @@ _sa110_clean_cache_area:
/*
* Function: sa110_flush_ram_page (unsigned long page)
- * Params : address Area start address
- * : size size of area
- * : flags b0 = I cache as well
- * Purpose : clean & flush all cache lines associated with this area of memory
+ * Params : page Area start address
+ * Purpose : clean all cache lines associated with this area of memory
*/
.align 5
-_sa110_flush_ram_page:
+ENTRY(cpu_sa110_flush_ram_page)
mov r1, #4096
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c6, 1 @ flush D entry
add r0, r0, #32
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c6, 1 @ flush D entry
add r0, r0, #32
- subs r1, r1, #64
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #32
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #32
+ subs r1, r1, #128
bne 1b
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c7, c5, 0 @ flush I cache
mov pc, lr
/*
@@ -169,7 +169,7 @@ _sa110_flush_ram_page:
* Purpose : flush all TLB entries in all caches
*/
.align 5
-_sa110_flush_tlb_all:
+ENTRY(cpu_sa110_flush_tlb_all)
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c8, c7, 0 @ flush I & D tlbs
@@ -179,11 +179,11 @@ _sa110_flush_tlb_all:
* Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
* Params : address Area start address
* : end Area end address
- * : flags b0 = I cache as well
+ * : flags b0 = I-TLB as well
* Purpose : flush a TLB entry
*/
.align 5
-_sa110_flush_tlb_area:
+ENTRY(cpu_sa110_flush_tlb_area)
mov r3, #0
mcr p15, 0, r3, c7, c10, 4 @ drain WB
1: cmp r0, r1
@@ -198,7 +198,7 @@ _sa110_flush_tlb_area:
mov pc, lr
.align 5
-_sa110_flush_icache_area:
+ENTRY(cpu_sa110_flush_icache_area)
1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
add r0, r0, #32
subs r1, r1, #32
@@ -207,40 +207,35 @@ _sa110_flush_icache_area:
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c5, 0 @ flush I cache
mov pc, lr
+
/*
- * Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next)
- * Params : prev Old task structure
- * : next New task structure for process to run
- * Returns : prev
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- * the new.
- * Notes : We don't fiddle with the FP registers here - we postpone this until
- * the new task actually uses FP. This way, we don't swap FP for tasks
- * that do not require it.
+ * Function: sa110_data_abort ()
+ * Params : r0 = address of aborted instruction
+ * Purpose : obtain information about current aborted instruction
+ * Returns : r0 = address of abort
+ * : r1 = FSR
+ * : r2 != 0 if writing
*/
.align 5
-_sa110_switch_to:
- stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
- mrs ip, cpsr
- stmfd sp!, {ip} @ Save cpsr_SVC
- ldr r2, [r0, #TSS_MEMMAP] @ Get old page tables
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldr r5, [r1, #TSK_ADDR_LIMIT]
- ldr r4, [r1, #TSS_MEMMAP] @ Page table pointer
- teq r5, #0
- moveq r5, #DOM_KERNELDOMAIN
- movne r5, #DOM_USERDOMAIN
- mcr p15, 0, r5, c3, c0 @ Set segment
+ENTRY(cpu_sa110_data_abort)
+ ldr r2, [r0] @ read instruction causing problem
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ mov r2, r2, lsr #19 @ b1 = L
+ and r3, r2, #0x69 << 2
+ and r2, r2, #2
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ and r1, r1, #255
+ mov pc, lr
+
+ .align 5
/*
- * Flushing the cache is nightmarishly slow, so we take any excuse
- * to get out of it. If the old page table is the same as the new,
- * this is a CLONE_VM relative of the old task and there is no need
- * to flush. The overhead of the tests isn't even on the radar
- * compared to the cost of the flush itself.
+ * Function: sa110_set_pgd(unsigned long pgd_phys)
+ * Params : pgd_phys Physical address of page table
+ * Purpose : Perform a task switch, saving the old processes state, and restoring
+ * the new.
*/
- teq r4, r2
- beq 2f
+ .align 5
+ENTRY(cpu_sa110_set_pgd)
ldr r3, =Lclean_switch
ldr r2, [r3]
ands r2, r2, #1
@@ -255,29 +250,8 @@ _sa110_switch_to:
mov r1, #0
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
-2: ldmfd sp!, {ip}
- msr spsr, ip @ Save tasks CPSR into SPSR for this return
- ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
-
-/*
- * Function: sa110_data_abort ()
- * Params : r0 = address of aborted instruction
- * Purpose : obtain information about current aborted instruction
- * Returns : r0 = address of abort
- * : r1 = FSR
- * : r2 != 0 if writing
- */
- .align 5
-_sa110_data_abort:
- ldr r2, [r0] @ read instruction causing problem
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mov r2, r2, lsr #19 @ b1 = L
- and r3, r2, #0x69 << 2
- and r2, r2, #2
- mrc p15, 0, r1, c5, c0, 0 @ get FSR
- and r1, r1, #255
mov pc, lr
/*
@@ -287,7 +261,8 @@ _sa110_data_abort:
* Purpose : Set a PMD and flush it out
*/
.align 5
-_sa110_set_pmd: str r1, [r0]
+ENTRY(cpu_sa110_set_pmd)
+ str r1, [r0]
mcr p15, 0, r0, c7, c10, 1 @ clean D entry
mcr p15, 0, r0, c7, c10, 4 @ drain WB (TLB bypasses WB)
mov pc, lr
@@ -299,7 +274,8 @@ _sa110_set_pmd: str r1, [r0]
* Purpose : Set a PTE and flush it out
*/
.align 5
-_sa110_set_pte: str r1, [r0], #-1024 @ linux version
+ENTRY(cpu_sa110_set_pte)
+ str r1, [r0], #-1024 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
@@ -328,26 +304,27 @@ _sa110_set_pte: str r1, [r0], #-1024 @ linux version
* : sa110_proc_fin (void)
* Notes : This processor does not require these
*/
-_sa110_check_bugs:
+ENTRY(cpu_sa110_check_bugs)
mrs ip, cpsr
bic ip, ip, #F_BIT
msr cpsr, ip
-_sa110_proc_init:
-_sa110_proc_fin:
+ENTRY(cpu_sa110_proc_init)
+ENTRY(cpu_sa110_proc_fin)
mov pc, lr
/*
* Function: sa110_reset
* Notes : This sets up everything for a reset
*/
-_sa110_reset: mrs r1, cpsr
+ENTRY(cpu_sa110_reset)
+ mrs r1, cpsr
orr r1, r1, #F_BIT | I_BIT
msr cpsr, r1
stmfd sp!, {r1, lr}
mov r2, #1
- bl _sa110_flush_cache_all
- bl _sa110_flush_tlb_all
+ bl cpu_sa110_flush_cache_all
+ bl cpu_sa110_flush_tlb_all
mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1800
@@ -357,29 +334,60 @@ _sa110_reset: mrs r1, cpsr
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
-_sa110_name: .ascii "sa110\0"
+
+cpu_manu_name: .asciz "Intel"
+ENTRY(cpu_sa110_name)
+ .asciz "sa110"
.align
+ .section ".text.init", #alloc, #execinstr
+
+ .type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
- .word _sa110_name @ 0
- .word _sa110_switch_to @ 4
- .word _sa110_data_abort @ 8
- .word _sa110_check_bugs @ 12
- .word _sa110_proc_init @ 16
- .word _sa110_proc_fin @ 20
-
- .word _sa110_flush_cache_all @ 24
- .word _sa110_flush_cache_area @ 28
- .word _sa110_flush_cache_entry @ 32
- .word _sa110_clean_cache_area @ 36
- .word _sa110_flush_ram_page @ 40
- .word _sa110_flush_tlb_all @ 44
- .word _sa110_flush_tlb_area @ 48
-
- .word _sa110_set_pmd @ 52
- .word _sa110_set_pte @ 56
- .word _sa110_reset @ 60
- .word _sa110_flush_icache_area @ 64
-
- .word _sa110_cache_wback_area @ 68
- .word _sa110_cache_purge_area @ 72
+ .word cpu_sa110_data_abort
+ .word cpu_sa110_check_bugs
+ .word cpu_sa110_proc_init
+ .word cpu_sa110_proc_fin
+ .word cpu_sa110_flush_cache_all
+ .word cpu_sa110_flush_cache_area
+ .word cpu_sa110_flush_cache_entry
+ .word cpu_sa110_clean_cache_area
+ .word cpu_sa110_flush_ram_page
+ .word cpu_sa110_flush_tlb_all
+ .word cpu_sa110_flush_tlb_area
+ .word cpu_sa110_set_pgd
+ .word cpu_sa110_set_pmd
+ .word cpu_sa110_set_pte
+ .word cpu_sa110_reset
+ .word cpu_sa110_flush_icache_area
+ .word cpu_sa110_cache_wback_area
+ .word cpu_sa110_cache_purge_area
+
+ .size sa110_processor_functions, . - sa110_processor_functions
+
+ .type cpu_sa110_info, #object
+cpu_sa110_info:
+ .long cpu_manu_name
+ .long cpu_sa110_name
+ .size cpu_sa110_info, . - cpu_sa110_info
+
+ .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
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+ .type __sa110_proc_info,#object
+__sa110_proc_info:
+ .long 0x4401a100
+ .long 0xfffffff0
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF
+ .long cpu_sa110_info
+ .long sa110_processor_functions
+ .size __sa110_proc_info, . - __sa110_proc_info