Commit 49e4d78b authored by Ian Molton's avatar Ian Molton Committed by Linus Torvalds

[PATCH] arm26 updates

Not much to write home about. mostly tidying, some debug, and XIP support.

just keeping arm26 up to date really.
parent 45ad6fd3
...@@ -96,6 +96,7 @@ config ZBOOT_ROM ...@@ -96,6 +96,7 @@ config ZBOOT_ROM
directly from ROM or flash. If unsure, say N. directly from ROM or flash. If unsure, say N.
config ZBOOT_ROM_TEXT config ZBOOT_ROM_TEXT
depends on ZBOOT_ROM
hex "Compressed ROM boot loader base address" hex "Compressed ROM boot loader base address"
default "0" default "0"
help help
...@@ -103,6 +104,7 @@ config ZBOOT_ROM_TEXT ...@@ -103,6 +104,7 @@ config ZBOOT_ROM_TEXT
should not change this value. should not change this value.
config ZBOOT_ROM_BSS config ZBOOT_ROM_BSS
depends on ZBOOT_ROM
hex "Compressed ROM boot loader BSS address" hex "Compressed ROM boot loader BSS address"
default "0" default "0"
help help
...@@ -110,6 +112,12 @@ config ZBOOT_ROM_BSS ...@@ -110,6 +112,12 @@ config ZBOOT_ROM_BSS
while the decompressor is running. Unless you have special requirements, while the decompressor is running. Unless you have special requirements,
you should not change this value. 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 config HOTPLUG
bool "Support for hot-pluggable devices" bool "Support for hot-pluggable devices"
---help--- ---help---
......
...@@ -12,8 +12,6 @@ LDFLAGS_BLOB :=--format binary ...@@ -12,8 +12,6 @@ LDFLAGS_BLOB :=--format binary
AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
GZFLAGS :=-9 GZFLAGS :=-9
#CFLAGS +=-pipe
CFLAGS :=$(CFLAGS:-O2=-Os)
ifeq ($(CONFIG_FRAME_POINTER),y) ifeq ($(CONFIG_FRAME_POINTER),y)
CFLAGS +=-fno-omit-frame-pointer -mno-sched-prolog 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 ...@@ -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 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 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 head-y := arch/arm26/machine/head.o arch/arm26/kernel/init_task.o
LDFLAGS_BLOB += --oformat elf32-littlearm LDFLAGS_BLOB += --oformat elf32-littlearm
ifeq ($(CONFIG_ROM_KERNEL),y)
DATAADDR := 0x02080000 ifeq ($(CONFIG_XIP_KERNEL),y)
textaddr-y := 0x03800000 TEXTADDR := 0x03880000
else DATAADDR := 0x02080000
textaddr-y := 0x02080000 else
endif TEXTADDR := 0x02080000
DATAADDR := .
endif endif
TEXTADDR := $(textaddr-y)
ifeq ($(incdir-y),) ifeq ($(incdir-y),)
incdir-y := incdir-y :=
endif endif
...@@ -74,7 +68,7 @@ maketools: FORCE ...@@ -74,7 +68,7 @@ maketools: FORCE
bzImage: vmlinux bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage $(Q)$(MAKE) $(build)=$(boot) $(boot)/zImage
zImage Image bootpImage: vmlinux zImage Image bootpImage xipImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
zinstall install: vmlinux zinstall install: vmlinux
......
...@@ -36,7 +36,7 @@ endif ...@@ -36,7 +36,7 @@ endif
export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS export ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
targets := Image zImage bootpImage targets := Image zImage bootpImage xipImage
$(obj)/Image: vmlinux FORCE $(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
...@@ -49,6 +49,15 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE ...@@ -49,6 +49,15 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(obj)/compressed/vmlinux: vmlinux FORCE $(obj)/compressed/vmlinux: vmlinux FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(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 .PHONY: initrd
initrd: initrd:
@test "$(INITRD_PHYS)" != "" || \ @test "$(INITRD_PHYS)" != "" || \
......
...@@ -580,7 +580,7 @@ static void ecard_proc_init(void) ...@@ -580,7 +580,7 @@ static void ecard_proc_init(void)
#define ec_set_resource(ec,nr,st,sz,flg) \ #define ec_set_resource(ec,nr,st,sz,flg) \
do { \ do { \
(ec)->resource[nr].name = ec->dev.name; \ (ec)->resource[nr].name = ec->dev.bus_id; \
(ec)->resource[nr].start = st; \ (ec)->resource[nr].start = st; \
(ec)->resource[nr].end = (st) + (sz) - 1; \ (ec)->resource[nr].end = (st) + (sz) - 1; \
(ec)->resource[nr].flags = flg; \ (ec)->resource[nr].flags = flg; \
...@@ -621,7 +621,17 @@ static ssize_t ecard_show_irq(struct device *dev, char *buf) ...@@ -621,7 +621,17 @@ static ssize_t ecard_show_irq(struct device *dev, char *buf)
return sprintf(buf, "%u\n", ec->irq); 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) 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) ...@@ -629,8 +639,6 @@ static ssize_t ecard_show_dma(struct device *dev, char *buf)
return sprintf(buf, "%u\n", ec->dma); 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) static ssize_t ecard_show_resources(struct device *dev, char *buf)
{ {
struct expansion_card *ec = ECARD_DEV(dev); struct expansion_card *ec = ECARD_DEV(dev);
...@@ -646,6 +654,10 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf) ...@@ -646,6 +654,10 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf)
return str - 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); static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
/* /*
...@@ -717,8 +729,6 @@ ecard_probe(int slot, card_type_t type) ...@@ -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.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.parent = NULL;
ec->dev.bus = &ecard_bus_type; ec->dev.bus = &ecard_bus_type;
ec->dev.dma_mask = &ec->dma_mask; ec->dev.dma_mask = &ec->dma_mask;
...@@ -745,6 +755,8 @@ ecard_probe(int slot, card_type_t type) ...@@ -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_dma);
device_create_file(&ec->dev, &dev_attr_irq); device_create_file(&ec->dev, &dev_attr_irq);
device_create_file(&ec->dev, &dev_attr_resource); 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; return 0;
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
@ @
@ Stack format (ensured by USER_* and SVC_*) @ 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_OLD_R0 64
#define S_PSR 60 #define S_PSR 60
#define S_PC 60 #define S_PC 60
...@@ -77,11 +77,11 @@ ...@@ -77,11 +77,11 @@
.endm .endm
.macro slow_restore_user_regs .macro slow_restore_user_regs
ldmia sp, {r0 - lr}^ ldmia sp, {r0 - lr}^ @ restore the user regs
mov r0, r0 mov r0, r0 @ no-op
ldr lr, [sp, #15*4] ldr lr, [sp, #15*4] @ get user PC
add sp, sp, #15*4+8 add sp, sp, #15*4+8 @ free stack
movs pc, lr movs pc, lr @ return
.endm .endm
.macro fast_restore_user_regs .macro fast_restore_user_regs
...@@ -514,31 +514,37 @@ Lfiqmsg: .ascii "*** Unexpected FIQ\n\0" ...@@ -514,31 +514,37 @@ Lfiqmsg: .ascii "*** Unexpected FIQ\n\0"
* Handles floating point instructions * Handles floating point instructions
*/ */
vector_undefinstr: vector_undefinstr:
tst lr,#3 tst lr, #MODE_SVC26 @ did we come from a non-user mode?
bne __und_svc bne __und_svc @ yes - deal with it.
/* Otherwise, fall through for the user-space (common) case. */
save_user_regs save_user_regs
zero_fp zero_fp @ zero frame pointer
teqp pc, #PSR_I_BIT | MODE_SVC26 teqp pc, #PSR_I_BIT | MODE_SVC26 @ disable IRQs
.Lbug_undef: .Lbug_undef:
ldr r4, .LC2 ldr r4, .LC2
ldr pc, [r4] @ Call FP module USR entry point ldr pc, [r4] @ Call FP module entry point
/* FIXME - should we trap for a null pointer here? */
.globl fpundefinstr
fpundefinstr: @ Called by FP module on undefined instr /* 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 r0, lr
mov r1, sp mov r1, sp
teqp pc, #MODE_SVC26 teqp pc, #MODE_SVC26
bl do_undefinstr bl do_undefinstr
b ret_from_exception @ Normal FP exit 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 #if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
/* The FPE is always present */ /* The FPE is always present */
.equ fpe_not_present, 0 .equ fpe_not_present, 0
...@@ -548,6 +554,7 @@ __und_svc: SVC_SAVE_ALL @ Non-user mode ...@@ -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 * 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 * operation. This is a hack to allow some basic userland binaries
* to run so that the emulator module proper can be loaded. --philb * to run so that the emulator module proper can be loaded. --philb
* FIXME - probably a broken useless hack...
*/ */
fpe_not_present: fpe_not_present:
adr r10, wfs_mask_data adr r10, wfs_mask_data
...@@ -587,14 +594,14 @@ wfs_mask_data: .word 0x0e200110 @ WFS/RFS ...@@ -587,14 +594,14 @@ wfs_mask_data: .word 0x0e200110 @ WFS/RFS
* Prefetch abort handler * Prefetch abort handler
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
*/ */
#define DEBUG_UNDEF
/* remember: lr = USR pc */ /* remember: lr = USR pc */
vector_prefetch: vector_prefetch:
sub lr, lr, #4 sub lr, lr, #4
tst lr, #3 tst lr, #MODE_SVC26
bne __pabt_invalid bne __pabt_invalid
save_user_regs save_user_regs
teqp pc, #MODE_SVC26 teqp pc, #MODE_SVC26 @ Enable IRQs...
mask_pc r0, lr @ Address of abort mask_pc r0, lr @ Address of abort
mov r1, sp @ Tasks registers mov r1, sp @ Tasks registers
bl do_PrefetchAbort bl do_PrefetchAbort
...@@ -604,7 +611,7 @@ vector_prefetch: ...@@ -604,7 +611,7 @@ vector_prefetch:
adr r0, t adr r0, t
bl printk bl printk
#endif #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!) b .Lbug_undef @ broken at the moment though!)
__pabt_invalid: SVC_SAVE_ALL __pabt_invalid: SVC_SAVE_ALL
...@@ -707,7 +714,7 @@ vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case... ...@@ -707,7 +714,7 @@ vector_IRQ: ldr r13, .LCirq @ I will leave this one in just in case...
bne asm_do_IRQ bne asm_do_IRQ
mov why, #0 mov why, #0
get_thread_info r5 get_thread_info tsk @ FIXME - was r5, but seemed wrong.
b ret_to_user b ret_to_user
irq_prio_table irq_prio_table
......
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/irqchip.h> #include <asm/irqchip.h>
//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 * Maximum IRQ count. Currently, this is arbitary. However, it should
* not be set too low to prevent false triggering. Conversely, if it * not be set too low to prevent false triggering. Conversely, if it
......
...@@ -58,6 +58,10 @@ extern void squash_mem_tags(struct tag *tag); ...@@ -58,6 +58,10 @@ extern void squash_mem_tags(struct tag *tag);
extern void bootmem_init(struct meminfo *); extern void bootmem_init(struct meminfo *);
extern int root_mountflags; extern int root_mountflags;
extern int _stext, _text, _etext, _edata, _end; extern int _stext, _text, _etext, _edata, _end;
#ifdef CONFIG_XIP_KERNEL
extern int _endtext, _sdata;
#endif
unsigned int processor_id; unsigned int processor_id;
unsigned int __machine_arch_type; unsigned int __machine_arch_type;
...@@ -121,6 +125,7 @@ static void __init setup_processor(void) ...@@ -121,6 +125,7 @@ static void __init setup_processor(void)
for (list = &__proc_info_begin; list < &__proc_info_end ; list++) for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
if ((processor_id & list->cpu_mask) == list->cpu_val) if ((processor_id & list->cpu_mask) == list->cpu_val)
break; break;
/* /*
* If processor type is unrecognised, then we * If processor type is unrecognised, then we
* can do nothing... * can do nothing...
...@@ -220,7 +225,11 @@ request_standard_resources(struct meminfo *mi) ...@@ -220,7 +225,11 @@ request_standard_resources(struct meminfo *mi)
kernel_code.start = init_mm.start_code; kernel_code.start = init_mm.start_code;
kernel_code.end = init_mm.end_code - 1; 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; kernel_data.start = init_mm.end_code;
#endif
kernel_data.end = init_mm.brk - 1; kernel_data.end = init_mm.brk - 1;
for (i = 0; i < mi->nr_banks; i++) { for (i = 0; i < mi->nr_banks; i++) {
...@@ -456,7 +465,10 @@ void __init setup_arch(char **cmdline_p) ...@@ -456,7 +465,10 @@ void __init setup_arch(char **cmdline_p)
else else
machine_name = "UNKNOWN"; 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; tags = (struct tag *)0x0207c000;
/* /*
...@@ -474,7 +486,12 @@ void __init setup_arch(char **cmdline_p) ...@@ -474,7 +486,12 @@ void __init setup_arch(char **cmdline_p)
} }
init_mm.start_code = (unsigned long) &_text; init_mm.start_code = (unsigned long) &_text;
#ifndef CONFIG_XIP_KERNEL
init_mm.end_code = (unsigned long) &_etext; 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.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end; init_mm.brk = (unsigned long) &_end;
......
/* ld script to make ARM Linux kernel
* taken from the i386 version by Russell King
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
* borrowed from Russels ARM port by Ian Molton
*/
#include <asm-generic/vmlinux.lds.h>
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) }
}
/* ld script to make ARM Linux kernel /* ld script to make ARM Linux kernel
* taken from the i386 version by Russell King * taken from the i386 version by Russell King
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
* borrowed from Russels ARM port by Ian Molton * borrowed from Russels ARM port by Ian Molton and subsequently modified.
*/ */
#include <asm-generic/vmlinux.lds.h> #include <asm-generic/vmlinux.lds.h>
......
#include <linux/config.h> #include <linux/config.h>
#ifdef CONFIG_ROM_KERNEL #ifdef CONFIG_XIP_KERNEL
#include "vmlinux-armo-rom.lds.in" #include "vmlinux-arm26-xip.lds.in"
#else #else
#include "vmlinux-armo.lds.in" #include "vmlinux-arm26.lds.in"
#endif #endif
...@@ -24,12 +24,13 @@ ...@@ -24,12 +24,13 @@
ENTRY(stext) ENTRY(stext)
__entry: cmp pc, #0x02000000 __entry: cmp pc, #0x02000000
ldrlt pc, LC0 @ if 0x01800000, call at 0x02080000 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 blne oldparams @ Move page if old
adr r0, LC0 adr r0, LC0
ldmib r0, {r2-r5, sp} @ Setup stack ldmib r0, {r2-r5, sp} @ Setup stack (and fetch other values)
mov r0, #0
1: cmp r2, r3 @ Clear BSS mov r0, #0 @ Clear BSS
1: cmp r2, r3
strcc r0, [r2], #4 strcc r0, [r2], #4
bcc 1b bcc 1b
...@@ -38,6 +39,17 @@ __entry: cmp pc, #0x02000000 ...@@ -38,6 +39,17 @@ __entry: cmp pc, #0x02000000
bl detect_arch_type bl detect_arch_type
str r0, [r5] 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 mov fp, #0
b start_kernel b start_kernel
...@@ -47,8 +59,14 @@ LC0: .word _stext ...@@ -47,8 +59,14 @@ LC0: .word _stext
.word processor_id @ r4 .word processor_id @ r4
.word __machine_arch_type @ r5 .word __machine_arch_type @ r5
.word init_thread_union+8192 @ sp .word init_thread_union+8192 @ sp
arm2_id: .long 0x41560200 #ifdef CONFIG_XIP_KERNEL
arm250_id: .long 0x41560250 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 .align
oldparams: mov r4, #0x02000000 oldparams: mov r4, #0x02000000
......
...@@ -123,7 +123,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, ...@@ -123,7 +123,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
show_pte(tsk->mm, addr); show_pte(tsk->mm, addr);
show_regs(regs); show_regs(regs);
//dump_backtrace(regs, tsk); // FIXME ARM32 dropped this - why? //dump_backtrace(regs, tsk); // FIXME ARM32 dropped this - why?
while(1); while(1); //FIXME - hack to stop debug going nutso
#endif #endif
tsk->thread.address = addr; tsk->thread.address = addr;
...@@ -212,7 +212,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ...@@ -212,7 +212,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
tsk = current; tsk = current;
mm = tsk->mm; 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 * If we're in an interrupt or have no user
* context, we must not take the fault.. * 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) ...@@ -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 * If we are in kernel mode at this point, we
* have no context to handle this fault with. * have no context to handle this fault with.
* FIXME - is this test right?
*/ */
if (!user_mode(regs)){ if (!user_mode(regs)){
goto no_context; goto no_context;
......
...@@ -32,15 +32,18 @@ ...@@ -32,15 +32,18 @@
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/tlb.h> #include <asm/tlb.h>
//#include <asm/arch.h>
#include <asm/map.h> #include <asm/map.h>
#define TABLE_SIZE PTRS_PER_PTE * sizeof(pte_t)) #define TABLE_SIZE PTRS_PER_PTE * sizeof(pte_t))
struct mmu_gather mmu_gathers[NR_CPUS]; struct mmu_gather mmu_gathers[NR_CPUS];
extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern char _stext, _text, _etext, _end, __init_begin, __init_end; 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_start;
extern unsigned long phys_initrd_size; extern unsigned long phys_initrd_size;
...@@ -152,6 +155,7 @@ static void __init ...@@ -152,6 +155,7 @@ static void __init
find_memend_and_nodes(struct meminfo *mi, struct node_info *np) find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
{ {
unsigned int memend_pfn = 0; unsigned int memend_pfn = 0;
numnodes = 1; numnodes = 1;
np->bootmap_pages = 0; np->bootmap_pages = 0;
...@@ -186,45 +190,6 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np) ...@@ -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 * Initialise the bootmem allocator for all nodes. This is called
* early during the architecture specific initialisation. * early during the architecture specific initialisation.
...@@ -233,6 +198,7 @@ void __init bootmem_init(struct meminfo *mi) ...@@ -233,6 +198,7 @@ void __init bootmem_init(struct meminfo *mi)
{ {
struct node_info node_info; struct node_info node_info;
unsigned int bootmap_pfn; unsigned int bootmap_pfn;
pg_data_t *pgdat = NODE_DATA(0);
find_memend_and_nodes(mi, &node_info); find_memend_and_nodes(mi, &node_info);
...@@ -247,18 +213,54 @@ void __init bootmem_init(struct meminfo *mi) ...@@ -247,18 +213,54 @@ void __init bootmem_init(struct meminfo *mi)
/* /*
* Initialise the bootmem allocator. * 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. * 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) ...@@ -299,16 +301,15 @@ void __init paging_init(struct meminfo *mi)
pgdat = NODE_DATA(0); pgdat = NODE_DATA(0);
bdata = pgdat->bdata; bdata = pgdat->bdata;
zone_size[0] = bdata->node_low_pfn - zone_size[0] = bdata->node_low_pfn -
(bdata->node_boot_start >> PAGE_SHIFT); (bdata->node_boot_start >> PAGE_SHIFT);
if (!zone_size[0]) if (!zone_size[0])
BUG(); BUG();
free_area_init_node(0, pgdat, 0, zone_size, 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 * finish off the bad pages once
...@@ -345,8 +346,15 @@ void __init mem_init(void) ...@@ -345,8 +346,15 @@ void __init mem_init(void)
pg_data_t *pgdat = NODE_DATA(0); pg_data_t *pgdat = NODE_DATA(0);
extern int sysctl_overcommit_memory; 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; codepages = &_etext - &_text;
datapages = &_end - &_etext;
#endif
initpages = &__init_end - &__init_begin; initpages = &__init_end - &__init_begin;
high_memory = (void *)__va(meminfo.end); high_memory = (void *)__va(meminfo.end);
...@@ -356,15 +364,14 @@ void __init mem_init(void) ...@@ -356,15 +364,14 @@ void __init mem_init(void)
if (pgdat->node_spanned_pages != 0) if (pgdat->node_spanned_pages != 0)
totalram_pages += free_all_bootmem_node(pgdat); totalram_pages += free_all_bootmem_node(pgdat);
printk(KERN_INFO "Memory:");
num_physpages = meminfo.bank[0].size >> PAGE_SHIFT; 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, " printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
"%dK data, %dK init)\n", "%dK data, %dK init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10), (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
codepages >> 10, datapages >> 10, initpages >> 10); codepages >> 10, datapages >> 10, initpages >> 10);
/* /*
* Turn on overcommit on tiny machines * Turn on overcommit on tiny machines
*/ */
...@@ -374,11 +381,12 @@ void __init mem_init(void) ...@@ -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), free_area((unsigned long)(&__init_begin),
(unsigned long)(&__init_end), (unsigned long)(&__init_end),
"init"); "init");
#endif
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
...@@ -387,7 +395,12 @@ static int keep_initrd; ...@@ -387,7 +395,12 @@ static int keep_initrd;
void free_initrd_mem(unsigned long start, unsigned long end) 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) if (!keep_initrd)
#endif
free_area(start, end, "initrd"); free_area(start, end, "initrd");
} }
......
...@@ -163,27 +163,27 @@ struct expansion_card { ...@@ -163,27 +163,27 @@ struct expansion_card {
struct resource resource[ECARD_NUM_RESOURCES]; struct resource resource[ECARD_NUM_RESOURCES];
/* Public data */ /* Public data */
volatile unsigned char *irqaddr; /* address of IRQ register */ volatile unsigned char *irqaddr; /* address of IRQ register */
volatile unsigned char *fiqaddr; /* address of FIQ register */ volatile unsigned char *fiqaddr; /* address of FIQ register */
unsigned char irqmask; /* IRQ mask */ unsigned char irqmask; /* IRQ mask */
unsigned char fiqmask; /* FIQ mask */ unsigned char fiqmask; /* FIQ mask */
unsigned char claimed; /* Card claimed? */ unsigned char claimed; /* Card claimed? */
void *irq_data; /* Data for use for IRQ by card */ void *irq_data; /* Data for use for IRQ by card */
void *fiq_data; /* Data for use for FIQ by card */ void *fiq_data; /* Data for use for FIQ by card */
const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
CONST unsigned int slot_no; /* Slot number */ CONST unsigned int slot_no; /* Slot number */
CONST unsigned int dma; /* DMA number (for request_dma) */ CONST unsigned int dma; /* DMA number (for request_dma) */
CONST unsigned int irq; /* IRQ number (for request_irq) */ CONST unsigned int irq; /* IRQ number (for request_irq) */
CONST unsigned int fiq; /* FIQ number (for request_irq) */ CONST unsigned int fiq; /* FIQ number (for request_irq) */
CONST card_type_t type; /* Type of card */ CONST card_type_t type; /* Type of card */
CONST struct in_ecid cid; /* Card Identification */ CONST struct in_ecid cid; /* Card Identification */
/* Private internal data */ /* Private internal data */
const char *card_desc; /* Card description */ const char *card_desc; /* Card description */
CONST unsigned int podaddr; /* Base Linux address for card */ CONST unsigned int podaddr; /* Base Linux address for card */
CONST loader_t loader; /* loader program */ CONST loader_t loader; /* loader program */
u64 dma_mask; u64 dma_mask;
}; };
......
//FIXME - nicked from arm32 - check it is correct...
#include <asm-generic/local.h>
//FIXME - nicked from arm32 - check its correct.
#include <asm-generic/sections.h>
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
/* /*
* These are the values used to represent the user `fs' and the kernel `ds' * 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 #define USER_DS 0x02000000
extern uaccess_t uaccess_user, uaccess_kernel; extern uaccess_t uaccess_user, uaccess_kernel;
...@@ -28,7 +30,7 @@ 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) static inline void set_fs (mm_segment_t fs)
{ {
current_thread_info()->addr_limit = 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) ({ \ #define __range_ok(addr,size) ({ \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment