From 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 4 Feb 2000 07:40:19 +0000 Subject: Merge with Linux 2.3.32. --- arch/arm/Makefile | 4 +- arch/arm/boot/compressed/head-netwinder.S | 1 + arch/arm/config.in | 1 + arch/arm/def-configs/brutus | 3 - arch/arm/def-configs/footbridge | 21 +- arch/arm/defconfig | 3 +- arch/arm/kernel/armksyms.c | 2 +- arch/arm/kernel/bios32.c | 27 ++ arch/arm/kernel/bios32.h | 9 + arch/arm/kernel/dec21285.c | 14 +- arch/arm/kernel/ecard.c | 6 +- arch/arm/kernel/entry-armv.S | 226 +++++------- arch/arm/kernel/fiq.c | 2 +- arch/arm/kernel/head-armv.S | 1 + arch/arm/kernel/hw-footbridge.c | 10 + arch/arm/kernel/ioport.c | 1 + arch/arm/kernel/process.c | 93 ++--- arch/arm/kernel/setup.c | 594 +++++++++++++++++++----------- arch/arm/kernel/signal.c | 3 +- arch/arm/kernel/sys_arm.c | 201 +++++----- arch/arm/kernel/traps.c | 13 +- arch/arm/lib/backtrace.S | 22 +- arch/arm/mm/init.c | 85 +++-- arch/arm/mm/ioremap.c | 4 +- arch/arm/mm/map.h | 1 + arch/arm/mm/mm-armo.c | 16 +- arch/arm/mm/mm-armv.c | 96 +++-- arch/arm/mm/proc-arm2,3.S | 6 +- arch/arm/mm/proc-arm6,7.S | 8 +- arch/arm/mm/proc-sa110.S | 4 +- arch/arm/mm/small_page.c | 6 +- 31 files changed, 879 insertions(+), 604 deletions(-) create mode 100644 arch/arm/kernel/bios32.h (limited to 'arch/arm') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index f8c91aca3..2c81731b9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -156,7 +156,7 @@ endif ifeq ($(CONFIG_ARCH_ACORN),y) SUBDIRS += drivers/acorn DRIVERS += drivers/acorn/block/acorn-block.a -DRIVERS += drivers/acorn/char/acorn-char.a +DRIVERS += drivers/acorn/char/acorn-char.o DRIVERS += drivers/acorn/net/acorn-net.a DRIVERS += drivers/acorn/scsi/acorn-scsi.a endif @@ -241,5 +241,3 @@ victor_config: empeg_config: $(RM) arch/arm/defconfig cp arch/arm/def-configs/empeg arch/arm/defconfig - - diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S index 1dcdfcd14..489bb4d96 100644 --- a/arch/arm/boot/compressed/head-netwinder.S +++ b/arch/arm/boot/compressed/head-netwinder.S @@ -24,6 +24,7 @@ bcs 1b movs r4, r5 mov r5, #0 + mov r1, #5 @ only here to fix NeTTroms which dont set r1 movne pc, r0 mov r0, #0 diff --git a/arch/arm/config.in b/arch/arm/config.in index 249759e1a..e1d54c4e7 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -110,6 +110,7 @@ fi if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then define_bool CONFIG_PCI y + source drivers/pci/Config.h fi # diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus index a700f7d17..aade81639 100644 --- a/arch/arm/def-configs/brutus +++ b/arch/arm/def-configs/brutus @@ -203,9 +203,6 @@ CONFIG_EXT2_FS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set diff --git a/arch/arm/def-configs/footbridge b/arch/arm/def-configs/footbridge index a3acd8954..fa410d522 100644 --- a/arch/arm/def-configs/footbridge +++ b/arch/arm/def-configs/footbridge @@ -100,16 +100,27 @@ CONFIG_IDEDISK_MULTI_MODE=y # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_IDEDMA_PCI_AUTO=y +# IDEDMA_NEW_DRIVE_LISTINGS is not set +IDEDMA_PCI_EXPERIMENTAL=y CONFIG_BLK_DEV_OFFBOARD=y -CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_AEC6210 is not set +# CONFIG_BLK_DEV_CMD646 is not set +CONFIG_BLK_DEV_CY82C693=y +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_PDC202XX=y +# PDC202XX_FORCE_BURST_BIT is not set +# PDC202XX_FORCE_MASTER_MODE is not set # CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_CMD646 is not set CONFIG_BLK_DEV_SL82C105=y +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDEDMA_AUTO=y # CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_CPQ_DA is not set # # Additional Block Devices diff --git a/arch/arm/defconfig b/arch/arm/defconfig index ef7d1e315..2aba351c2 100644 --- a/arch/arm/defconfig +++ b/arch/arm/defconfig @@ -18,6 +18,7 @@ CONFIG_ARCH_EBSA285=y CONFIG_ARCH_NETWINDER=y # CONFIG_ARCH_ACORN is not set CONFIG_PCI=y +CONFIG_PCI_NAMES=y CONFIG_ISA_DMA=y CONFIG_CPU_32=y # CONFIG_CPU_26 is not set @@ -91,7 +92,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_VIA82C586 is not set # CONFIG_BLK_DEV_CMD646 is not set CONFIG_BLK_DEV_SL82C105=y # CONFIG_IDE_CHIPSETS is not set diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 43cc0574f..cdd7a9821 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 28c12d3e8..041d4f4ed 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -47,6 +47,7 @@ void pcibios_report_device_errors(void) * - (0x48) enable all memory requests from ISA to be channeled to PCI * - (0x42) disable ping-pong (as per errata) * - (0x40) enable PCI packet retry + * - (0x44) Route INTA to IRQ11 * - (0x83) don't use CPU park enable, park on last master, disable GAT bit * - (0x80) default rotating priorities * - (0x81) rotate bank 4 @@ -62,6 +63,7 @@ static void __init pci_fixup_83c553(struct pci_dev *dev) pci_write_config_byte(dev, 0x48, 0xff); pci_write_config_byte(dev, 0x42, 0x00); pci_write_config_byte(dev, 0x40, 0x22); + pci_write_config_word(dev, 0x44, 0xb000); pci_write_config_byte(dev, 0x83, 0x02); pci_write_config_byte(dev, 0x80, 0xe0); pci_write_config_byte(dev, 0x81, 0x01); @@ -203,6 +205,15 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) } } +void __init +pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) { return 0; @@ -218,6 +229,14 @@ static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { + if (dev->vendor == PCI_VENDOR_ID_CONTAQ && + dev->device == PCI_DEVICE_ID_CONTAQ_82C693) + switch (PCI_FUNC(dev->devfn)) { + case 1: return 14; + case 2: return 15; + case 3: return 12; + } + return irqmap_ebsa285[(slot + pin) & 3]; } @@ -261,6 +280,8 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) #define DEV(v,d) ((v)<<16|(d)) switch (DEV(dev->vendor, dev->device)) { case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN): return IRQ_NETWINDER_ETHER100; case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): @@ -273,6 +294,7 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) return IRQ_ISA_HARDDISK1; case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): return IRQ_NETWINDER_VGA; default: @@ -339,3 +361,8 @@ char * __init pcibios_setup(char *str) } return str; } + +void __init +pcibios_align_resource(void *data, struct resource *res, unsigned long size) +{ +} diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h new file mode 100644 index 000000000..fb3117452 --- /dev/null +++ b/arch/arm/kernel/bios32.h @@ -0,0 +1,9 @@ +struct hw_pci { + void (*init)(void); + unsigned long io_start; + unsigned long mem_start; + u8 (*swizzle)(struct pci_dev *dev, u8 *pin); + int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); +}; + +void __init dc21285_init(void); diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c index 2622dec25..dc7cc054e 100644 --- a/arch/arm/kernel/dec21285.c +++ b/arch/arm/kernel/dec21285.c @@ -205,6 +205,7 @@ static struct irqaction dc21285_error_action = { void __init dc21285_init(void) { + static struct resource csrmem, csrio; unsigned int mem_size; unsigned long cntl; @@ -217,6 +218,15 @@ void __init dc21285_init(void) *CSR_PCIADDR_EXTN = 0; #ifdef CONFIG_HOST_FOOTBRIDGE + + csrio.flags = IORESOURCE_IO; + csrmem.flags = IORESOURCE_MEM; + + allocate_resource(&ioport_resource, &csrio, 128, + 0xff00, 0xffff, 128, NULL, NULL); + allocate_resource(&iomem_resource, &csrmem, 128, + 0xf4000000, 0xf8000000, 128, NULL, NULL); + /* * Map our SDRAM at a known address in PCI space, just in case * the firmware had other ideas. Using a nonzero base is @@ -224,8 +234,8 @@ void __init dc21285_init(void) * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). */ *CSR_PCICACHELINESIZE = 0x00002008; - *CSR_PCICSRBASE = 0; - *CSR_PCICSRIOBASE = 0; + *CSR_PCICSRBASE = csrmem.start; + *CSR_PCICSRIOBASE = csrio.start; *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); *CSR_PCIROMBASE = 0; *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index c777db993..c7d1da3e1 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_ARCH_ARC @@ -865,7 +865,7 @@ static int ecard_prints(char *buffer, ecard_t *ec) return buffer - start; } -int get_ecard_dev_info(char *buf, char **start, off_t pos, int count, int wr) +static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count) { ecard_t *ec = cards; off_t at = 0; @@ -892,7 +892,7 @@ static struct proc_dir_entry *proc_bus_ecard_dir = NULL; static void ecard_proc_init(void) { - proc_bus_ecard_dir = create_proc_entry("ecard", S_IFDIR, proc_bus); + proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus); create_proc_info_entry("devices", 0, proc_bus_ecard_dir, get_ecard_dev_info); } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7e6d4fe51..6d4107ede 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -20,6 +20,10 @@ #include "../lib/constants.h" +#ifndef MODE_SVC +#define MODE_SVC 0x13 +#endif + .text #define PF_TRACESYS 0x20 @@ -342,10 +346,8 @@ irq_prio_ebsa110: .endm .macro restore_user_regs - mrs r1, cpsr @ disable IRQs - orr r1, r1, #I_BIT ldr r0, [sp, #S_PSR] @ Get calling cpsr - msr cpsr, r1 + msr cpsr_c, #I_BIT | MODE_SVC @ disable IRQs msr spsr, r0 @ save in spsr_svc ldmia sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 @@ -360,16 +362,13 @@ irq_prio_ebsa110: /* If we're optimising for StrongARM the resulting code won't run on an ARM7 and we can save a couple of instructions. --pb */ -#ifdef __ARM_ARCH_4__ - .macro arm700_bug_check, instr, temp - .endm -#else .macro arm700_bug_check, instr, temp +#ifndef __ARM_ARCH_4__ and \temp, \instr, #0x0f000000 @ check for SWI teq \temp, #0x0f000000 bne .Larm700bug - .endm #endif + .endm .macro enable_irqs, temp mrs \temp, cpsr @@ -389,6 +388,13 @@ irq_prio_ebsa110: adr\cond \reg, \label .endm + .macro alignment_trap, rbase, rtemp, sym +#ifdef CONFIG_ALIGNMENT_TRAP + ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)] + mcr p15, 0, \rtemp, c1, c0 +#endif + .endm + /* * Invalid mode handlers */ @@ -473,11 +479,9 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - mrs r9, cpsr @ Enable interrupts if they were tst r3, #I_BIT biceq r9, r9, #I_BIT @ previously - mov r0, r2 /* * This routine must not corrupt r9 @@ -489,9 +493,10 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE #else bl cpu_data_abort #endif - msr cpsr, r9 + msr cpsr_c, r9 mov r3, sp bl SYMBOL_NAME(do_DataAbort) + msr cpsr_c, #I_BIT | MODE_SVC ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr @@ -512,7 +517,7 @@ __irq_svc: sub sp, sp, #S_FRAME_SIZE @ adrsvc ne, lr, 1b bne do_IRQ - ldr r0, [sp, #S_PSR] + ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr @@ -533,7 +538,8 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE mov r1, sp @ struct pt_regs *regs bl SYMBOL_NAME(do_undefinstr) -1: ldr lr, [sp, #S_PSR] @ Get SVC cpsr +1: msr cpsr_c, #I_BIT | MODE_SVC + ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers @@ -554,10 +560,6 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE /* * User mode handlers */ -#ifdef DEBUG_UNDEF -t: .ascii "Prefetch -> undefined instruction\n\0" - .align -#endif .align 5 __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ save r0 - r12 @@ -566,12 +568,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ldmia r4, {r0 - r2} @ Get USR pc, cpsr stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0 stmdb r3, {sp, lr}^ - -#ifdef CONFIG_ALIGNMENT_TRAP - ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)] - mcr p15, 0, r7, c1, c0 -#endif - + alignment_trap r4, r7, __temp_abt mov fp, #0 #ifdef MULTI_CPU ldr r2, .LCprocfns @@ -580,10 +577,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go #else bl cpu_data_abort #endif - mrs r3, cpsr @ Enable interrupts if they were - bic r3, r3, #I_BIT @ previously - msr cpsr, r3 - + msr cpsr_c, #MODE_SVC @ Enable interrupts mov r3, sp adrsvc al, lr, ret_from_sys_call b SYMBOL_NAME(do_DataAbort) @@ -596,12 +590,7 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE ldmia r4, {r5 - r7} @ get saved PC, SPSR stmia r8, {r5 - r7} @ save pc, psr, old_r0 stmdb r8, {sp, lr}^ - -#ifdef CONFIG_ALIGNMENT_TRAP - ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_irq)] - mcr p15, 0, r7, c1, c0 -#endif - + alignment_trap r4, r7, __temp_irq mov fp, #0 1: get_irqnr_and_base r0, r6, r5 movne r1, sp @@ -621,12 +610,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ldmia r4, {r5 - r7} stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save user r0 - r12 - -#ifdef CONFIG_ALIGNMENT_TRAP - ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_und)] - mcr p15, 0, r7, c1, c0 -#endif - + alignment_trap r4, r7, __temp_und mov fp, #0 adrsvc al, r9, ret_from_sys_call @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return @@ -640,9 +624,7 @@ call_fpe: get_current_task r10 fpundefinstr: mov r0, lr mov r1, sp - mrs r4, cpsr @ Enable interrupts - bic r4, r4, #I_BIT - msr cpsr, r4 + msr cpsr_c, #MODE_SVC @ Enable interrupts adrsvc al, lr, ret_from_sys_call b SYMBOL_NAME(do_undefinstr) @@ -654,16 +636,9 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ldmia r4, {r5 - r7} @ Get USR pc, cpsr stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr - -#ifdef CONFIG_ALIGNMENT_TRAP - ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)] - mcr p15, 0, r7, c1, c0 -#endif - + alignment_trap r4, r7, __temp_abt mov fp, #0 - mrs r7, cpsr @ Enable interrupts if they were - bic r7, r7, #I_BIT @ previously - msr cpsr, r7 + msr cpsr_c, #MODE_SVC @ Enable interrupts mov r0, r5 @ address (pc) mov r1, sp @ regs bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler @@ -681,6 +656,11 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore USR registers +#ifdef DEBUG_UNDEF +t: .ascii "Prefetch -> undefined instruction\n\0" + .align +#endif + #include "entry-common.S" .text @@ -738,14 +718,31 @@ vector_IRQ: @ @ @ now branch to the relevent MODE handling routine @ - bic r13, lr, #63 - orr r13, r13, #0x93 - msr spsr, r13 @ switch to SVC_32 mode + msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode and lr, lr, #15 - adr r13, .LCtab_irq - ldr lr, [r13, lr, lsl #2] + ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches + +.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32) + .word __irq_invalid @ 1 (FIQ_26 / FIQ_32) + .word __irq_invalid @ 2 (IRQ_26 / IRQ_32) + .word __irq_svc @ 3 (SVC_26 / SVC_32) + .word __irq_invalid @ 4 + .word __irq_invalid @ 5 + .word __irq_invalid @ 6 + .word __irq_invalid @ 7 + .word __irq_invalid @ 8 + .word __irq_invalid @ 9 + .word __irq_invalid @ a + .word __irq_invalid @ b + .word __irq_invalid @ c + .word __irq_invalid @ d + .word __irq_invalid @ e + .word __irq_invalid @ f + + .align 5 + /* * Data abort dispatcher - dispatches it to the correct handler for the processor mode * Enter in ABT mode, spsr = USR CPSR, lr = USR PC @@ -761,15 +758,31 @@ vector_data: @ @ @ now branch to the relevent MODE handling routine @ - bic r13, lr, #63 - orr r13, r13, #0x93 - msr spsr, r13 @ switch to SVC_32 mode + msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode and lr, lr, #15 - adr r13, .LCtab_dabt - ldr lr, [r13, lr, lsl #2] + ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches +.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32) + .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32) + .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32) + .word __dabt_svc @ 3 (SVC_26 / SVC_32) + .word __dabt_invalid @ 4 + .word __dabt_invalid @ 5 + .word __dabt_invalid @ 6 + .word __dabt_invalid @ 7 + .word __dabt_invalid @ 8 + .word __dabt_invalid @ 9 + .word __dabt_invalid @ a + .word __dabt_invalid @ b + .word __dabt_invalid @ c + .word __dabt_invalid @ d + .word __dabt_invalid @ e + .word __dabt_invalid @ f + + .align 5 + /* * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode * Enter in ABT mode, spsr = USR CPSR, lr = USR PC @@ -786,15 +799,18 @@ vector_prefetch: @ @ now branch to the relevent MODE handling routine @ - bic r13, lr, #63 - orr r13, r13, #0x93 - msr spsr, r13 @ switch to SVC_32 mode + msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode ands lr, lr, #15 ldreq lr, .LCtab_pabt ldrne lr, .LCtab_pabt + 4 movs pc, lr +.LCtab_pabt: .word __pabt_usr + .word __pabt_invalid + + .align 5 + /* * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC @@ -810,15 +826,31 @@ vector_undefinstr: @ @ now branch to the relevent MODE handling routine @ - bic r13, lr, #63 - orr r13, r13, #0x93 - msr spsr, r13 @ switch to SVC_32 mode + msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode and lr, lr, #15 - adr r13, .LCtab_und - ldr lr, [r13, lr, lsl #2] + ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches +.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32) + .word __und_invalid @ 1 (FIQ_26 / FIQ_32) + .word __und_invalid @ 2 (IRQ_26 / IRQ_32) + .word __und_svc @ 3 (SVC_26 / SVC_32) + .word __und_invalid @ 4 + .word __und_invalid @ 5 + .word __und_invalid @ 6 + .word __und_invalid @ 7 + .word __und_invalid @ 8 + .word __und_invalid @ 9 + .word __und_invalid @ a + .word __und_invalid @ b + .word __und_invalid @ c + .word __und_invalid @ d + .word __und_invalid @ e + .word __und_invalid @ f + + .align 5 + /*============================================================================= * Undefined FIQs *----------------------------------------------------------------------------- @@ -848,60 +880,6 @@ vector_addrexcptn: */ .align 5 -.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32) - .word __irq_invalid @ 1 (FIQ_26 / FIQ_32) - .word __irq_invalid @ 2 (IRQ_26 / IRQ_32) - .word __irq_svc @ 3 (SVC_26 / SVC_32) - .word __irq_invalid @ 4 - .word __irq_invalid @ 5 - .word __irq_invalid @ 6 - .word __irq_invalid @ 7 - .word __irq_invalid @ 8 - .word __irq_invalid @ 9 - .word __irq_invalid @ a - .word __irq_invalid @ b - .word __irq_invalid @ c - .word __irq_invalid @ d - .word __irq_invalid @ e - .word __irq_invalid @ f - -.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32) - .word __und_invalid @ 1 (FIQ_26 / FIQ_32) - .word __und_invalid @ 2 (IRQ_26 / IRQ_32) - .word __und_svc @ 3 (SVC_26 / SVC_32) - .word __und_invalid @ 4 - .word __und_invalid @ 5 - .word __und_invalid @ 6 - .word __und_invalid @ 7 - .word __und_invalid @ 8 - .word __und_invalid @ 9 - .word __und_invalid @ a - .word __und_invalid @ b - .word __und_invalid @ c - .word __und_invalid @ d - .word __und_invalid @ e - .word __und_invalid @ f - -.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32) - .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32) - .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32) - .word __dabt_svc @ 3 (SVC_26 / SVC_32) - .word __dabt_invalid @ 4 - .word __dabt_invalid @ 5 - .word __dabt_invalid @ 6 - .word __dabt_invalid @ 7 - .word __dabt_invalid @ 8 - .word __dabt_invalid @ 9 - .word __dabt_invalid @ a - .word __dabt_invalid @ b - .word __dabt_invalid @ c - .word __dabt_invalid @ d - .word __dabt_invalid @ e - .word __dabt_invalid @ f - -.LCtab_pabt: .word __pabt_usr - .word __pabt_invalid - .LCvswi: .word vector_swi .LCsirq: .word __temp_irq @@ -921,7 +899,7 @@ __stubs_end: b __real_stubs_start + (vector_IRQ - __stubs_start) b __real_stubs_start + (vector_FIQ - __stubs_start) -ENTRY(trap_init) +ENTRY(__trap_init) stmfd sp!, {r4 - r6, lr} adr r1, .LCvectors @ set up the vectors diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 7a16832c7..6597de184 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -42,7 +42,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S index 16436684e..2996d89af 100644 --- a/arch/arm/kernel/head-armv.S +++ b/arch/arm/kernel/head-armv.S @@ -189,6 +189,7 @@ __create_page_tables: str r3, [r0], #4 add r3, r3, #1 << 20 str r3, [r0], #4 +1: #endif #endif #ifdef CONFIG_ARCH_RPC diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c index 117011e1d..e06c8092d 100644 --- a/arch/arm/kernel/hw-footbridge.c +++ b/arch/arm/kernel/hw-footbridge.c @@ -678,6 +678,7 @@ void __init hw_init(void) */ if (machine_is_netwinder()) { unsigned long flags; + extern int isapnp_disable; wb977_init(); cpld_init(); @@ -686,6 +687,15 @@ void __init hw_init(void) spin_lock_irqsave(&gpio_lock, flags); gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS); spin_unlock_irqrestore(&gpio_lock, flags); + +#ifdef CONFIG_ISAPNP + /* + * We must not use the kernels ISAPnP code + * on the NetWinder - it will reset the settings + * for the WaveArtist chip and render it inoperable. + */ + isapnp_disable = 1; +#endif } #endif #ifdef CONFIG_CATS diff --git a/arch/arm/kernel/ioport.c b/arch/arm/kernel/ioport.c index d40ea1cf1..07a52ba8e 100644 --- a/arch/arm/kernel/ioport.c +++ b/arch/arm/kernel/ioport.c @@ -4,6 +4,7 @@ * IO permission support for ARM. */ +#include #include #include #include diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3c82ee68c..9afacbde3 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -5,10 +5,6 @@ * Origional Copyright (C) 1995 Linus Torvalds */ -/* - * This file handles the architecture-dependent parts of process handling.. - */ - #include #include @@ -39,7 +35,7 @@ extern char *processor_modes[]; asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); -static int hlt_counter=0; +static int hlt_counter; void disable_hlt(void) { @@ -51,6 +47,21 @@ void enable_hlt(void) hlt_counter--; } +static int __init nohlt_setup(char *__unused) +{ + hlt_counter = 1; + return 0; +} + +static int __init hlt_setup(char *__unused) +{ + hlt_counter = 0; + return 0; +} + +__setup("nohlt", nohlt_setup); +__setup("hlt", hlt_setup); + /* * The idle loop on an ARM... */ @@ -91,8 +102,9 @@ void machine_restart(char * __unused) arch_reset(reboot_mode); + mdelay(1000); printk("Reboot failed -- System halted\n"); - + cli(); while (1); } @@ -110,18 +122,18 @@ void show_regs(struct pt_regs * regs) flags = condition_codes(regs); - printk( "pc : [<%08lx>] lr : [<%08lx>]\n" - "sp : %08lx ip : %08lx fp : %08lx\n", + printk("pc : [<%08lx>] lr : [<%08lx>]\n" + "sp : %08lx ip : %08lx fp : %08lx\n", instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); - printk( "r10: %08lx r9 : %08lx r8 : %08lx\n", + printk("r10: %08lx r9 : %08lx r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); - printk( "r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); - printk( "r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); printk("Flags: %c%c%c%c", @@ -179,62 +191,51 @@ void show_fpregs(struct user_fp *regs) /* * Task structure and kernel stack allocation. - * - * Taken from the i386 version. */ +static struct task_struct *task_struct_head; +static unsigned int nr_task_struct; + #ifdef CONFIG_CPU_32 -#define EXTRA_TASK_STRUCT 8 -static struct task_struct *task_struct_stack[EXTRA_TASK_STRUCT]; -static int task_struct_stack_ptr = -1; +#define EXTRA_TASK_STRUCT 4 +#else +#define EXTRA_TASK_STRUCT 0 #endif struct task_struct *alloc_task_struct(void) { struct task_struct *tsk; -#ifndef EXTRA_TASK_STRUCT - tsk = ll_alloc_task_struct(); -#else - int index; - - index = task_struct_stack_ptr; - if (index >= EXTRA_TASK_STRUCT/2) - goto use_cache; - - tsk = ll_alloc_task_struct(); + if (EXTRA_TASK_STRUCT) + tsk = task_struct_head; + else + tsk = NULL; - if (!tsk) { - index = task_struct_stack_ptr; + if (tsk) { + task_struct_head = tsk->next_task; + nr_task_struct -= 1; + } else + tsk = ll_alloc_task_struct(); - if (index >= 0) { -use_cache: tsk = task_struct_stack[index]; - task_struct_stack_ptr = index - 1; - } - } -#endif #ifdef CONFIG_SYSRQ - /* You need this if you want SYSRQ-T to give sensible stack - * usage information + /* + * The stack must be cleared if you want SYSRQ-T to + * give sensible stack usage information */ if (tsk) { char *p = (char *)tsk; memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); } #endif - return tsk; } -void free_task_struct(struct task_struct *p) +void __free_task_struct(struct task_struct *p) { -#ifdef EXTRA_TASK_STRUCT - int index = task_struct_stack_ptr + 1; - - if (index < EXTRA_TASK_STRUCT) { - task_struct_stack[index] = p; - task_struct_stack_ptr = index; + if (EXTRA_TASK_STRUCT && nr_task_struct < EXTRA_TASK_STRUCT) { + p->next_task = task_struct_head; + task_struct_head = p; + nr_task_struct += 1; } else -#endif ll_free_task_struct(p); } @@ -263,6 +264,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, struct pt_regs * childregs; struct context_save_struct * save; + atomic_set(&p->thread.refcount, 1); + childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1; *childregs = *regs; childregs->ARM_r0 = 0; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 340700dbe..a060bf4d9 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -3,12 +3,6 @@ * * Copyright (C) 1995-1999 Russell King */ - -/* - * This file obtains various parameters about the system that the kernel - * is running on. - */ - #include #include #include @@ -37,11 +31,7 @@ #define CONFIG_CMDLINE "" #endif -#ifndef PARAMS_BASE -#define PARAMS_BASE NULL -#endif - -extern void reboot_setup(char *str, int *ints); +extern void reboot_setup(char *str); extern void disable_hlt(void); extern int root_mountflags; extern int _stext, _text, _etext, _edata, _end; @@ -61,6 +51,20 @@ unsigned int number_mfm_drives; struct meminfo meminfo; +struct machine_desc { + const char *name; /* architecture name */ + unsigned int param_offset; /* parameter page */ + unsigned int reserve_lp0 :1; /* never has lp0 */ + unsigned int reserve_lp1 :1; /* never has lp1 */ + unsigned int reserve_lp2 :1; /* never has lp2 */ + unsigned int broken_hlt :1; /* hlt is broken */ + unsigned int soft_reboot :1; /* soft reboot */ + unsigned int video_start; /* start of video RAM */ + unsigned int video_end; /* end of video RAM */ + void (*fixup)(struct machine_desc *, + struct param_struct *, char **); +}; + #ifdef MULTI_CPU struct processor processor; #endif @@ -81,6 +85,7 @@ char elf_platform[ELF_PLATFORM_SIZE]; char saved_command_line[COMMAND_LINE_SIZE]; static struct proc_info_item proc_info; +static const char *machine_name; static char command_line[COMMAND_LINE_SIZE] = { 0, }; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; @@ -91,16 +96,14 @@ static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', ' * Standard memory resources */ static struct resource mem_res[] = { - { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY }, { "Video RAM", 0, 0, IORESOURCE_MEM }, { "Kernel code", 0, 0, IORESOURCE_MEM }, { "Kernel data", 0, 0, IORESOURCE_MEM } }; -#define system_ram mem_res[0] -#define video_ram mem_res[1] -#define kernel_code mem_res[2] -#define kernel_data mem_res[3] +#define video_ram mem_res[0] +#define kernel_code mem_res[1] +#define kernel_data mem_res[2] static struct resource io_res[] = { { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, @@ -140,6 +143,10 @@ static void __init setup_processor(void) #ifdef MULTI_CPU processor = *list->proc; + + printk("Processor: %s %s revision %d\n", + proc_info.manufacturer, proc_info.cpu_name, + (int)processor_id & 15); #endif sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); @@ -218,10 +225,7 @@ static void __init setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) { #ifdef CONFIG_BLK_DEV_RAM - extern int rd_doload; - extern int rd_prompt; - extern int rd_image_start; - extern int rd_size; + extern int rd_doload, rd_prompt, rd_image_start, rd_size; rd_image_start = image_start; rd_prompt = prompt; @@ -245,133 +249,205 @@ static void __init setup_initrd(unsigned int start, unsigned int size) #endif } +#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define P_PFN_DOWN(x) O_PFN_DOWN((x) - PHYS_OFFSET) +#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) + +#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) +#define P_PFN_UP(x) O_PFN_UP((x) - PHYS_OFFSET) +#define V_PFN_UP(x) O_PFN_UP(__pa(x)) + +#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) +#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ + (((unsigned long)(s)) & PAGE_MASK)) + +#define free_bootmem(s,sz) free_bootmem((s)< (meminfo.end + PHYS_OFFSET)) { + printk ("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx) - disabling initrd\n", + __pa(initrd_end), meminfo.end + PHYS_OFFSET); + initrd_start = 0; + initrd_end = 0; + } + } +#endif + + for (bank = 0; bank < meminfo.nr_banks; bank ++) { + unsigned int start, end; + + if (meminfo.bank[bank].size == 0) + continue; + + start = O_PFN_UP(meminfo.bank[bank].start); + end = O_PFN_DOWN(meminfo.bank[bank].size + + meminfo.bank[bank].start); + + if (end < start_pfn) + continue; + + if (start < start_pfn) + start = start_pfn; + + if (end <= start) + continue; + + if (end - start >= bootmap_pages) { + bootmap_pfn = start; + break; + } + } + + if (bootmap_pfn == 0) + BUG(); + + return bootmap_pfn; +} + /* - * Work out our memory regions. Note that "pfn" is the physical page number - * relative to the first physical page, not the physical address itself. + * Initialise the bootmem allocator. */ static void __init setup_bootmem(void) { - unsigned int end_pfn, bootmem_end; - int bank; + unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn; + unsigned int i; /* - * Calculate the end of memory. + * Calculate the physical address of the top of memory. */ - for (bank = 0; bank < meminfo.nr_banks; bank++) { - if (meminfo.bank[bank].size) { - unsigned long end; + meminfo.end = 0; + for (i = 0; i < meminfo.nr_banks; i++) { + unsigned long end; - end = meminfo.bank[bank].start + - meminfo.bank[bank].size; + if (meminfo.bank[i].size != 0) { + end = meminfo.bank[i].start + meminfo.bank[i].size; if (meminfo.end < end) meminfo.end = end; } } - bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end)); - end_pfn = meminfo.end >> PAGE_SHIFT; + start_pfn = O_PFN_UP(PHYS_OFFSET); + end_pfn = O_PFN_DOWN(meminfo.end); + bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); + bootmap_pfn = find_bootmap_pfn(bootmap_pages); /* * Initialise the boot-time allocator */ - bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn); + init_bootmem_start(bootmap_pfn, start_pfn, end_pfn); /* * Register all available RAM with the bootmem allocator. - * The address is relative to the start of physical memory. */ - for (bank = 0; bank < meminfo.nr_banks; bank ++) - free_bootmem(meminfo.bank[bank].start, meminfo.bank[bank].size); + for (i = 0; i < meminfo.nr_banks; i++) + if (meminfo.bank[i].size) + free_bootmem(O_PFN_UP(meminfo.bank[i].start), + PFN_SIZE(meminfo.bank[i].size)); /* - * reserve the following regions: - * physical page 0 - it contains the exception vectors - * kernel and the bootmem structure - * swapper page directory (if any) - * initrd (if any) + * Register the reserved regions with bootmem */ - reserve_bootmem(0, PAGE_SIZE); + reserve_bootmem(bootmap_pfn, bootmap_pages); + reserve_bootmem(V_PFN_DOWN(&_stext), PFN_RANGE(&_stext, &_end)); + #ifdef CONFIG_CPU_32 - reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *)); + /* + * Reserve the page tables. These are already in use. + */ + reserve_bootmem(V_PFN_DOWN(swapper_pg_dir), + PFN_SIZE(PTRS_PER_PGD * sizeof(void *))); #endif - reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext)); #ifdef CONFIG_BLK_DEV_INITRD - if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) { - printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08x) - disabling initrd\n", - __pa(initrd_end), end_pfn << PAGE_SHIFT); - initrd_start = 0; - } - if (initrd_start) - reserve_bootmem(__pa(initrd_start), - initrd_end - initrd_start); + reserve_bootmem(O_PFN_DOWN(initrd_start), + PFN_RANGE(initrd_start, initrd_end)); #endif } -static void __init request_standard_resources(void) +static void __init request_standard_resources(struct machine_desc *mdesc) { - kernel_code.start = __virt_to_bus((unsigned long) &_text); - kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1); - kernel_data.start = __virt_to_bus((unsigned long) &_etext); - kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1); - system_ram.start = __virt_to_bus(PAGE_OFFSET); - system_ram.end = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1); - - request_resource(&iomem_resource, &system_ram); - request_resource(&system_ram, &kernel_code); - request_resource(&system_ram, &kernel_data); - - if (video_ram.start != video_ram.end) + struct resource *res; + int i; + + kernel_code.start = __virt_to_bus(init_mm.start_code); + kernel_code.end = __virt_to_bus(init_mm.end_code - 1); + kernel_data.start = __virt_to_bus(init_mm.end_code); + kernel_data.end = __virt_to_bus(init_mm.brk - 1); + + for (i = 0; i < meminfo.nr_banks; i++) { + unsigned long virt_start, virt_end; + + if (meminfo.bank[i].size == 0) + continue; + + virt_start = __phys_to_virt(meminfo.bank[i].start); + virt_end = virt_start + meminfo.bank[i].size - 1; + + res = alloc_bootmem_low(sizeof(*res)); + res->name = "System RAM"; + res->start = __virt_to_bus(virt_start); + res->end = __virt_to_bus(virt_end); + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + request_resource(&iomem_resource, res); + + if (kernel_code.start >= res->start && + kernel_code.end <= res->end) + request_resource(res, &kernel_code); + if (kernel_data.start >= res->start && + kernel_data.end <= res->end) + request_resource(res, &kernel_data); + } + + if (mdesc->video_start) { + video_ram.start = mdesc->video_start; + video_ram.end = mdesc->video_end; request_resource(&iomem_resource, &video_ram); + } /* * Some machines don't have the possibility of ever - * possessing LPT1 (lp0) and LPT3 (lp2) + * possessing lp0, lp1 or lp2 */ - if (machine_is_ebsa110() || machine_is_riscpc() || - machine_is_netwinder()) + if (mdesc->reserve_lp0) request_resource(&ioport_resource, &lp0); - if (machine_is_riscpc()) + if (mdesc->reserve_lp1) request_resource(&ioport_resource, &lp1); - if (machine_is_ebsa110() || machine_is_netwinder()) + if (mdesc->reserve_lp2) request_resource(&ioport_resource, &lp2); } -void __init setup_arch(char **cmdline_p) +/* + * Architecture specific fixups. This is where any + * parameters in the params struct are fixed up, or + * any additional architecture specific information + * is pulled from the params struct. + */ +static void __init +fixup_acorn(struct machine_desc *desc, struct param_struct *params, + char **cmdline) { - struct param_struct *params = (struct param_struct *)PARAMS_BASE; - char *from = default_command_line; - -#if defined(CONFIG_ARCH_ARC) - __machine_arch_type = MACH_TYPE_ARCHIMEDES; -#elif defined(CONFIG_ARCH_A5K) - __machine_arch_type = MACH_TYPE_A5K; -#endif - - setup_processor(); - - /* - * Defaults - */ - ROOT_DEV = MKDEV(0, 255); - setup_ramdisk(1, 1, 0, 0); - - /* - * Add your machine dependencies here - */ - switch (machine_arch_type) { - case MACH_TYPE_EBSA110: - /* EBSA110 locks if we execute 'wait for interrupt' */ - disable_hlt(); - if (params && params->u1.s.page_size != PAGE_SIZE) - params = NULL; - break; - #ifdef CONFIG_ARCH_ACORN -#ifdef CONFIG_ARCH_RPC - case MACH_TYPE_RISCPC: - /* RiscPC can't handle half-word loads and stores */ + int i; + + if (machine_is_riscpc()) { + /* + * RiscPC can't handle half-word loads and stores + */ elf_hwcap &= ~HWCAP_HALF; switch (params->u1.s.pages_in_vram) { @@ -382,106 +458,219 @@ void __init setup_arch(char **cmdline_p) default: break; } - { - int i; - - for (i = 0; i < 4; i++) { - meminfo.bank[i].start = i << 26; - meminfo.bank[i].size = - params->u1.s.pages_in_bank[i] * - params->u1.s.page_size; - } - meminfo.nr_banks = 4; + + if (vram_size) { + desc->video_start = 0x02000000; + desc->video_end = 0x02000000 + vram_size; } -#endif - case MACH_TYPE_ARCHIMEDES: - case MACH_TYPE_A5K: - memc_ctrl_reg = params->u1.s.memc_control_reg; - number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; - break; -#endif - case MACH_TYPE_EBSA285: - if (params) { - ORIG_X = params->u1.s.video_x; - ORIG_Y = params->u1.s.video_y; - ORIG_VIDEO_COLS = params->u1.s.video_num_cols; - ORIG_VIDEO_LINES = params->u1.s.video_num_rows; - video_ram.start = 0x0a0000; - video_ram.end = 0x0bffff; + for (i = 0; i < 4; i++) { + meminfo.bank[i].start = PHYS_OFFSET + (i << 26); + meminfo.bank[i].size = + params->u1.s.pages_in_bank[i] * + params->u1.s.page_size; } - break; + meminfo.nr_banks = 4; + } + memc_ctrl_reg = params->u1.s.memc_control_reg; + number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; +#endif +} - case MACH_TYPE_CO285: - { +static void __init +fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline) +{ + ORIG_X = params->u1.s.video_x; + ORIG_Y = params->u1.s.video_y; + ORIG_VIDEO_COLS = params->u1.s.video_num_cols; + ORIG_VIDEO_LINES = params->u1.s.video_num_rows; +} + +/* + * Older NeTTroms either do not provide a parameters + * page, or they don't supply correct information in + * the parameter page. + */ +static void __init +fixup_netwinder(struct machine_desc *desc, struct param_struct *params, + char **cmdline) +{ + if (params->u1.s.nr_pages != 0x2000 && + params->u1.s.nr_pages != 0x4000) { + printk(KERN_WARNING "Warning: bad NeTTrom parameters " + "detected, using defaults\n"); + + params->u1.s.nr_pages = 0x2000; /* 32MB */ + params->u1.s.ramdisk_size = 0; + params->u1.s.flags = FLAG_READONLY; + params->u1.s.initrd_start = 0; + params->u1.s.initrd_size = 0; + params->u1.s.rd_start = 0; + } +} + +/* + * CATS uses soft-reboot by default, since + * hard reboots fail on early boards. + */ +static void __init +fixup_cats(struct machine_desc *desc, struct param_struct *params, + char **cmdline) +{ + ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_POINTS = 16; + ORIG_Y = 24; +} + +static void __init +fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline) +{ #if 0 - extern unsigned long boot_memory_end; - extern char boot_command_line[]; + if (machine_is_co285()) { + extern unsigned long boot_memory_end; + extern char boot_command_line[]; - from = boot_command_line; - memory_end = boot_memory_end; -#endif - params = NULL; - } - break; + meminfo.nr_banks = 1; + meminfo.bank[0].start = PHYS_OFFSET; + meminfo.bank[0].size = boot_memory_end; - case MACH_TYPE_CATS: - /* CATS uses soft-reboot by default, since hard reboots - * fail on early boards. - */ - reboot_setup("s", NULL); - params = NULL; - ORIG_VIDEO_LINES = 25; - ORIG_VIDEO_POINTS = 16; - ORIG_Y = 24; - video_ram.start = 0x0a0000; - video_ram.end = 0x0bffff; - break; + *cmdline = boot_command_line; + } +#endif +} - case MACH_TYPE_NETWINDER: - /* - * to be fixed in a future NeTTrom - */ - if (params->u1.s.page_size == PAGE_SIZE) { - if (params->u1.s.nr_pages != 0x2000 && - params->u1.s.nr_pages != 0x4000) { - printk("Warning: bad NeTTrom parameters detected, using defaults\n"); - /* - * This stuff doesn't appear to be initialised - * properly by NeTTrom 2.0.6 and 2.0.7 - */ - params->u1.s.nr_pages = 0x2000; /* 32MB */ - params->u1.s.ramdisk_size = 0; - params->u1.s.flags = FLAG_READONLY; - params->u1.s.initrd_start = 0; - params->u1.s.initrd_size = 0; - params->u1.s.rd_start = 0; - } - } else { - printk("Warning: no NeTTrom parameter page detected, using " - "compiled-in settings\n"); - params = NULL; - } - video_ram.start = 0x0a0000; - video_ram.end = 0x0bffff; - break; +#define NO_PARAMS 0 +#define NO_VIDEO 0, 0 - default: - break; +/* + * This is the list of all architectures supported by + * this kernel. This should be integrated with the list + * in head-armv.S. + */ +static struct machine_desc machine_desc[] __initdata = { + { "EBSA110", /* RMK */ + 0x00000400, + NO_VIDEO, + 1, 0, 1, 1, 1, + NULL + }, { "Acorn-RiscPC", /* RMK */ + 0x10000100, + NO_VIDEO, + 1, 1, 0, 0, 0, + fixup_acorn + }, { "unknown", + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "Nexus-FTV/PCI", /* Philip Blundell */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "EBSA285", /* RMK */ + 0x00000100, + 0x000a0000, 0x000bffff, + 0, 0, 0, 0, 0, + fixup_ebsa285 + }, { "Rebel-NetWinder", /* RMK */ + 0x00000100, + 0x000a0000, 0x000bffff, + 1, 0, 1, 0, 0, + fixup_netwinder + }, { "Chalice-CATS", /* Philip Blundell */ + NO_PARAMS, + 0x000a0000, 0x000bffff, + 0, 0, 0, 0, 1, + fixup_cats + }, { "unknown-TBOX", /* Philip Blundell */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "co-EBSA285", /* Mark van Doesburg */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + fixup_coebsa285 + }, { "CL-PS7110", /* Werner Almesberger */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "Acorn-Archimedes",/* RMK/DAG */ + 0x0207c000, + NO_VIDEO, + 0, 0, 0, 0, 0, + fixup_acorn + }, { "Acorn-A5000", /* RMK/PB */ + 0x0207c000, + NO_VIDEO, + 0, 0, 0, 0, 0, + fixup_acorn + }, { "Etoile", /* Alex de Vries */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "LaCie_NAS", /* Benjamin Herrenschmidt */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "CL-PS7500", /* Philip Blundell */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL + }, { "Shark", /* Alexander Schulz */ + NO_PARAMS, + NO_VIDEO, + 0, 0, 0, 0, 0, + NULL } +}; + +void __init setup_arch(char **cmdline_p) +{ + struct param_struct *params = NULL; + struct machine_desc *mdesc; + char *from = default_command_line; + +#if defined(CONFIG_ARCH_ARC) + __machine_arch_type = MACH_TYPE_ARCHIMEDES; +#elif defined(CONFIG_ARCH_A5K) + __machine_arch_type = MACH_TYPE_A5K; +#endif + + setup_processor(); + + ROOT_DEV = MKDEV(0, 255); + + mdesc = machine_desc + machine_arch_type; + machine_name = mdesc->name; + + if (mdesc->broken_hlt) + disable_hlt(); + + if (mdesc->soft_reboot) + reboot_setup("s"); + + if (mdesc->param_offset) + params = phys_to_virt(mdesc->param_offset); + + if (mdesc->fixup) + mdesc->fixup(mdesc, params, &from); if (params && params->u1.s.page_size != PAGE_SIZE) { - printk("Warning: wrong page size configuration, " + printk(KERN_WARNING "Warning: bad configuration page, " "trying to continue\n"); params = NULL; } if (params) { - if (meminfo.nr_banks == 0) { - meminfo.nr_banks = 1; - meminfo.bank[0].start = 0; - meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT; - } ROOT_DEV = to_kdev_t(params->u1.s.rootdev); system_rev = params->u1.s.system_rev; system_serial_low = params->u1.s.system_serial_low; @@ -503,8 +692,11 @@ void __init setup_arch(char **cmdline_p) if (meminfo.nr_banks == 0) { meminfo.nr_banks = 1; - meminfo.bank[0].start = 0; - meminfo.bank[0].size = MEM_SIZE; + meminfo.bank[0].start = PHYS_OFFSET; + if (params) + meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT; + else + meminfo.bank[0].size = MEM_SIZE; } init_mm.start_code = (unsigned long) &_text; @@ -512,12 +704,11 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, from, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; parse_cmdline(cmdline_p, from); setup_bootmem(); - request_standard_resources(); + request_standard_resources(mdesc); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) @@ -528,26 +719,6 @@ void __init setup_arch(char **cmdline_p) #endif } -static const char *machine_desc[] = { - /* Machine name Allocater */ - "EBSA110", /* RMK */ - "Acorn-RiscPC", /* RMK */ - "unknown", - "Nexus-FTV/PCI", /* Philip Blundell */ - "EBSA285", /* RMK */ - "Rebel-NetWinder", /* RMK */ - "Chalice-CATS", /* Philip Blundell */ - "unknown-TBOX", /* Philip Blundell */ - "co-EBSA285", /* Mark van Doesburg */ - "CL-PS7110", /* Werner Almesberger */ - "Acorn-Archimedes", /* RMK/DAG */ - "Acorn-A5000", /* RMK/PB */ - "Etoile", /* Alex de Vries */ - "LaCie_NAS", /* Benjamin Herrenschmidt */ - "CL-PS7500", /* Philip Blundell */ - "Shark" /* Alexander Schulz */ -}; - int get_cpuinfo(char * buffer) { char *p = buffer; @@ -560,8 +731,7 @@ int get_cpuinfo(char * buffer) (loops_per_sec+2500) / 500000, ((loops_per_sec+2500) / 5000) % 100); - p += sprintf(p, "Hardware\t: %s\n", - machine_desc[machine_arch_type]); + p += sprintf(p, "Hardware\t: %s\n", machine_name); p += sprintf(p, "Revision\t: %04x\n", system_rev); diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 3f86f4740..852bbfac1 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -21,7 +21,7 @@ #include #include -#include +#include #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -545,6 +545,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) case SIGQUIT: case SIGILL: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: if (do_coredump(signr, regs)) exit_code |= 0x80; /* FALLTHRU */ diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index f25544c14..408149bc5 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -49,6 +49,36 @@ asmlinkage int sys_pipe(unsigned long * fildes) return error; } +/* common code for old and new mmaps */ +static inline long do_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down(¤t->mm->mmap_sem); + lock_kernel(); + + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + + unlock_kernel(); + up(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + /* * Perform the select(nd, in, out, ex, tv) and mmap() system * calls. ARM Linux didn't use to be able to handle more than @@ -68,30 +98,20 @@ struct mmap_arg_struct { asmlinkage int old_mmap(struct mmap_arg_struct *arg) { int error = -EFAULT; - struct file * file = NULL; struct mmap_arg_struct a; - down(¤t->mm->mmap_sem); - lock_kernel(); if (copy_from_user(&a, arg, sizeof(a))) + goto out;; + + error = -EINVAL; + if (a.offset & ~PAGE_MASK) goto out; - if (!(a.flags & MAP_ANONYMOUS)) { - error = -EBADF; - file = fget(a.fd); - if (!file) - goto out; - } - a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset); - if (file) - fput(file); + + error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); out: - unlock_kernel(); - up(¤t->mm->mmap_sem); return error; } - extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); struct sel_arg_struct { @@ -119,104 +139,73 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, { int version, ret; - lock_kernel(); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; - if (call <= SEMCTL) - switch (call) { - case SEMOP: - ret = sys_semop (first, (struct sembuf *)ptr, second); - goto out; - case SEMGET: - ret = sys_semget (first, second, third); - goto out; - case SEMCTL: { - union semun fourth; - ret = -EINVAL; + switch (call) { + case SEMOP: + return sys_semop (first, (struct sembuf *)ptr, second); + case SEMGET: + return sys_semget (first, second, third); + case SEMCTL: { + union semun fourth; + if (!ptr) + return -EINVAL; + if (get_user(fourth.__pad, (void **) ptr)) + return -EFAULT; + return sys_semctl (first, second, third, fourth); + } + + case MSGSND: + return sys_msgsnd (first, (struct msgbuf *) ptr, + second, third); + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; if (!ptr) - goto out; - ret = -EFAULT; - if (get_user(fourth.__pad, (void **) ptr)) - goto out; - ret = sys_semctl (first, second, third, fourth); - goto out; - } - default: - ret = -EINVAL; - goto out; + return -EINVAL; + if (copy_from_user(&tmp,(struct ipc_kludge *) ptr, + sizeof (tmp))) + return -EFAULT; + return sys_msgrcv (first, tmp.msgp, second, + tmp.msgtyp, third); } - if (call <= MSGCTL) - switch (call) { - case MSGSND: - ret = sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); - goto out; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - ret = -EINVAL; - if (!ptr) - goto out; - ret = -EFAULT; - if (copy_from_user(&tmp,(struct ipc_kludge *) ptr, - sizeof (tmp))) - goto out; - ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); - goto out; - } - case 1: default: - ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); - goto out; - } - case MSGGET: - ret = sys_msgget ((key_t) first, second); - goto out; - case MSGCTL: - ret = sys_msgctl (first, second, (struct msqid_ds *) ptr); - goto out; default: - ret = -EINVAL; - goto out; + return sys_msgrcv (first, + (struct msgbuf *) ptr, + second, fifth, third); } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - case 0: default: { - ulong raddr; - ret = sys_shmat (first, (char *) ptr, second, &raddr); - if (ret) - goto out; - ret = put_user (raddr, (ulong *) third); - goto out; - } - case 1: /* iBCS2 emulator entry point */ - ret = -EINVAL; - if (!segment_eq(get_fs(), get_ds())) - goto out; - ret = sys_shmat (first, (char *) ptr, second, (ulong *) third); - goto out; - } - case SHMDT: - ret = sys_shmdt ((char *)ptr); - goto out; - case SHMGET: - ret = sys_shmget (first, second, third); - goto out; - case SHMCTL: - ret = sys_shmctl (first, second, (struct shmid_ds *) ptr); - goto out; - default: - ret = -EINVAL; - goto out; + case MSGGET: + return sys_msgget ((key_t) first, second); + case MSGCTL: + return sys_msgctl (first, second, (struct msqid_ds *) ptr); + + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = sys_shmat (first, (char *) ptr, second, &raddr); + if (ret) + return ret; + return put_user (raddr, (ulong *) third); } - else - ret = -EINVAL; -out: - unlock_kernel(); - return ret; + case 1: /* iBCS2 emulator entry point */ + if (!segment_eq(get_fs(), get_ds())) + return -EINVAL; + return sys_shmat (first, (char *) ptr, + second, (ulong *) third); + } + case SHMDT: + return sys_shmdt ((char *)ptr); + case SHMGET: + return sys_shmget (first, second, third); + case SHMCTL: + return sys_shmctl (first, second, + (struct shmid_ds *) ptr); + default: + return -EINVAL; + } } /* Fork a new task - this creates a new program thread. diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 038946e9c..26ecfa194 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,7 @@ static void dump_instr(unsigned long pc, int user) printk ("pc not in code space\n"); } -spinlock_t die_lock; +spinlock_t die_lock = SPIN_LOCK_UNLOCKED; /* * This function is protected against re-entrancy. @@ -423,3 +424,13 @@ asmlinkage void __div0(void) printk("Division by zero in kernel.\n"); __backtrace(); } + +void __init trap_init(void) +{ + extern void __trap_init(void); + + __trap_init(); +#ifdef CONFIG_CPU_32 + modify_domain(DOMAIN_USER, DOMAIN_CLIENT); +#endif +} diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index fd85107c3..e871f2615 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -83,28 +83,34 @@ ENTRY(c_backtrace) #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 mov reg, #9 - + mov r7, #0 1: mov r3, #1 tst instr, r3, lsl reg beq 2f + add r7, r7, #1 + teq r7, #4 + moveq r7, #0 + moveq r3, #'\n' + movne r3, #' ' ldr r2, [stack], #-4 mov r1, reg adr r0, .Lfp bl SYMBOL_NAME(printk) 2: subs reg, reg, #1 bpl 1b - + teq r7, #0 + adrne r0, .Lcr + blne SYMBOL_NAME(printk) mov r0, stack - LOADREGS(fd, sp!, {instr, reg, stack, pc}) + LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) -.Lfe: .ascii "Function entered at [<%p>] from [<%p>]\n" - .byte 0 -.Lfp: .ascii " r%d = %p\n" - .byte 0 +.Lfe: .asciz "Function entered at [<%p>] from [<%p>]\n" +.Lfp: .asciz " r%d = %08X%c" +.Lcr: .asciz "\n" .align .Ldsi: .word 0x00e92dd8 >> 2 .word 0x00e92d00 >> 2 diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 229b4dcd7..17972e427 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -168,6 +168,7 @@ void show_mem(void) void __init paging_init(void) { void *zero_page, *bad_page, *bad_table; + unsigned int zone_size[3]; #ifdef CONFIG_CPU_32 #define TABLE_OFFSET (PTRS_PER_PTE) @@ -189,7 +190,11 @@ void __init paging_init(void) pagetable_init(); flush_tlb_all(); - free_area_init(max_low_pfn); + /* + * Initialise the zones and mem_map + */ + zonesize_init(zone_size); + free_area_init(zone_size); /* * finish off the bad pages once @@ -235,22 +240,23 @@ static inline void free_unused_mem_map(void) */ void __init mem_init(void) { - int codepages = 0; - int reservedpages = 0; - int datapages = 0; - int initpages = 0, i, min_nr; + extern char __init_begin, __init_end, _text, _etext, _end; + unsigned int codepages, datapages, initpages; + int i; - max_mapnr = max_low_pfn; - high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); + codepages = &_etext - &_text; + datapages = &_end - &_etext; + initpages = &__init_end - &__init_begin; + + max_mapnr = max_low_pfn; + high_memory = (void *)__va(PHYS_OFFSET + max_low_pfn * PAGE_SIZE); -#ifdef CONFIG_CPU_32 /* * We may have non-contiguous memory. Setup the PageSkip stuff, * and mark the areas of mem_map which can be freed */ if (meminfo.nr_banks != 1) create_memmap_holes(); -#endif /* this will put all unused low memory onto the freelists */ totalram_pages += free_all_bootmem(); @@ -259,42 +265,28 @@ void __init mem_init(void) * Since our memory may not be contiguous, calculate the * real number of pages we have in this system */ + printk("Memory:"); + num_physpages = 0; - for (i = 0; i < meminfo.nr_banks; i++) + for (i = 0; i < meminfo.nr_banks; i++) { num_physpages += meminfo.bank[i].size >> PAGE_SHIFT; + printk(" %ldMB", meminfo.bank[i].size >> 20); + } - printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n", - (unsigned long) nr_free_pages << (PAGE_SHIFT-10), - num_physpages >> (20 - PAGE_SHIFT), - codepages << (PAGE_SHIFT-10), - reservedpages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10), - initpages << (PAGE_SHIFT-10)); + printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); + printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + codepages >> 10, datapages >> 10, initpages >> 10); - /* - * Correct freepages watermarks - */ - i = nr_free_pages >> 7; - if (PAGE_SIZE < 32768) - min_nr = 10; - else - min_nr = 2; - if (i < min_nr) - i = min_nr; - if (i > 256) - i = 256; - freepages.min = i; - freepages.low = i * 2; - freepages.high = i * 3; - -#ifdef CONFIG_CPU_26 - if (max_mapnr <= 128) { + if (PAGE_SIZE >= 16384 && num_physpages <= 128) { extern int sysctl_overcommit_memory; - /* On a machine this small we won't get anywhere without - overcommit, so turn it on by default. */ + /* + * On a machine this small we won't get + * anywhere without overcommit, so turn + * it on by default. + */ sysctl_overcommit_memory = 1; } -#endif } static inline void free_area(unsigned long addr, unsigned long end, char *s) @@ -344,11 +336,24 @@ void free_initmem(void) printk("\n"); } +#ifdef CONFIG_BLK_DEV_INITRD +void free_initrd_mem(unsigned long start, unsigned long end) +{ + for (; start < end; start += PAGE_SIZE) { + ClearPageReserved(mem_map + MAP_NR(start)); + set_page_count(mem_map+MAP_NR(start), 1); + free_page(start); + totalram_pages++; + } + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +} +#endif + void si_meminfo(struct sysinfo *val) { val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages; + val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); val->totalhigh = 0; val->freehigh = 0; diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 141644ae2..fb3007f8a 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, @@ -136,7 +136,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag /* * Ok, go for it.. */ - area = get_vm_area(size); + area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; addr = area->addr; diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h index 0a3ee8b4d..b596c6479 100644 --- a/arch/arm/mm/map.h +++ b/arch/arm/mm/map.h @@ -19,6 +19,7 @@ struct map_desc { extern struct map_desc io_desc[]; extern unsigned int io_desc_size; +extern void zonesize_init(unsigned int *); extern void create_memmap_holes(void); extern void pagetable_init(void); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index 5ee95ea45..680a52948 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -133,6 +134,20 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) return (pte_t *) pmd_page(*pmd) + offset; } +/* + * Calculate the size of the DMA, normal and highmem zones. + * On 26-bit ARMs, we don't have any real DMA or highmem, + * so we allocate the whole memory as being DMA-capable. + */ +void __init zonesize_init(unsigned int *zone_size) +{ + int i; + + zone_size[0] = max_low_pfn; + zone_size[1] = 0; + zone_size[2] = 0; +} + /* * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 * machine. This is both processor & architecture specific, and requires @@ -147,7 +162,6 @@ void __init pagetable_init(void) page_nr = max_low_pfn; pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); - memzero(pte, PTRS_PER_PTE * sizeof(pte_t)); pte[0] = mk_pte_phys(PAGE_OFFSET + 491520, PAGE_READONLY); set_pmd(pmd_offset(swapper_pg_dir, 0), mk_kernel_pmd(pte)); diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 3df6c13b5..ee4750c62 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,31 @@ extern unsigned long get_page_2k(int priority); extern void free_page_2k(unsigned long page); extern pte_t *get_bad_pte_table(void); +/* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static int __init nocache_setup(char *__unused) +{ + cr_alignment &= ~4; + cr_no_alignment &= ~4; + set_cr(cr_alignment); + return 1; +} + +static int __init nowrite_setup(char *__unused) +{ + cr_alignment &= ~(8|4); + cr_no_alignment &= ~(8|4); + set_cr(cr_alignment); + return 1; +} + +__setup("nocache", nocache_setup); +__setup("nowb", nowrite_setup); + /* * need to get a 16k page for level 1 */ @@ -178,7 +204,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot) pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); - memzero(ptep, 2 * PTRS_PER_PTE * sizeof(pte_t)); ptep += PTRS_PER_PTE; set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain))); @@ -266,6 +291,32 @@ static struct map_desc init_map[] __initdata = { #define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0])) +/* + * Calculate the size of the DMA, normal and highmem zones. + * On ARM, we don't have any problems with DMA, so all memory + * is allocated to the DMA zone. We also don't have any + * highmem either. + */ +void __init zonesize_init(unsigned int *zone_size) +{ + int i; + + zone_size[0] = 0; + zone_size[1] = 0; + zone_size[2] = 0; + + for (i = 0; i < meminfo.nr_banks; i++) { + if (meminfo.bank[i].size) { + unsigned int end; + + end = (meminfo.bank[i].start - PHYS_OFFSET + + meminfo.bank[i].size) >> PAGE_SHIFT; + if (end > zone_size[0]) + zone_size[0] = end; + } + } +} + void __init pagetable_init(void) { unsigned long address = 0; @@ -274,7 +325,7 @@ void __init pagetable_init(void) /* * Setup the above mappings */ - init_map[0].physical = PHYS_OFFSET; + init_map[0].physical = virt_to_phys(alloc_bootmem_low_pages(PAGE_SIZE)); init_map[5].physical = FLUSH_BASE_PHYS; init_map[5].virtual = FLUSH_BASE; #ifdef FLUSH_BASE_MINICACHE @@ -284,8 +335,9 @@ void __init pagetable_init(void) #endif for (i = 0; i < meminfo.nr_banks; i++) { - init_map[i+1].physical = PHYS_OFFSET + meminfo.bank[i].start; - init_map[i+1].virtual = PAGE_OFFSET + meminfo.bank[i].start; + init_map[i+1].physical = meminfo.bank[i].start; + init_map[i+1].virtual = meminfo.bank[i].start + + PAGE_OFFSET - PHYS_OFFSET; init_map[i+1].length = meminfo.bank[i].size; } @@ -327,13 +379,15 @@ void __init create_memmap_holes(void) { unsigned int start_pfn, end_pfn = -1; struct page *pg = NULL; - unsigned int sz, i; + unsigned int i; + +#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT) for (i = 0; i < meminfo.nr_banks; i++) { if (meminfo.bank[i].size == 0) continue; - start_pfn = meminfo.bank[i].start >> PAGE_SHIFT; + start_pfn = PFN(meminfo.bank[i].start); /* * subtle here - if we have a full bank, then @@ -344,8 +398,8 @@ void __init create_memmap_holes(void) set_bit(PG_skip, &pg->flags); pg->next_hash = mem_map + start_pfn; - start_pfn = PAGE_ALIGN(__pa(pg + 1)); - end_pfn = __pa(pg->next_hash) & PAGE_MASK; + start_pfn = PFN(PAGE_ALIGN(__pa(pg + 1))); + end_pfn = PFN(__pa(pg->next_hash) & PAGE_MASK); if (end_pfn != start_pfn) free_bootmem(start_pfn, end_pfn - start_pfn); @@ -353,8 +407,7 @@ void __init create_memmap_holes(void) pg = NULL; } - end_pfn = (meminfo.bank[i].start + - meminfo.bank[i].size) >> PAGE_SHIFT; + end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size); if (end_pfn != meminfo.end >> PAGE_SHIFT) pg = mem_map + end_pfn; @@ -364,27 +417,4 @@ void __init create_memmap_holes(void) set_bit(PG_skip, &pg->flags); pg->next_hash = NULL; } - -#if 0 - /* - * setup address validity map - * - don't think this is used anymore? - */ - sz = meminfo.end >> (PAGE_SHIFT + 8); /* in MB */ - sz = (sz + 31) >> 3; - - valid_addr_bitmap = alloc_bootmem(sz); - memzero(valid_addr_bitmap, sz); - - for (i = 0; i < meminfo.nr_banks; i++) { - int idx, end; - - idx = meminfo.bank[i].start >> 20; - end = (meminfo.bank[i].start + - meminfo.bank[i].size) >> 20; - do - set_bit(idx, valid_addr_bitmap); - while (++idx < end); - } -#endif } diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S index dcb5c10dc..36a9d8b28 100644 --- a/arch/arm/mm/proc-arm2,3.S +++ b/arch/arm/mm/proc-arm2,3.S @@ -270,9 +270,9 @@ _arm2_3_check_bugs: bics pc, lr, #0x04000000 @ Clear FIQ disable bit armvlsi_name: .asciz "ARM/VLSI" -_arm2_name: .asciz "arm2" -_arm250_name: .asciz "arm250" -_arm3_name: .asciz "arm3" +_arm2_name: .asciz "ARM 2" +_arm250_name: .asciz "ARM 250" +_arm3_name: .asciz "ARM 3" .section ".text.init", #alloc, #execinstr /* diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S index b085c3c4e..d453269d2 100644 --- a/arch/arm/mm/proc-arm6,7.S +++ b/arch/arm/mm/proc-arm6,7.S @@ -413,12 +413,12 @@ ENTRY(cpu_arm7_reset) cpu_armvlsi_name: .asciz "ARM/VLSI" -cpu_arm6_name: .asciz "arm6" +cpu_arm6_name: .asciz "ARM 6" cpu_arm610_name: - .asciz "arm610" -cpu_arm7_name: .asciz "arm7" + .asciz "ARM 610" +cpu_arm7_name: .asciz "ARM 7" cpu_arm710_name: - .asciz "arm710" + .asciz "ARM 710" .align .section ".text.init", #alloc, #execinstr diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 266d960b5..2d57b1030 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -456,9 +456,9 @@ ENTRY(cpu_sa1100_reset) cpu_manu_name: .asciz "Intel" ENTRY(cpu_sa110_name) - .asciz "sa110" + .asciz "StrongARM-110" ENTRY(cpu_sa1100_name) - .asciz "sa1100" + .asciz "StrongARM-1100" .align .section ".text.init", #alloc, #execinstr diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c index ac303d45e..ee7f571a7 100644 --- a/arch/arm/mm/small_page.c +++ b/arch/arm/mm/small_page.c @@ -66,9 +66,9 @@ static struct order orders[] = { #endif }; -#define USED_MAP(pg) ((pg)->offset) -#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &(pg)->offset)) -#define SET_USED(pg,off) (set_bit(off, &(pg)->offset)) +#define USED_MAP(pg) ((pg)->index) +#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 void add_page_to_queue(struct page *page, struct page **p) { -- cgit v1.2.3