diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch/arm/mm | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/Makefile | 65 | ||||
-rw-r--r-- | arch/arm/mm/consistent.c | 28 | ||||
-rw-r--r-- | arch/arm/mm/extable.c | 2 | ||||
-rw-r--r-- | arch/arm/mm/fault-armo.c | 5 | ||||
-rw-r--r-- | arch/arm/mm/fault-armv.c | 11 | ||||
-rw-r--r-- | arch/arm/mm/fault-common.c | 10 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 26 | ||||
-rw-r--r-- | arch/arm/mm/ioremap.c | 2 | ||||
-rw-r--r-- | arch/arm/mm/map.h | 25 | ||||
-rw-r--r-- | arch/arm/mm/mm-armo.c | 19 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 59 | ||||
-rw-r--r-- | arch/arm/mm/mm-clps7500.c | 23 | ||||
-rw-r--r-- | arch/arm/mm/mm-ebsa110.c | 24 | ||||
-rw-r--r-- | arch/arm/mm/mm-footbridge.c | 112 | ||||
-rw-r--r-- | arch/arm/mm/mm-l7200.c | 19 | ||||
-rw-r--r-- | arch/arm/mm/mm-nexuspci.c | 27 | ||||
-rw-r--r-- | arch/arm/mm/mm-rpc.c | 31 | ||||
-rw-r--r-- | arch/arm/mm/mm-sa1100.c | 212 | ||||
-rw-r--r-- | arch/arm/mm/mm-shark.c | 25 | ||||
-rw-r--r-- | arch/arm/mm/mm-tbox.c | 57 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm2,3.S | 14 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm6,7.S | 149 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm720.S | 160 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm920.S | 602 | ||||
-rw-r--r-- | arch/arm/mm/proc-sa110.S | 1170 | ||||
-rw-r--r-- | arch/arm/mm/proc-syms.c | 31 | ||||
-rw-r--r-- | arch/arm/mm/small_page.c | 28 |
27 files changed, 1886 insertions, 1050 deletions
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 075193467..fe3cf5eac 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -9,40 +9,61 @@ USE_STANDARD_AS_RULE := true +EXTRA_AFLAGS := -traditional O_TARGET := mm.o -O_OBJS := extable.o fault-$(PROCESSOR).o init.o \ + +# Object file lists. + +obj-y := extable.o fault-$(PROCESSOR).o init.o \ mm-$(PROCESSOR).o small_page.o +obj-m := +obj-n := +obj- := +export-objs := proc-syms.o -ifeq ($(CONFIG_CPU_26),y) - O_OBJS += proc-arm2,3.o -endif +p-$(CONFIG_CPU_26) += proc-arm2,3.o +p-$(CONFIG_CPU_ARM6) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM7) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM720) += proc-arm720.o +p-$(CONFIG_CPU_ARM920) += proc-arm920.o +p-$(CONFIG_CPU_ARM10) += proc-arm10.o +p-$(CONFIG_CPU_SA110) += proc-sa110.o +p-$(CONFIG_CPU_SA1100) += proc-sa110.o +obj-$(CONFIG_CPU_32) += consistent.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_ARM720),y) - P_OBJS += proc-arm720.o - endif - ifeq ($(CONFIG_CPU_SA110),y) - P_OBJS += proc-sa110.o - endif - ifeq ($(CONFIG_CPU_SA1100),y) - P_OBJS += proc-sa110.o - endif - O_OBJS += mm-$(MACHINE).o consistent.o ioremap.o $(sort $(P_OBJS)) +obj-$(CONFIG_MODULES) += proc-syms.o +endif + +# Integrator follows "new style" +# Soon, others will do too, and we can get rid of this +MMMACH := mm-$(MACHINE).o +ifeq ($(MMMACH),$(wildcard $(MMMACH))) +obj-$(CONFIG_CPU_32) += $(MMMACH) endif +obj-y += $(sort $(p-y)) + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + include $(TOPDIR)/Rules.make # Special dependencies -fault-armv.o: fault-common.c -fault-armo.o: fault-common.c +fault-armv.o: fault-common.c +fault-armo.o: fault-common.c proc-arm2,3.o: ../lib/constants.h proc-arm6,7.o: ../lib/constants.h proc-arm720.o: ../lib/constants.h +proc-arm920.o: ../lib/constants.h +proc-arm10.o: ../lib/constants.h proc-sa110.o: ../lib/constants.h diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index b21bc1d8a..4b06c4cad 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -1,5 +1,13 @@ /* - * Dynamic DMA mapping support. + * linux/arch/arm/mm/consistent.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Dynamic DMA mapping support. */ #include <linux/config.h> #include <linux/types.h> @@ -43,18 +51,19 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ret = __ioremap(virt_to_phys((void *)page), size, 0); if (ret) { /* free wasted pages */ - unsigned long end = page + (PAGE_SIZE << order); + unsigned long end; /* * we need to ensure that there are no * cachelines in use, or worse dirty in * this area. */ - dma_cache_inv(page, size); - dma_cache_inv(ret, size); + invalidate_dcache_range(page, page + size); + invalidate_dcache_range((unsigned long)ret, (unsigned long)ret + size); - *dma_handle = virt_to_bus((void *)page); + *dma_handle = __virt_to_bus(page); + end = page + (PAGE_SIZE << order); page += size; while (page < end) { free_page(page); @@ -102,17 +111,20 @@ void consistent_free(void *vaddr) */ void consistent_sync(void *vaddr, size_t size, int direction) { + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; + switch (direction) { case PCI_DMA_NONE: BUG(); case PCI_DMA_FROMDEVICE: /* invalidate only */ - dma_cache_inv(vaddr, size); + invalidate_dcache_range(start, end); break; case PCI_DMA_TODEVICE: /* writeback only */ - dma_cache_wback(vaddr, size); + clean_dcache_range(start, end); break; case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */ - dma_cache_wback_inv(vaddr, size); + flush_dcache_range(start, end); break; } } diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c index e603b6362..e32d40c8e 100644 --- a/arch/arm/mm/extable.c +++ b/arch/arm/mm/extable.c @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mm/extable.c + * linux/arch/arm/mm/extable.c */ #include <linux/config.h> diff --git a/arch/arm/mm/fault-armo.c b/arch/arm/mm/fault-armo.c index 19a1fff7c..85b2dc2f4 100644 --- a/arch/arm/mm/fault-armo.c +++ b/arch/arm/mm/fault-armo.c @@ -3,8 +3,11 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index c3d03f251..f184b4e68 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -3,8 +3,11 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ - #include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> @@ -399,7 +402,11 @@ do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr) return; bad: force_sig(inf->sig, current); - die_if_kernel(inf->name, regs, fsr); + + printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n", + inf->name, fsr, addr); + show_pte(current->mm, addr); + die_if_kernel("Oops", regs, 0); return; weirdness: diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index 519f1965a..0e198ab8a 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -3,6 +3,10 @@ * * Copyright (C) 1995 Linus Torvalds * Modifications for ARM processor (c) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> @@ -12,7 +16,7 @@ extern void die(const char *msg, struct pt_regs *regs, int err); * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. */ -static void show_pte(struct mm_struct *mm, unsigned long addr) +void show_pte(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; @@ -31,7 +35,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) break; if (pgd_bad(*pgd)) { - printk("(bad)\n"); + printk("(bad)"); break; } @@ -42,7 +46,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) break; if (pmd_bad(*pmd)) { - printk("(bad)\n"); + printk("(bad)"); break; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index ba58e8bad..a235232d9 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -2,6 +2,10 @@ * linux/arch/arm/mm/init.c * * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include <linux/config.h> #include <linux/signal.h> @@ -27,7 +31,8 @@ #include <asm/hardware.h> #include <asm/setup.h> -#include "map.h" +#include <asm/mach/arch.h> +#include <asm/mach/map.h> #ifndef CONFIG_DISCONTIGMEM #define NR_NODES 1 @@ -387,6 +392,12 @@ static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot */ reserve_bootmem_node(0, __pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *)); +#else + /* + * Stop this memory from being grabbed - its special DMA + * memory that is required for the screen. + */ + reserve_bootmem_node(0, 0x02000000, 0x00080000); #endif /* * And don't forget to reserve the allocator bitmap, @@ -466,7 +477,7 @@ void __init bootmem_init(struct meminfo *mi) * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. */ -void __init paging_init(struct meminfo *mi) +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) { void *zero_page, *bad_page, *bad_table; int node; @@ -474,16 +485,19 @@ void __init paging_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); /* - * allocate what we need for the bad pages + * allocate what we need for the bad pages. + * note that we count on this going ok. */ zero_page = alloc_bootmem_low_pages(PAGE_SIZE); bad_page = alloc_bootmem_low_pages(PAGE_SIZE); bad_table = alloc_bootmem_low_pages(TABLE_SIZE); /* - * initialise the page tables + * initialise the page tables. */ - pagetable_init(mi); + memtable_init(mi); + if (mdesc->map_io) + mdesc->map_io(); flush_tlb_all(); /* @@ -528,7 +542,7 @@ void __init paging_init(struct meminfo *mi) zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; } - free_area_init_node(node, pgdat, zone_size, + free_area_init_node(node, pgdat, 0, zone_size, bdata->node_boot_start, zhole_size); } diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index d59b4e16c..e90c25018 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -1,5 +1,5 @@ /* - * arch/arm/mm/ioremap.c + * linux/arch/arm/mm/ioremap.c * * Re-map IO memory to kernel address space so that we can access it. * diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h deleted file mode 100644 index 1d071748d..000000000 --- a/arch/arm/mm/map.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/arch/arm/mm/map.h - * - * Copyright (C) 1999 Russell King - * - * Page table mapping constructs and function prototypes - */ -struct map_desc { - unsigned long virtual; - unsigned long physical; - unsigned long length; - int domain:4, - prot_read:1, - prot_write:1, - cacheable:1, - bufferable:1; -}; - -extern struct map_desc io_desc[]; -extern unsigned int io_desc_size; - -struct meminfo; - -extern void create_memmap_holes(struct meminfo *); -extern void pagetable_init(struct meminfo *); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index dc1647a2d..9a426fc18 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-armo.c + * linux/arch/arm/mm/mm-armo.c * - * Page table sludge for older ARM processor architectures. + * Copyright (C) 1998-2000 Russell King * - * Copyright (C) 1998-2000 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table sludge for older ARM processor architectures. */ #include <linux/sched.h> #include <linux/mm.h> @@ -15,7 +19,7 @@ #include <asm/page.h> #include <asm/arch/memory.h> -#include "map.h" +#include <asm/mach/map.h> #define MEMC_TABLE_SIZE (256*sizeof(unsigned long)) #define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR) @@ -147,7 +151,7 @@ void setup_mm_for_reboot(char mode) * some more work to get it to fit into our separate processor and * architecture structure. */ -void __init pagetable_init(struct meminfo *mi) +void __init memtable_init(struct meminfo *mi) { pte_t *pte; int i; @@ -162,6 +166,11 @@ void __init pagetable_init(struct meminfo *mi) pgd_val(swapper_pg_dir[i]) = 0; } +void __init iotable_init(struct map_desc *io_desc) +{ + /* nothing to do */ +} + /* * We never have holes in the memmap */ diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index e656a25d2..9ddcc84bc 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -1,9 +1,13 @@ /* * linux/arch/arm/mm/mm-armv.c * - * Page table sludge for ARM v3 and v4 processor architectures. - * * Copyright (C) 1998-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table sludge for ARM v3 and v4 processor architectures. */ #include <linux/sched.h> #include <linux/mm.h> @@ -16,7 +20,7 @@ #include <asm/io.h> #include <asm/setup.h> -#include "map.h" +#include <asm/mach/map.h> unsigned long *valid_addr_bitmap; @@ -62,6 +66,10 @@ __setup("nowb", nowrite_setup); #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) +#define clean_cache_area(start,size) \ + cpu_cache_clean_invalidate_range((unsigned long)start, ((unsigned long)start) + size, 0); + + /* * need to get a 16k page for level 1 */ @@ -72,10 +80,13 @@ pgd_t *get_pgd_slow(void) if (pgd) { pgd_t *init = pgd_offset_k(0); - + memzero(pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); memcpy(pgd + FIRST_KERNEL_PGD_NR, init + FIRST_KERNEL_PGD_NR, (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + /* + * FIXME: this should not be necessary + */ clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t)); /* @@ -310,18 +321,17 @@ void setup_mm_for_reboot(char mode) } } -void __init pagetable_init(struct meminfo *mi) +/* + * 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. + */ +void __init memtable_init(struct meminfo *mi) { struct map_desc *init_maps, *p, *q; unsigned long address = 0; int i; - /* - * 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); @@ -401,16 +411,21 @@ void __init pagetable_init(struct meminfo *mi) } } while (address != 0); - /* - * Create the architecture specific mappings - */ - for (i = 0; i < io_desc_size; i++) - create_mapping(io_desc + i); - flush_cache_all(); } -static inline void free_memmap(unsigned long start, unsigned long end) +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc) +{ + int i; + + for (i = 0; io_desc[i].last == 0; i++) + create_mapping(io_desc + i); +} + +static inline void free_memmap(int node, unsigned long start, unsigned long end) { unsigned long pg, pgend; @@ -422,10 +437,8 @@ static inline void free_memmap(unsigned long start, unsigned long end) start = __virt_to_phys(pg); end = __virt_to_phys(pgend); - /* - * The mem_map is always stored in node 0 - */ - free_bootmem_node(0, start, end - start); + + free_bootmem_node(node, start, end - start); } static inline void free_unused_memmap_node(int node, struct meminfo *mi) @@ -449,7 +462,7 @@ static inline void free_unused_memmap_node(int node, struct meminfo *mi) * between the current bank and the previous, free it. */ if (prev_bank_end && prev_bank_end != bank_start) - free_memmap(prev_bank_end, bank_start); + free_memmap(node, prev_bank_end, bank_start); prev_bank_end = PAGE_ALIGN(mi->bank[i].start + mi->bank[i].size); diff --git a/arch/arm/mm/mm-clps7500.c b/arch/arm/mm/mm-clps7500.c index b9199de80..765367c47 100644 --- a/arch/arm/mm/mm-clps7500.c +++ b/arch/arm/mm/mm-clps7500.c @@ -1,12 +1,11 @@ /* - * arch/arm/mm/mm-cl7500.c + * linux/arch/arm/mm/mm-cl7500.c * - * Extra MM routines for CL7500 architecture + * Copyright (C) 1998 Russell King + * Copyright (C) 1999 Nexus Electronics Ltd * - * Copyright (C) 1998 Russell King - * Copyright (C) 1999 Nexus Electronics Ltd + * Extra MM routines for CL7500 architecture */ - #include <linux/init.h> #include <asm/hardware.h> @@ -14,15 +13,17 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { +static struct map_desc cl7500_io_desc[] __initdata = { { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1 }, /* IO space */ { ISA_BASE, ISA_START, ISA_SIZE , DOMAIN_IO, 0, 1 }, /* ISA space */ { FLASH_BASE, FLASH_START, FLASH_SIZE, DOMAIN_IO, 0, 1 }, /* Flash */ - { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 } /* LED */ + { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 }, /* LED */ + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init clps7500_map_io(void) +{ + iotable_init(cl7500_io_desc); +} diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c index f16c93793..9402dfb8f 100644 --- a/arch/arm/mm/mm-ebsa110.c +++ b/arch/arm/mm/mm-ebsa110.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the EBSA-110 architecture + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for the EBSA-110 architecture */ #include <linux/mm.h> #include <linux/init.h> @@ -12,13 +16,15 @@ #include <asm/pgtable.h> #include <asm/page.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -struct map_desc io_desc[] __initdata = { +static struct map_desc ebsa110_io_desc[] __initdata = { { IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, - { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 } + { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init ebsa110_map_io(void) +{ + iotable_init(ebsa110_io_desc); +} diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c index 2c555f46d..b0eff7485 100644 --- a/arch/arm/mm/mm-footbridge.c +++ b/arch/arm/mm/mm-footbridge.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-footbridge.c + * linux/arch/arm/mm/mm-footbridge.c * - * Extra MM routines for the EBSA285 architecture + * Copyright (C) 1998-2000 Russell King, Dave Gilbert. * - * Copyright (C) 1998-1999 Russell King, Dave Gilbert. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for the EBSA285 architecture */ #include <linux/config.h> #include <linux/sched.h> @@ -13,73 +17,83 @@ #include <asm/pgtable.h> #include <asm/page.h> #include <asm/io.h> -#include <asm/dec21285.h> - -#include "map.h" +#include <asm/hardware/dec21285.h> +#include <asm/mach-types.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> /* - * The first entry allows us to fiddle with the EEPROM from user-space. - * This entry will go away in time, once the fmu32 can mmap() the - * flash. It can't at the moment. - * - * If you want to fiddle with PCI VGA cards from user space, then - * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }' - * You can then access the PCI bus at 0xe0000000 and 0xffe00000. + * Common mapping for all systems. Note that the outbound write flush is + * commented out since there is a "No Fix" problem with it. Not mapping + * it means that we have extra bullet protection on our feet. */ - -#ifdef CONFIG_FOOTBRIDGE_HOST +static struct map_desc fb_common_io_desc[] __initdata = { + { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC +}; /* - * The mapping when the footbridge is in host mode. + * The mapping when the footbridge is in host mode. We don't map any of + * this when we are in add-in mode. */ -#define MAPPING \ - { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 } - -#else +static struct map_desc ebsa285_host_io_desc[] __initdata = { +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST) + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, +#endif + LAST_DESC +}; /* - * The mapping when the footbridge is in add-in mode. + * The CO-ebsa285 mapping. */ -#define MAPPING \ - { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \ - { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 } - +static struct map_desc co285_io_desc[] __initdata = { +#ifdef CONFIG_ARCH_CO285 + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, #endif - -struct map_desc io_desc[] __initdata = { - MAPPING + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); - +void __init footbridge_map_io(void) +{ + struct map_desc *desc = NULL; + + /* + * Set up the common mapping first; we need this to + * determine whether we're in host mode or not. + */ + iotable_init(fb_common_io_desc); + + /* + * Now, work out what we've got to map in addition on this + * platform. + */ + if (machine_is_co285()) + desc = co285_io_desc; + else if (footbridge_cfn_mode()) + desc = ebsa285_host_io_desc; + + if (desc) + iotable_init(desc); +} #ifdef CONFIG_FOOTBRIDGE_ADDIN /* - * These two functions convert virtual addresses to PCI addresses - * and PCI addresses to virtual addresses. Note that it is only - * legal to use these on memory obtained via get_free_page or - * kmalloc. + * These two functions convert virtual addresses to PCI addresses and PCI + * addresses to virtual addresses. Note that it is only legal to use these + * on memory obtained via get_free_page or kmalloc. */ unsigned long __virt_to_bus(unsigned long res) { #ifdef CONFIG_DEBUG_ERRORS if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) { - printk("__virt_to_phys: invalid virtual address 0x%08lx\n", res); + printk("__virt_to_bus: invalid virtual address 0x%08lx\n", res); __backtrace(); } #endif @@ -93,7 +107,7 @@ unsigned long __bus_to_virt(unsigned long res) #ifdef CONFIG_DEBUG_ERRORS if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) { - printk("__phys_to_virt: invalid virtual address 0x%08lx\n", res); + printk("__bus_to_virt: invalid virtual address 0x%08lx\n", res); __backtrace(); } #endif diff --git a/arch/arm/mm/mm-l7200.c b/arch/arm/mm/mm-l7200.c index 8a252d684..bd7c6e2dd 100644 --- a/arch/arm/mm/mm-l7200.c +++ b/arch/arm/mm/mm-l7200.c @@ -1,11 +1,10 @@ /* - * arch/arm/mm/mm-lusl7200.c + * linux/arch/arm/mm/mm-lusl7200.c * - * Extra MM routines for L7200 architecture + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * Extra MM routines for L7200 architecture */ - #include <linux/init.h> #include <asm/hardware.h> @@ -13,13 +12,15 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { +static struct map_desc l7200_io_desc[] __initdata = { { IO_BASE, IO_START, IO_SIZE, DOMAIN_IO, 0, 1 ,0 ,0}, { IO_BASE_2, IO_START_2, IO_SIZE_2, DOMAIN_IO, 0, 1 ,0 ,0}, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init l7200_map_io(void) +{ + iotable_init(l7200_io_desc); +} diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c index ccb6c8a5c..31d619433 100644 --- a/arch/arm/mm/mm-nexuspci.c +++ b/arch/arm/mm/mm-nexuspci.c @@ -1,13 +1,12 @@ /* - * arch/arm/mm/mm-nexuspci.c - * from arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-nexuspci.c + * from linux/arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the FTV/PCI architecture + * Copyright (C) 1998-1999 Phil Blundell + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Phil Blundell - * Copyright (C) 1998-1999 Russell King + * Extra MM routines for the FTV/PCI architecture */ - #include <linux/sched.h> #include <linux/mm.h> #include <linux/init.h> @@ -16,16 +15,18 @@ #include <asm/page.h> #include <asm/io.h> -#include "map.h" - -struct map_desc io_desc[] __initdata = { +#include <asm/mach/map.h> + +static struct map_desc nexuspci_io_desc[] __initdata = { { INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, { PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, { PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, { DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } + { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init nexuspci_map_io(void) +{ + iotable_init(nexuspci_io_desc); +} diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index 494a61988..023fee8e0 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -1,9 +1,13 @@ /* - * arch/arm/mm/mm-rpc.c + * linux/arch/arm/mm/mm-rpc.c * - * Extra MM routines for RiscPC architecture + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998-1999 Russell King + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Extra MM routines for RiscPC architecture */ #include <linux/init.h> @@ -12,17 +16,16 @@ #include <asm/proc/domain.h> #include <asm/setup.h> -#include "map.h" - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) +#include <asm/mach/map.h> -struct map_desc io_desc[] __initdata = { - /* VRAM */ - { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, - /* IO space */ - { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - /* EASI space */ - { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 } +static struct map_desc rpc_io_desc[] __initdata = { + { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, /* VRAM */ + { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space */ + { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space */ + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init rpc_map_io(void) +{ + iotable_init(rpc_io_desc); +} diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index aaf28f880..54fe435c6 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -1,20 +1,19 @@ /* - * arch/arm/mm/mm-sa1100.c + * linux/arch/arm/mm/mm-sa1100.c * - * Extra MM routines for the SA1100 architecture + * Copyright (C) 1998-1999 Russell King + * Copyright (C) 1999 Hugo Fiennes * - * Copyright (C) 1998-1999 Russell King - * Copyright (C) 1999 Hugo Fiennes + * Extra MM routines for the SA1100 architecture * - * 1999/12/04 Nicolas Pitre <nico@cam.org> + * 1999/12/04 Nicolas Pitre <nico@cam.org> * Converted memory definition for struct meminfo initialisations. * Memory is listed physically now. * - * 2000/04/07 Nicolas Pitre <nico@cam.org> + * 2000/04/07 Nicolas Pitre <nico@cam.org> * Reworked for run-time selection of memory definitions * */ - #include <linux/config.h> #include <linux/mm.h> #include <linux/init.h> @@ -25,171 +24,158 @@ #include <asm/page.h> #include <asm/mach-types.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - - -#define SA1100_STD_IO_MAPPING \ +static struct map_desc standard_io_desc[] __initdata = { /* virtual physical length domain r w c b */ \ - { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */ \ - { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */ \ - { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 attr */ \ - { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 attr */ \ - { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 mem */ \ - { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 mem */ \ - { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ \ - { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ \ - { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ \ - { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */ + { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */ + { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */ + { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ + { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ + { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ + { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD + DMA */ + LAST_DESC +}; +/* + * Typically, static virtual address mappings are as follow: + * + * 0xe8000000-0xefffffff: flash memory (especially when multiple flash + * banks need to be mapped contigously) + * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.) + * 0xf4000000-0xf4ffffff: SA-1111 + * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area) + * 0xf6000000-0xffffffff: reserved (internal SA1100 IO defined above) + * + * Below 0xe8000000 is reserved for vm allocation. + */ static struct map_desc assabet_io_desc[] __initdata = { #ifdef CONFIG_SA1100_ASSABET - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ - { 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */ - { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ - SA1100_STD_IO_MAPPING -#endif -}; - -static struct map_desc nanoengine_io_desc[] __initdata = { -#ifdef CONFIG_SA1100_NANOENGINE - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ - { 0xdc000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ + { 0xf1000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */ + { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */ + { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ #endif + LAST_DESC }; static struct map_desc bitsy_io_desc[] __initdata = { #ifdef CONFIG_SA1100_BITSY - { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - { 0xdc000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */ #endif + LAST_DESC }; static struct map_desc cerf_io_desc[] __initdata = { #ifdef CONFIG_SA1100_CERF - { 0xd8000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */ - { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */ #endif + LAST_DESC }; static struct map_desc empeg_io_desc[] __initdata = { #ifdef CONFIG_SA1100_EMPEG { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ - SA1100_STD_IO_MAPPING #endif + LAST_DESC }; static struct map_desc graphicsclient_io_desc[] __initdata = { #ifdef CONFIG_SA1100_GRAPHICSCLIENT - { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */ - { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ #endif + LAST_DESC }; static struct map_desc lart_io_desc[] __initdata = { #ifdef CONFIG_SA1100_LART - { 0xd0000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */ - { 0xd8000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */ + { 0xec000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */ #endif + LAST_DESC +}; + +static struct map_desc nanoengine_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_NANOENGINE + { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */ + { 0xf1000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */ +#endif + LAST_DESC }; static struct map_desc thinclient_io_desc[] __initdata = { #ifdef CONFIG_SA1100_THINCLIENT #if 0 - { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ + { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ #else - { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ + { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ #endif - { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ - SA1100_STD_IO_MAPPING + { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ #endif + LAST_DESC }; static struct map_desc tifon_io_desc[] __initdata = { #ifdef CONFIG_SA1100_TIFON - { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xe8800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ #endif + LAST_DESC }; static struct map_desc victor_io_desc[] __initdata = { #ifdef CONFIG_SA1100_VICTOR - { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ - SA1100_STD_IO_MAPPING + { 0xe8000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ #endif + LAST_DESC }; static struct map_desc xp860_io_desc[] __initdata = { #ifdef CONFIG_SA1100_XP860 - { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ - { 0xda000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */ - { 0xdc000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */ - SA1100_STD_IO_MAPPING + { 0xf4000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */ + { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */ + { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */ #endif + LAST_DESC }; -static struct map_desc default_io_desc[] __initdata = { - SA1100_STD_IO_MAPPING -}; - - -/* - * Here it would be wiser to simply assign a pointer to the appropriate - * list, but io_desc is already declared as an array in "map.h". - */ -struct map_desc io_desc[20] __initdata = {}; -unsigned int io_desc_size; - -void __init select_sa1100_io_desc(void) +void __init sa1100_map_io(void) { - if( machine_is_assabet() ) { - memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) ); - io_desc_size = SIZE(assabet_io_desc); - } else if( machine_is_nanoengine() ) { - memcpy( io_desc, nanoengine_io_desc, sizeof(nanoengine_io_desc) ); - io_desc_size = SIZE(nanoengine_io_desc); - } else if( machine_is_bitsy() ) { - memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) ); - io_desc_size = SIZE(bitsy_io_desc); - } else if( machine_is_cerf() ) { - memcpy( io_desc, cerf_io_desc, sizeof(cerf_io_desc) ); - io_desc_size = SIZE(cerf_io_desc); - } else if( machine_is_empeg() ) { - memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) ); - io_desc_size = SIZE(empeg_io_desc); - } else if( machine_is_graphicsclient() ) { - memcpy( io_desc, graphicsclient_io_desc, sizeof(graphicsclient_io_desc) ); - io_desc_size = SIZE(graphicsclient_io_desc); - } else if( machine_is_lart() ) { - memcpy( io_desc, lart_io_desc, sizeof(lart_io_desc) ); - io_desc_size = SIZE(lart_io_desc); - } else if( machine_is_thinclient() ) { - memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) ); - io_desc_size = SIZE(thinclient_io_desc); - } else if( machine_is_tifon() ) { - memcpy( io_desc, tifon_io_desc, sizeof(tifon_io_desc) ); - io_desc_size = SIZE(tifon_io_desc); - } else if( machine_is_victor() ) { - memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) ); - io_desc_size = SIZE(victor_io_desc); - } else if( machine_is_xp860() ) { - memcpy( io_desc, xp860_io_desc, sizeof(xp860_io_desc) ); - io_desc_size = SIZE(xp860_io_desc); - } else { - memcpy( io_desc, default_io_desc, sizeof(default_io_desc) ); - io_desc_size = SIZE(default_io_desc); - } + struct map_desc *desc = NULL; + + iotable_init(standard_io_desc); + + if (machine_is_assabet()) + desc = assabet_io_desc; + else if (machine_is_nanoengine()) + desc = nanoengine_io_desc; + else if (machine_is_bitsy()) + desc = bitsy_io_desc; + else if (machine_is_cerf()) + desc = cerf_io_desc; + else if (machine_is_empeg()) + desc = empeg_io_desc; + else if (machine_is_graphicsclient()) + desc = graphicsclient_io_desc; + else if (machine_is_lart()) + desc = lart_io_desc; + else if (machine_is_thinclient()) + desc = thinclient_io_desc; + else if (machine_is_tifon()) + desc = tifon_io_desc; + else if (machine_is_victor()) + desc = victor_io_desc; + else if (machine_is_xp860()) + desc = xp860_io_desc; + + if (desc) + iotable_init(desc); } diff --git a/arch/arm/mm/mm-shark.c b/arch/arm/mm/mm-shark.c deleted file mode 100644 index dc8e6e12b..000000000 --- a/arch/arm/mm/mm-shark.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/arm/mm/mm-shark.c - * - * by Alexander.Schulz@stud.uni-karlsruhe.de - */ -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/pgtable.h> -#include <asm/page.h> -#include <asm/io.h> - -#include "map.h" - -struct map_desc io_desc[] __initdata = { - { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - { FB_BASE , FB_START , FB_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, - { FBREG_BASE , FBREG_START , FBREG_SIZE , DOMAIN_IO, 0, 1, 0, 0 } -}; - - -#define SIZEOFMAP (sizeof(io_desc) / sizeof(io_desc[0])) - -unsigned int __initdata io_desc_size = SIZEOFMAP; diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c index 78250336e..e927d05d3 100644 --- a/arch/arm/mm/mm-tbox.c +++ b/arch/arm/mm/mm-tbox.c @@ -1,13 +1,11 @@ /* - * arch/arm/mm/mm-tbox.c - * from arch/arm/mm/mm-ebsa110.c + * linux/arch/arm/mm/mm-tbox.c * - * Extra MM routines for the Tbox architecture + * Copyright (C) 1998, 1999, 2000 Phil Blundell + * Copyright (C) 1998-1999 Russell King * - * Copyright (C) 1998 Phil Blundell - * Copyright (C) 1998-1999 Russell King + * Extra MM routines for the Tbox architecture */ - #include <linux/sched.h> #include <linux/mm.h> #include <linux/init.h> @@ -16,44 +14,15 @@ #include <asm/pgtable.h> #include <asm/page.h> -#include "map.h" +#include <asm/mach/map.h> -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -/* Logical Physical - * 0xffff1000 0x00100000 DMA registers - * 0xffff2000 0x00200000 MPEG - * 0xffff3000 0x00300000 FPGA1 local control - * 0xffff4000 0x00400000 External serial - * 0xffff5000 0x00500000 Internal serial - * 0xffff6000 0x00600000 Parallel - * 0xffff7000 0x00700000 Interrupt control - * 0xffff8000 0x00800000 Computer video - * 0xffff9000 0x00900000 Control register 0 - * 0xffffs000 0x00a00000 Control register 1 - * 0xffffb000 0x00b00000 Control register 2 - * 0xffffc000 0x00c00000 FPGA2 local control - * 0xffffd000 0x00d00000 Interrupt reset - * 0xffffe000 0x00e00000 MPEG DMA throttle - */ - -const struct map_desc io_desc[] __initdata = { - { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } +static struct map_desc tbox_io_desc[] __initdata = { + /* See hardware.h for details */ + { IO_BASE, IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, + LAST_DESC }; -unsigned int __initdata io_desc_size = SIZE(io_desc); +void __init tbox_map_io(void) +{ + iotable_init(tbox_io_desc); +} diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index 6dd48c919..76377cf9c 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -1,10 +1,16 @@ /* - * linux/arch/arm/mm/proc-arm2,3.S: MMU functions for ARM2,3 + * linux/arch/arm/mm/proc-arm2,3.S * - * (C) 1997-1999 Russell King + * Copyright (C) 1997-1999 Russell King * - * These are the low level assembler for performing cache - * and memory functions on ARM2, ARM250 and ARM3 processors. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for ARM2,3 + * + * 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> diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index b18d69d98..61e135e19 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -1,20 +1,25 @@ /* - * linux/arch/arm/mm/proc-arm6,7.S: MMU functions for ARM6 + * linux/arch/arm/mm/proc-arm6,7.S * - * (C) 1997-2000 Russell King + * Copyright (C) 1997-2000 Russell King * - * These are the low level assembler for performing cache and TLB - * functions on the ARM6 & ARM7. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for ARM6 + * + * 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 <asm/errno.h> #include "../lib/constants.h" /* - * Function: arm6_7_flush_cache_all (void) - * : arm6_7_flush_cache_page (unsigned long address, int size, int flags) + * Function: arm6_7_cache_clean_invalidate_all (void) + * : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags) * * Params : address Area start address * : size size of area @@ -22,41 +27,41 @@ * * Purpose : Flush all cache lines */ -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_flush_icache_page) -ENTRY(cpu_arm7_flush_icache_page) -ENTRY(cpu_arm6_cache_wback_area) -ENTRY(cpu_arm7_cache_wback_area) -ENTRY(cpu_arm6_cache_purge_area) -ENTRY(cpu_arm7_cache_purge_area) +ENTRY(cpu_arm6_cache_clean_invalidate_all) +ENTRY(cpu_arm7_cache_clean_invalidate_all) +ENTRY(cpu_arm6_cache_clean_invalidate_range) +ENTRY(cpu_arm7_cache_clean_invalidate_range) +ENTRY(cpu_arm6_invalidate_icache_range) +ENTRY(cpu_arm7_invalidate_icache_range) +ENTRY(cpu_arm6_invalidate_icache_page) +ENTRY(cpu_arm7_invalidate_icache_page) +ENTRY(cpu_arm6_dcache_clean_range) +ENTRY(cpu_arm7_dcache_clean_range) +ENTRY(cpu_arm6_dcache_invalidate_range) +ENTRY(cpu_arm7_dcache_invalidate_range) mov r0, #0 mcr p15, 0, r0, c7, c0, 0 @ flush cache -ENTRY(cpu_arm6_clean_cache_area) -ENTRY(cpu_arm7_clean_cache_area) +ENTRY(cpu_arm6_dcache_clean_page) +ENTRY(cpu_arm7_dcache_clean_page) +ENTRY(cpu_arm6_dcache_clean_entry) +ENTRY(cpu_arm7_dcache_clean_entry) ENTRY(cpu_arm6_flush_ram_page) ENTRY(cpu_arm7_flush_ram_page) mov pc, lr /* - * Function: arm6_7_flush_tlb_all (void) + * Function: arm6_7_tlb_invalidate_all (void) * * Purpose : flush all TLB entries in all caches */ -ENTRY(cpu_arm6_flush_tlb_all) -ENTRY(cpu_arm7_flush_tlb_all) +ENTRY(cpu_arm6_tlb_invalidate_all) +ENTRY(cpu_arm7_tlb_invalidate_all) mov r0, #0 mcr p15, 0, r0, c5, c0, 0 @ flush TLB mov pc, lr /* - * Function: arm6_7_flush_tlb_page (unsigned long address, int end, int flags) + * Function: arm6_7_tlb_invalidate_page (unsigned long address, int end, int flags) * * Params : address Area start address * : end Area end address @@ -64,8 +69,8 @@ ENTRY(cpu_arm7_flush_tlb_all) * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm6_flush_tlb_area) -ENTRY(cpu_arm7_flush_tlb_area) +ENTRY(cpu_arm6_tlb_invalidate_range) +ENTRY(cpu_arm7_tlb_invalidate_range) 1: mcr p15, 0, r0, c6, c0, 0 @ flush TLB add r0, r0, #4096 cmp r0, r1 @@ -73,15 +78,15 @@ ENTRY(cpu_arm7_flush_tlb_area) mov pc, lr /* - * Function: arm6_7_flush_tlb_page (unsigned long address, int flags) + * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags) * * Params : address Address * : flags b0 = I-TLB as well * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm6_flush_tlb_page) -ENTRY(cpu_arm7_flush_tlb_page) +ENTRY(cpu_arm6_tlb_invalidate_page) +ENTRY(cpu_arm7_tlb_invalidate_page) mcr p15, 0, r0, c6, c0, 0 @ flush TLB mov pc, lr @@ -392,23 +397,33 @@ ENTRY(arm6_processor_functions) .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_reset + .word cpu_arm6_do_idle + + /* cache */ + .word cpu_arm6_cache_clean_invalidate_all + .word cpu_arm6_cache_clean_invalidate_range .word cpu_arm6_flush_ram_page - .word cpu_arm6_flush_tlb_all - .word cpu_arm6_flush_tlb_area + + /* dcache */ + .word cpu_arm6_dcache_invalidate_range + .word cpu_arm6_dcache_clean_range + .word cpu_arm6_dcache_clean_page + .word cpu_arm6_dcache_clean_entry + + /* icache */ + .word cpu_arm6_invalidate_icache_range + .word cpu_arm6_invalidate_icache_page + + /* tlb */ + .word cpu_arm6_tlb_invalidate_all + .word cpu_arm6_tlb_invalidate_range + .word cpu_arm6_tlb_invalidate_page + + /* pgtable */ .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 - .word cpu_arm6_flush_tlb_page - .word cpu_arm6_do_idle - .word cpu_arm6_flush_icache_page .size arm6_processor_functions, . - arm6_processor_functions /* @@ -421,23 +436,33 @@ ENTRY(arm7_processor_functions) .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_reset + .word cpu_arm7_do_idle + + /* cache */ + .word cpu_arm7_cache_clean_invalidate_all + .word cpu_arm7_cache_clean_invalidate_range .word cpu_arm7_flush_ram_page - .word cpu_arm7_flush_tlb_all - .word cpu_arm7_flush_tlb_area + + /* dcache */ + .word cpu_arm7_dcache_invalidate_range + .word cpu_arm7_dcache_clean_range + .word cpu_arm7_dcache_clean_page + .word cpu_arm7_dcache_clean_entry + + /* icache */ + .word cpu_arm7_invalidate_icache_range + .word cpu_arm7_invalidate_icache_page + + /* tlb */ + .word cpu_arm7_tlb_invalidate_all + .word cpu_arm7_tlb_invalidate_range + .word cpu_arm7_tlb_invalidate_page + + /* pgtable */ .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 - .word cpu_arm7_flush_tlb_page - .word cpu_arm7_do_idle - .word cpu_arm7_flush_icache_page .size arm7_processor_functions, . - arm7_processor_functions .type cpu_arm6_info, #object @@ -479,7 +504,7 @@ cpu_elf_name: .asciz "v3" __arm6_proc_info: .long 0x41560600 .long 0xfffffff0 - .long 0x00000c12 + .long 0x00000c1e b __arm6_setup .long cpu_arch_name .long cpu_elf_name @@ -492,7 +517,7 @@ __arm6_proc_info: __arm610_proc_info: .long 0x41560610 .long 0xfffffff0 - .long 0x00000c12 + .long 0x00000c1e b __arm6_setup .long cpu_arch_name .long cpu_elf_name @@ -505,7 +530,7 @@ __arm610_proc_info: __arm7_proc_info: .long 0x41007000 .long 0xffffff00 - .long 0x00000c12 + .long 0x00000c1e b __arm7_setup .long cpu_arch_name .long cpu_elf_name @@ -518,7 +543,7 @@ __arm7_proc_info: __arm710_proc_info: .long 0x41007100 .long 0xfff8ff00 - .long 0x00000c12 + .long 0x00000c1e b __arm7_setup .long cpu_arch_name .long cpu_elf_name diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index 262a4fd8b..13620ad5f 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -1,27 +1,44 @@ /* - * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720 + * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720 + * + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * Rob Scott (rscott@mtrob.fdns.net) + * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) - * Rob Scott (rscott@mtrob.fdns.net) * * These are the low level assembler for performing cache and TLB - * functions on the ARM720T. + * functions on the ARM720T. The ARM720T has a writethrough IDC + * cache, so we don't need to clean it. * - * Changelog: - * 05-09-2000 SJH Created by moving 720 specific functions - * out of 'proc-arm6,7.S' per RSK discussion - * 07-25-2000 SJH Added idle function. + * Changelog: + * 05-09-2000 SJH Created by moving 720 specific functions + * out of 'proc-arm6,7.S' per RMK discussion + * 07-25-2000 SJH Added idle function. + * 08-25-2000 DBS Updated for integration of ARM Ltd version. */ #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/procinfo.h> -#include <asm/errno.h> #include <asm/hardware.h> #include "../lib/constants.h" /* - * Function: arm720_flush_cache_all (void) - * : arm720_flush_cache_page (unsigned long address, int size, + * Function: arm720_cache_clean_invalidate_all (void) + * : arm720_cache_clean_invalidate_page (unsigned long address, int size, * int flags) * * Params : address Area start address @@ -30,33 +47,37 @@ * * Purpose : Flush all cache lines */ -ENTRY(cpu_arm720_flush_cache_all) -ENTRY(cpu_arm720_flush_cache_area) -ENTRY(cpu_arm720_flush_cache_entry) -ENTRY(cpu_arm720_flush_icache_area) -ENTRY(cpu_arm720_flush_icache_page) -ENTRY(cpu_arm720_cache_wback_area) -ENTRY(cpu_arm720_cache_purge_area) +ENTRY(cpu_arm720_cache_clean_invalidate_all) +ENTRY(cpu_arm720_cache_clean_invalidate_range) +ENTRY(cpu_arm720_icache_invalidate_range) +ENTRY(cpu_arm720_icache_invalidate_page) +ENTRY(cpu_arm720_dcache_invalidate_range) mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush cache mov pc, lr -ENTRY(cpu_arm720_clean_cache_area) +/* + * These just expect cache lines to be cleaned. Since we have a writethrough + * cache, we never have any dirty cachelines to worry about. + */ +ENTRY(cpu_arm720_dcache_clean_range) +ENTRY(cpu_arm720_dcache_clean_page) +ENTRY(cpu_arm720_dcache_clean_entry) ENTRY(cpu_arm720_flush_ram_page) mov pc, lr /* - * Function: arm720_flush_tlb_all (void) + * Function: arm720_tlb_invalidate_all (void) * * Purpose : flush all TLB entries in all caches */ -ENTRY(cpu_arm720_flush_tlb_all) +ENTRY(cpu_arm720_tlb_invalidate_all) mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mov pc, lr /* - * Function: arm720_flush_tlb_page (unsigned long address, int end, int flags) + * Function: arm720_tlb_invalidate_page (unsigned long address, int end, int flags) * * Params : address Area start address * : end Area end address @@ -64,7 +85,7 @@ ENTRY(cpu_arm720_flush_tlb_all) * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm720_flush_tlb_area) +ENTRY(cpu_arm720_tlb_invalidate_range) 1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4) add r0, r0, #4096 cmp r0, r1 @@ -72,14 +93,14 @@ ENTRY(cpu_arm720_flush_tlb_area) mov pc, lr /* - * Function: arm720_flush_tlb_page (unsigned long address, int flags) + * Function: arm720_tlb_invalidate_page (unsigned long address, int flags) * * Params : address Address * : flags b0 = I-TLB as well * * Purpose : flush a TLB entry */ -ENTRY(cpu_arm720_flush_tlb_page) +ENTRY(cpu_arm720_tlb_invalidate_page) mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4) mov pc, lr @@ -262,12 +283,15 @@ ENTRY(cpu_arm720_proc_init) mov pc, lr ENTRY(cpu_arm720_proc_fin) - mrs r0, cpsr - orr r0, r0, #F_BIT | I_BIT - msr cpsr, r0 - mov r0, #0x31 @ ....S..DP...M + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. mcr p15, 0, r0, c1, c0, 0 @ disable caches - mov pc, lr + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache + ldmfd sp!, {pc} /* * Function: arm720_proc_do_idle (void) @@ -281,10 +305,12 @@ ENTRY(cpu_arm720_proc_fin) * Purpose : put the processer in proper idle mode */ ENTRY(cpu_arm720_do_idle) +#if 0 /* FIXME: is this part of the processor? */ ldr r2, =IO_BASE @ Virt addr of IO add r2, r2, #0x00050000 @ Start of PMU regs mov r1, #0x01 @ Idle mode - str r1, [r2, #4] + str r1, [r2, #4] +#endif mov pc, lr /* @@ -295,7 +321,7 @@ ENTRY(cpu_arm720_do_idle) */ ENTRY(cpu_arm720_set_pgd) mov r1, #0 - mcr p15, 0, r1, c7, c7, 0 @ flush cache + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) mov pc, lr @@ -340,9 +366,6 @@ ENTRY(cpu_arm720_set_pte) movne r2, #0 str r2, [r0] @ hardware version - - mcr p15, 0, r0, c7, c7, 0 @ flush cache - mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mov pc, lr /* @@ -351,30 +374,37 @@ ENTRY(cpu_arm720_set_pte) * Notes : This sets up everything for a reset */ ENTRY(cpu_arm720_reset) - mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 @ flush cache - mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) - mov pc, lr + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 cpu_armvlsi_name: .asciz "ARM/VLSI" cpu_arm720_name: - .asciz "ARM 720" + .asciz "ARM720T" .align .section ".text.init", #alloc, #execinstr __arm720_setup: mov r0, #0 - mcr p15, 0, r0, c7, c7, 0 @ flush caches on v4 + mcr p15, 0, r0, c7, c7, 0 @ invalidate caches mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) mcr p15, 0, r4, c2, c0 @ load page table pointer mov r0, #0x1f @ Domains 0, 1 = client mcr p15, 0, r0, c3, c0 @ load domain access register - - /* Set CP15 Control reg bits (RSBLDPWCAM) */ - mov r0, #0x7d @ ...LDPWC.M - orr r0, r0, #0x100 @ .S.LDPWC.M + + mrc p15, 0, r0, c1, c0 @ get control register + bic r0, r0, #0x2e00 + bic r0, r0, #0x000e + orr r0, r0, #0x0031 @ ..V...RSBLDPWCAM + orr r0, r0, #0x0100 @ .........111.... (old) + orr r0, r0, #0x000c @ ..0...01..111101 (new) mov pc, lr @ __ret (head-armv.S) /* @@ -387,23 +417,33 @@ ENTRY(arm720_processor_functions) .word cpu_arm720_check_bugs .word cpu_arm720_proc_init .word cpu_arm720_proc_fin - .word cpu_arm720_flush_cache_all - .word cpu_arm720_flush_cache_area - .word cpu_arm720_flush_cache_entry - .word cpu_arm720_clean_cache_area + .word cpu_arm720_reset + .word cpu_arm720_do_idle + + /* cache */ + .word cpu_arm720_cache_clean_invalidate_all + .word cpu_arm720_cache_clean_invalidate_range .word cpu_arm720_flush_ram_page - .word cpu_arm720_flush_tlb_all - .word cpu_arm720_flush_tlb_area + + /* dcache */ + .word cpu_arm720_dcache_invalidate_range + .word cpu_arm720_dcache_clean_range + .word cpu_arm720_dcache_clean_page + .word cpu_arm720_dcache_clean_entry + + /* icache */ + .word cpu_arm720_icache_invalidate_range + .word cpu_arm720_icache_invalidate_page + + /* tlb */ + .word cpu_arm720_tlb_invalidate_all + .word cpu_arm720_tlb_invalidate_range + .word cpu_arm720_tlb_invalidate_page + + /* pgtable */ .word cpu_arm720_set_pgd .word cpu_arm720_set_pmd .word cpu_arm720_set_pte - .word cpu_arm720_reset - .word cpu_arm720_flush_icache_area - .word cpu_arm720_cache_wback_area - .word cpu_arm720_cache_purge_area - .word cpu_arm720_flush_tlb_page - .word cpu_arm720_do_idle - .word cpu_arm720_flush_icache_page .size arm720_processor_functions, . - arm720_processor_functions .type cpu_arm720_info, #object @@ -431,11 +471,11 @@ cpu_elf_name: .asciz "v4" __arm720_proc_info: .long 0x41807200 @ cpu_val .long 0xffffff00 @ cpu_mask - .long 0x00000c12 @ __cpu_mmu_flags + .long 0x00000c0e @ __cpu_mmu_flags b __arm720_setup @ --cpu_flush .long cpu_arch_name @ arch_name .long cpu_elf_name @ elf_name - .long HWCAP_SWP | HWCAP_26BIT @ elf_hwcap + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT @ elf_hwcap .long cpu_arm720_info @ info .long arm720_processor_functions .size __arm720_proc_info, . - __arm720_proc_info diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S new file mode 100644 index 000000000..a4306f08a --- /dev/null +++ b/arch/arm/mm/proc-arm920.S @@ -0,0 +1,602 @@ +/* + * linux/arch/arm/mm/arm920.S: MMU functions for ARM920 + * + * Copyright (C) 1999,2000 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm920. + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <asm/assembler.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include "../lib/constants.h" + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 16384 + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 +#define ICACHELINESIZE 32 + +/* + * and the page size + */ +#define PAGESIZE 4096 + + .text + +/* + * cpu_arm920_data_abort() + * + * obtain information about current aborted instruction + * + * r0 = address of aborted instruction + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR + */ + .align 5 +ENTRY(cpu_arm920_data_abort) + ldr r1, [r0] @ read aborted instruction + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov r1, r1, lsr #19 @ b1 = L + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r1, r1, #2 + and r3, r3, #255 + mov pc, lr + +/* + * cpu_arm920_check_bugs() + */ +ENTRY(cpu_arm920_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr + +/* + * cpu_arm920_proc_init() + */ +ENTRY(cpu_arm920_proc_init) + mov pc, lr + +/* + * cpu_arm920_proc_fin() + */ +ENTRY(cpu_arm920_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_arm920_cache_clean_invalidate_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm920_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm920_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm920_do_idle() + */ + .align 5 +ENTRY(cpu_arm920_do_idle) +#if defined(CONFIG_CPU_ARM920_CPU_IDLE) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt +#endif + mov pc, lr + +/* ================================= CACHE ================================ */ + + +/* + * cpu_arm920_cache_clean_invalidate_all() + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times + */ + .align 5 +ENTRY(cpu_arm920_cache_clean_invalidate_all) + mov r2, #1 +cpu_arm920_cache_clean_invalidate_all_r2: + mov ip, #0 +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +/* + * 'Clean & Invalidate whole DCache' + * Re-written to use Index Ops. + * Uses registers r1, r3 and ip + */ + mov r1, #7 << 5 @ 8 segments +1: orr r3, r1, #63 << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well + */ + .align 5 +ENTRY(cpu_arm920_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_arm920_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + teq r2, #0 + movne r0, #0 + mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +/* + * cpu_arm920_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate + */ + .align 5 +ENTRY(cpu_arm920_flush_ram_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ + +/* + * cpu_arm920_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_dcache_invalidate_range) + tst r0, #DCACHELINESIZE - 1 + bic r0, r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm920_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_arm920_cache_clean_invalidate_all_r2 + +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bpl 1b + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_dcache_clean_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * page: virtual address of page to clean from dcache + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_page) +#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b +#endif + mov pc, lr + +/* + * cpu_arm920_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_arm920_dcache_clean_entry) +#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ + +/* + * cpu_arm920_icache_invalidate_range(start, end) + * + * invalidate a range of virtual addresses from the Icache + * + * start: virtual start address + * end: virtual end address + */ + .align 5 +ENTRY(cpu_arm920_icache_invalidate_range) +1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB +ENTRY(cpu_arm920_icache_invalidate_page) + /* why no invalidate I cache --rmk */ + mov pc, lr + + +/* ================================== TLB ================================= */ + +/* + * cpu_arm920_tlb_invalidate_all() + * + * Invalidate all TLB entries + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm920_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blt 1b + mov pc, lr + +/* + * cpu_arm920_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_arm920_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm920_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm920_set_pgd) + mov ip, #0 +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */ + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +@ && Re-written to use Index Ops. +@ && Uses registers r1, r3 and ip + + mov r1, #7 << 5 @ 8 segments +1: orr r3, r1, #63 << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm920_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store + */ + .align 5 +ENTRY(cpu_arm920_set_pmd) +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + eor r2, r1, #0x0a @ C & Section + tst r2, #0x0b + biceq r1, r1, #4 @ clear bufferable bit +#endif + str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * cpu_arm920_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm920_set_pte) + str r1, [r0], #-1024 @ linux version + + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ + + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE + + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + +cpu_manu_name: + .asciz "ARM/VLSI" +ENTRY(cpu_arm920_name) + .ascii "Arm920" +#if defined(CONFIG_CPU_ARM920_CPU_IDLE) + .ascii "s" +#endif +#if defined(CONFIG_CPU_ARM920_I_CACHE_ON) + .ascii "i" +#endif +#if defined(CONFIG_CPU_ARM920_D_CACHE_ON) + .ascii "d" +#if defined(CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH) + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + .align + + .section ".text.init", #alloc, #execinstr + +__arm920_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 +/* + * Clear out 'unwanted' bits (then put them in if we need them) + */ + bic r0, r0, #0x0e00 @ ....??r......... + bic r0, r0, #0x0002 @ ..............a. + bic r0, r0, #0x000c @ W,D + bic r0, r0, #0x1000 @ I +/* + * Turn on what we want + */ + orr r0, r0, #0x0031 @ ..........DP...M + orr r0, r0, #0x0100 @ .......S........ + +#ifdef CONFIG_CPU_ARM920_D_CACHE_ON + orr r0, r0, #0x0004 @ Enable D cache +#endif +#ifdef CONFIG_CPU_ARM920_I_CACHE_ON + orr r0, r0, #0x1000 @ I Cache on +#endif + mov pc, lr + + .text + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm920_processor_functions, #object +arm920_processor_functions: + .word cpu_arm920_data_abort + .word cpu_arm920_check_bugs + .word cpu_arm920_proc_init + .word cpu_arm920_proc_fin + .word cpu_arm920_reset + .word cpu_arm920_do_idle + + /* cache */ + .word cpu_arm920_cache_clean_invalidate_all + .word cpu_arm920_cache_clean_invalidate_range + .word cpu_arm920_flush_ram_page + + /* dcache */ + .word cpu_arm920_dcache_invalidate_range + .word cpu_arm920_dcache_clean_range + .word cpu_arm920_dcache_clean_page + .word cpu_arm920_dcache_clean_entry + + /* icache */ + .word cpu_arm920_icache_invalidate_range + .word cpu_arm920_icache_invalidate_page + + /* tlb */ + .word cpu_arm920_tlb_invalidate_all + .word cpu_arm920_tlb_invalidate_range + .word cpu_arm920_tlb_invalidate_page + + /* pgtable */ + .word cpu_arm920_set_pgd + .word cpu_arm920_set_pmd + .word cpu_arm920_set_pte + .size arm920_processor_functions, . - arm920_processor_functions + + .type cpu_arm920_info, #object +cpu_arm920_info: + .long cpu_manu_name + .long cpu_arm920_name + .size cpu_arm920_info, . - cpu_arm920_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 __arm920_proc_info,#object +__arm920_proc_info: + .long 0x41009200 + .long 0xff00fff0 + .long 0x00000c1e @ mmuflags + b __arm920_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_arm920_info + .long arm920_processor_functions + .size __arm920_proc_info, . - __arm920_proc_info diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index bf75c97a2..031ba648a 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -1,15 +1,21 @@ /* - * linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110 + * linux/arch/arm/mm/proc-sa110.S * - * (C) 1997-2000 Russell King + * Copyright (C) 1997-2000 Russell King * - * These are the low level assembler for performing cache and TLB - * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MMU functions for SA110 + * + * These are the low level assembler for performing cache and TLB + * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110. * - * Note that SA1100 and SA1110 share everything but their name and CPU ID. + * Note that SA1100 and SA1110 share everything but their name and CPU ID. * - * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl): - * Flush the read buffer at context switches + * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl): + * Flush the read buffer at context switches */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -21,24 +27,35 @@ * is larger than this, then we flush the whole cache */ #define MAX_AREA_SIZE 32768 + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 + +/* + * and the page size + */ +#define PAGESIZE 4096 + #define FLUSH_OFFSET 32768 .macro flush_110_dcache rd, ra, re add \re, \ra, #16384 @ only necessary for 16k -1001: ldr \rd, [\ra], #32 +1001: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1001b .endm .macro flush_1100_dcache rd, ra, re add \re, \ra, #8192 @ only necessary for 8k -1001: ldr \rd, [\ra], #32 +1001: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1001b #ifdef FLUSH_BASE_MINICACHE add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE add \re, \ra, #512 @ only 512 bytes -1002: ldr \rd, [\ra], #32 +1002: ldr \rd, [\ra], #DCACHELINESIZE teq \re, \ra bne 1002b #endif @@ -48,610 +65,705 @@ Lclean_switch: .long 0 .text + /* - * Function: sa110_flush_cache_all (void) - * Purpose : Flush all cache lines + * cpu_sa110_data_abort() + * + * obtain information about current aborted instruction + * + * r0 = address of aborted instruction + * + * Returns: + * r0 = address of abort + * r1 != 0 if writing + * r3 = FSR */ - .align 5 -ENTRY(cpu_sa110_flush_cache_all) @ preserves r0 - mov r2, #1 -cpu_sa110_flush_cache_all_r2: - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r1, [r3] - ands r1, r1, #1 - eor r1, r1, #1 - str r1, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_110_dcache r3, ip, r1 - mov ip, #0 - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - - .align 5 -ENTRY(cpu_sa1100_flush_cache_all) @ preserves r0 - mov r2, #1 -cpu_sa1100_flush_cache_all_r2: - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r1, [r3] - ands r1, r1, #1 - eor r1, r1, #1 - str r1, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_1100_dcache r3, ip, r1 - mov ip, #0 - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, r1, c9, c0, 0 @ flush RB - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_data_abort) +ENTRY(cpu_sa1100_data_abort) + ldr r1, [r0] @ read aborted instruction + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov r1, r1, lsr #19 @ b1 = L + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r1, r1, #2 + and r3, r3, #255 + mov pc, lr /* - * Function: sa110_flush_cache_area (unsigned long address, int end, int flags) - * Params : address Area start address - * : end Area end address - * : flags b0 = I cache as well - * Purpose : clean & flush all cache lines associated with this area of memory + * cpu_sa110_check_bugs() */ - .align 5 -ENTRY(cpu_sa110_flush_cache_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - 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 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c6, 1 @ flush D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - teq r2, #0 - movne r0, #0 - mcrne p15, 0, r0, c7, c5, 0 @ flush I cache - mov pc, lr - -ENTRY(cpu_sa1100_flush_cache_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - bgt cpu_sa1100_flush_cache_all_r2 - b 1b +ENTRY(cpu_sa110_check_bugs) +ENTRY(cpu_sa1100_check_bugs) + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip + mov pc, lr /* - * Function: sa110_cache_wback_area(unsigned long address, unsigned long end) - * Params : address Area start address - * : end Area end address - * Purpose : ensure all dirty cachelines in the specified area have been - * written out to memory (for DMA) + * cpu_sa110_proc_init() */ - .align 5 -ENTRY(cpu_sa110_cache_wback_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - mov r2, #0 - 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 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - mcr p15, 0, r2, c7, c10, 4 @ drain WB - mov pc, lr - -ENTRY(cpu_sa1100_cache_wback_area) - sub r3, r1, r0 - cmp r3, #MAX_AREA_SIZE - mov r2, #0 - bgt cpu_sa1100_flush_cache_all_r2 - bic r0, r0, #31 - b 1b +ENTRY(cpu_sa110_proc_init) +ENTRY(cpu_sa1100_proc_init) + mov r0, #0 + mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching + mov pc, lr + /* - * Function: sa110_cache_purge_area(unsigned long address, unsigned long end) - * Params : address Area start address - * : end Area end address - * Purpose : throw away all D-cached data in specified region without - * an obligation to write it back. - * Note : Must clean the D-cached entries around the boundaries if the - * start and/or end address are not cache aligned. + * cpu_sa110_proc_fin() */ - .align 5 -ENTRY(cpu_sa110_cache_purge_area) -ENTRY(cpu_sa1100_cache_purge_area) - tst r0, #31 - bic r0, r0, #31 - mcrne p15, 0, r0, c7, c10, 1 @ clean D entry - tst r1, #31 - mcrne p15, 0, r1, c7, c10, 1 @ clean D entry -1: mcr p15, 0, r0, c7, c6, 1 @ flush D entry - add r0, r0, #32 - cmp r0, r1 - blt 1b - mov pc, lr +ENTRY(cpu_sa110_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_sa110_cache_clean_invalidate_all @ clean caches +1: mov r0, #0 + mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +ENTRY(cpu_sa1100_proc_fin) + stmfd sp!, {lr} + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip + bl cpu_sa1100_cache_clean_invalidate_all @ clean caches + b 1b /* - * Function: sa110_flush_cache_entry (unsigned long address) - * Params : address Address of cache line to flush - * Purpose : clean & flush an entry + * cpu_sa110_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset */ - .align 5 -ENTRY(cpu_sa110_flush_cache_entry) -ENTRY(cpu_sa1100_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 - mcr p15, 0, r1, c7, c5, 0 @ flush I cache - mov pc, lr + .align 5 +ENTRY(cpu_sa110_reset) +ENTRY(cpu_sa1100_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 /* - * Function: sa110_clean_cache_area(unsigned long start, unsigned long size) - * Params : address Address of cache line to clean - * Purpose : Ensure that physical memory reflects cache at this location - * for page table purposes. + * cpu_sa110_do_idle(type) + * + * Cause the processor to idle + * + * type: call type: + * 0 = slow idle + * 1 = fast idle + * 2 = switch to slow processor clock + * 3 = switch to fast processor clock */ -ENTRY(cpu_sa110_clean_cache_area) -ENTRY(cpu_sa1100_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 - bhi 1b - mov pc, lr + .align 5 +idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned + mov r0, r0 @ safety + mov pc, lr + +ENTRY(cpu_sa110_do_idle) + mov ip, #0 + cmp r0, #4 + addcc pc, pc, r0, lsl #2 + mov pc, lr + + b idle + b idle + b slow_clock + b fast_clock + +fast_clock: + mcr p15, 0, ip, c15, c1, 2 @ enable clock switching + mov pc, lr + +slow_clock: + mcr p15, 0, ip, c15, c2, 2 @ disable clock switching + ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc + ldr r1, [r1, #0] @ force switch to MCLK + mov pc, lr + + .align 5 +ENTRY(cpu_sa1100_do_idle) + mov r0, r0 @ 4 nop padding + mov r0, r0 + mov r0, r0 + mov r0, #0 + ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address + mrs r2, cpsr + orr r3, r2, #192 @ disallow interrupts + msr cpsr_c, r3 + @ --- aligned to a cache line + mcr p15, 0, r0, c15, c2, 2 @ disable clock switching + ldr r1, [r1, #0] @ force switch to MCLK + mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt + mov r0, r0 @ safety + mcr p15, 0, r0, c15, c1, 2 @ enable clock switching + msr cpsr_c, r2 @ allow interrupts + mov pc, lr + +/* ================================= CACHE ================================ */ + /* - * Function: sa110_flush_ram_page (unsigned long page) - * Params : page Area start address - * Purpose : clean all cache lines associated with this area of memory + * cpu_sa110_cache_clean_invalidate_all (void) + * + * clean and invalidate all cache lines + * + * Note: + * 1. we should preserve r0 at all times */ - .align 5 -ENTRY(cpu_sa110_flush_ram_page) -ENTRY(cpu_sa1100_flush_ram_page) - mov r1, #4096 -1: 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 - 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 - mov pc, lr + .align 5 +ENTRY(cpu_sa110_cache_clean_invalidate_all) + mov r2, #1 +cpu_sa110_cache_clean_invalidate_all_r2: + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r1, [r3] + ands r1, r1, #1 + eor r1, r1, #1 + str r1, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_110_dcache r3, ip, r1 + mov ip, #0 + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + + .align 5 +ENTRY(cpu_sa1100_cache_clean_invalidate_all) + mov r2, #1 +cpu_sa1100_cache_clean_invalidate_all_r2: + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r1, [r3] + ands r1, r1, #1 + eor r1, r1, #1 + str r1, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_1100_dcache r3, ip, r1 + mov ip, #0 + teq r2, #0 + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr /* - * Function: sa110_flush_tlb_all (void) - * Purpose : flush all TLB entries in all caches + * cpu_sa110_cache_clean_invalidate_range(start, end, flags) + * + * clean and invalidate all cache lines associated with this area of memory + * + * start: Area start address + * end: Area end address + * flags: nonzero for I cache as well */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_all) -ENTRY(cpu_sa1100_flush_tlb_all) - mov ip, #0 - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs - mov pc, lr + .align 5 +ENTRY(cpu_sa110_cache_clean_invalidate_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_sa110_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + teq r2, #0 + movne r0, #0 + mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +ENTRY(cpu_sa1100_cache_clean_invalidate_range) + sub r3, r1, r0 + cmp r3, #MAX_AREA_SIZE + bgt cpu_sa1100_cache_clean_invalidate_all_r2 + b 1b /* - * 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-TLB as well - * Purpose : flush a TLB entry + * cpu_sa110_flush_ram_page(page) + * + * clean and invalidate all cache lines associated with this area of memory + * + * page: page to clean and invalidate */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_area) -ENTRY(cpu_sa1100_flush_tlb_area) - mov r3, #0 - mcr p15, 0, r3, c7, c10, 4 @ drain WB -1: cmp r0, r1 - mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry - addlt r0, r0, #4096 - cmp r0, r1 - mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry - addlt r0, r0, #4096 - blt 1b - teq r2, #0 - mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_flush_ram_page) +ENTRY(cpu_sa1100_flush_ram_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ D-CACHE =============================== */ /* - * Function: sa110_flush_tlb_page (unsigned long address, int flags) - * Params : address Address to flush - * : flags b0 = I-TLB as well - * Purpose : flush a TLB entry + * cpu_sa110_dcache_invalidate_range(start, end) + * + * throw away all D-cached data in specified region without an obligation + * to write them back. Note however that we must clean the D-cached entries + * around the boundaries if the start and/or end address are not cache + * aligned. + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_flush_tlb_page) -ENTRY(cpu_sa1100_flush_tlb_page) - mov r3, #0 - mcr p15, 0, r3, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c8, c6, 1 @ flush D TLB entry - teq r1, #0 - mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_invalidate_range) +ENTRY(cpu_sa1100_dcache_invalidate_range) + tst r0, #DCACHELINESIZE - 1 + bic r0, r0, #DCACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #DCACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blt 1b + mov pc, lr /* - * Function: sa110_flush_icache_area (unsigned long address, unsigned long size) - * Params : address Address of area to flush - * : size Size of area to flush - * Purpose : flush an area from the Icache + * cpu_sa110_dcache_clean_range(start, end) + * + * For the specified virtual address range, ensure that all caches contain + * clean data, such that peripheral accesses to the physical RAM fetch + * correct data. + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_flush_icache_area) -ENTRY(cpu_sa1100_flush_icache_area) -1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry - add r0, r0, #32 - subs r1, r1, #32 - bhi 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 - - .align 5 -ENTRY(cpu_sa110_flush_icache_page) -ENTRY(cpu_sa1100_flush_icache_page) - mcr p15, 0, r0, c7, c5, 0 @ flush I cache - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_sa110_cache_clean_invalidate_all_r2 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bpl 1b + mcr p15, 0, r2, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(cpu_sa1100_dcache_clean_range) + bic r0, r0, #DCACHELINESIZE - 1 + sub r1, r1, r0 + cmp r1, #MAX_AREA_SIZE + mov r2, #0 + bgt cpu_sa1100_cache_clean_invalidate_all_r2 + b 1b /* - * Function: sa110_data_abort () - * Params : r0 = address of aborted instruction - * Purpose : obtain information about current aborted instruction - * Returns : r0 = address of abort - * : r1 != 0 if writing - * : r3 = FSR + * cpu_sa110_clean_dcache_page(page) + * + * Cleans a single page of dcache so that if we have any future aliased + * mappings, they will be consistent at the time that they are created. + * + * Note: + * 1. we don't need to flush the write buffer in this case. + * 2. we don't invalidate the entries since when we write the page + * out to disk, the entries may get reloaded into the cache. */ - .align 5 -ENTRY(cpu_sa110_data_abort) -ENTRY(cpu_sa1100_data_abort) - ldr r1, [r0] @ read instruction causing problem - mrc p15, 0, r0, c6, c0, 0 @ get FAR - mov r1, r1, lsr #19 @ b1 = L - mrc p15, 0, r3, c5, c0, 0 @ get FSR - and r1, r1, #2 - and r3, r3, #255 - mov pc, lr - - .align 5 + .align 5 +ENTRY(cpu_sa110_dcache_clean_page) +ENTRY(cpu_sa1100_dcache_clean_page) + mov r1, #PAGESIZE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #2 * DCACHELINESIZE + bne 1b + mov pc, lr + /* - * 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. + * cpu_sa110_dcache_clean_entry(addr) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address */ - .align 5 -ENTRY(cpu_sa110_set_pgd) - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r2, [r3] - ands r2, r2, #1 - eor r2, r2, #1 - str r2, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_110_dcache r3, ip, r1 - 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, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, r1, c8, c7, 0 @ flush TLBs - mov pc, lr - - .align 5 -ENTRY(cpu_sa1100_set_pgd) - ldr r3, =Lclean_switch - ldr ip, =FLUSH_BASE - ldr r2, [r3] - ands r2, r2, #1 - eor r2, r2, #1 - str r2, [r3] - addne ip, ip, #FLUSH_OFFSET - flush_1100_dcache r3, ip, r1 - mov r1, #0 - mcr p15, 0, r1, c7, c5, 0 @ flush I cache - mcr p15, 0, r1, c9, c0, 0 @ flush RB - mcr p15, 0, r1, c7, c10, 4 @ drain WB - mcr p15, 0, r0, c2, c0, 0 @ load page table pointer - mcr p15, 0, r1, c8, c7, 0 @ flush TLBs - mov pc, lr + .align 5 +ENTRY(cpu_sa110_dcache_clean_entry) +ENTRY(cpu_sa1100_dcache_clean_entry) + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* ================================ I-CACHE =============================== */ /* - * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd) - * Params : r0 = Address to set - * : r1 = value to set - * Purpose : Set a PMD and flush it out + * cpu_sa110_icache_invalidate_range(start, end) + * + * invalidate a range of virtual addresses from the Icache + * + * start: virtual start address + * end: virtual end address */ - .align 5 -ENTRY(cpu_sa110_set_pmd) -ENTRY(cpu_sa1100_set_pmd) - str r1, [r0] - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr + .align 5 +ENTRY(cpu_sa110_icache_invalidate_range) +ENTRY(cpu_sa1100_icache_invalidate_range) +1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #DCACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB +ENTRY(cpu_sa110_icache_invalidate_page) +ENTRY(cpu_sa1100_icache_invalidate_page) + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mov pc, lr + +/* ================================== TLB ================================= */ /* - * Function: sa110_set_pte(pte_t *ptep, pte_t pte) - * Params : r0 = Address to set - * : r1 = value to set - * Purpose : Set a PTE and flush it out + * cpu_sa110_tlb_invalidate_all() + * + * Invalidate all TLB entries */ - .align 5 -ENTRY(cpu_sa110_set_pte) -ENTRY(cpu_sa1100_set_pte) - str r1, [r0], #-1024 @ linux version - - eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_all) +ENTRY(cpu_sa1100_tlb_invalidate_all) + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr - bic r2, r1, #0xff0 - bic r2, r2, #3 - orr r2, r2, #HPTE_TYPE_SMALL - - tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? - orrne r2, r2, #HPTE_AP_READ +/* + * cpu_sa110_tlb_invalidate_range(start, end) + * + * invalidate TLB entries covering the specified range + * + * start: range start address + * end: range end address + */ + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_range) +ENTRY(cpu_sa1100_tlb_invalidate_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGESIZE + cmp r0, r1 + blt 1b + mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB + mov pc, lr - tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? - orreq r2, r2, #HPTE_AP_WRITE +/* + * cpu_sa110_tlb_invalidate_page(page, flags) + * + * invalidate the TLB entries for the specified page. + * + * page: page to invalidate + * flags: non-zero if we include the I TLB + */ + .align 5 +ENTRY(cpu_sa110_tlb_invalidate_page) +ENTRY(cpu_sa1100_tlb_invalidate_page) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + teq r1, #0 + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB + mov pc, lr + +/* =============================== PageTable ============================== */ - tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? - movne r2, #0 +/* + * cpu_sa110_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa110_set_pgd) + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_110_dcache r3, ip, r1 + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr - str r2, [r0] @ hardware version - mov r0, r0 - mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr +/* + * cpu_sa1100_set_pgd(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa1100_set_pgd) + ldr r3, =Lclean_switch + ldr ip, =FLUSH_BASE + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + addne ip, ip, #FLUSH_OFFSET + flush_1100_dcache r3, ip, r1 + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr /* - * Function: sa110_check_bugs (void) - * : sa110_proc_init (void) - * : sa110_proc_fin (void) - * Notes : This processor does not require these + * cpu_sa110_set_pmd(pmdp, pmd) + * + * Set a level 1 translation table entry, and clean it out of + * any caches such that the MMUs can load it correctly. + * + * pmdp: pointer to PMD entry + * pmd: PMD value to store */ -ENTRY(cpu_sa110_check_bugs) -ENTRY(cpu_sa1100_check_bugs) - mrs ip, cpsr - bic ip, ip, #F_BIT - msr cpsr, ip - mov pc, lr + .align 5 +ENTRY(cpu_sa110_set_pmd) +ENTRY(cpu_sa1100_set_pmd) + str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr -ENTRY(cpu_sa110_proc_init) -ENTRY(cpu_sa1100_proc_init) - mov r0, #0 - mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching - mov pc, lr +/* + * cpu_sa110_arm920_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_sa110_set_pte) +ENTRY(cpu_sa1100_set_pte) + str r1, [r0], #-1024 @ linux version -ENTRY(cpu_sa110_proc_fin) - stmfd sp!, {r1, lr} - mov ip, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, ip - bl cpu_sa110_flush_cache_all @ clean caches -1: mov r0, #0 - mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x1000 @ ...i............ - bic r0, r0, #0x000e @ ............wca. - mcr p15, 0, r0, c1, c0, 0 @ disable caches - ldmfd sp!, {r1, pc} + eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY -ENTRY(cpu_sa1100_proc_fin) - stmfd sp!, {r1, lr} - mov ip, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, ip - bl cpu_sa1100_flush_cache_all @ clean caches - b 1b + bic r2, r1, #0xff0 + bic r2, r2, #3 + orr r2, r2, #HPTE_TYPE_SMALL + tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec? + orrne r2, r2, #HPTE_AP_READ - .align 5 -idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned - mov r0, r0 @ safety - mov pc, lr -/* - * Function: *_do_idle - * Params : r0 = call type: - * 0 = slow idle - * 1 = fast idle - * 2 = switch to slow processor clock - * 3 = switch to fast processor clock - */ -ENTRY(cpu_sa110_do_idle) -ENTRY(cpu_sa1100_do_idle) - mov ip, #0 - cmp r0, #4 - addcc pc, pc, r0, lsl #2 - mov pc, lr + tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty? + orreq r2, r2, #HPTE_AP_WRITE - b idle - b idle - b slow_clock - b fast_clock + tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young? + movne r2, #0 -fast_clock: mcr p15, 0, ip, c15, c1, 2 @ enable clock switching - mov pc, lr + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr -slow_clock: mcr p15, 0, ip, c15, c2, 2 @ disable clock switching - ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc - ldr r1, [r1, #0] @ force switch to MCLK - mov pc, lr -/* - * Function: sa110_reset - * Params : r0 = address to jump to - * Notes : This sets up everything for a reset - */ - .align 5 -ENTRY(cpu_sa110_reset) -ENTRY(cpu_sa1100_reset) - mov ip, #0 - mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs - mrc p15, 0, ip, c1, c0, 0 @ ctrl register - bic ip, ip, #0x000f @ ............wcam - bic ip, ip, #0x1100 @ ...i...s........ - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 - - -cpu_manu_name: .asciz "Intel" -cpu_sa110_name: .asciz "StrongARM-110" +cpu_manu_name: + .asciz "Intel" +cpu_sa110_name: + .asciz "StrongARM-110" cpu_sa1100_name: - .asciz "StrongARM-1100" + .asciz "StrongARM-1100" cpu_sa1110_name: - .asciz "StrongARM-1110" - .align + .asciz "StrongARM-1110" + .align - .section ".text.init", #alloc, #execinstr + .section ".text.init", #alloc, #execinstr __sa1100_setup: @ Allow read-buffer operations from userland - mcr p15, 0, r0, c9, c0, 5 - -__sa110_setup: mov r0, #F_BIT | I_BIT | SVC_MODE - msr cpsr_c, r0 - mov r0, #0 - mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 - mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 - mcr p15, 0, r4, c2, c0 @ load page table pointer - mov r0, #0x1f @ Domains 0, 1 = client - mcr p15, 0, r0, c3, c0 @ load domain access register - mrc p15, 0, r0, c1, c0 @ get control register v4 - bic r0, r0, #0x0e00 @ ....??r......... - bic r0, r0, #0x0002 @ ..............a. - orr r0, r0, #0x003d @ ..........DPWC.M - orr r0, r0, #0x1100 @ ...I...S........ - mov pc, lr - - .text + mcr p15, 0, r0, c9, c0, 5 + +__sa110_setup: + mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer + mov r0, #0x1f @ Domains 0, 1 = client + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 @ get control register v4 + bic r0, r0, #0x0e00 @ ....??r......... + bic r0, r0, #0x0002 @ ..............a. + orr r0, r0, #0x003d @ ..........DPWC.M + orr r0, r0, #0x1100 @ ...I...S........ + mov pc, lr + + .text /* * Purpose : Function pointers used to access above functions - all calls * come through these */ - .type sa110_processor_functions, #object + .type sa110_processor_functions, #object ENTRY(sa110_processor_functions) - .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 - .word cpu_sa110_flush_tlb_page - .word cpu_sa110_do_idle - .word cpu_sa110_flush_icache_page - .size sa110_processor_functions, . - sa110_processor_functions - - .type cpu_sa110_info, #object + .word cpu_sa110_data_abort + .word cpu_sa110_check_bugs + .word cpu_sa110_proc_init + .word cpu_sa110_proc_fin + .word cpu_sa110_reset + .word cpu_sa110_do_idle + + /* cache */ + .word cpu_sa110_cache_clean_invalidate_all + .word cpu_sa110_cache_clean_invalidate_range + .word cpu_sa110_flush_ram_page + + /* dcache */ + .word cpu_sa110_dcache_invalidate_range + .word cpu_sa110_dcache_clean_range + .word cpu_sa110_dcache_clean_page + .word cpu_sa110_dcache_clean_entry + + /* icache */ + .word cpu_sa110_icache_invalidate_range + .word cpu_sa110_icache_invalidate_page + + /* tlb */ + .word cpu_sa110_tlb_invalidate_all + .word cpu_sa110_tlb_invalidate_range + .word cpu_sa110_tlb_invalidate_page + + /* pgtable */ + .word cpu_sa110_set_pgd + .word cpu_sa110_set_pmd + .word cpu_sa110_set_pte + .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 + .long cpu_manu_name + .long cpu_sa110_name + .size cpu_sa110_info, . - cpu_sa110_info /* * SA1100 and SA1110 share the same function calls */ - .type sa1100_processor_functions, #object + .type sa1100_processor_functions, #object ENTRY(sa1100_processor_functions) - .word cpu_sa1100_data_abort - .word cpu_sa1100_check_bugs - .word cpu_sa1100_proc_init - .word cpu_sa1100_proc_fin - .word cpu_sa1100_flush_cache_all - .word cpu_sa1100_flush_cache_area - .word cpu_sa1100_flush_cache_entry - .word cpu_sa1100_clean_cache_area - .word cpu_sa1100_flush_ram_page - .word cpu_sa1100_flush_tlb_all - .word cpu_sa1100_flush_tlb_area - .word cpu_sa1100_set_pgd - .word cpu_sa1100_set_pmd - .word cpu_sa1100_set_pte - .word cpu_sa1100_reset - .word cpu_sa1100_flush_icache_area - .word cpu_sa1100_cache_wback_area - .word cpu_sa1100_cache_purge_area - .word cpu_sa1100_flush_tlb_page - .word cpu_sa1100_do_idle - .word cpu_sa1100_flush_icache_page - .size sa1100_processor_functions, . - sa1100_processor_functions + .word cpu_sa1100_data_abort + .word cpu_sa1100_check_bugs + .word cpu_sa1100_proc_init + .word cpu_sa1100_proc_fin + .word cpu_sa1100_reset + .word cpu_sa1100_do_idle + + /* cache */ + .word cpu_sa1100_cache_clean_invalidate_all + .word cpu_sa1100_cache_clean_invalidate_range + .word cpu_sa1100_flush_ram_page + + /* dcache */ + .word cpu_sa1100_dcache_invalidate_range + .word cpu_sa1100_dcache_clean_range + .word cpu_sa1100_dcache_clean_page + .word cpu_sa1100_dcache_clean_entry + + /* icache */ + .word cpu_sa1100_icache_invalidate_range + .word cpu_sa1100_icache_invalidate_page + + /* tlb */ + .word cpu_sa1100_tlb_invalidate_all + .word cpu_sa1100_tlb_invalidate_range + .word cpu_sa1100_tlb_invalidate_page + + /* pgtable */ + .word cpu_sa1100_set_pgd + .word cpu_sa1100_set_pmd + .word cpu_sa1100_set_pte + .size sa1100_processor_functions, . - sa1100_processor_functions cpu_sa1100_info: - .long cpu_manu_name - .long cpu_sa1100_name - .size cpu_sa1100_info, . - cpu_sa1100_info + .long cpu_manu_name + .long cpu_sa1100_name + .size cpu_sa1100_info, . - cpu_sa1100_info cpu_sa1110_info: - .long cpu_manu_name - .long cpu_sa1110_name - .size cpu_sa1110_info, . - cpu_sa1110_info + .long cpu_manu_name + .long cpu_sa1110_name + .size cpu_sa1110_info, . - cpu_sa1110_info + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name - .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 - .type cpu_elf_name, #object -cpu_elf_name: .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - .align + .section ".proc.info", #alloc, #execinstr - .section ".proc.info", #alloc, #execinstr - - .type __sa110_proc_info,#object + .type __sa110_proc_info,#object __sa110_proc_info: - .long 0x4401a100 - .long 0xfffffff0 - .long 0x00000c02 - b __sa110_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa110_info - .long sa110_processor_functions - .size __sa110_proc_info, . - __sa110_proc_info - - .type __sa1100_proc_info,#object + .long 0x4401a100 + .long 0xfffffff0 + .long 0x00000c0e + b __sa110_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa110_info + .long sa110_processor_functions + .size __sa110_proc_info, . - __sa110_proc_info + + .type __sa1100_proc_info,#object __sa1100_proc_info: - .long 0x4401a110 - .long 0xfffffff0 - .long 0x00000c02 - b __sa1100_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa1100_info - .long sa1100_processor_functions - .size __sa1100_proc_info, . - __sa1100_proc_info - - .type __sa1110_proc_info,#object + .long 0x4401a110 + .long 0xfffffff0 + .long 0x00000c0e + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa1100_info + .long sa1100_processor_functions + .size __sa1100_proc_info, . - __sa1100_proc_info + + .type __sa1110_proc_info,#object __sa1110_proc_info: - .long 0x6901b110 - .long 0xfffffff0 - .long 0x00000c02 - b __sa1100_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_sa1110_info - .long sa1100_processor_functions - .size __sa1110_proc_info, . - __sa1110_proc_info - - + .long 0x6901b110 + .long 0xfffffff0 + .long 0x00000c0e + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa1110_info + .long sa1100_processor_functions + .size __sa1110_proc_info, . - __sa1110_proc_info diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c new file mode 100644 index 000000000..07ceac0f9 --- /dev/null +++ b/arch/arm/mm/proc-syms.c @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/mm/proc-syms.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <asm/proc-fns.h> + +#ifndef MULTI_CPU +EXPORT_SYMBOL(cpu_cache_clean_invalidate_all); +EXPORT_SYMBOL(cpu_cache_clean_invalidate_range); +EXPORT_SYMBOL(cpu_flush_ram_page); +EXPORT_SYMBOL(cpu_dcache_clean_page); +EXPORT_SYMBOL(cpu_dcache_clean_entry); +EXPORT_SYMBOL(cpu_dcache_clean_range); +EXPORT_SYMBOL(cpu_dcache_invalidate_range); +EXPORT_SYMBOL(cpu_icache_invalidate_range); +EXPORT_SYMBOL(cpu_icache_invalidate_page); +EXPORT_SYMBOL(cpu_tlb_invalidate_all); +EXPORT_SYMBOL(cpu_tlb_invalidate_range); +EXPORT_SYMBOL(cpu_tlb_invalidate_page); +EXPORT_SYMBOL(cpu_set_pgd); +EXPORT_SYMBOL(cpu_set_pmd); +EXPORT_SYMBOL(cpu_set_pte); +#else +EXPORT_SYMBOL(processor); +#endif diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c index 27fb0f663..634cc1ead 100644 --- a/arch/arm/mm/small_page.c +++ b/arch/arm/mm/small_page.c @@ -3,12 +3,15 @@ * * Copyright (C) 1996 Russell King * - * Changelog: - * 26/01/1996 RMK Cleaned up various areas to make little more generic - * 07/02/1999 RMK Support added for 16K and 32K page sizes + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 26/01/1996 RMK Cleaned up various areas to make little more generic + * 07/02/1999 RMK Support added for 16K and 32K page sizes * containing 8K blocks */ - #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -70,6 +73,8 @@ static struct order orders[] = { #define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &USED_MAP(pg))) #define SET_USED(pg,off) (set_bit(off, &USED_MAP(pg))) +static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED; + static void add_page_to_queue(struct page *page, struct page **p) { #ifdef PEDANTIC @@ -99,11 +104,10 @@ static unsigned long __get_small_page(int priority, struct order *order) struct page *page; int offset; - save_flags(flags); if (!order->queue) goto need_new_page; - cli(); + spin_lock_irqsave(&small_page_lock, flags); page = order->queue; again: #ifdef PEDANTIC @@ -114,12 +118,14 @@ again: SET_USED(page, offset); if (USED_MAP(page) == order->all_used) remove_page_from_queue(page); - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); return (unsigned long) page_address(page) + (offset << order->shift); need_new_page: page = alloc_page(priority); + + spin_lock_irqsave(&small_page_lock, flags); if (!order->queue) { if (!page) goto no_page; @@ -135,7 +141,7 @@ need_new_page: goto again; no_page: - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); return 0; } @@ -164,7 +170,7 @@ static void __free_small_page(unsigned long spage, struct order *order) /* * the following must be atomic wrt get_page */ - save_flags_cli(flags); + spin_lock_irqsave(&small_page_lock, flags); if (USED_MAP(page) == order->all_used) add_page_to_queue(page, &order->queue); @@ -175,7 +181,7 @@ static void __free_small_page(unsigned long spage, struct order *order) if (USED_MAP(page) == 0) goto free_page; - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); } return; @@ -184,7 +190,7 @@ free_page: * unlink the page from the small page queue and free it */ remove_page_from_queue(page); - restore_flags(flags); + spin_unlock_irqrestore(&small_page_lock, flags); ClearPageReserved(page); __free_page(page); return; |