summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-04 07:40:19 +0000
commit33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch)
tree2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /arch/arm
parent216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff)
Merge with Linux 2.3.32.
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-netwinder.S1
-rw-r--r--arch/arm/config.in1
-rw-r--r--arch/arm/def-configs/brutus3
-rw-r--r--arch/arm/def-configs/footbridge21
-rw-r--r--arch/arm/defconfig3
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/bios32.c27
-rw-r--r--arch/arm/kernel/bios32.h9
-rw-r--r--arch/arm/kernel/dec21285.c14
-rw-r--r--arch/arm/kernel/ecard.c6
-rw-r--r--arch/arm/kernel/entry-armv.S226
-rw-r--r--arch/arm/kernel/fiq.c2
-rw-r--r--arch/arm/kernel/head-armv.S1
-rw-r--r--arch/arm/kernel/hw-footbridge.c10
-rw-r--r--arch/arm/kernel/ioport.c1
-rw-r--r--arch/arm/kernel/process.c93
-rw-r--r--arch/arm/kernel/setup.c594
-rw-r--r--arch/arm/kernel/signal.c3
-rw-r--r--arch/arm/kernel/sys_arm.c201
-rw-r--r--arch/arm/kernel/traps.c13
-rw-r--r--arch/arm/lib/backtrace.S22
-rw-r--r--arch/arm/mm/init.c85
-rw-r--r--arch/arm/mm/ioremap.c4
-rw-r--r--arch/arm/mm/map.h1
-rw-r--r--arch/arm/mm/mm-armo.c16
-rw-r--r--arch/arm/mm/mm-armv.c96
-rw-r--r--arch/arm/mm/proc-arm2,3.S6
-rw-r--r--arch/arm/mm/proc-arm6,7.S8
-rw-r--r--arch/arm/mm/proc-sa110.S4
-rw-r--r--arch/arm/mm/small_page.c6
31 files changed, 879 insertions, 604 deletions
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 <asm/io.h>
#include <asm/irq.h>
#include <asm/dma.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/proc-fns.h>
#include <asm/semaphore.h>
#include <asm/system.h>
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 <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#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 <asm/fiq.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/uaccess.h>
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 <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
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 <stdarg.h>
#include <linux/errno.h>
@@ -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 <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -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)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+
+static unsigned int __init find_bootmap_pfn(unsigned int bootmap_pages)
+{
+ unsigned int start_pfn, bank, bootmap_pfn;
+
+ start_pfn = V_PFN_UP(&_end);
+ bootmap_pfn = 0;
+
+ /*
+ * FIXME: We really want to avoid allocating the bootmap
+ * over the top of the initrd.
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if (__pa(initrd_end) > (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 <asm/ucontext.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#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(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+ unlock_kernel();
+ up(&current->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(&current->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(&current->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 <linux/sched.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -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 <asm/system.h>
#include <asm/segment.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include <asm/setup.h>
@@ -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 <linux/vmalloc.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/io.h>
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 <linux/bootmem.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/arch/memory.h>
@@ -134,6 +135,20 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long 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
* some more work to get it to fit into our separate processor and
@@ -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 <linux/bootmem.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/io.h>
#include <asm/setup.h>
@@ -24,6 +25,31 @@ 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
*/
pgd_t *get_pgd_slow(void)
@@ -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)
{