summaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
commit012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch)
tree87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch/arm/mm
parent625a1589d3d6464b5d90b8a0918789e3afffd220 (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/Makefile65
-rw-r--r--arch/arm/mm/consistent.c28
-rw-r--r--arch/arm/mm/extable.c2
-rw-r--r--arch/arm/mm/fault-armo.c5
-rw-r--r--arch/arm/mm/fault-armv.c11
-rw-r--r--arch/arm/mm/fault-common.c10
-rw-r--r--arch/arm/mm/init.c26
-rw-r--r--arch/arm/mm/ioremap.c2
-rw-r--r--arch/arm/mm/map.h25
-rw-r--r--arch/arm/mm/mm-armo.c19
-rw-r--r--arch/arm/mm/mm-armv.c59
-rw-r--r--arch/arm/mm/mm-clps7500.c23
-rw-r--r--arch/arm/mm/mm-ebsa110.c24
-rw-r--r--arch/arm/mm/mm-footbridge.c112
-rw-r--r--arch/arm/mm/mm-l7200.c19
-rw-r--r--arch/arm/mm/mm-nexuspci.c27
-rw-r--r--arch/arm/mm/mm-rpc.c31
-rw-r--r--arch/arm/mm/mm-sa1100.c212
-rw-r--r--arch/arm/mm/mm-shark.c25
-rw-r--r--arch/arm/mm/mm-tbox.c57
-rw-r--r--arch/arm/mm/proc-arm2,3.S14
-rw-r--r--arch/arm/mm/proc-arm6,7.S149
-rw-r--r--arch/arm/mm/proc-arm720.S160
-rw-r--r--arch/arm/mm/proc-arm920.S602
-rw-r--r--arch/arm/mm/proc-sa110.S1170
-rw-r--r--arch/arm/mm/proc-syms.c31
-rw-r--r--arch/arm/mm/small_page.c28
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;