diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Makefile | 14 | ||||
-rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 3 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 57 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 11 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/jornada720.c | 64 | ||||
-rw-r--r-- | arch/arm/mm/init.c | 30 |
9 files changed, 118 insertions, 66 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 299bc0468702..64cf480b0b02 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -8,7 +8,7 @@ # Copyright (C) 1995-2001 by Russell King LDFLAGS_vmlinux :=-p --no-undefined -X -CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) +CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 #CFLAGS +=-pipe @@ -108,27 +108,19 @@ export CFLAGS_3c589_cs.o endif TEXTADDR := $(textaddr-y) -ifeq ($(CONFIG_XIP_KERNEL),y) - DATAADDR := $(TEXTADDR) - xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000 - xipaddr-y ?= 0xbf000000 - # Replace phys addr with virt addr while keeping offset from base. - TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ - awk --non-decimal-data '/[:xdigit:]/ \ - { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) -endif ifeq ($(incdir-y),) incdir-y := $(machine-y) endif INCDIR := arch-$(incdir-y) + ifneq ($(machine-y),) MACHINE := arch/arm/mach-$(machine-y)/ else MACHINE := endif -export TEXTADDR DATAADDR GZFLAGS +export TEXTADDR GZFLAGS # Do we have FASTFPE? FASTFPE :=arch/arm/fastfpe diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 3e1b0327e4d7..c11169b5ed9a 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) +AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR) # Object file lists. diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index c1ff4d1f1bfd..04d3082a7b94 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -94,7 +94,6 @@ int main(void) DEFINE(VM_EXEC, VM_EXEC); BLANK(); DEFINE(PAGE_SZ, PAGE_SIZE); - DEFINE(VIRT_OFFSET, PAGE_OFFSET); BLANK(); DEFINE(SYS_ERROR0, 0x9f0000); BLANK(); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 93b5e8e5292e..be439cab92c6 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -15,6 +15,7 @@ */ #include <linux/config.h> +#include <asm/memory.h> #include <asm/glue.h> #include <asm/vfpmacros.h> #include <asm/hardware.h> /* should be moved into entry-macro.S */ @@ -310,7 +311,7 @@ __pabt_svc: #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) @ make sure our user space atomic helper is aborted - cmp r2, #VIRT_OFFSET + cmp r2, #TASK_SIZE bichs r3, r3, #PSR_Z_BIT #endif diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 539626351348..8d8748407cbe 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -21,6 +21,7 @@ #include <asm/procinfo.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> +#include <asm/memory.h> #include <asm/thread_info.h> #include <asm/system.h> @@ -33,52 +34,28 @@ #define MACHINFO_PGOFFIO 12 #define MACHINFO_NAME 16 -#ifndef CONFIG_XIP_KERNEL /* - * We place the page tables 16K below TEXTADDR. Therefore, we must make sure - * that TEXTADDR is correctly set. Currently, we expect the least significant - * 16 bits to be 0x8000, but we could probably relax this restriction to - * TEXTADDR >= PAGE_OFFSET + 0x4000 - * - * Note that swapper_pg_dir is the virtual address of the page tables, and - * pgtbl gives us a position-independent reference to these tables. We can - * do this because stext == TEXTADDR + * swapper_pg_dir is the virtual address of the initial page table. + * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must + * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect + * the least significant 16 bits to be 0x8000, but we could probably + * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000. */ -#if (TEXTADDR & 0xffff) != 0x8000 -#error TEXTADDR must start at 0xXXXX8000 +#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000 +#error KERNEL_RAM_ADDR must start at 0xXXXX8000 #endif .globl swapper_pg_dir - .equ swapper_pg_dir, TEXTADDR - 0x4000 + .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000 - .macro pgtbl, rd, phys - adr \rd, stext - sub \rd, \rd, #0x4000 + .macro pgtbl, rd + ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000)) .endm -#else -/* - * XIP Kernel: - * - * We place the page tables 16K below DATAADDR. Therefore, we must make sure - * that DATAADDR is correctly set. Currently, we expect the least significant - * 16 bits to be 0x8000, but we could probably relax this restriction to - * DATAADDR >= PAGE_OFFSET + 0x4000 - * - * Note that pgtbl is meant to return the physical address of swapper_pg_dir. - * We can't make it relative to the kernel position in this case since - * the kernel can physically be anywhere. - */ -#if (DATAADDR & 0xffff) != 0x8000 -#error DATAADDR must start at 0xXXXX8000 -#endif - - .globl swapper_pg_dir - .equ swapper_pg_dir, DATAADDR - 0x4000 - .macro pgtbl, rd, phys - ldr \rd, =((DATAADDR - 0x4000) - VIRT_OFFSET) - add \rd, \rd, \phys - .endm +#ifdef CONFIG_XIP_KERNEL +#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) +#else +#define TEXTADDR KERNEL_RAM_ADDR #endif /* @@ -279,7 +256,7 @@ __turn_mmu_on: .type __create_page_tables, %function __create_page_tables: ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram - pgtbl r4, r5 @ page table address + pgtbl r4 @ page table address /* * Clear the 16K level 1 swapper page table @@ -324,7 +301,7 @@ __create_page_tables: /* * Then map first 1MB of ram in case it contains our boot params. */ - add r0, r4, #VIRT_OFFSET >> 18 + add r0, r4, #PAGE_OFFSET >> 18 orr r6, r5, r7 str r6, [r0] diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 0d5db5279c5c..80c8e4c8cefa 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -6,14 +6,23 @@ #include <asm-generic/vmlinux.lds.h> #include <linux/config.h> #include <asm/thread_info.h> +#include <asm/memory.h> OUTPUT_ARCH(arm) ENTRY(stext) + #ifndef __ARMEB__ jiffies = jiffies_64; #else jiffies = jiffies_64 + 4; #endif + +#ifdef CONFIG_XIP_KERNEL +#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) +#else +#define TEXTADDR KERNEL_RAM_ADDR +#endif + SECTIONS { . = TEXTADDR; @@ -95,7 +104,7 @@ SECTIONS #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ - . = DATAADDR; + . = KERNEL_RAM_ADDR; #else . = ALIGN(THREAD_SIZE); __data_loc = .; diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 93619497779c..f94b0fbcdcc8 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -23,6 +23,7 @@ #include <asm/system.h> #include <asm/pgtable.h> #include <asm/mach/map.h> +#include <asm/mach/flash.h> #include <asm/irq.h> #include "generic.h" @@ -283,6 +284,7 @@ static struct platform_device sa11x0mtd_device = { void sa11x0_set_flash_data(struct flash_platform_data *flash, struct resource *res, int nr) { + flash->name = "sa1100"; sa11x0mtd_device.dev.platform_data = flash; sa11x0mtd_device.resource = res; sa11x0mtd_device.num_resources = nr; diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 9c363bfcf310..89af0c831e8f 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -8,6 +8,8 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/ioport.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> #include <asm/hardware.h> #include <asm/hardware/sa1111.h> @@ -16,6 +18,7 @@ #include <asm/setup.h> #include <asm/mach/arch.h> +#include <asm/mach/flash.h> #include <asm/mach/map.h> #include <asm/mach/serial_sa1100.h> @@ -108,6 +111,66 @@ static void __init jornada720_map_io(void) sa1100_register_uart(1, 1); } +static struct mtd_partition jornada720_partitions[] = { + { + .name = "JORNADA720 boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "JORNADA720 kernel", + .size = 0x000c0000, + .offset = 0x00040000, + }, { + .name = "JORNADA720 params", + .size = 0x00040000, + .offset = 0x00100000, + }, { + .name = "JORNADA720 initrd", + .size = 0x00100000, + .offset = 0x00140000, + }, { + .name = "JORNADA720 root cramfs", + .size = 0x00300000, + .offset = 0x00240000, + }, { + .name = "JORNADA720 usr cramfs", + .size = 0x00800000, + .offset = 0x00540000, + }, { + .name = "JORNADA720 usr local", + .size = 0, /* will expand to the end of the flash */ + .offset = 0x00d00000, + } +}; + +static void jornada720_set_vpp(int vpp) +{ + if (vpp) + PPSR |= 0x80; + else + PPSR &= ~0x80; + PPDR |= 0x80; +} + +static struct flash_platform_data jornada720_flash_data = { + .map_name = "cfi_probe", + .set_vpp = jornada720_set_vpp, + .parts = jornada720_partitions, + .nr_parts = ARRAY_SIZE(jornada720_partitions), +}; + +static struct resource jornada720_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static void __init jornada720_mach_init(void) +{ + sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1); +} + MACHINE_START(JORNADA720, "HP Jornada 720") /* Maintainer: Michael Gernoth <michael@gernoth.net> */ .phys_ram = 0xc0000000, @@ -117,4 +180,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720") .map_io = jornada720_map_io, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, + .init_machine = jornada720_mach_init, MACHINE_END diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index f4496813615a..fd079ff1fc53 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -363,20 +363,16 @@ static void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); -#ifdef CONFIG_XIP_KERNEL -#error needs fixing - p->pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PMD_MASK); - p->virtual = (unsigned long)&_stext & PMD_MASK; - p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; - p->type = MT_ROM; - p ++; -#endif - /* * Clear out all the mappings below the kernel image. - * FIXME: what about XIP? */ - for (addr = 0; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) pmd_clear(pmd_off_k(addr)); /* @@ -436,6 +432,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc) pmd_clear(pmd_off_k(addr)); /* + * Map the kernel if it is XIP. + * It is always first in the modulearea. + */ +#ifdef CONFIG_XIP_KERNEL + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK); + map.virtual = MODULE_START; + map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK; + map.type = MT_ROM; + create_mapping(&map); +#endif + + /* * Map the cache flushing regions. */ #ifdef FLUSH_BASE |