diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /arch/arm/mm | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/fault-armv.c | 184 | ||||
-rw-r--r-- | arch/arm/mm/fault-common.c | 15 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 31 | ||||
-rw-r--r-- | arch/arm/mm/mm-armo.c | 14 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 139 | ||||
-rw-r--r-- | arch/arm/mm/mm-sa1100.c | 53 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm6,7.S | 14 | ||||
-rw-r--r-- | arch/arm/mm/proc-sa110.S | 17 |
8 files changed, 239 insertions, 228 deletions
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 8715ea271..5151591b8 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -29,6 +29,8 @@ #define DO_COW(m) (!((m) & FAULT_CODE_READ)) #define READ_FAULT(m) ((m) & FAULT_CODE_READ) +extern void die_if_kernel(const char *str, struct pt_regs *regs, int err); + #include "fault-common.c" #ifdef DEBUG @@ -118,17 +120,18 @@ static int proc_alignment_read(char *page, char **start, off_t off, * This needs to be done after sysctl_init, otherwise sys/ * will be overwritten. */ -void __init alignment_init(void) +static int __init alignment_init(void) { create_proc_read_entry("sys/debug/alignment", 0, NULL, - proc_alignment_read); + proc_alignment_read, NULL); + return 0; } __initcall(alignment_init); #endif /* CONFIG_SYSCTL */ static int -do_alignment_exception(struct pt_regs *regs) +do_alignment(unsigned long addr, int error_code, struct pt_regs *regs) { unsigned int instr, rd, rn, correction, nr_regs, regbits; unsigned long eaddr; @@ -308,116 +311,99 @@ do_alignment_exception(struct pt_regs *regs) return 0; } +#else + +#define do_alignment NULL + #endif -#define BUG_PROC_MSG \ - "Buggy processor (%08X), trying to continue.\n" \ - "Please read http://www.arm.linux.org.uk/state.html for more information" +#ifdef CONFIG_DEBUG_USER -asmlinkage void -do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs) +static int +do_sect_fault(unsigned long addr, int error_code, struct pt_regs *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 BUG_PROC_MSG, fsr); - first = 0; + printk("%s: permission fault on section, " + "address=0x%08lx, code %d\n", + current->comm, addr, error_code); +#ifdef DEBUG + { + unsigned int i, j; + unsigned long *sp; + + sp = (unsigned long *) (regs->ARM_sp - 128); + for (j = 0; j < 20 && sp_valid(sp); j++) { + printk("%p: ", sp); + for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++) + printk("%08lx ", *sp); + printk("\n"); } - return; + show_regs(regs); + c_backtrace(regs->ARM_fp, regs->ARM_cpsr); } +#endif } + return 1; /* not fixed up */ +} +#else -#define DIE(signr,nam)\ - force_sig(signr, current);\ - die(nam, regs, fsr);\ - do_exit(signr);\ - break - - switch (fsr & 15) { - /* - * 0 - vector exception - */ - case 0: - force_sig(SIGSEGV, current); - if (!user_mode(regs)) { - die("vector exception", regs, fsr); - do_exit(SIGSEGV); - } - break; - - /* - * 15 - permission fault on page - * 5 - page-table entry descriptor fault - * 7 - first-level descriptor fault - */ - case 15: case 5: case 7: - do_page_fault(addr, error_code, regs); - break; +#define do_sect_fault NULL - /* - * 13 - permission fault on section - */ - case 13: - force_sig(SIGSEGV, current); - if (!user_mode(regs)) { - die("section permission fault", regs, fsr); - do_exit(SIGSEGV); - } else { -#ifdef CONFIG_DEBUG_USER - printk("%s: permission fault on section, " - "address=0x%08lx, code %d\n", - current->comm, addr, error_code); -#ifdef DEBUG - { - unsigned int i, j; - unsigned long *sp; - - sp = (unsigned long *) (regs->ARM_sp - 128); - for (j = 0; j < 20 && sp_valid(sp); j++) { - printk("%p: ", sp); - for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++) - printk("%08lx ", *sp); - printk("\n"); - } - show_regs(regs); - c_backtrace(regs->ARM_fp, regs->ARM_cpsr); - } -#endif #endif + +static struct fsr_info { + int (*fn)(unsigned long addr, int error_code, struct pt_regs *regs); + int sig; + char *name; +} fsr_info[] = { + { NULL, SIGSEGV, "vector exception" }, + { do_alignment, SIGBUS, "alignment exception" }, + { NULL, SIGKILL, "terminal exception" }, + { do_alignment, SIGBUS, "alignment exception" }, + { NULL, SIGBUS, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, "page fault" }, + { NULL, SIGBUS, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, "page fault" }, + { NULL, SIGBUS, "external abort on non-linefetch" }, + { NULL, SIGSEGV, "domain fault" }, + { NULL, SIGBUS, "external abort on non-linefetch" }, + { NULL, SIGSEGV, "domain fault" }, + { NULL, SIGBUS, "external abort on translation" }, + { do_sect_fault, SIGSEGV, "section permission fault" }, + { NULL, SIGBUS, "external abort on translation" }, + { do_page_fault, SIGSEGV, "page permission fault" } +}; + +/* + * Currently dropped down to debug level + */ +#define BUG_PROC_MSG \ + KERN_DEBUG "Weird data abort (%08X).\n" \ + KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for more information" + +asmlinkage void +do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs) +{ + struct fsr_info *inf; + + if (user_mode(regs) && addr == regs->ARM_pc) { + static int first = 1; + if (first) { + /* + * I want statistical information on this problem, + * but we don't want to hastle the users too much. + */ + printk(BUG_PROC_MSG, fsr); + first = 0; } - break; + return; + } - case 1: - case 3: -#ifdef CONFIG_ALIGNMENT_TRAP - if (!do_alignment_exception(regs)) - break; -#endif - /* - * this should never happen - */ - DIE(SIGBUS, "Alignment exception"); - break; + inf = fsr_info + (fsr & 15); - case 2: - DIE(SIGKILL, "Terminal exception"); - case 12: - case 14: - DIE(SIGBUS, "External abort on translation"); - case 9: - case 11: - DIE(SIGSEGV, "Domain fault"); - - case 4: - case 6: - DIE(SIGBUS, "External abort on linefetch"); - case 8: - case 10: - DIE(SIGBUS, "External abort on non-linefetch"); + if (!inf->fn || inf->fn(addr, error_code, regs)) { + force_sig(inf->sig, current); + die_if_kernel(inf->name, regs, fsr); } } diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index e516261ed..d04808ffa 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -6,7 +6,7 @@ */ #include <linux/config.h> -extern void die(char *msg, struct pt_regs *regs, unsigned int err); +extern void die(const char *msg, struct pt_regs *regs, unsigned int err); /* * This is useful to dump out the page tables associated with @@ -79,7 +79,7 @@ kernel_page_fault(unsigned long addr, int write_access, struct pt_regs *regs, do_exit(SIGKILL); } -static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) +static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) { struct task_struct *tsk; struct mm_struct *mm; @@ -127,7 +127,7 @@ good_area: goto do_sigbus; up(&mm->mmap_sem); - return; + return 0; /* * Something tried to access memory that isn't in our memory map.. @@ -138,6 +138,7 @@ bad_area: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { + tsk->thread.address = addr; tsk->thread.error_code = mode; tsk->thread.trap_no = 14; #ifdef CONFIG_DEBUG_USER @@ -145,7 +146,7 @@ bad_area: tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode); #endif force_sig(SIGSEGV, tsk); - return; + return 0; } no_context: @@ -156,11 +157,11 @@ no_context: tsk->comm, regs->ARM_pc, addr, fixup); #endif regs->ARM_pc = fixup; - return; + return 0; } kernel_page_fault(addr, mode, regs, tsk, mm); - return; + return 0; do_sigbus: /* @@ -173,6 +174,7 @@ do_sigbus: * Send a sigbus, regardless of whether we were in kernel * or user mode. */ + tsk->thread.address = addr; tsk->thread.error_code = mode; tsk->thread.trap_no = 14; force_sig(SIGBUS, tsk); @@ -180,6 +182,7 @@ do_sigbus: /* Kernel mode? Handle exceptions or die */ if (!user_mode(regs)) goto no_context; + return 0; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 17972e427..bc4cf1ed1 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -168,7 +168,8 @@ void show_mem(void) void __init paging_init(void) { void *zero_page, *bad_page, *bad_table; - unsigned int zone_size[3]; + unsigned int zone_size[MAX_NR_ZONES]; + int i; #ifdef CONFIG_CPU_32 #define TABLE_OFFSET (PTRS_PER_PTE) @@ -193,7 +194,24 @@ void __init paging_init(void) /* * Initialise the zones and mem_map */ - zonesize_init(zone_size); + for (i = 0; i < MAX_NR_ZONES; i++) + zone_size[i] = 0; + + /* + * Calculate the size of the zones. On ARM, we don't have + * any problems with DMA or highmem, so all memory is + * allocated to the DMA zone. + */ + for (i = 0; i < meminfo.nr_banks; i++) { + if (meminfo.bank[i].size) { + unsigned int end; + + end = (meminfo.bank[i].start - PHYS_OFFSET + + meminfo.bank[i].size) >> PAGE_SHIFT; + if (zone_size[0] < end) + zone_size[0] = end; + } + } free_area_init(zone_size); /* @@ -339,10 +357,11 @@ void free_initmem(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(mem_map + MAP_NR(start)); - set_page_count(mem_map+MAP_NR(start), 1); - free_page(start); + unsigned long addr; + for (addr = start; addr < end; addr += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(addr)); + set_page_count(mem_map+MAP_NR(addr), 1); + free_page(addr); totalram_pages++; } printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index 680a52948..a5d4cdfe8 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -135,20 +135,6 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) } /* - * Calculate the size of the DMA, normal and highmem zones. - * On 26-bit ARMs, we don't have any real DMA or highmem, - * so we allocate the whole memory as being DMA-capable. - */ -void __init zonesize_init(unsigned int *zone_size) -{ - int i; - - zone_size[0] = max_low_pfn; - zone_size[1] = 0; - zone_size[2] = 0; -} - -/* * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 * machine. This is both processor & architecture specific, and requires * some more work to get it to fit into our separate processor and diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index ee4750c62..76d101507 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -46,6 +46,15 @@ static int __init nowrite_setup(char *__unused) return 1; } +static int __init noalign_setup(char *__unused) +{ + cr_alignment &= ~2; + cr_no_alignment &= ~2; + set_cr(cr_alignment); + return 1; +} + +__setup("noalign", noalign_setup); __setup("nocache", nocache_setup); __setup("nowb", nowrite_setup); @@ -218,7 +227,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot) * the clearance is done by the middle-level functions (pmd) * rather than the top-level (pgd) functions. */ -static inline void free_init_section(unsigned long virt) +static inline void clear_mapping(unsigned long virt) { pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); } @@ -273,73 +282,76 @@ static void __init create_mapping(struct map_desc *md) } } -/* - * Initial boot-time mapping. This covers just the zero page, kernel and - * the flush area. NB: it must be sorted by virtual address, and no - * virtual address overlaps. - * init_map[2..4] are for architectures with banked memory. - */ -static struct map_desc init_map[] __initdata = { - { 0, 0, PAGE_SIZE, DOMAIN_USER, 0, 0, 1, 0 }, /* zero page */ - { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */ - { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* (4 banks) */ - { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, - { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, - { 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */ - { 0, 0, 0, DOMAIN_KERNEL, 1, 0, 1, 0 } /* cache flush 2 */ -}; - -#define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0])) - -/* - * Calculate the size of the DMA, normal and highmem zones. - * On ARM, we don't have any problems with DMA, so all memory - * is allocated to the DMA zone. We also don't have any - * highmem either. - */ -void __init zonesize_init(unsigned int *zone_size) +void __init pagetable_init(void) { + struct map_desc *init_maps, *p; + unsigned long address = 0; int i; - zone_size[0] = 0; - zone_size[1] = 0; - zone_size[2] = 0; + /* + * Setup initial mappings. We use the page we allocated + * for zero page to hold the mappings, which will get + * overwritten by the vectors in traps_init(). The + * mappings must be in virtual address order. + */ + init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); + + p->physical = virt_to_phys(init_maps); + p->virtual = 0; + p->length = PAGE_SIZE; + p->domain = DOMAIN_USER; + p->prot_read = 0; + p->prot_write = 0; + p->cacheable = 1; + p->bufferable = 0; + + p ++; for (i = 0; i < meminfo.nr_banks; i++) { - if (meminfo.bank[i].size) { - unsigned int end; + if (meminfo.bank[i].size == 0) + continue; - end = (meminfo.bank[i].start - PHYS_OFFSET + - meminfo.bank[i].size) >> PAGE_SHIFT; - if (end > zone_size[0]) - zone_size[0] = end; - } + p->physical = meminfo.bank[i].start; + p->virtual = __phys_to_virt(p->physical); + p->length = meminfo.bank[i].size; + p->domain = DOMAIN_KERNEL; + p->prot_read = 0; + p->prot_write = 1; + p->cacheable = 1; + p->bufferable = 1; + + p ++; } -} -void __init pagetable_init(void) -{ - unsigned long address = 0; - int i; + p->physical = FLUSH_BASE_PHYS; + p->virtual = FLUSH_BASE; + p->length = PGDIR_SIZE; + p->domain = DOMAIN_KERNEL; + p->prot_read = 1; + p->prot_write = 0; + p->cacheable = 1; + p->bufferable = 1; + + p ++; - /* - * Setup the above mappings - */ - init_map[0].physical = virt_to_phys(alloc_bootmem_low_pages(PAGE_SIZE)); - init_map[5].physical = FLUSH_BASE_PHYS; - init_map[5].virtual = FLUSH_BASE; #ifdef FLUSH_BASE_MINICACHE - init_map[6].physical = FLUSH_BASE_PHYS + PGDIR_SIZE; - init_map[6].virtual = FLUSH_BASE_MINICACHE; - init_map[6].length = PGDIR_SIZE; + p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE; + p->virtual = FLUSH_BASE_MINICACHE; + p->length = PGDIR_SIZE; + p->domain = DOMAIN_KERNEL; + p->prot_read = 1; + p->prot_write = 0; + p->cacheable = 1; + p->bufferable = 0; + + p ++; #endif - for (i = 0; i < meminfo.nr_banks; i++) { - init_map[i+1].physical = meminfo.bank[i].start; - init_map[i+1].virtual = meminfo.bank[i].start + - PAGE_OFFSET - PHYS_OFFSET; - init_map[i+1].length = meminfo.bank[i].size; - } + /* + * We may have a mapping in virtual address 0. + * Clear it out. + */ + clear_mapping(0); /* * Go through the initial mappings, but clear out any @@ -347,18 +359,16 @@ void __init pagetable_init(void) */ i = 0; do { - if (address < init_map[i].virtual || i == NR_INIT_MAPS) { - free_init_section(address); + if (address < init_maps->virtual || init_maps == p) { + clear_mapping(address); address += PGDIR_SIZE; } else { - create_mapping(init_map + i); + create_mapping(init_maps); - address = init_map[i].virtual + init_map[i].length; + address = init_maps->virtual + init_maps->length; address = (address + PGDIR_SIZE - 1) & PGDIR_MASK; - do { - i += 1; - } while (init_map[i].length == 0 && i < NR_INIT_MAPS); + init_maps ++; } } while (address != 0); @@ -382,6 +392,7 @@ void __init create_memmap_holes(void) unsigned int i; #define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT) +#define free_bootmem(s,sz) free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT) for (i = 0; i < meminfo.nr_banks; i++) { if (meminfo.bank[i].size == 0) @@ -409,7 +420,7 @@ void __init create_memmap_holes(void) end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size); - if (end_pfn != meminfo.end >> PAGE_SHIFT) + if (end_pfn != PFN(meminfo.end)) pg = mem_map + end_pfn; } diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index eba2984b6..c6f9f2e8b 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -6,11 +6,11 @@ * Copyright (C) 1998-1999 Russell King * Copyright (C) 1999 Hugo Fiennes * - * 1999/09/12 Nicolas Pitre <nico@visuaide.com> - * Specific RAM implementation details are in - * linux/include/asm/arch-sa1100/memory.h now. - * Allows for better macro optimisations when possible. + * 1999/12/04 Nicolas Pitre <nico@cam.org> + * Converted memory definition for struct meminfo initialisations. + * Memory is listed physically now. */ + #include <linux/config.h> #include <linux/mm.h> #include <linux/init.h> @@ -22,33 +22,37 @@ #define SIZE(x) (sizeof(x) / sizeof(x[0])) + /* - * These are the memory size mappings for the - * SA1100. Note that LART is a special case - - * it doesn't use physical address A23 on the - * DRAM, so we effectively have 4 * 8MB in - * two banks. + * These are the RAM memory mappings for SA1100 implementations. + * Note that LART is a special case - it doesn't use physical + * address line A23 on the DRAM, so we effectively have 4 * 8MB + * in two banks. */ -struct mem_desc mem_desc[] __initdata = { - /* virt start virt end */ +struct mem_desc { + unsigned long phys_start; + unsigned long length; +} mem_desc[] __initdata = { #if defined(CONFIG_SA1100_BRUTUS) - { 0xc0000000, 0xc0400000 }, /* 4MB */ - { 0xc1000000, 0xc1400000 }, /* 4MB */ - { 0xc2000000, 0xc2400000 }, /* 4MB */ - { 0xc3000000, 0xc3400000 } /* 4MB */ + { 0xc0000000, 0x00400000 }, /* 4MB */ + { 0xc8000000, 0x00400000 }, /* 4MB */ +#if 0 /* only two banks until the bootmem stuff is fixed... */ + { 0xd0000000, 0x00400000 }, /* 4MB */ + { 0xd8000000, 0x00400000 } /* 4MB */ +#endif #elif defined(CONFIG_SA1100_EMPEG) - { 0xc0000000, 0xc0400000 }, /* 4MB */ - { 0xc1000000, 0xc1400000 } /* 4MB */ + { 0xc0000000, 0x00400000 }, /* 4MB */ + { 0xc8000000, 0x00400000 } /* 4MB */ #elif defined(CONFIG_SA1100_LART) - { 0xc0000000, 0xc0800000 }, /* 16MB */ - { 0xc1000000, 0xc1800000 }, - { 0xc2000000, 0xc2800000 }, /* 16MB */ - { 0xc3000000, 0xc3800000 } + { 0xc0000000, 0x00800000 }, /* 8MB */ + { 0xc1000000, 0x00800000 }, /* 8MB */ + { 0xc8000000, 0x00800000 }, /* 8MB */ + { 0xc9000000, 0x00800000 } /* 8MB */ #elif defined(CONFIG_SA1100_VICTOR) - { 0xc0000000, 0xc0400000 } /* 4MB */ + { 0xc0000000, 0x00400000 } /* 4MB */ #elif defined(CONFIG_SA1100_TIFON) - { 0xc0000000, 0xc1000000 }, /* 16MB */ - { 0xc1000000, 0xc2000000 } /* 16MB */ + { 0xc0000000, 0x01000000 }, /* 16MB */ + { 0xc8000000, 0x01000000 } /* 16MB */ #else #error missing memory configuration #endif @@ -56,6 +60,7 @@ struct mem_desc mem_desc[] __initdata = { unsigned int __initdata mem_desc_size = SIZE(mem_desc); + struct map_desc io_desc[] __initdata = { /* virtual physical length domain r w c b */ #if defined(CONFIG_SA1100_VICTOR) diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index d453269d2..23508c197 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -134,14 +134,10 @@ ENTRY(cpu_arm7_data_abort) b Ldata_simple @ ldc rd, [rn, #m] b Ldata_unknown Ldata_unknown: @ Part of jumptable - ldr r3, [sp, #15 * 4] @ Get PC - str r3, [sp, #-4]! - mov r1, r1, lsr #2 - mov r3, r4 - mov r2, r0 - adr r0, Lukabttxt - bl SYMBOL_NAME(panic) -Lstop: b Lstop + mov r0, r1 + mov r1, r4 + mov r2, r3 + b baddataabort Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit beq Ldata_simple @@ -468,7 +464,7 @@ ENTRY(arm6_processor_functions) .word cpu_arm6_cache_wback_area .word cpu_arm6_cache_purge_area .word cpu_arm6_flush_tlb_page - .word cpu_arm7_do_idle + .word cpu_arm6_do_idle .size arm6_processor_functions, . - arm6_processor_functions /* diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 2d57b1030..5431f14a0 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -16,6 +16,7 @@ * is larger than this, then we flush the whole cache */ #define MAX_AREA_SIZE 32768 +#define FLUSH_OFFSET 32768 .macro flush_110_dcache rd, ra, re add \re, \ra, #16384 @ only necessary for 16k @@ -56,7 +57,7 @@ cpu_sa110_flush_cache_all_r2: ands r1, r1, #1 eor r1, r1, #1 str r1, [r3] - addne ip, ip, #32768 + addne ip, ip, #FLUSH_OFFSET flush_110_dcache r3, ip, r1 mov ip, #0 teq r2, #0 @@ -74,7 +75,7 @@ cpu_sa1100_flush_cache_all_r2: ands r1, r1, #1 eor r1, r1, #1 str r1, [r3] - addne ip, ip, #32768 + addne ip, ip, #FLUSH_OFFSET flush_1100_dcache r3, ip, r1 mov ip, #0 teq r2, #0 @@ -321,7 +322,7 @@ ENTRY(cpu_sa110_set_pgd) ands r2, r2, #1 eor r2, r2, #1 str r2, [r3] - addne ip, ip, #32768 + addne ip, ip, #FLUSH_OFFSET flush_110_dcache r3, ip, r1 mov r1, #0 mcr p15, 0, r1, c7, c5, 0 @ flush I cache @@ -338,7 +339,7 @@ ENTRY(cpu_sa1100_set_pgd) ands r2, r2, #1 eor r2, r2, #1 str r2, [r3] - addne ip, ip, #32768 + addne ip, ip, #FLUSH_OFFSET flush_1100_dcache r3, ip, r1 mov r1, #0 mcr p15, 0, r1, c7, c5, 0 @ flush I cache @@ -430,8 +431,12 @@ ENTRY(cpu_sa110_do_idle) ENTRY(cpu_sa1100_do_idle) mov r0, #0 mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching - @ load from uncacheable loc? - mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt + ldr r1, =FLUSH_BASE+FLUSH_OFFSET*2 @ load from uncacheable loc + ldr r1, [r1, #0] + b 1f + + .align 5 +1: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching mov pc, lr |