From 49e4d78b5969d07b7bb393b187f66adcb3c51025 Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Sun, 7 Sep 2003 02:53:07 -0700 Subject: [PATCH] [PATCH] arm26 updates Not much to write home about. mostly tidying, some debug, and XIP support. just keeping arm26 up to date really. --- arch/arm26/Kconfig | 8 ++ arch/arm26/Makefile | 22 ++- arch/arm26/boot/Makefile | 11 +- arch/arm26/kernel/ecard.c | 24 +++- arch/arm26/kernel/entry.S | 61 ++++---- arch/arm26/kernel/irq.c | 3 + arch/arm26/kernel/setup.c | 19 ++- arch/arm26/kernel/vmlinux-arm26-xip.lds.in | 133 ++++++++++++++++++ .../vmlinux-arm26.lds.in} | 2 +- arch/arm26/kernel/vmlinux.lds.S | 6 +- arch/arm26/machine/head.S | 30 +++- arch/arm26/mm/fault.c | 5 +- arch/arm26/mm/init.c | 123 ++++++++-------- include/asm-arm26/ecard.h | 38 ++--- include/asm-arm26/local.h | 2 + include/asm-arm26/sections.h | 2 + include/asm-arm26/uaccess-asm.h | 6 +- 17 files changed, 358 insertions(+), 137 deletions(-) create mode 100644 arch/arm26/kernel/vmlinux-arm26-xip.lds.in rename arch/arm26/{vmlinux-armo.lds.in => kernel/vmlinux-arm26.lds.in} (96%) create mode 100644 include/asm-arm26/local.h create mode 100644 include/asm-arm26/sections.h diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index 847cc6441f61b..e05f274e0bfdd 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -96,6 +96,7 @@ config ZBOOT_ROM directly from ROM or flash. If unsure, say N. config ZBOOT_ROM_TEXT + depends on ZBOOT_ROM hex "Compressed ROM boot loader base address" default "0" help @@ -103,6 +104,7 @@ config ZBOOT_ROM_TEXT should not change this value. config ZBOOT_ROM_BSS + depends on ZBOOT_ROM hex "Compressed ROM boot loader BSS address" default "0" help @@ -110,6 +112,12 @@ config ZBOOT_ROM_BSS while the decompressor is running. Unless you have special requirements, you should not change this value. +config XIP_KERNEL + bool "Execute In Place (XIP) kernel image" + help + Select this option to create a kernel that can be programed into + the OS ROMs. + config HOTPLUG bool "Support for hot-pluggable devices" ---help--- diff --git a/arch/arm26/Makefile b/arch/arm26/Makefile index 2f9f4739c0daa..3b0294a8d06b3 100644 --- a/arch/arm26/Makefile +++ b/arch/arm26/Makefile @@ -12,8 +12,6 @@ LDFLAGS_BLOB :=--format binary AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 -#CFLAGS +=-pipe -CFLAGS :=$(CFLAGS:-O2=-Os) ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mno-sched-prolog @@ -29,21 +27,17 @@ CFLAGS_BOOT :=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu CFLAGS +=-mapcs-26 -mcpu=arm3 -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm AFLAGS +=-mapcs-26 -mcpu=arm3 -mno-fpu -msoft-float -Wa,-mno-fpu -#Default value -DATAADDR := . - -ifeq ($(CONFIG_CPU_26),y) head-y := arch/arm26/machine/head.o arch/arm26/kernel/init_task.o LDFLAGS_BLOB += --oformat elf32-littlearm - ifeq ($(CONFIG_ROM_KERNEL),y) - DATAADDR := 0x02080000 - textaddr-y := 0x03800000 - else - textaddr-y := 0x02080000 - endif + +ifeq ($(CONFIG_XIP_KERNEL),y) + TEXTADDR := 0x03880000 + DATAADDR := 0x02080000 +else + TEXTADDR := 0x02080000 + DATAADDR := . endif -TEXTADDR := $(textaddr-y) ifeq ($(incdir-y),) incdir-y := endif @@ -74,7 +68,7 @@ maketools: FORCE bzImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage -zImage Image bootpImage: vmlinux +zImage Image bootpImage xipImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ zinstall install: vmlinux diff --git a/arch/arm26/boot/Makefile b/arch/arm26/boot/Makefile index 26fab5c945c87..3d992e5977544 100644 --- a/arch/arm26/boot/Makefile +++ b/arch/arm26/boot/Makefile @@ -36,7 +36,7 @@ endif export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS -targets := Image zImage bootpImage +targets := Image zImage bootpImage xipImage $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) @@ -49,6 +49,15 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(obj)/compressed/vmlinux: vmlinux FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ +ifeq ($(CONFIG_XIP_KERNEL),y) +$(obj)/xipImage: vmlinux FORCE + $(OBJCOPY) -S -O binary -R .data -R .comment vmlinux vmlinux-text.bin + $(OBJCOPY) -S -O binary -R .init -R .text -R .comment -R __ex_table -R __ksymtab vmlinux vmlinux-data.bin + cat vmlinux-text.bin vmlinux-data.bin > $@ + $(RM) -f vmlinux-text.bin vmlinux-data.bin + @echo ' Kernel: $@ is ready' +endif + .PHONY: initrd initrd: @test "$(INITRD_PHYS)" != "" || \ diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c index b57a2e6b87eb4..8434f0f0c2dd1 100644 --- a/arch/arm26/kernel/ecard.c +++ b/arch/arm26/kernel/ecard.c @@ -580,7 +580,7 @@ static void ecard_proc_init(void) #define ec_set_resource(ec,nr,st,sz,flg) \ do { \ - (ec)->resource[nr].name = ec->dev.name; \ + (ec)->resource[nr].name = ec->dev.bus_id; \ (ec)->resource[nr].start = st; \ (ec)->resource[nr].end = (st) + (sz) - 1; \ (ec)->resource[nr].flags = flg; \ @@ -621,7 +621,17 @@ static ssize_t ecard_show_irq(struct device *dev, char *buf) return sprintf(buf, "%u\n", ec->irq); } -static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL); +static ssize_t ecard_show_vendor(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->cid.manufacturer); +} + +static ssize_t ecard_show_device(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->cid.product); +} static ssize_t ecard_show_dma(struct device *dev, char *buf) { @@ -629,8 +639,6 @@ static ssize_t ecard_show_dma(struct device *dev, char *buf) return sprintf(buf, "%u\n", ec->dma); } -static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL); - static ssize_t ecard_show_resources(struct device *dev, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); @@ -646,6 +654,10 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf) return str - buf; } +static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL); +static DEVICE_ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL); +static DEVICE_ATTR(device, S_IRUGO, ecard_show_device, NULL); +static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL); static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL); /* @@ -717,8 +729,6 @@ ecard_probe(int slot, card_type_t type) } snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot); - snprintf(ec->dev.name, sizeof(ec->dev.name), "ecard %04x:%04x", - ec->cid.manufacturer, ec->cid.product); ec->dev.parent = NULL; ec->dev.bus = &ecard_bus_type; ec->dev.dma_mask = &ec->dma_mask; @@ -745,6 +755,8 @@ ecard_probe(int slot, card_type_t type) device_create_file(&ec->dev, &dev_attr_dma); device_create_file(&ec->dev, &dev_attr_irq); device_create_file(&ec->dev, &dev_attr_resource); + device_create_file(&ec->dev, &dev_attr_vendor); + device_create_file(&ec->dev, &dev_attr_device); return 0; diff --git a/arch/arm26/kernel/entry.S b/arch/arm26/kernel/entry.S index b1d98ec525b3f..e9565ce926e30 100644 --- a/arch/arm26/kernel/entry.S +++ b/arch/arm26/kernel/entry.S @@ -47,7 +47,7 @@ @ @ Stack format (ensured by USER_* and SVC_*) @ -#define S_FRAME_SIZE 72 +#define S_FRAME_SIZE 72 @ FIXME: Really? #define S_OLD_R0 64 #define S_PSR 60 #define S_PC 60 @@ -77,11 +77,11 @@ .endm .macro slow_restore_user_regs - ldmia sp, {r0 - lr}^ - mov r0, r0 - ldr lr, [sp, #15*4] - add sp, sp, #15*4+8 - movs pc, lr + ldmia sp, {r0 - lr}^ @ restore the user regs + mov r0, r0 @ no-op + ldr lr, [sp, #15*4] @ get user PC + add sp, sp, #15*4+8 @ free stack + movs pc, lr @ return .endm .macro fast_restore_user_regs @@ -514,31 +514,37 @@ Lfiqmsg: .ascii "*** Unexpected FIQ\n\0" * Handles floating point instructions */ vector_undefinstr: - tst lr,#3 - bne __und_svc + tst lr, #MODE_SVC26 @ did we come from a non-user mode? + bne __und_svc @ yes - deal with it. +/* Otherwise, fall through for the user-space (common) case. */ save_user_regs - zero_fp - teqp pc, #PSR_I_BIT | MODE_SVC26 + zero_fp @ zero frame pointer + teqp pc, #PSR_I_BIT | MODE_SVC26 @ disable IRQs .Lbug_undef: ldr r4, .LC2 - ldr pc, [r4] @ Call FP module USR entry point - - .globl fpundefinstr -fpundefinstr: @ Called by FP module on undefined instr + ldr pc, [r4] @ Call FP module entry point +/* FIXME - should we trap for a null pointer here? */ + +/* The SVC mode case */ +__und_svc: SVC_SAVE_ALL @ Non-user mode + mask_pc r0, lr + and r2, lr, #3 + sub r0, r0, #4 + mov r1, sp + bl do_undefinstr + SVC_RESTORE_ALL + +/* We get here if the FP emulator doesnt handle the undef instr. + * If the insn WAS handled, the emulator jumps to ret_from_exception by itself/ + */ + .globl fpundefinstr +fpundefinstr: mov r0, lr mov r1, sp teqp pc, #MODE_SVC26 bl do_undefinstr b ret_from_exception @ Normal FP exit -__und_svc: SVC_SAVE_ALL @ Non-user mode - mask_pc r0, lr - and r2, lr, #3 - sub r0, r0, #4 - mov r1, sp - bl do_undefinstr - SVC_RESTORE_ALL - #if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE /* The FPE is always present */ .equ fpe_not_present, 0 @@ -548,6 +554,7 @@ __und_svc: SVC_SAVE_ALL @ Non-user mode * a WFS, we just perform a normal return as if we had emulated the * operation. This is a hack to allow some basic userland binaries * to run so that the emulator module proper can be loaded. --philb + * FIXME - probably a broken useless hack... */ fpe_not_present: adr r10, wfs_mask_data @@ -587,14 +594,14 @@ wfs_mask_data: .word 0x0e200110 @ WFS/RFS * Prefetch abort handler *----------------------------------------------------------------------------- */ - +#define DEBUG_UNDEF /* remember: lr = USR pc */ vector_prefetch: sub lr, lr, #4 - tst lr, #3 + tst lr, #MODE_SVC26 bne __pabt_invalid save_user_regs - teqp pc, #MODE_SVC26 + teqp pc, #MODE_SVC26 @ Enable IRQs... mask_pc r0, lr @ Address of abort mov r1, sp @ Tasks registers bl do_PrefetchAbort @@ -604,7 +611,7 @@ vector_prefetch: adr r0, t bl printk #endif - ldr lr, [sp,#S_PC] @ program to test this on. I think its + ldr lr, [sp,#S_PC] @ FIXME program to test this on. I think its b .Lbug_undef @ broken at the moment though!) __pabt_invalid: SVC_SAVE_ALL @@ -707,7 +714,7 @@ vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case... bne asm_do_IRQ mov why, #0 - get_thread_info r5 + get_thread_info tsk @ FIXME - was r5, but seemed wrong. b ret_to_user irq_prio_table diff --git a/arch/arm26/kernel/irq.c b/arch/arm26/kernel/irq.c index ddd2ea591afd3..28220356efd13 100644 --- a/arch/arm26/kernel/irq.c +++ b/arch/arm26/kernel/irq.c @@ -36,6 +36,9 @@ #include #include +//FIXME - this ought to be in a header IMO +void __init arc_init_irq(void); + /* * Maximum IRQ count. Currently, this is arbitary. However, it should * not be set too low to prevent false triggering. Conversely, if it diff --git a/arch/arm26/kernel/setup.c b/arch/arm26/kernel/setup.c index f58d849d09a4c..bd326269e9263 100644 --- a/arch/arm26/kernel/setup.c +++ b/arch/arm26/kernel/setup.c @@ -58,6 +58,10 @@ extern void squash_mem_tags(struct tag *tag); extern void bootmem_init(struct meminfo *); extern int root_mountflags; extern int _stext, _text, _etext, _edata, _end; +#ifdef CONFIG_XIP_KERNEL +extern int _endtext, _sdata; +#endif + unsigned int processor_id; unsigned int __machine_arch_type; @@ -121,6 +125,7 @@ static void __init setup_processor(void) for (list = &__proc_info_begin; list < &__proc_info_end ; list++) if ((processor_id & list->cpu_mask) == list->cpu_val) break; + /* * If processor type is unrecognised, then we * can do nothing... @@ -220,7 +225,11 @@ request_standard_resources(struct meminfo *mi) kernel_code.start = init_mm.start_code; kernel_code.end = init_mm.end_code - 1; +#ifdef CONFIG_XIP_KERNEL + kernel_data.start = init_mm.start_data; +#else kernel_data.start = init_mm.end_code; +#endif kernel_data.end = init_mm.brk - 1; for (i = 0; i < mi->nr_banks; i++) { @@ -456,7 +465,10 @@ void __init setup_arch(char **cmdline_p) else machine_name = "UNKNOWN"; - //FIXME - this may need altering when we get ROM images working + //FIXME - the tag struct is always copied here but this is a block + // of RAM that is accidentally reserved along with video RAM. perhaps + // it would be a good idea to explicitly reserve this? + tags = (struct tag *)0x0207c000; /* @@ -474,7 +486,12 @@ void __init setup_arch(char **cmdline_p) } init_mm.start_code = (unsigned long) &_text; +#ifndef CONFIG_XIP_KERNEL init_mm.end_code = (unsigned long) &_etext; +#else + init_mm.end_code = (unsigned long) &_endtext; + init_mm.start_data = (unsigned long) &_sdata; +#endif init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; diff --git a/arch/arm26/kernel/vmlinux-arm26-xip.lds.in b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in new file mode 100644 index 0000000000000..602a77c022d7d --- /dev/null +++ b/arch/arm26/kernel/vmlinux-arm26-xip.lds.in @@ -0,0 +1,133 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version by Russell King + * Written by Martin Mares + * borrowed from Russels ARM port by Ian Molton + */ + +#include + +OUTPUT_ARCH(arm) +ENTRY(stext) +jiffies = jiffies_64; +SECTIONS +{ + . = TEXTADDR; + .init : { /* Init code and data */ + _stext = .; + __init_begin = .; + _sinittext = .; + *(.init.text) + _einittext = .; + __proc_info_begin = .; + *(.proc.info) + __proc_info_end = .; + __arch_info_begin = .; + *(.arch.info) + __arch_info_end = .; + __tagtable_begin = .; + *(.taglist) + __tagtable_end = .; + . = ALIGN(16); + __setup_start = .; + *(.init.setup) + __setup_end = .; + __early_begin = .; + *(__early_param) + __early_end = .; + __start___param = .; + *(__param) + __stop___param = .; + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + . = ALIGN(32); + __initramfs_start = .; + usr/built-in.o(.init.ramfs) + __initramfs_end = .; + . = ALIGN(32768); + __init_end = .; + } + + /DISCARD/ : { /* Exit code and data */ + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .text : { /* Real text segment */ + _text = .; /* Text and read-only data */ + *(.text) + *(.fixup) + *(.gnu.warning) + *(.rodata) + *(.rodata.*) + *(.glue_7) + *(.glue_7t) + *(.got) /* Global offset table */ + + _etext = .; /* End of text section */ + } + + . = ALIGN(16); + __ex_table : { /* Exception table */ + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + RODATA + + _endtext = .; + + . = DATAADDR; + + _sdata = .; + + .data : { + /* + * first, the init thread union, aligned + * to an 8192 byte boundary. + */ + *(.init.task) + + /* + * The cacheline aligned data + */ + . = ALIGN(32); + *(.data.cacheline_aligned) + + /* + * and the usual data section + */ + *(.data) + CONSTRUCTORS + + *(.init.data) + + _edata = .; + } + + .bss : { + __bss_start = .; /* BSS */ + *(.bss) + *(COMMON) + _end = . ; + } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm26/vmlinux-armo.lds.in b/arch/arm26/kernel/vmlinux-arm26.lds.in similarity index 96% rename from arch/arm26/vmlinux-armo.lds.in rename to arch/arm26/kernel/vmlinux-arm26.lds.in index 65b197fdb96ef..8782fe36f0a8f 100644 --- a/arch/arm26/vmlinux-armo.lds.in +++ b/arch/arm26/kernel/vmlinux-arm26.lds.in @@ -1,7 +1,7 @@ /* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares - * borrowed from Russels ARM port by Ian Molton + * borrowed from Russels ARM port by Ian Molton and subsequently modified. */ #include diff --git a/arch/arm26/kernel/vmlinux.lds.S b/arch/arm26/kernel/vmlinux.lds.S index 7493d297fb5b3..811a690480108 100644 --- a/arch/arm26/kernel/vmlinux.lds.S +++ b/arch/arm26/kernel/vmlinux.lds.S @@ -1,12 +1,12 @@ #include -#ifdef CONFIG_ROM_KERNEL +#ifdef CONFIG_XIP_KERNEL -#include "vmlinux-armo-rom.lds.in" +#include "vmlinux-arm26-xip.lds.in" #else -#include "vmlinux-armo.lds.in" +#include "vmlinux-arm26.lds.in" #endif diff --git a/arch/arm26/machine/head.S b/arch/arm26/machine/head.S index 30eff6580c2c0..7a8c4370c798d 100644 --- a/arch/arm26/machine/head.S +++ b/arch/arm26/machine/head.S @@ -24,12 +24,13 @@ ENTRY(stext) __entry: cmp pc, #0x02000000 ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000 - teq r0, #0 @ Check for old calling method + teq r0, #0 @ Check for old calling method blne oldparams @ Move page if old adr r0, LC0 - ldmib r0, {r2-r5, sp} @ Setup stack - mov r0, #0 -1: cmp r2, r3 @ Clear BSS + ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values) + + mov r0, #0 @ Clear BSS +1: cmp r2, r3 strcc r0, [r2], #4 bcc 1b @@ -38,6 +39,17 @@ __entry: cmp pc, #0x02000000 bl detect_arch_type str r0, [r5] +#ifdef CONFIG_XIP_KERNEL + ldr r3, ETEXT @ data section copy + ldr r4, SDATA + ldr r5, EDATA +1: + ldr r6, [r3], #4 + str r6, [r4], #4 + cmp r4, r5 + blt 1b +#endif + mov fp, #0 b start_kernel @@ -47,8 +59,14 @@ LC0: .word _stext .word processor_id @ r4 .word __machine_arch_type @ r5 .word init_thread_union+8192 @ sp -arm2_id: .long 0x41560200 -arm250_id: .long 0x41560250 +#ifdef CONFIG_XIP_KERNEL +ETEXT: .word _endtext +SDATA: .word _sdata +EDATA: .word __bss_start +#endif + +arm2_id: .long 0x41560200 @ ARM2 and 250 dont have a CPUID +arm250_id: .long 0x41560250 @ So we create some after probing for them .align oldparams: mov r4, #0x02000000 diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c index b73ca26fcc42d..beef99b48b864 100644 --- a/arch/arm26/mm/fault.c +++ b/arch/arm26/mm/fault.c @@ -123,7 +123,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, show_pte(tsk->mm, addr); show_regs(regs); //dump_backtrace(regs, tsk); // FIXME ARM32 dropped this - why? - while(1); + while(1); //FIXME - hack to stop debug going nutso #endif tsk->thread.address = addr; @@ -212,7 +212,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) tsk = current; mm = tsk->mm; - printk("do_page_fault: pid: %d\n", tsk->pid); + printk("do_page_fault: pid: %d %08x\n", tsk->pid, addr); /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -241,6 +241,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * If we are in kernel mode at this point, we * have no context to handle this fault with. + * FIXME - is this test right? */ if (!user_mode(regs)){ goto no_context; diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c index 7013d0bd03a17..a4f56b2b493b6 100644 --- a/arch/arm26/mm/init.c +++ b/arch/arm26/mm/init.c @@ -32,15 +32,18 @@ #include #include -//#include #include + #define TABLE_SIZE PTRS_PER_PTE * sizeof(pte_t)) struct mmu_gather mmu_gathers[NR_CPUS]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern char _stext, _text, _etext, _end, __init_begin, __init_end; +#ifdef CONFIG_XIP_KERNEL +extern char _endtext, _sdata; +#endif extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; @@ -152,6 +155,7 @@ static void __init find_memend_and_nodes(struct meminfo *mi, struct node_info *np) { unsigned int memend_pfn = 0; + numnodes = 1; np->bootmap_pages = 0; @@ -186,45 +190,6 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np) } -/* - * Reserve the various regions of node 0 - */ -static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages) -{ - pg_data_t *pgdat = NODE_DATA(0); - - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ - reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); - - /* - * And don't forget to reserve the allocator bitmap, - * which will be freed later. - */ - reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT, - bootmap_pages << PAGE_SHIFT); - - /* - * These should likewise go elsewhere. They pre-reserve - * the screen memory region at the start of main system - * memory. - */ - reserve_bootmem_node(pgdat, 0x02000000, 0x00080000); - -#ifdef CONFIG_BLK_DEV_INITRD - initrd_start = phys_initrd_start; - initrd_end = initrd_start + phys_initrd_size; - - /* Achimedes machines only have one node, so initrd is in node 0 */ - reserve_bootmem_node(pgdat, __pa(initrd_start), - initrd_end - initrd_start); -#endif - -} - - /* * Initialise the bootmem allocator for all nodes. This is called * early during the architecture specific initialisation. @@ -233,6 +198,7 @@ void __init bootmem_init(struct meminfo *mi) { struct node_info node_info; unsigned int bootmap_pfn; + pg_data_t *pgdat = NODE_DATA(0); find_memend_and_nodes(mi, &node_info); @@ -247,18 +213,54 @@ void __init bootmem_init(struct meminfo *mi) /* * Initialise the bootmem allocator. */ - init_bootmem_node(NODE_DATA(node), bootmap_pfn, node_info.start, node_info.end); + init_bootmem_node(pgdat, bootmap_pfn, node_info.start, node_info.end); /* * Register all available RAM in this node with the bootmem allocator. */ - free_bootmem_node(NODE_DATA(node), mi->bank->start, mi->bank->size); + free_bootmem_node(pgdat, mi->bank->start, mi->bank->size); + + /* + * Register the kernel text and data with bootmem. + * Note: with XIP we dont register .text since + * its in ROM. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&_sdata), &_end - &_sdata); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif - /* - * Reserve ram for stuff like initrd, video, kernel, etc. - */ + /* + * And don't forget to reserve the allocator bitmap, + * which will be freed later. + */ + reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT, + node_info.bootmap_pages << PAGE_SHIFT); + + /* + * These should likewise go elsewhere. They pre-reserve + * the screen memory region at the start of main system + * memory. FIXME - screen RAM is not 512K! + */ + reserve_bootmem_node(pgdat, 0x02000000, 0x00080000); + +#ifdef CONFIG_BLK_DEV_INITRD + initrd_start = phys_initrd_start; + initrd_end = initrd_start + phys_initrd_size; + + /* Achimedes machines only have one node, so initrd is in node 0 */ +#ifdef CONFIG_XIP_KERNEL + /* Only reserve initrd space if it is in RAM */ + if(initrd_start && initrd_start < 0x03000000){ +#else + if(initrd_start){ +#endif + reserve_bootmem_node(pgdat, __pa(initrd_start), + initrd_end - initrd_start); + } +#endif /* CONFIG_BLK_DEV_INITRD */ - reserve_node_zero(bootmap_pfn, node_info.bootmap_pages); } @@ -299,16 +301,15 @@ void __init paging_init(struct meminfo *mi) pgdat = NODE_DATA(0); bdata = pgdat->bdata; - zone_size[0] = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); if (!zone_size[0]) BUG(); free_area_init_node(0, pgdat, 0, zone_size, - bdata->node_boot_start >> PAGE_SHIFT, 0); + bdata->node_boot_start >> PAGE_SHIFT, zhole_size); - mem_map = contig_page_data.node_mem_map; + mem_map = NODE_DATA(0)->node_mem_map; /* * finish off the bad pages once @@ -345,8 +346,15 @@ void __init mem_init(void) pg_data_t *pgdat = NODE_DATA(0); extern int sysctl_overcommit_memory; - datapages = &_end - &_etext; + + /* Note: data pages includes BSS */ +#ifdef CONFIG_XIP_KERNEL + codepages = &_endtext - &_text; + datapages = &_end - &_sdata; +#else codepages = &_etext - &_text; + datapages = &_end - &_etext; +#endif initpages = &__init_end - &__init_begin; high_memory = (void *)__va(meminfo.end); @@ -356,15 +364,14 @@ void __init mem_init(void) if (pgdat->node_spanned_pages != 0) totalram_pages += free_all_bootmem_node(pgdat); - printk(KERN_INFO "Memory:"); - num_physpages = meminfo.bank[0].size >> PAGE_SHIFT; - printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); + printk(KERN_INFO "Memory: %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); printk(KERN_NOTICE "Memory: %luKB available (%dK code, " "%dK data, %dK init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), codepages >> 10, datapages >> 10, initpages >> 10); + /* * Turn on overcommit on tiny machines */ @@ -374,11 +381,12 @@ void __init mem_init(void) } } -void free_initmem(void) -{ +void free_initmem(void){ +#ifndef CONFIG_XIP_KERNEL free_area((unsigned long)(&__init_begin), (unsigned long)(&__init_end), "init"); +#endif } #ifdef CONFIG_BLK_DEV_INITRD @@ -387,7 +395,12 @@ static int keep_initrd; void free_initrd_mem(unsigned long start, unsigned long end) { +#ifdef CONFIG_XIP_KERNEL + /* Only bin initrd if it is in RAM... */ + if(!keep_initrd && start < 0x03000000) +#else if (!keep_initrd) +#endif free_area(start, end, "initrd"); } diff --git a/include/asm-arm26/ecard.h b/include/asm-arm26/ecard.h index 8318a0c1df81a..66691939c3c11 100644 --- a/include/asm-arm26/ecard.h +++ b/include/asm-arm26/ecard.h @@ -163,27 +163,27 @@ struct expansion_card { struct resource resource[ECARD_NUM_RESOURCES]; /* Public data */ - volatile unsigned char *irqaddr; /* address of IRQ register */ - volatile unsigned char *fiqaddr; /* address of FIQ register */ - unsigned char irqmask; /* IRQ mask */ - unsigned char fiqmask; /* FIQ mask */ - unsigned char claimed; /* Card claimed? */ - - void *irq_data; /* Data for use for IRQ by card */ - void *fiq_data; /* Data for use for FIQ by card */ - const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ - - CONST unsigned int slot_no; /* Slot number */ - CONST unsigned int dma; /* DMA number (for request_dma) */ - CONST unsigned int irq; /* IRQ number (for request_irq) */ - CONST unsigned int fiq; /* FIQ number (for request_irq) */ - CONST card_type_t type; /* Type of card */ - CONST struct in_ecid cid; /* Card Identification */ + volatile unsigned char *irqaddr; /* address of IRQ register */ + volatile unsigned char *fiqaddr; /* address of FIQ register */ + unsigned char irqmask; /* IRQ mask */ + unsigned char fiqmask; /* FIQ mask */ + unsigned char claimed; /* Card claimed? */ + + void *irq_data; /* Data for use for IRQ by card */ + void *fiq_data; /* Data for use for FIQ by card */ + const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ + + CONST unsigned int slot_no; /* Slot number */ + CONST unsigned int dma; /* DMA number (for request_dma) */ + CONST unsigned int irq; /* IRQ number (for request_irq) */ + CONST unsigned int fiq; /* FIQ number (for request_irq) */ + CONST card_type_t type; /* Type of card */ + CONST struct in_ecid cid; /* Card Identification */ /* Private internal data */ - const char *card_desc; /* Card description */ - CONST unsigned int podaddr; /* Base Linux address for card */ - CONST loader_t loader; /* loader program */ + const char *card_desc; /* Card description */ + CONST unsigned int podaddr; /* Base Linux address for card */ + CONST loader_t loader; /* loader program */ u64 dma_mask; }; diff --git a/include/asm-arm26/local.h b/include/asm-arm26/local.h new file mode 100644 index 0000000000000..6759e9183cef7 --- /dev/null +++ b/include/asm-arm26/local.h @@ -0,0 +1,2 @@ +//FIXME - nicked from arm32 - check it is correct... +#include diff --git a/include/asm-arm26/sections.h b/include/asm-arm26/sections.h new file mode 100644 index 0000000000000..10b6370efad02 --- /dev/null +++ b/include/asm-arm26/sections.h @@ -0,0 +1,2 @@ +//FIXME - nicked from arm32 - check its correct. +#include diff --git a/include/asm-arm26/uaccess-asm.h b/include/asm-arm26/uaccess-asm.h index 4f3ca200d4378..19f798e338c97 100644 --- a/include/asm-arm26/uaccess-asm.h +++ b/include/asm-arm26/uaccess-asm.h @@ -19,8 +19,10 @@ /* * These are the values used to represent the user `fs' and the kernel `ds' + * FIXME - the KERNEL_DS should end at 0x03000000 but we want to access ROM at + * 0x03400000. ideally we want to forbid access to the IO space inbetween. */ -#define KERNEL_DS 0x03000000 +#define KERNEL_DS 0x03FFFFFF #define USER_DS 0x02000000 extern uaccess_t uaccess_user, uaccess_kernel; @@ -28,7 +30,7 @@ extern uaccess_t uaccess_user, uaccess_kernel; static inline void set_fs (mm_segment_t fs) { current_thread_info()->addr_limit = fs; - current->thread.uaccess = fs == USER_DS ? &uaccess_user : &uaccess_kernel; + current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel); } #define __range_ok(addr,size) ({ \ -- 2.53.0