- ext2: final truncate piece - fix the innd problem.
- use "sfence" for x86 memory barrier when available.
- remove the thread-group signal code for now: no feedback.
Leave the cleanups in place so that we can add it back in
cleanly later, but remove the new features.
- ARM update.
- released for Al Viro to check the truncate thing
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */
.quad sys_acct
- .quad osf_sigpending
+ .quad sys_sigpending
.quad alpha_ni_syscall
.quad sys_ioctl
.quad alpha_ni_syscall /* 55 */
return ret;
}
-asmlinkage int
-osf_sigpending(old_sigset_t *set)
-{
- sigset_t pending;
-
- spin_lock_irq(¤t->sigmask_lock);
- sigandsets(&pending, ¤t->blocked, ¤t->signal);
- spin_unlock_irq(¤t->sigmask_lock);
-
- return copy_to_user(set, &pending, sizeof(*set));
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
default:
lock_kernel();
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
GZFLAGS = -9
# Ensure this is ld "2.9.4" or later
-NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
+NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
-ifneq ($(NEW_LINKER),y)
+ifneq ($(NEW_LINKER),0)
dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
@echo '*** Please upgrade your binutils to 2.9.5.'
@false
endif
# GCC 2.7 uses different options to later compilers; sort out which we have
-NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
+NEW_GCC := $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?)
#
# select flags depending on the compiler
#
-ifeq ($(NEW_GCC),y)
+ifneq ($(NEW_GCC),0)
CFLAGS += -mshort-load-bytes
CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os
CFLAGS_PROC_CPU_32v3 := -march=armv3
CFLAGS_ARM6 := -mtune=arm6
CFLAGS_ARM7 := -mtune=arm7
CFLAGS_ARM720 := -mtune=arm7tdmi
+CFLAGS_ARM920 := -mtune=arm9tdmi
CFLAGS_SA110 := -mtune=strongarm110
else
CFLAGS += -DNO_TEXT_SECTIONS
CFLAGS_ARM6 := -m6
CFLAGS_ARM7 := -m6
CFLAGS_ARM720 := -m6
+CFLAGS_ARM920 := -m6
CFLAGS_SA110 := -m6
endif
ifeq ($(CONFIG_CPU_ARM720),y)
CFLAGS += $(CFLAGS_ARM720)
else
+ ifeq ($(CONFIG_CPU_ARM920),y)
+ CFLAGS += $(CFLAGS_ARM920)
+ else
ifeq ($(CONFIG_CPU_SA110),y)
CFLAGS += $(CFLAGS_SA110)
else
endif
endif
endif
+ endif
endif
LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
ifeq ($(CONFIG_ARCH_ARCA5K),y)
MACHINE = arc
-ARCHDIR = arc
endif
ifeq ($(CONFIG_ARCH_RPC),y)
MACHINE = rpc
-ARCHDIR = rpc
endif
ifeq ($(CONFIG_ARCH_EBSA110),y)
MACHINE = ebsa110
-ARCHDIR = ebsa110
endif
ifeq ($(CONFIG_ARCH_CLPS7500),y)
MACHINE = clps7500
-ARCHDIR = cl7500
+INCDIR = cl7500
endif
ifeq ($(CONFIG_FOOTBRIDGE),y)
MACHINE = footbridge
-ARCHDIR = ebsa285
+INCDIR = ebsa285
endif
ifeq ($(CONFIG_ARCH_CO285),y)
TEXTADDR = 0x60008000
+MACHINE = footbridge
+INCDIR = ebsa285
endif
ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
MACHINE = nexuspci
-ARCHDIR = nexuspci
endif
ifeq ($(CONFIG_ARCH_SHARK),y)
MACHINE = shark
-ARCHDIR = shark
endif
ifeq ($(CONFIG_ARCH_SA1100),y)
MACHINE = sa1100
-ARCHDIR = sa1100
endif
ifeq ($(CONFIG_ARCH_L7200),y)
MACHINE = l7200
-ARCHDIR = l7200
+endif
+
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+MACHINE = integrator
+endif
+
+# Only set INCDIR if its not already defined above
+INCDIR ?= $(MACHINE)
+
+# If we have a machine-specific directory, then include it in the build.
+MACHDIR := arch/arm/mach-$(MACHINE)
+ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
+SUBDIRS += $(MACHDIR)
+CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
# to date before starting compilation
$(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \
- constants \
include/asm-arm/mach-types.h
-include/asm-arm/mach-types.h: \
- arch/arm/tools/mach-types \
- arch/arm/tools/gen-mach-types
+$(patsubst %, _dir_%, $(SUBDIRS)) : constants
+
+include/asm-arm/mach-types.h: arch/arm/tools/mach-types \
+ arch/arm/tools/gen-mach-types
@awk -f arch/arm/tools/gen-mach-types arch/arm/tools/mach-types > $@
-constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy
+constants: dummy
@$(MAKE) -C arch/arm/lib constants.h
symlinks: archsymlinks
archsymlinks:
$(RM) include/asm-arm/arch include/asm-arm/proc
- (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc)
+ (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc)
vmlinux: arch/arm/vmlinux.lds
arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
-arch/arm/kernel: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel
-
-arch/arm/mm: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm
-
-arch/arm/lib: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib
+arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
+ $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
bzImage zImage zinstall Image bootpImage install: vmlinux
@$(MAKEBOOT) $@
$(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds
$(RM) include/asm-arm/mach-types.h
-archdep: symlinks
+archdep: archsymlinks
@$(MAKEBOOT) dep
# My testing targets (that short circuit a few dependencies)
brutus_config victor_config \
empeg_config thinclient_config \
assabet_config lart_config \
- cerf_config
+ cerf_config lusl7200_config
$(CFGS):
@( \
echo "$$CFG does not exist"; \
fi; \
)
-
-l7200_config:
- $(RM) arch/arm/defconfig
- cp arch/arm/def-configs/lusl7200 arch/arm/defconfig
@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
install: $(CONFIGURE) Image
- sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
- sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
clean:
$(RM) Image zImage bootpImage
.PHONY: $(INITRD) $(ZSYSTEM)
-clean:; $(RM) bootp bootp.lds
+clean:; $(RM) bootp
--- /dev/null
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ _text = .;
+ .text : {
+ _stext = .;
+ _start = .;
+ init.o(.start)
+ kernel_start = .;
+ kernel.o
+ kernel_len = . - kernel_start;
+ . = ALIGN(32);
+ *(.text)
+ initrd_start = .;
+ initrd.o
+ initrd_len = . - initrd_start;
+ . = ALIGN(32);
+ _etext = .;
+ }
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
--- /dev/null
+/*
+ * linux/arch/arm/boot/compressed/head-ftvpci.S
+ *
+ * Copyright (C) 2000 FutureTV Labs Ltd.
+ *
+ * Special startup code for FTV PCI board.
+ */
+
+ .section ".start", #alloc, #execinstr
+ftv_start:
+ mcr p15, 0, r0, c7, c5, 0 @ flush I cache
+ mrc p15, 0, r0, c1, c0
+ orr r0, r0, #1 << 12
+ mcr p15, 0, r0, c1, c0 @ enable I cache
+ mov r0, #0
+ mcreq p15, 0, r0, c15, c1, 2 @ enable clock switching
+
+ /* check to see if the kernel must be relocated */
+ ldr ip, =ftv_start
+ adr sl, ftv_start
+ teq ip, sl
+ beq 2f @ no need to copy
+
+ /* in the wrong place -> presumably, executing out of ROM */
+ sub ip, ip, sl @ displacement
+ ldr lr, =_start @ destination
+ sub sp, lr, ip @ source
+ ldr fp, =_edata @ end of copied area
+1: ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r10}
+ stmia lr!, {r0, r1, r2, r3, r4, r5, r6, r10}
+ cmp lr, fp
+ ble 1b
+
+2:
+ mov r8, #0
+ mov r7, #3
+ b 1f
+.ltorg
+1:
+ /* fall back into head.S */
+++ /dev/null
-/*
- * linux/arch/arm/boot/compressed/head-nexuspci.S
- *
- * Copyright (C) 1996, 1997, 1998 Philip Blundell
- *
- * NexusPCI is unusual because we don't have a bootloader -- the kernel is
- * run directly out of ROM at the moment. Maybe this will change one day and
- * then this file can go away.
- *
- */
-
- .text
-
-.globl _start
-_start: b reset
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b go_uncompress
-
-reset: mov r2, #0x20000000 @ LED off
- mov r1, #0x1a
- str r1, [r2]
-
- mov r2, #0x10000000 @ SCC init
-
- mov r1, #42
- strb r1, [r2, #8]
-
- mov r1, #48
- strb r1, [r2, #8]
-
- mov r1, #16
- strb r1, [r2, #8]
-
- mov r1, #0x93
- strb r1, [r2, #0]
- mov r1, #0x17
- strb r1, [r2, #0]
-
- mov r1, #0xbb
- strb r1, [r2, #0x4]
-
- mov r1, #0x78
- strb r1, [r2, #0x10]
-
- mov r1, #160
- strb r1, [r2, #0x8]
-
- mov r1, #5
- strb r1, [r2, #0x8]
-
- ldr r2, =_start
- ldr r3, =_edata
- mov r8, r2
- mov r0, #0
-1:
- ldmia r0!, {r4, r5, r6, r7}
- stmia r2!, {r4, r5, r6, r7}
- cmp r2, r3
- ble 1b
-
- ldr r3, =_edata
- ldr r1, =_end
- mov r2, #0
-1:
- strb r2, [r3]
- cmp r3, r1
- beq 2f
- add r3, r3, #1
- b 1b
-2:
- add pc, r8, #0x20
-
-undefined: ldr r4, =undef_msg
-1: ldrb r0, [r4], #1
- movs r0, r0
-2: beq 2b
- bl _ll_write_char
- b 1b
-
-undef_msg: .ascii "Undefined instruction (or other problem)\000"
- .align 4
-
-/*
- * Uncompress the kernel
- */
-go_uncompress:
- mov r0, #0x40000000
- ldr sp, =user_stack
- add sp, sp, #4096
- bl decompress_kernel
-
- mov r2, #0x40000000
- mov r0, #0
- mov r1, #3
- add pc, r2, #0x20 @ call via EXEC entry
.word 0x016f2818 @ Magic numbers to help the loader
.word start
1: mov r7, r1 @ save architecture ID
- mov r8, r0 @ save r0
+ mov r8, #0 @ save r0
#ifdef CONFIG_ANGELBOOT
/*
* Booting from Angel - need to enter SVC mode and disable
1:
sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer
- bic r3, r3, #0x3f
+ bic r3, r3, #0x3f00
/*
- * Initialise the page tables
+ * Initialise the page tables, turning on the cacheable and bufferable
+ * bits for the RAM area only.
*/
mov r0, r3
mov r8, r0, lsr #18
add r1, r1, #1048576
teq r0, r2
bne 1b
+/*
+ * If ever we are running from Flash, then we surely want the cache
+ * to be enabled also for our execution instance... We map 2MB of it
+ * so there is no map overlap problem for up to 1 MB compressed kernel.
+ * If the execution is in RAM then we would only be duplicating the above.
+ */
+ mov r1, #0x1e
+ orr r1, r1, #3 << 10
+ mov r2, pc, lsr #20
+ orr r1, r1, r2, lsl #20
+ add r0, r3, r2, lsl #2
+ str r1, [r0], #4
+ add r1, r1, #1048576
+ str r1, [r0]
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
#define GPIO_2_9 0x3fc
+/*
+ * void sa1100_setup( int arch_id );
+ *
+ * This is called from decompress_kernel() with the arch_decomp_setup() macro.
+ */
+
/*
* void sa1100_setup( int arch_id );
*
@ The machine type is passed in r0
mov r0, r3
#ifdef CONFIG_SA1100_NANOENGINE
- teq r0, #32 @ MACH_TYPE_NANOENGINE
+ teq r0, #MACH_TYPE_NANOENGINE
beq SYMBOL_NAME(bse_setup)
#endif
#include <linux/pci.h>
#include <linux/init.h>
+#include <asm/page.h> /* for BUG() */
#include <asm/irq.h>
#include <asm/mach-types.h>
-
-#include "bios32.h"
+#include <asm/mach/pci.h>
static int debug_pci;
int have_isa_bridge;
-extern void hw_init(void);
-
void pcibios_report_status(u_int status_mask, int warn)
{
struct pci_dev *dev;
}
}
+/*
+ * Put the DEC21142 to sleep
+ */
+static void __init pci_fixup_dec21142(struct pci_dev *dev)
+{
+ pci_write_config_dword(dev, 0x40, 0x80000000);
+}
+
struct pci_fixup pcibios_fixups[] = {
{
PCI_FIXUP_HEADER,
PCI_FIXUP_HEADER,
PCI_ANY_ID, PCI_ANY_ID,
pci_fixup_ide_bases
+ }, {
+ PCI_FIXUP_HEADER,
+ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ pci_fixup_dec21142
}, { 0 }
};
* SERR and PERR reporting - this chip doesn't drive the
* parity line correctly.
*/
-#if 1 /* !testing */
if (dev->vendor == PCI_VENDOR_ID_INTERG &&
dev->device == PCI_DEVICE_ID_INTERG_2000)
busdata->features &= ~(PCI_COMMAND_SERR |
PCI_COMMAND_PARITY);
-#endif
+
/*
* Calculate the maximum devsel latency.
*/
u16 cmd;
u8 min_gnt, latency;
- /*
- * architecture specific hacks. I don't really want
- * this here, but I don't see any other place for it
- * to live. Shame the device doesn't support
- * capabilities
- */
- if (machine_is_netwinder() &&
- dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_21142)
- /* Put the chip to sleep in case the driver isn't loaded */
- pci_write_config_dword(dev, 0x40, 0x80000000);
-
/*
* Calculate this masters latency timer value.
* This is rather primitive - it does not take
ranges->mem_end -= bus->resource[1]->start;
}
-static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
+u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
{
return 0;
}
-/* ebsa285 host-specific stuff */
-
-#ifdef CONFIG_ARCH_EBSA285
-static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
-
-static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
-{
- return PCI_SLOT(dev->devfn);
-}
-
-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];
-}
-
-static struct hw_pci ebsa285_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- ebsa285_swizzle,
- ebsa285_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_CATS
-/* cats host-specific stuff */
-static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
-
-static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- if (dev->irq >= 128)
- return dev->irq & 0x1f;
-
- if (dev->irq >= 1 && dev->irq <= 4)
- return irqmap_cats[dev->irq - 1];
-
- if (dev->irq != 0)
- printk("PCI: device %02x:%02x has unknown irq line %x\n",
- dev->bus->number, dev->devfn, dev->irq);
-
- return -1;
-}
-
-static struct hw_pci cats_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- cats_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_NETWINDER
-/* netwinder host-specific stuff */
-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):
- return IRQ_NETWINDER_ETHER10;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
- return 0;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
- 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):
- case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000):
- return IRQ_NETWINDER_VGA;
-
- case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285):
- return 0;
-
- default:
- printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
- dev->bus->number, dev->devfn,
- dev->vendor, dev->device);
- return 0;
- }
-}
-
-static struct hw_pci netwinder_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- netwinder_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_PERSONAL_SERVER
-static int irqmap_personal_server[] __initdata = {
- IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
- IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
-};
-
-static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- unsigned char line;
-
- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-
- if (line > 0x40 && line <= 0x5f) {
- /* line corresponds to the bit controlling this interrupt
- * in the footbridge. Ignore the first 8 interrupt bits,
- * look up the rest in the map. IN0 is bit number 8
- */
- return irqmap_personal_server[(line & 0x1f) - 8];
- } else if (line == 0) {
- /* no interrupt */
- return 0;
- } else
- return irqmap_personal_server[(line - 1) & 3];
-}
-
-static struct hw_pci personal_server_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- personal_server_map_irq
-};
-
-#endif
-
-#ifdef CONFIG_ARCH_NEXUSPCI
-/*
- * Owing to a PCB cockup, issue A backplanes are wired thus:
- *
- * Slot 1 2 3 4 5 Bridge
- * IRQ D C B A A
- * A D C B B
- * B A D C C
- * C B A D D
- *
- * ID A31 A30 A29 A28 A27 A26
- */
-
-static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D };
-
-static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- return irqmap_ftv[(slot + pin) & 3];
-}
-
-/* ftv host-specific stuff */
-static struct hw_pci ftv_pci __initdata = {
- plx90x0_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- ftv_map_irq
-};
-#endif
+extern struct hw_pci ebsa285_pci;
+extern struct hw_pci cats_pci;
+extern struct hw_pci netwinder_pci;
+extern struct hw_pci personal_server_pci;
+extern struct hw_pci ftv_pci;
+extern struct hw_pci integrator_pci;
void __init pcibios_init(void)
{
struct hw_pci *hw_pci = NULL;
+ struct arm_pci_sysdata sysdata;
+ int i;
do {
#ifdef CONFIG_ARCH_EBSA285
break;
}
#endif
- } while (0);
+#ifdef CONFIG_ARCH_INTEGRATOR
+ if (machine_is_integrator()) {
+ hw_pci = &integrator_pci;
+ break;
+ }
+#endif
+ } while (0);
if (hw_pci == NULL)
return;
+ for (i = 0; i < MAX_NR_BUS; i++) {
+ sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY;
+ sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+ }
+
/*
* Set up the host bridge, and scan the bus.
*/
- hw_pci->init();
+ hw_pci->init(&sysdata);
/*
* Other architectures don't seem to do this... should we?
pcibios_claim_resources();
/*
- * Assign any unassigned resources. Note that we really ought to
- * have min/max stuff here - max mem address is 0x0fffffff
+ * Assign any unassigned resources.
*/
pci_assign_unassigned_resources();
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
+++ /dev/null
-#define MAX_NR_BUS 2
-
-struct arm_bus_sysdata {
- /*
- * bitmask of features we can turn.
- * See PCI command register for more info.
- */
- u16 features;
- /*
- * Maximum devsel for this bus.
- */
- u16 maxdevsel;
- /*
- * The maximum latency that devices on this
- * bus can withstand.
- */
- u8 max_lat;
-};
-
-struct arm_pci_sysdata {
- struct arm_bus_sysdata bus[MAX_NR_BUS];
-};
-
-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);
-void __init plx90x0_init(void);
#include <asm/irq.h>
#include <asm/system.h>
-#include "bios32.h"
+#include <asm/mach/pci.h>
#define MAX_SLOTS 21
add_timer(timer);
}
-void __init dc21285_init(void)
+void __init dc21285_init(struct arm_pci_sysdata *sysdata)
{
unsigned long cntl;
unsigned int mem_size;
"central function" : "addin");
if (cfn_mode) {
- static struct resource csrmem, csrio;
- struct arm_pci_sysdata sysdata;
- int i;
+ static struct resource csrmem, csrio, busmem, busmempf;
+ struct pci_bus *bus;
csrio.flags = IORESOURCE_IO;
- csrio.name = "DC21285";
+ csrio.name = "Footbridge";
csrmem.flags = IORESOURCE_MEM;
- csrmem.name = "DC21285";
+ csrmem.name = "Footbridge";
+ busmem.flags = IORESOURCE_MEM;
+ busmem.name = "Footbridge non-prefetch";
+ busmempf.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ busmempf.name = "Footbridge prefetch";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
allocate_resource(&iomem_resource, &csrmem, 128,
0xf4000000, 0xf8000000, 128, NULL, NULL);
+ allocate_resource(&iomem_resource, &busmempf, 0x20000000,
+ 0x00000000, 0x80000000, 0x20000000, NULL, NULL);
+ allocate_resource(&iomem_resource, &busmem, 0x40000000,
+ 0x00000000, 0x80000000, 0x40000000, NULL, NULL);
/*
* Map our SDRAM at a known address in PCI space, just in case
*CSR_PCICACHELINESIZE = 0x00002008;
*CSR_PCICSRBASE = csrmem.start;
*CSR_PCICSRIOBASE = csrio.start;
- *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
*CSR_PCICMD = pci_cmd |
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
- for (i = 0; i < MAX_NR_BUS; i++) {
- sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_SERR |
- PCI_COMMAND_PARITY;
- sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
- }
-
- pci_scan_bus(0, &dc21285_ops, &sysdata);
+ bus = pci_scan_bus(0, &dc21285_ops, sysdata);
+ /*
+ * bus->resource[0] is the IO resource for this bus
+ * bus->resource[1] is the mem resource for this bus
+ * bus->resource[2] is the prefetch mem resource for this bus
+ */
+ bus->resource[1] = &busmem;
+ bus->resource[2] = &busmempf;
- pci_cmd |= sysdata.bus[0].features;
+ pci_cmd |= sysdata->bus[0].features;
printk("PCI: Fast back to back transfers %sabled\n",
- (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ?
+ (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
"en" : "dis");
/*
* We don't want /any/ signals, not even SIGKILL
*/
sigfillset(&tsk->blocked);
- sigemptyset(&tsk->signal);
+ sigemptyset(&tsk->pending.signal);
recalc_sigpending(tsk);
strcpy(tsk->comm, "kecardd");
req = xchg(&ecard_req, NULL);
if (req == NULL) {
- sigemptyset(&tsk->signal);
+ sigemptyset(&tsk->pending.signal);
interruptible_sleep_on(&ecard_wait);
}
} while (req == NULL);
mov pc, lr
detect_proc_type:
+ mov ip, lr
mov r2, #0xea000000 @ Point undef instr to continuation
adr r0, continue - 12
orr r0, r2, r0, lsr #2
ldr r0, arm2_id
swp r2, r2, [r1] @ check for swp (ARM2 can't)
ldr r0, arm250_id
- mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't)
+ mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 can't)
+ mov r0, r3
continue: mov r2, #0xeb000000 @ Make undef vector loop
sub r2, r2, #2
str r2, [r1, #4]
- mov pc, lr
+ mov pc, ip
void flush_thread(void)
{
- memset(¤t->thread.debug, 0, sizeof(current->thread.debug));
- memset(¤t->thread.fpstate, 0, sizeof(current->thread.fpstate));
+ memset(¤t->thread.debug, 0, sizeof(struct debug_info));
+ memset(¤t->thread.fpstate, 0, sizeof(union fp_state));
current->used_math = 0;
current->flags &= ~PF_USEDFPU;
}
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
+ struct task_struct *tsk = current;
+
dump->magic = CMAGIC;
- dump->start_code = current->mm->start_code;
+ dump->start_code = tsk->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
- dump->u_tsize = (current->mm->end_code - current->mm->start_code) >> PAGE_SHIFT;
- dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+ dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
- dump->u_debugreg[0] = current->thread.debug.bp[0].address;
- dump->u_debugreg[1] = current->thread.debug.bp[1].address;
- dump->u_debugreg[2] = current->thread.debug.bp[0].insn;
- dump->u_debugreg[3] = current->thread.debug.bp[1].insn;
- dump->u_debugreg[4] = current->thread.debug.nsaved;
+ dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
+ dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
+ dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
+ dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+ dump->u_debugreg[4] = tsk->thread.debug.nsaved;
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
static inline int
put_stack_long(struct task_struct *task, int offset, long data)
{
- get_user_regs(task)->uregs[offset] = data;
+ struct pt_regs newregs, *regs = get_user_regs(task);
+ int ret = -EINVAL;
+
+ newregs = *regs;
+ newregs.uregs[offset] = data;
+
+ if (valid_user_regs(&newregs)) {
+ regs->uregs[offset] = data;
+ ret = 0;
+ }
- return 0;
+ return ret;
}
static inline int
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break;
- if (addr < sizeof (struct pt_regs))
+ if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, (int)addr >> 2, data);
break;
* Set all gp regs in the child.
*/
case PTRACE_SETREGS: {
- struct pt_regs *regs = get_user_regs(child);
-
- ret = 0;
- if (copy_from_user(regs, (void *)data,
- sizeof(struct pt_regs)))
- ret = -EFAULT;
+ struct pt_regs newregs;
+
+ ret = -EFAULT;
+ if (copy_from_user(&newregs, (void *)data,
+ sizeof(struct pt_regs)) == 0) {
+ struct pt_regs *regs = get_user_regs(child);
+
+ ret = -EINVAL;
+ if (valid_user_regs(&newregs)) {
+ *regs = newregs;
+ ret = 0;
+ }
+ }
break;
}
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
L_TARGET := lib.a
L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \
- memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \
- strrchr.o testchangebit.o testclearbit.o testsetbit.o \
- uaccess.o
+ memchr.o memcpy.o memset.o memzero.o setbit.o \
+ strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o uaccess.o
O_TARGET := lib.o
O_OBJS := backtrace.o delay.o
#include <asm/assembler.h>
#include "constants.h"
- .text
+ .text
+ .align 5
/*
* StrongARM optimised copy_page routine
- * now 1.72bytes/cycle, was 1.60 bytes/cycle
- * (50MHz bus -> 86MB/s)
+ * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s)
+ * Note that we probably achieve closer to the 100MB/s target with
+ * the core clock switching.
*/
-
ENTRY(copy_page)
stmfd sp!, {r4, lr} @ 2
mov r2, #PAGE_SZ/64 @ 1
-1: ldmia r1!, {r3, r4, ip, lr} @ 4
- subs r2, r2, #1 @ 1
- stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
+1: stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmneia r1!, {r3, r4, ip, lr} @ 4
bne 1b @ 1
LOADREGS(fd, sp!, {r4, pc}) @ 3
-
-
subs r0, r0, #1
bcs SYMBOL_NAME(__delay)
RETINSTR(mov,pc,lr)
-
/*
* linux/arch/arm/lib/memchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
- *
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
- .text
+ .text
+ .align 5
ENTRY(memchr)
- str lr, [sp, #-4]!
-1: ldrb r3, [r0], #1
- teq r3, r1
- beq 2f
- subs r2, r2, #1
- bpl 1b
-2: movne r0, #0
- subeq r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
+1: ldrb r3, [r0], #1
+ teq r3, r1
+ beq 2f
+ subs r2, r2, #1
+ bpl 1b
+2: movne r0, #0
+ subeq r0, r0, #1
+ RETINSTR(mov,pc,lr)
* Copyright (C) 1995-1999 Russell King
*
* ASM optimised string functions
- *
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
b 24b
.align
-
-
/*
* linux/arch/arm/lib/memset.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
- *
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
- .text
- .align 5
-ENTRY(memset)
- mov r3, r0
- cmp r2, #16
- blt 6f
- ands ip, r3, #3
- beq 1f
- cmp ip, #2
- strltb r1, [r3], #1 @ Align destination
- strleb r1, [r3], #1
- strb r1, [r3], #1
- rsb ip, ip, #4
- sub r2, r2, ip
-1: orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- cmp r2, #256
- blt 4f
- stmfd sp!, {r4, r5, lr}
- mov r4, r1
- mov r5, r1
- mov lr, r1
- mov ip, r2, lsr #6
- sub r2, r2, ip, lsl #6
-2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time.
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- subs ip, ip, #1
- bne 2b
- teq r2, #0
- LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go.
- tst r2, #32
- stmneia r3!, {r1, r4, r5, lr}
- stmneia r3!, {r1, r4, r5, lr}
- tst r2, #16
- stmneia r3!, {r1, r4, r5, lr}
- ldmia sp!, {r4, r5}
-3: tst r2, #8
- stmneia r3!, {r1, lr}
- tst r2, #4
- strne r1, [r3], #4
- tst r2, #2
- strneb r1, [r3], #1
- strneb r1, [r3], #1
- tst r2, #1
- strneb r1, [r3], #1
- LOADREGS(fd, sp!, {pc})
+ .text
+ .align 5
+ .word 0
-4: movs ip, r2, lsr #3
- beq 3b
- sub r2, r2, ip, lsl #3
- str lr, [sp, #-4]!
- mov lr, r1
- subs ip, ip, #4
-5: stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- subges ip, ip, #4
- bge 5b
- tst ip, #2
- stmneia r3!, {r1, lr}
- stmneia r3!, {r1, lr}
- tst ip, #1
- stmneia r3!, {r1, lr}
- teq r2, #0
- LOADREGS(eqfd, sp!, {pc})
- b 3b
+1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [r0], #1 @ 1
+ strleb r1, [r0], #1 @ 1
+ strb r1, [r0], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memzero again.
+ */
-6: subs r2, r2, #1
- strgeb r1, [r3], #1
- bgt 6b
- RETINSTR(mov, pc, lr)
+ENTRY(memset)
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]!
+ mov ip, r1
+ mov lr, r1
+2: subs r2, r2, #64
+ stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ bgt 2b
+ LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia r0!, {r1, r3, ip, lr}
+ stmneia r0!, {r1, r3, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r1, r3, ip, lr}
+ ldr lr, [sp], #4
+4: tst r2, #8
+ stmneia r0!, {r1, r3}
+ tst r2, #4
+ strne r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [r0], #1
+ strneb r1, [r0], #1
+ tst r2, #1
+ strneb r1, [r0], #1
+ RETINSTR(mov,pc,lr)
/*
* linux/arch/arm/lib/memzero.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
-
- .text
+ .text
+ .align 5
+ .word 0
/*
- * Prototype: void memzero(void *d, size_t n)
+ * Align the pointer in r0. r3 contains the number of bytes that we are
+ * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
+ * don't bother; we use byte stores instead.
+ */
+1: subs r1, r1, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r2, [r0], #1 @ 1
+ strleb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memzero again.
*/
-1: @ 4 <= r1
- cmp ip, #2 @ 1
- strltb r2, [r0], #1 @ 1
- strleb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- rsb ip, ip, #4 @ 1
- sub r1, r1, ip @ 1
- cmp r1, #3 @ 1
- bgt 2f @ 1 @ +8
- b 4f @ 1 @ +9
-
- .align 5
ENTRY(__memzero)
- mov r2, #0 @ 1
- cmp r1, #4 @ 1
- blt 4f @ 1 @ = 3
-
- @ r1 >= 4
-
- ands ip, r0, #3 @ 1
- bne 1b @ 1 @ = 5
-
-2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11
-
- str lr, [sp, #-4]! @ 1
- mov r3, #0 @ 1
- mov ip, #0 @ 1
- mov lr, #0 @ 1
-
- @ 4 <= r1 <= 32 @ = 9 or 15
-
-3: subs r1, r1, #32 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- bgt 3b @ 1
- LOADREGS(eqfd, sp!, {pc}) @ 1/2
-
- @ -28 <= r1 <= -1
-
- cmp r1, #-16 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- ldr lr, [sp], #4 @ 1
- addlts r1, r1, #16 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -12 <= r1 <= -1
-
- cmp r1, #-8 @ 1
- stmgeia r0!, {r2, r3} @ 2
- addlts r1, r1, #8 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -4 <= r1 <= -1
-
- cmp r1, #-4 @ 1
- strge r2, [r0], #4 @ 1
- adds r1, r1, #4 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
-4: @ 1 <= r1 <= 3
- cmp r1, #2 @ 1
- strgtb r2, [r0], #1 @ 1
- strgeb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- RETINSTR(mov,pc,lr) @ 1
+ mov r2, #0 @ 1
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
+ */
+ cmp r1, #16 @ 1 we can skip this chunk if we
+ blt 4f @ 1 have < 16 bytes
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]! @ 1
+ mov ip, r2 @ 1
+ mov lr, r2 @ 1
+
+3: subs r1, r1, #64 @ 1 write 32 bytes out per loop
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ bgt 3b @ 1
+ LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r1, #32 @ 1
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ tst r1, #16 @ 1 16 bytes or more?
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ ldr lr, [sp], #4 @ 1
+
+4: tst r1, #8 @ 1 8 bytes or more?
+ stmneia r0!, {r2, r3} @ 2
+ tst r1, #4 @ 1 4 bytes or more?
+ strne r2, [r0], #4 @ 1
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r1, #2 @ 1 2 bytes or more?
+ strneb r2, [r0], #1 @ 1
+ strneb r2, [r0], #1 @ 1
+ tst r1, #1 @ 1 a byte left over
+ strneb r2, [r0], #1 @ 1
+ RETINSTR(mov,pc,lr) @ 1
/*
* linux/arch/arm/lib/strchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
- *
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
.text
+ .align 5
ENTRY(strchr)
- str lr, [sp, #-4]!
- mov r3, #0
1: ldrb r2, [r0], #1
teq r2, r1
teqne r2, #0
teq r2, #0
moveq r0, #0
subne r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
-
+ RETINSTR(mov,pc,lr)
--- /dev/null
+/*
+ * linux/arch/arm/lib/strncpy_from_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/*
+ * Copy a string from user space to kernel space.
+ * r0 = dst, r1 = src, r2 = byte length
+ * returns the number of characters copied (strlen of copied string),
+ * -EFAULT on exception, or "len" if we fill the whole buffer
+ */
+ENTRY(__arch_strncpy_from_user)
+ save_lr
+ mov ip, r1
+1: subs r2, r2, #1
+USER( ldrplbt r3, [r1], #1)
+ bmi 2f
+ strb r3, [r0], #1
+ teq r3, #0
+ bne 1b
+ sub r1, r1, #1 @ take NUL character out of count
+2: sub r0, r1, ip
+ restore_pc
+
+ .section .fixup,"ax"
+ .align 0
+9001: mov r3, #0
+ strb r3, [r0, #0] @ null terminate
+ mov r0, #-EFAULT
+ restore_pc
+ .previous
+
--- /dev/null
+/*
+ * linux/arch/arm/lib/strnlen_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
+ * Purpose : get length of a string in user memory
+ * Params : str - address of string in user memory
+ * Returns : length of string *including terminator*
+ * or zero on exception, or n + 1 if too long
+ */
+ENTRY(__arch_strnlen_user)
+ save_lr
+ mov r2, r0
+1:
+USER( ldrbt r3, [r0], #1)
+ teq r3, #0
+ beq 2f
+ subs r1, r1, #1
+ bne 1b
+ add r0, r0, #1
+2: sub r0, r0, r2
+ restore_pc
+
+ .section .fixup,"ax"
+ .align 0
+9001: mov r0, #0
+ restore_pc
+ .previous
/*
* linux/arch/arm/lib/strrchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
- *
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
.text
+ .align 5
ENTRY(strrchr)
- str lr, [sp, #-4]!
mov r3, #0
1: ldrb r2, [r0], #1
teq r2, r1
teq r2, #0
bne 1b
mov r0, r3
- LOADREGS(fd, sp!, {pc})
-
-
+ RETINSTR(mov,pc,lr)
.text
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
.globl SYMBOL_NAME(uaccess_user)
SYMBOL_NAME(uaccess_user):
.word uaccess_user_put_byte
.text
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
#define PAGE_SHIFT 12
/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
9001: LOADREGS(fd,sp!, {r0, pc})
.previous
-/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
- * Purpose : get length of a string in user memory
- * Params : str - address of string in user memory
- * Returns : length of string *including terminator*
- * or zero on exception, or n + 1 if too long
- */
-ENTRY(__arch_strnlen_user)
- str lr, [sp, #-4]!
- mov r2, r0
-1:
-USER( ldrbt r3, [r0], #1)
- teq r3, #0
- beq 2f
- subs r1, r1, #1
- bne 1b
- add r0, r0, #1
-2: sub r0, r0, r2
- LOADREGS(fd,sp!, {pc})
-
- .section .fixup,"ax"
- .align 0
-9001: mov r0, #0
- LOADREGS(fd,sp!,{pc})
- .previous
-
-/* Prototype: size_t __arch_strncpy_from_user(char *dst, char *src, size_t len)
- * Purpose : copy a string from user memory to kernel memory
- * Params : dst - kernel memory destination
- * : src - user memory source
- * : len - maximum length of string
- * Returns : number of characters copied
- */
-ENTRY(__arch_strncpy_from_user)
- str lr, [sp, #-4]!
- add ip, r1, #1
-1: subs r2, r2, #1
- bmi 2f
-USER( ldrbt r3, [r1], #1)
- strb r3, [r0], #1
- teq r3, #0
- bne 1b
- sub r0, r1, ip
- LOADREGS(fd, sp!, {pc})
-2: sub ip, ip, #1
- sub r0, r1, ip
- LOADREGS(fd, sp!, {pc})
-
- .section .fixup,"ax"
- .align 0
-9001: mov ip, #0
-1: strb ip, [r0], #1
- subs r2, r2, #1
- bpl 1b
- mov r0, #-EFAULT
- LOADREGS(fd, sp!, {pc})
- .previous
-
- .align
-
--- /dev/null
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+O_TARGET := footbridge.o
+
+# Object file lists.
+
+obj-y := #arch.o dma.o mm.o
+obj-m :=
+obj-n :=
+obj- :=
+
+export-objs := netwinder-hw.o
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_ARCH_CATS) += cats-pci.o
+obj-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o
+obj-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
+obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
+endif
+
+ifeq ($(CONFIG_LEDS),y)
+#obj-$(CONFIG_ARCH_CO285) += ebsa285-leds.o
+#obj-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
+#obj-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
+endif
+
+#obj-$(CONFIG_ARCH_CATS) += cats-hw.o
+#obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/arch.c
+ *
+ * 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.
+ */
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/dec21285.h>
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+extern void __init footbridge_map_io(void);
+
+#ifdef CONFIG_ARCH_EBSA285
+
+static void __init
+fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ 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;
+}
+
+MACHINE_START(EBSA285, "EBSA285")
+ MAINTAINER("Russell King")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ FIXUP(fixup_ebsa285)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * 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, struct meminfo *mi)
+{
+#ifdef CONFIG_ISAPNP
+ extern int isapnp_disable;
+
+ /*
+ * 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
+
+ if (params->u1.s.nr_pages != 0x02000 &&
+ params->u1.s.nr_pages != 0x04000 &&
+ params->u1.s.nr_pages != 0x08000 &&
+ params->u1.s.nr_pages != 0x10000) {
+ 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;
+ }
+}
+
+MACHINE_START(NETWINDER, "Rebel-NetWinder")
+ MAINTAINER("Russell King/Rebel.com")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ DISABLE_PARPORT(0)
+ DISABLE_PARPORT(2)
+ FIXUP(fixup_netwinder)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CATS
+/*
+ * 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, struct meminfo *mi)
+{
+ ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_POINTS = 16;
+ ORIG_Y = 24;
+}
+
+MACHINE_START(CATS, "Chalice-CATS")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ SOFT_REBOOT
+ FIXUP(fixup_cats)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CO285
+
+static void __init
+fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ extern unsigned long boot_memory_end;
+ extern char boot_command_line[];
+
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = boot_memory_end;
+ mi->bank[0].node = 0;
+
+ *cmdline = boot_command_line;
+}
+
+MACHINE_START(CO285, "co-EBSA285")
+ MAINTAINER("Mark van Doesburg")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
+ FIXUP(fixup_coebsa285)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
+MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
+ MAINTAINER("Jamey Hicks / George France")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/cats-hw.c
+ *
+ * CATS machine fixup
+ *
+ * Copyright (C) 1998, 1999 Russell King, Phil Blundell
+ */
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#define CFG_PORT 0x370
+#define INDEX_PORT (CFG_PORT)
+#define DATA_PORT (CFG_PORT + 1)
+
+static int __init cats_hw_init(void)
+{
+ if (machine_is_cats()) {
+ /* Set Aladdin to CONFIGURE mode */
+ outb(0x51, CFG_PORT);
+ outb(0x23, CFG_PORT);
+
+ /* Select logical device 3 */
+ outb(0x07, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ /* Set parallel port to DMA channel 3, ECP+EPP1.9,
+ enable EPP timeout */
+ outb(0x74, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ outb(0xf0, INDEX_PORT);
+ outb(0x0f, DATA_PORT);
+
+ outb(0xf1, INDEX_PORT);
+ outb(0x07, DATA_PORT);
+
+ /* Select logical device 4 */
+ outb(0x07, INDEX_PORT);
+ outb(0x04, DATA_PORT);
+
+ /* UART1 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Select logical device 5 */
+ outb(0x07, INDEX_PORT);
+ outb(0x05, DATA_PORT);
+
+ /* UART2 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Set Aladdin to RUN mode */
+ outb(0xbb, CFG_PORT);
+ }
+
+ return 0;
+}
+
+__initcall(cats_hw_init);
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/cats-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/* cats host-specific stuff */
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+
+static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->irq >= 128)
+ return dev->irq & 0x1f;
+
+ if (dev->irq >= 1 && dev->irq <= 4)
+ return irqmap_cats[dev->irq - 1];
+
+ if (dev->irq != 0)
+ printk("PCI: device %02x:%02x has unknown irq line %x\n",
+ dev->bus->number, dev->devfn, dev->irq);
+
+ return -1;
+}
+
+struct hw_pci cats_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: cats_map_irq,
+};
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285-leds.c
+ *
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * EBSA-285 control routines.
+ *
+ * The EBSA-285 uses the leds as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Amber - On if system is not idle
+ * - Red - currently unused
+ *
+ * Changelog:
+ * 02-05-1999 RMK Various cleanups
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+static char led_state;
+static char hw_led_state;
+
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+
+static void ebsa285_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
+#ifndef CONFIG_LEDS_CPU
+ hw_led_state |= XBUS_LED_AMBER;
+#endif
+ led_state |= LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= XBUS_LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= XBUS_LED_AMBER;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~XBUS_LED_AMBER;
+ break;
+#endif
+
+ case led_halted:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~XBUS_LED_RED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_AMBER;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_AMBER;
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_RED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_RED;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ *XBUS_LEDS = hw_led_state;
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_ebsa285() || machine_is_co285())
+ leds_event = ebsa285_leds_event;
+
+ leds_event(led_start);
+
+ return 0;
+}
+
+__initcall(leds_init);
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
+
+static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return PCI_SLOT(dev->devfn);
+}
+
+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];
+}
+
+struct hw_pci ebsa285_pci __initdata = {
+ init: dc21285_init,
+ swizzle: ebsa285_swizzle,
+ map_irq: ebsa285_map_irq,
+};
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-hw.c
+ *
+ * Netwinder machine fixup
+ *
+ * Copyright (C) 1998, 1999 Russell King, Phil Blundell
+ */
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#define IRDA_IO_BASE 0x180
+#define GP1_IO_BASE 0x338
+#define GP2_IO_BASE 0x33a
+
+
+#ifdef CONFIG_LEDS
+#define DEFAULT_LEDS 0
+#else
+#define DEFAULT_LEDS GPIO_GREEN_LED
+#endif
+
+/*
+ * Winbond WB83977F accessibility stuff
+ */
+static inline void wb977_open(void)
+{
+ outb(0x87, 0x370);
+ outb(0x87, 0x370);
+}
+
+static inline void wb977_close(void)
+{
+ outb(0xaa, 0x370);
+}
+
+static inline void wb977_wb(int reg, int val)
+{
+ outb(reg, 0x370);
+ outb(val, 0x371);
+}
+
+static inline void wb977_ww(int reg, int val)
+{
+ outb(reg, 0x370);
+ outb(val >> 8, 0x371);
+ outb(reg + 1, 0x370);
+ outb(val, 0x371);
+}
+
+#define wb977_device_select(dev) wb977_wb(0x07, dev)
+#define wb977_device_disable() wb977_wb(0x30, 0x00)
+#define wb977_device_enable() wb977_wb(0x30, 0x01)
+
+/*
+ * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
+ */
+spinlock_t gpio_lock = SPIN_LOCK_UNLOCKED;
+
+static unsigned int current_gpio_op = 0;
+static unsigned int current_gpio_io = 0;
+static unsigned int current_cpld = 0;
+
+void gpio_modify_op(int mask, int set)
+{
+ unsigned int new_gpio, changed;
+
+ new_gpio = (current_gpio_op & ~mask) | set;
+ changed = new_gpio ^ current_gpio_op;
+ current_gpio_op = new_gpio;
+
+ if (changed & 0xff)
+ outb(new_gpio, GP1_IO_BASE);
+ if (changed & 0xff00)
+ outb(new_gpio >> 8, GP2_IO_BASE);
+}
+
+static inline void __gpio_modify_io(int mask, int in)
+{
+ unsigned int new_gpio, changed;
+ int port;
+
+ new_gpio = (current_gpio_io & ~mask) | in;
+ changed = new_gpio ^ current_gpio_io;
+ current_gpio_io = new_gpio;
+
+ changed >>= 1;
+ new_gpio >>= 1;
+
+ wb977_device_select(7);
+
+ for (port = 0xe1; changed && port < 0xe8; changed >>= 1) {
+ wb977_wb(port, new_gpio & 1);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+
+ wb977_device_select(8);
+
+ for (port = 0xe8; changed && port < 0xec; changed >>= 1) {
+ wb977_wb(port, new_gpio & 1);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+}
+
+void gpio_modify_io(int mask, int in)
+{
+ /* Open up the SuperIO chip */
+ wb977_open();
+
+ __gpio_modify_io(mask, in);
+
+ /* Close up the EFER gate */
+ wb977_close();
+}
+
+int gpio_read(void)
+{
+ return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8;
+}
+
+/*
+ * Initialise the Winbond W83977F global registers
+ */
+static inline void wb977_init_global(void)
+{
+ /*
+ * Enable R/W config registers
+ */
+ wb977_wb(0x26, 0x40);
+
+ /*
+ * Power down FDC (not used)
+ */
+ wb977_wb(0x22, 0xfe);
+
+ /*
+ * GP12, GP11, CIRRX, IRRXH, GP10
+ */
+ wb977_wb(0x2a, 0xc1);
+
+ /*
+ * GP23, GP22, GP21, GP20, GP13
+ */
+ wb977_wb(0x2b, 0x6b);
+
+ /*
+ * GP17, GP16, GP15, GP14
+ */
+ wb977_wb(0x2c, 0x55);
+}
+
+/*
+ * Initialise the Winbond W83977F printer port
+ */
+static inline void wb977_init_printer(void)
+{
+ wb977_device_select(1);
+
+ /*
+ * mode 1 == EPP
+ */
+ wb977_wb(0xf0, 0x01);
+}
+
+/*
+ * Initialise the Winbond W83977F keyboard controller
+ */
+static inline void wb977_init_keyboard(void)
+{
+ wb977_device_select(5);
+
+ /*
+ * Keyboard controller address
+ */
+ wb977_ww(0x60, 0x0060);
+ wb977_ww(0x62, 0x0064);
+
+ /*
+ * Keyboard IRQ 1, active high, edge trigger
+ */
+ wb977_wb(0x70, 1);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * Mouse IRQ 5, active high, edge trigger
+ */
+ wb977_wb(0x72, 5);
+ wb977_wb(0x73, 0x02);
+
+ /*
+ * KBC 8MHz
+ */
+ wb977_wb(0xf0, 0x40);
+
+ /*
+ * Enable device
+ */
+ wb977_device_enable();
+}
+
+/*
+ * Initialise the Winbond W83977F Infra-Red device
+ */
+static inline void wb977_init_irda(void)
+{
+ wb977_device_select(6);
+
+ /*
+ * IR base address
+ */
+ wb977_ww(0x60, IRDA_IO_BASE);
+
+ /*
+ * IRDA IRQ 6, active high, edge trigger
+ */
+ wb977_wb(0x70, 6);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * RX DMA - ISA DMA 0
+ */
+ wb977_wb(0x74, 0x00);
+
+ /*
+ * TX DMA - Disable Tx DMA
+ */
+ wb977_wb(0x75, 0x04);
+
+ /*
+ * Append CRC, Enable bank selection
+ */
+ wb977_wb(0xf0, 0x03);
+
+ /*
+ * Enable device
+ */
+ wb977_device_enable();
+}
+
+/*
+ * Initialise Winbond W83977F general purpose IO
+ */
+static inline void wb977_init_gpio(void)
+{
+ unsigned long flags;
+
+ /*
+ * Set up initial I/O definitions
+ */
+ current_gpio_io = -1;
+ __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER);
+
+ wb977_device_select(7);
+
+ /*
+ * Group1 base address
+ */
+ wb977_ww(0x60, GP1_IO_BASE);
+ wb977_ww(0x62, 0);
+ wb977_ww(0x64, 0);
+
+ /*
+ * GP10 (Orage button) IRQ 10, active high, edge trigger
+ */
+ wb977_wb(0x70, 10);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * GP10: Debounce filter enabled, IRQ, input
+ */
+ wb977_wb(0xe0, 0x19);
+
+ /*
+ * Enable Group1
+ */
+ wb977_device_enable();
+
+ wb977_device_select(8);
+
+ /*
+ * Group2 base address
+ */
+ wb977_ww(0x60, GP2_IO_BASE);
+
+ /*
+ * Clear watchdog timer regs
+ * - timer disable
+ */
+ wb977_wb(0xf2, 0x00);
+
+ /*
+ * - disable LED, no mouse nor keyboard IRQ
+ */
+ wb977_wb(0xf3, 0x00);
+
+ /*
+ * - timer counting, disable power LED, disable timeouot
+ */
+ wb977_wb(0xf4, 0x00);
+
+ /*
+ * Enable group2
+ */
+ wb977_device_enable();
+
+ /*
+ * Set Group1/Group2 outputs
+ */
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
+ spin_unlock_irqrestore(&gpio_loc, flags);
+}
+
+/*
+ * Initialise the Winbond W83977F chip.
+ */
+static void __init wb977_init(void)
+{
+ request_region(0x370, 2, "W83977AF configuration");
+
+ /*
+ * Open up the SuperIO chip
+ */
+ wb977_open();
+
+ /*
+ * Initialise the global registers
+ */
+ wb977_init_global();
+
+ /*
+ * Initialise the various devices in
+ * the multi-IO chip.
+ */
+ wb977_init_printer();
+ wb977_init_keyboard();
+ wb977_init_irda();
+ wb977_init_gpio();
+
+ /*
+ * Close up the EFER gate
+ */
+ wb977_close();
+}
+
+void cpld_modify(int mask, int set)
+{
+ int msk;
+
+ current_cpld = (current_cpld & ~mask) | set;
+
+ gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0);
+ gpio_modify_op(GPIO_IOLOAD, 0);
+
+ for (msk = 8; msk; msk >>= 1) {
+ int bit = current_cpld & msk;
+
+ gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0);
+ gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK);
+ }
+
+ gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0);
+ gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK);
+ gpio_modify_op(GPIO_IOLOAD, 0);
+}
+
+static void __init cpld_init(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+}
+
+static unsigned char rwa_unlock[] __initdata =
+{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b,
+ 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74,
+ 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
+
+#ifndef DEBUG
+#define dprintk(x...)
+#else
+#define dprintk(x...) printk(x)
+#endif
+
+#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0)
+
+static inline void rwa010_unlock(void)
+{
+ int i;
+
+ WRITE_RWA(2, 2);
+ mdelay(10);
+
+ for (i = 0; i < sizeof(rwa_unlock); i++) {
+ outb(rwa_unlock[i], 0x279);
+ udelay(10);
+ }
+}
+
+static inline void rwa010_read_ident(void)
+{
+ unsigned char si[9];
+ int i, j;
+
+ WRITE_RWA(3, 0);
+ WRITE_RWA(0, 128);
+
+ outb(1, 0x279);
+
+ mdelay(1);
+
+ dprintk("Identifier: ");
+ for (i = 0; i < 9; i++) {
+ si[i] = 0;
+ for (j = 0; j < 8; j++) {
+ int bit;
+ udelay(250);
+ inb(0x203);
+ udelay(250);
+ bit = inb(0x203);
+ dprintk("%02X ", bit);
+ bit = (bit == 0xaa) ? 1 : 0;
+ si[i] |= bit << j;
+ }
+ dprintk("(%02X) ", si[i]);
+ }
+ dprintk("\n");
+}
+
+static inline void rwa010_global_init(void)
+{
+ WRITE_RWA(6, 2); // Assign a card no = 2
+
+ dprintk("Card no = %d\n", inb(0x203));
+
+ /* disable the modem section of the chip */
+ WRITE_RWA(7, 3);
+ WRITE_RWA(0x30, 0);
+
+ /* disable the cdrom section of the chip */
+ WRITE_RWA(7, 4);
+ WRITE_RWA(0x30, 0);
+
+ /* disable the MPU-401 section of the chip */
+ WRITE_RWA(7, 2);
+ WRITE_RWA(0x30, 0);
+}
+
+static inline void rwa010_game_port_init(void)
+{
+ int i;
+
+ WRITE_RWA(7, 5);
+
+ dprintk("Slider base: ");
+ WRITE_RWA(0x61, 1);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, 2);
+ dprintk("%02X%02X (201)\n", inb(0x203), i);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static inline void rwa010_waveartist_init(int base, int irq, int dma)
+{
+ int i;
+
+ WRITE_RWA(7, 0);
+
+ dprintk("WaveArtist base: ");
+ WRITE_RWA(0x61, base);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, base >> 8);
+ dprintk("%02X%02X (%X),", inb(0x203), i, base);
+
+ WRITE_RWA(0x70, irq);
+ dprintk(" irq: %d (%d),", inb(0x203), irq);
+
+ WRITE_RWA(0x74, dma);
+ dprintk(" dma: %d (%d)\n", inb(0x203), dma);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma)
+{
+ int i;
+
+ WRITE_RWA(7, 1);
+
+ dprintk("SoundBlaster base: ");
+ WRITE_RWA(0x61, sb_base);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, sb_base >> 8);
+ dprintk("%02X%02X (%X),", inb(0x203), i, sb_base);
+
+ dprintk(" irq: ");
+ WRITE_RWA(0x70, irq);
+ dprintk("%d (%d),", inb(0x203), irq);
+
+ dprintk(" 8-bit DMA: ");
+ WRITE_RWA(0x74, dma);
+ dprintk("%d (%d)\n", inb(0x203), dma);
+
+ dprintk("AdLib base: ");
+ WRITE_RWA(0x63, al_base);
+ i = inb(0x203);
+
+ WRITE_RWA(0x62, al_base >> 8);
+ dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static void rwa010_soundblaster_reset(void)
+{
+ int i;
+
+ outb(1, 0x226);
+ udelay(3);
+ outb(0, 0x226);
+
+ for (i = 0; i < 5; i++) {
+ if (inb(0x22e) & 0x80)
+ break;
+ mdelay(1);
+ }
+ if (i == 5)
+ printk("SoundBlaster: DSP reset failed\n");
+
+ dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a));
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: DSP not ready\n");
+ else {
+ outb(0xe1, 0x22c);
+
+ dprintk("SoundBlaster DSP id: ");
+ i = inb(0x22a);
+ udelay(1);
+ i |= inb(0x22a) << 8;
+ dprintk("%04X\n", i);
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: could not turn speaker off\n");
+
+ outb(0xd3, 0x22c);
+ }
+
+ /* turn on OPL3 */
+ outb(5, 0x38a);
+ outb(1, 0x38b);
+}
+
+static void __init rwa010_init(void)
+{
+ rwa010_unlock();
+ rwa010_read_ident();
+ rwa010_global_init();
+ rwa010_game_port_init();
+ rwa010_waveartist_init(0x250, 3, 7);
+ rwa010_soundblaster_init(0x220, 0x388, 3, 1);
+ rwa010_soundblaster_reset();
+}
+
+EXPORT_SYMBOL(gpio_lock);
+EXPORT_SYMBOL(gpio_modify_op);
+EXPORT_SYMBOL(gpio_modify_io);
+EXPORT_SYMBOL(cpld_modify);
+
+/*
+ * Initialise any other hardware after we've got the PCI bus
+ * initialised. We may need the PCI bus to talk to this other
+ * hardware.
+ */
+static int __init nw_hw_init(void)
+{
+ if (machine_is_netwinder()) {
+ unsigned long flags;
+
+ wb977_init();
+ cpld_init();
+ rwa010_init();
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ }
+ return 0;
+}
+
+__initcall(nw_hw_init);
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-leds.c
+ *
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * NetWinder LED control routines.
+ *
+ * The Netwinder uses the leds as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Red - On if the system is not idle
+ *
+ * Changelog:
+ * 02-05-1999 RMK Various cleanups
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+static char led_state;
+static char hw_led_state;
+
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+extern spinlock_t gpio_lock;
+
+static void netwinder_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch (evt) {
+ case led_start:
+ led_state |= LED_STATE_ENABLED;
+ hw_led_state = GPIO_GREEN_LED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= GPIO_GREEN_LED;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+#endif
+
+ case led_halted:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_GREEN_LED;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ default:
+ break;
+ }
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+
+ if (led_state & LED_STATE_ENABLED) {
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ }
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_netwinder())
+ leds_event = netwinder_leds_event;
+
+ leds_event(led_start);
+
+ return 0;
+}
+
+__initcall(leds_init);
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/* netwinder host-specific stuff */
+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):
+ return IRQ_NETWINDER_ETHER10;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
+ return 0;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
+ 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):
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000):
+ return IRQ_NETWINDER_VGA;
+
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285):
+ return 0;
+
+ default:
+ printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
+ dev->bus->number, dev->devfn,
+ dev->vendor, dev->device);
+ return 0;
+ }
+}
+
+struct hw_pci netwinder_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: netwinder_map_irq,
+};
--- /dev/null
+/*
+ * linux/arch/arm/mach-footbridge/personal-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+static int irqmap_personal_server[] __initdata = {
+ IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
+ IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
+};
+
+static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char line;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+
+ if (line > 0x40 && line <= 0x5f) {
+ /* line corresponds to the bit controlling this interrupt
+ * in the footbridge. Ignore the first 8 interrupt bits,
+ * look up the rest in the map. IN0 is bit number 8
+ */
+ return irqmap_personal_server[(line & 0x1f) - 8];
+ } else if (line == 0) {
+ /* no interrupt */
+ return 0;
+ } else
+ return irqmap_personal_server[(line - 1) & 3];
+}
+
+struct hw_pci personal_server_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: personal_server_map_irq,
+};
xp860 SA1100_XP860 XP860 30
cerf SA1100_CERF CERF 31
nanoengine SA1100_NANOENGINE NANOENGINE 32
+fpic SA1100_FPIC FPIC 33
+extenex1 SA1100_EXTENEX1 EXTENEX1 34
+sherman SA1100_SHERMAN SHERMAN 35
+accelent_sa SA1100_ACCELENT ACCELENT_SA 36
+accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37
# The following are unallocated
empeg SA1100_EMPEG EMPEG
.bss : {
- __bss_start = .; /* BSS */
+ __bss_start = .; /* BSS */
*(.bss)
- _end = . ;
+ *(COMMON)
+ _end = . ;
}
/* Stabs debugging sections. */
*(.text.lock) /* out-of-line lock text */
*(.rodata)
*(.kstrtab)
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
+ . = ALIGN(16);
+ __start___ex_table = .; /* Exception table */
*(__ex_table)
__stop___ex_table = .;
{
struct task_struct *tsk = current;
+ unlazy_fpu( tsk );
tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
if ( __copy_to_user( buf, &tsk->thread.i387.fsave,
sizeof(struct i387_fsave_struct) ) )
struct task_struct *tsk = current;
int err = 0;
+ unlazy_fpu( tsk );
+
if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) )
return -1;
case EFL:
value &= FLAG_MASK;
value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
+ break;
+ case EIP:
+ /* Mark us as not being in a system call, so that no restart issues happen */
+ put_stack_long(child, 4*ORIG_EAX - sizeof(struct pt_regs), -1);
+ break;
}
if (regno > GS*4)
regno -= 2*4;
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
notes[0].datasz = sizeof(prstatus);
notes[0].data = &prstatus;
prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
- prstatus.pr_sigpend = current->signal.sig[0];
+ prstatus.pr_sigpend = current->pending.signal.sig[0];
prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
asmlinkage int irix_sigpending(irix_sigset_t *set)
{
- int err;
-
- if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0)
- return -EFAULT;
-
- /* fill in "set" with signals pending but blocked. */
- spin_lock_irq(¤t->sigmask_lock);
- err = __put_user(current->blocked.sig[0] & current->signal.sig[0],
- &set->sig[0]);
- err |= __put_user(current->blocked.sig[1] & current->signal.sig[1],
- &set->sig[1]);
- err |= __put_user(current->blocked.sig[2] & current->signal.sig[2],
- &set->sig[2]);
- err |= __put_user(current->blocked.sig[3] & current->signal.sig[3],
- &set->sig[3]);
- spin_unlock_irq(¤t->sigmask_lock);
-
- return err;
+ return do_sigpending(set, sizeof(*set));
}
asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
expire = schedule_timeout(expire);
for (i=0; i<=4; i++)
- tmp |= (current->signal.sig[i] & kset.sig[i]);
+ tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
if (tmp)
break;
for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
if (sigismember (&kset, sig))
continue;
- if (sigismember (¤t->signal, sig)) {
+ if (sigismember (¤t->pending.signal, sig)) {
/* XXX need more than this... */
if (info)
info->sig = sig;
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
default:
lock_kernel();
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
default:
lock_kernel();
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* FALLTHRU */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
#endif
/* fall through */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
#endif
/* fall through */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
#endif
/* fall through */
default:
- sigaddset(¤t->signal, signr);
+ sigaddset(¤t->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
switch (which) {
case 1: /* sigpending */
spin_lock_irq(¤t->sigmask_lock);
- sigandsets(&s, ¤t->blocked, ¤t->signal);
+ sigandsets(&s, ¤t->blocked, ¤t->pending.signal);
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
break;
i, *ft_buffer[i]->address);
}
}
- if (sigtestsetmask(¤t->signal, _DONT_BLOCK) &&
- !(sigtestsetmask(¤t->signal, _NEVER_BLOCK)) &&
+ if (sigtestsetmask(¤t->pending.signal, _DONT_BLOCK) &&
+ !(sigtestsetmask(¤t->pending.signal, _NEVER_BLOCK)) &&
ftape_tape_running) {
TRACE(ft_t_warn,
"Interrupted by fatal signal and tape still running");
result = ftape_ready_wait(ftape_timeout.pause,&status);
}
} while (ftape_tape_running
- && !(sigtestsetmask(¤t->signal, _NEVER_BLOCK)));
+ && !(sigtestsetmask(¤t->pending.signal, _NEVER_BLOCK)));
#ifndef TESTING
ft_location.known = 0;
#endif
* to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!!
*/
if (ftape_read_id() < 0 || !ft_location.known ||
- sigtestsetmask(¤t->signal, _DONT_BLOCK)) {
+ sigtestsetmask(¤t->pending.signal, _DONT_BLOCK)) {
ft_location.known = 0;
if (!ftape_tape_running ||
++failures > FT_SECTORS_PER_SEGMENT) {
fast_seek(count, 1);
logical_forward();
if (ftape_read_id() < 0 || !ft_location.known ||
- (sigtestsetmask(¤t->signal, _DONT_BLOCK))) {
+ (sigtestsetmask(¤t->pending.signal, _DONT_BLOCK))) {
if ((!ftape_tape_running && !ft_location.known) ||
++failures > FT_SECTORS_PER_SEGMENT) {
TRACE_ABORT(-EIO, ft_t_err,
while (result < 0 &&
retry++ <= 5 &&
!ft_failure &&
- !(sigtestsetmask(¤t->signal, _DONT_BLOCK))) {
+ !(sigtestsetmask(¤t->pending.signal, _DONT_BLOCK))) {
if (retry && start_offset < 5) {
start_offset ++;
* but rather into ftape-rw.h (maybe)
*/
#define FT_SIGNAL_EXIT(sig_mask) \
- if (sigtestsetmask(¤t->signal, sig_mask)) { \
+ if (sigtestsetmask(¤t->pending.signal, sig_mask)) { \
TRACE_ABORT(-EINTR, \
ft_t_warn, \
"interrupted by non-blockable signal"); \
static inline int signal_pending(struct task_struct *p)
{
- return (p->signal & (~p->blocked != 0));
+ return (p->signal & ~p->blocked) != 0;
}
#else
return 0;
}
+/*
+ * If it would be '74 that would go into libc...
+ */
+int mem_is_zero(char *p, unsigned len)
+{
+ while (len--)
+ if (*p++)
+ return 0;
+ return 1;
+}
+
+int block_zero_page(struct address_space *mapping, loff_t from, unsigned length)
+{
+ unsigned long index = from >> PAGE_CACHE_SHIFT;
+ unsigned offset = from & (PAGE_CACHE_SIZE-1);
+ struct inode *inode = (struct inode *)mapping->host;
+ struct page *page;
+ char *kaddr;
+ int err;
+
+ if (!length)
+ return 0;
+
+ page = read_cache_page(mapping, index,
+ (filler_t *)mapping->a_ops->readpage, NULL);
+ err = PTR_ERR(page);
+ if (ERR_PTR(page))
+ goto out;
+ lock_page(page);
+ err = -EIO;
+ if (!Page_Uptodate(page))
+ goto unlock;
+ kaddr = (char*)kmap(page);
+ err = 0;
+ if (mem_is_zero(kaddr+offset, length))
+ goto unmap;
+ memset(kaddr+offset, 0, length);
+ flush_dcache_page(page);
+ __block_commit_write(inode, page, offset, offset+length);
+unmap:
+ kunmap(page);
+unlock:
+ UnlockPage(page);
+ page_cache_release(page);
+out:
+ return err;
+}
+
int block_write_full_page(struct page *page, get_block_t *get_block)
{
struct inode *inode = (struct inode*)page->mapping->host;
if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) {
/* if this process really wants to die, let it go */
- if ( sigismember(&(current->signal), SIGKILL) ||
- sigismember(&(current->signal), SIGINT) )
+ if ( sigismember(&(current->pending.signal), SIGKILL) ||
+ sigismember(&(current->pending.signal), SIGINT) )
break;
/* signal is present: after timeout always return
really smart idea, probably useless ... */
int nr = 0;
int n;
long iblock;
+ unsigned blocksize, tail;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
ext2_discard_prealloc(inode);
- iblock = (inode->i_size + inode->i_sb->s_blocksize-1)
+ blocksize = inode->i_sb->s_blocksize;
+ iblock = (inode->i_size + blocksize-1)
>> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
+ tail = (iblock << EXT2_BLOCK_SIZE_BITS(inode->i_sb)) - inode->i_size;
+
+ if (block_zero_page(inode->i_mapping, inode->i_size, tail) != 0)
+ return;
n = ext2_block_to_path(inode, iblock, offsets);
if (n == 0)
DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
spin_lock_irqsave(¤t->sigmask_lock, flags);
- sigpipe = sigismember(¤t->signal, SIGPIPE);
+ sigpipe = sigismember(¤t->pending.signal, SIGPIPE);
old_set = current->blocked;
siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
recalc_sigpending(current);
/* read/write errors are handled by errno */
spin_lock_irqsave(¤t->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe)
- sigdelset(¤t->signal, SIGPIPE);
+ sigdelset(¤t->pending.signal, SIGPIPE);
current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(¤t->sigmask_lock, flags);
goto bad_conn;
spin_lock_irqsave(¤t->sigmask_lock, flags);
- sigpipe = sigismember(¤t->signal, SIGPIPE);
+ sigpipe = sigismember(¤t->pending.signal, SIGPIPE);
old_set = current->blocked;
siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
recalc_sigpending(current);
/* read/write errors are handled by errno */
spin_lock_irqsave(¤t->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe)
- sigdelset(¤t->signal, SIGPIPE);
+ sigdelset(¤t->pending.signal, SIGPIPE);
current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(¤t->sigmask_lock, flags);
}
}
+ irq_mask[IRQ_KEYBOARDTX].noautoenable = 1;
+
init_FIQ();
}
#endif
do_leds();
do_timer(regs);
+ do_profile(regs);
}
/*
/* Virtual Physical Size
* 0xff800000 0x40000000 1MB X-Bus
* 0xff000000 0x7c000000 1MB PCI I/O space
- *
* 0xfe000000 0x42000000 1MB CSR
* 0xfd000000 0x78000000 1MB Outbound write flush (not supported)
* 0xfc000000 0x79000000 1MB PCI IACK/special space
- *
* 0xfb000000 0x7a000000 16MB PCI Config type 1
* 0xfa000000 0x7b000000 16MB PCI Config type 0
- *
* 0xf9000000 0x50000000 1MB Cache flush
- * 0xf8000000 0x41000000 16MB Flash memory
- *
- * 0xe1000000 unmapped (to catch bad ISA/PCI)
- *
- * 0xe0000000 0x80000000 16MB ISA memory
+ * 0xf0000000 0x80000000 16MB ISA memory
*/
#define XBUS_SIZE 0x00100000
#define XBUS_BASE 0xff800000
#define FLUSH_SIZE 0x00100000
#define FLUSH_BASE 0xf9000000
-#define FLASH_SIZE 0x01000000
-#define FLASH_BASE 0xf8000000
-
#define PCIMEM_SIZE 0x01000000
#define PCIMEM_BASE 0xf0000000
#define PCIMEM_SIZE 0x80000000
#define PCIMEM_BASE 0x80000000
-#define FLASH_SIZE 0x01000000
-#define FLASH_BASE 0x7f000000
-
#define FLUSH_SIZE 0x00100000
#define FLUSH_BASE 0x7e000000
*
* Copyright (C) 1996-1999 Russell King
*/
+#include <asm/mach-types.h>
/*
* Note! This could cause problems on the NetWinder
#define INTCONT_LED 0x1a
#define INTCONT_PCI_RESET 0x1c
+#define UNCACHEABLE_ADDR STATUS_BASE
+
#endif
__raw_writeb(0x10, DUART_BASE + 0x14);
timer_irq.handler = timer_interrupt;
+ timer_irq.flags = SA_SHIRQ;
setup_arm_irq(IRQ_TIMER, &timer_irq);
}
*/
static void puts(const char *s)
{
- while (*s)
+ while (*s) {
+ if (*s == '\n')
+ _ll_write_char('\r');
_ll_write_char(*(s++));
+ }
}
/*
irq_desc[irq].unmask = rpc_unmask_irq_b;
break;
- case 16 ... 22:
+ case 16 ... 21:
irq_desc[irq].valid = 1;
+ irq_desc[irq].noautoenable = 1;
irq_desc[irq].mask_ack = rpc_mask_irq_dma;
irq_desc[irq].mask = rpc_mask_irq_dma;
irq_desc[irq].unmask = rpc_unmask_irq_dma;
break;
- case 32 ... 40:
+ case 32 ... 39:
irq_desc[irq].valid = 1;
irq_desc[irq].mask_ack = ecard_disableirq;
irq_desc[irq].mask = ecard_disableirq;
irq_desc[irq].unmask = ecard_enableirq;
break;
- case 64 ... 72:
+ case 64 ... 71:
irq_desc[irq].valid = 1;
irq_desc[irq].mask_ack = rpc_mask_irq_fiq;
irq_desc[irq].mask = rpc_mask_irq_fiq;
}
}
+ irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
+
init_FIQ();
}
#ifndef _ASMARM_CURRENT_H
#define _ASMARM_CURRENT_H
-static inline unsigned long get_sp(void)
-{
- unsigned long sp;
- __asm__ ("mov %0,sp" : "=r" (sp));
- return sp;
-}
-
/* Old compilers seem to generate bad code if we allow `current' to be
non volatile. */
#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90)
static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
-#define __VOLATILE_CURRENT
-#else
-#define __VOLATILE_CURRENT volatile
#endif
static inline struct task_struct *get_current(void)
{
- struct task_struct *ts;
- __asm__ __VOLATILE_CURRENT (
- "bic %0, sp, #0x1f00 @ get_current
- bic %0, %0, #0x00ff"
- : "=r" (ts));
- return ts;
+ register unsigned long sp asm ("sp");
+ return (struct task_struct *)(sp & ~0x1fff);
}
#define current (get_current())
#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/memory.h>
+#include <asm/scatterlist.h>
#include <asm/arch/dma.h>
/*
--- /dev/null
+/*
+ * linux/include/asm-arm/mach/arch.h
+ *
+ * Copyright (C) 2000 Russell King
+ */
+
+/*
+ * The size of struct machine_desc
+ * (for assembler code)
+ */
+#define SIZEOF_MACHINE_DESC 44
+
+#ifndef __ASSEMBLY__
+
+struct machine_desc {
+ /*
+ * Note! The first four elements are used
+ * by assembler code in head-armv.S
+ */
+ unsigned int nr; /* architecture number */
+ unsigned int phys_ram; /* start of physical ram */
+ unsigned int phys_io; /* start of physical io */
+ unsigned int virt_io; /* start of virtual io */
+
+ const char *name; /* architecture name */
+ unsigned int param_offset; /* parameter page */
+
+ unsigned int video_start; /* start of video RAM */
+ unsigned int video_end; /* end of video RAM */
+
+ 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 */
+ void (*fixup)(struct machine_desc *,
+ struct param_struct *, char **,
+ struct meminfo *);
+ void (*map_io)(void);/* IO mapping function */
+};
+
+/*
+ * Set of macros to define architecture features. This is built into
+ * a table by the linker.
+ */
+#define MACHINE_START(_type,_name) \
+const struct machine_desc __mach_desc_##_type \
+ __attribute__((__section__(".arch.info"))) = { \
+ nr: MACH_TYPE_##_type##, \
+ name: _name,
+
+#define MAINTAINER(n)
+
+#define BOOT_MEM(_pram,_pio,_vio) \
+ phys_ram: _pram, \
+ phys_io: _pio, \
+ virt_io: _vio,
+
+#define BOOT_PARAMS(_params) \
+ param_offset: _params,
+
+#define VIDEO(_start,_end) \
+ video_start: _start, \
+ video_end: _end,
+
+#define DISABLE_PARPORT(_n) \
+ reserve_lp##_n##: 1,
+
+#define BROKEN_HLT \
+ broken_hlt: 1,
+
+#define SOFT_REBOOT \
+ soft_reboot: 1,
+
+#define FIXUP(_func) \
+ fixup: _func,
+
+#define MAPIO(_func) \
+ map_io: _func,
+
+#define MACHINE_END \
+};
+
+#endif
--- /dev/null
+/*
+ * linux/arch/arm/kernel/dma.h
+ *
+ * Copyright (C) 1998-2000 Russell King
+ *
+ * This header file describes the interface between the generic DMA handler
+ * (dma.c) and the architecture-specific DMA backends (dma-*.c)
+ */
+
+struct dma_struct;
+typedef struct dma_struct dma_t;
+
+struct dma_ops {
+ int (*request)(dmach_t, dma_t *); /* optional */
+ void (*free)(dmach_t, dma_t *); /* optional */
+ void (*enable)(dmach_t, dma_t *); /* mandatory */
+ void (*disable)(dmach_t, dma_t *); /* mandatory */
+ int (*residue)(dmach_t, dma_t *); /* optional */
+ int (*setspeed)(dmach_t, dma_t *, int); /* optional */
+ char *type;
+};
+
+struct dma_struct {
+ struct scatterlist buf; /* single DMA */
+ int sgcount; /* number of DMA SG */
+ struct scatterlist *sg; /* DMA Scatter-Gather List */
+
+ unsigned int active:1; /* Transfer active */
+ unsigned int invalid:1; /* Address/Count changed */
+ unsigned int using_sg:1; /* using scatter list? */
+ dmamode_t dma_mode; /* DMA mode */
+ int speed; /* DMA speed */
+
+ unsigned int lock; /* Device is allocated */
+ const char *device_id; /* Device name */
+
+ unsigned int dma_base; /* Controller base address */
+ int dma_irq; /* Controller IRQ */
+ int state; /* Controller state */
+ struct scatterlist cur_sg; /* Current controller buffer */
+
+ struct dma_ops *d_ops;
+};
+
+/* Prototype: void arch_dma_init(dma)
+ * Purpose : Initialise architecture specific DMA
+ * Params : dma - pointer to array of DMA structures
+ */
+void arch_dma_init(dma_t *dma);
--- /dev/null
+/*
+ * linux/include/asm-arm/map.h
+ *
+ * Copyright (C) 1999-2000 Russell King
+ *
+ * Page table mapping constructs and function prototypes
+ */
+struct map_desc {
+ unsigned long virtual;
+ unsigned long physical;
+ unsigned long length;
+ int domain:4,
+ prot_read:1,
+ prot_write:1,
+ cacheable:1,
+ bufferable:1,
+ last:1;
+};
+
+#define LAST_DESC \
+ { last: 1 }
+
+struct meminfo;
+
+extern void create_memmap_holes(struct meminfo *);
+extern void memtable_init(struct meminfo *);
+extern void iotable_init(struct map_desc *);
+extern void setup_io_desc(void);
--- /dev/null
+/*
+ * linux/include/asm-arm/mach/pci.h
+ */
+#define MAX_NR_BUS 2
+
+struct arm_bus_sysdata {
+ /*
+ * bitmask of features we can turn.
+ * See PCI command register for more info.
+ */
+ u16 features;
+ /*
+ * Maximum devsel for this bus.
+ */
+ u16 maxdevsel;
+ /*
+ * The maximum latency that devices on this
+ * bus can withstand.
+ */
+ u8 max_lat;
+};
+
+struct arm_pci_sysdata {
+ struct arm_bus_sysdata bus[MAX_NR_BUS];
+};
+
+struct hw_pci {
+ void (*init)(struct arm_pci_sysdata *);
+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
+ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+};
+
+extern u8 no_swizzle(struct pci_dev *dev, u8 *pin);
+
+void __init dc21285_init(struct arm_pci_sysdata *);
+void __init plx90x0_init(struct arm_pci_sysdata *);
#define destroy_context(mm) do { } while(0)
#define init_new_context(tsk,mm) 0
+/*
+ * This is called when "tsk" is about to enter lazy TLB mode.
+ *
+ * mm: describes the currently active mm context
+ * tsk: task which is entering lazy tlb
+ * cpu: cpu number which is entering lazy tlb
+ *
+ * tsk->mm will be NULL
+ */
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
{
}
+
/*
* This is the actual mm switch as far as the scheduler
* is concerned. No registers are touched.
{
int i;
- for (i = 0; i < nents; i++, sg++)
+ for (i = 0; i < nents; i++, sg++) {
consistent_sync(sg->address, sg->length, direction);
+ sg->dma_address = virt_to_bus(sg->address);
+ }
return nents;
}
int i;
for (i = 0; i < nelems; i++, sg++)
- consistent_sync(sg->address, sg->length, 3);
+ consistent_sync(sg->address, sg->length, direction);
}
/* Return whether the given PCI device DMA address mask can
return 1;
}
-/* These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
- */
-#define sg_dma_address(sg) (virt_to_bus((sg)->address))
-#define sg_dma_len(sg) ((sg)->length)
-
#endif /* __KERNEL__ */
#endif
*/
#include <asm/proc/cache.h>
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start,
- unsigned long end)
-{
-}
+/*
+ * ARM processors do not cache TLB tables in RAM.
+ */
+#define flush_tlb_pgtables(mm,start,end) do { } while (0)
/*
* Page table cache stuff
.macro restore_irqs, oldcpsr
@ This be restore_irqs
.endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do. On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+ .macro save_lr
+ str lr, [sp, #-4]!
+ .endm
+
+ .macro restore_pc
+ ldmfd sp!, {pc}^
+ .endm
+
+#define USER(x...) \
+9999: x; \
+ .section __ex_table,"a"; \
+ .align 3; \
+ .long 9999b,9001f; \
+ .previous
+
+
/*
- * Cache flushing...
+ * Cache handling for 26-bit ARM processors.
*/
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_range(mm,start,end) do { } while (0)
#define flush_cache_page(vma,vmaddr) do { } while (0)
#define flush_page_to_ram(page) do { } while (0)
+
+#define invalidate_dcache_range(start,end) do { } while (0)
+#define clean_dcache_range(start,end) do { } while (0)
+#define flush_dcache_range(start,end) do { } while (0)
#define flush_dcache_page(page) do { } while (0)
-#define flush_icache_page(vma,page) do { } while (0)
+#define clean_dcache_entry(_s) do { } while (0)
+#define clean_cache_entry(_start) do { } while (0)
+
#define flush_icache_range(start,end) do { } while (0)
+#define flush_icache_page(vma,page) do { } while (0)
/* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
#define clean_cache_area(_start,_size) do { } while (0)
({ \
__asm__ __volatile__ ( \
"@ atomic down operation\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
" ldr lr, [%0]\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
" subs lr, lr, #1\n" \
" str lr, [%0]\n" \
-" orrmi r0, r0, #0x80000000 @ set N\n" \
-" teqp r0, #0\n" \
-" movmi r0, %0\n" \
+" orrmi ip, ip, #0x80000000 @ set N\n" \
+" teqp ip, #0\n" \
+" movmi ip, %0\n" \
" blmi " SYMBOL_NAME_STR(fail) \
: \
: "r" (ptr) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
})
#define __down_op_ret(ptr,fail) \
unsigned int result; \
__asm__ __volatile__ ( \
" @ down_op_ret\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
" ldr lr, [%1]\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
" subs lr, lr, #1\n" \
" str lr, [%1]\n" \
-" orrmi r0, r0, #0x80000000 @ set N\n" \
-" teqp r0, #0\n" \
-" movmi r0, %1\n" \
-" movpl r0, #0\n" \
+" orrmi ip, ip, #0x80000000 @ set N\n" \
+" teqp ip, #0\n" \
+" movmi ip, %1\n" \
+" movpl ip, #0\n" \
" blmi " SYMBOL_NAME_STR(fail) "\n" \
-" mov %0, r0" \
+" mov %0, ip" \
: "=&r" (result) \
: "r" (ptr) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
result; \
})
({ \
__asm__ __volatile__ ( \
"@ up_op\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
" ldr lr, [%0]\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
" adds lr, lr, #1\n" \
" str lr, [%0]\n" \
-" orrle r0, r0, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
-" teqp r0, #0\n" \
-" movmi r0, %0\n" \
+" orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
+" teqp ip, #0\n" \
+" movmi ip, %0\n" \
" blmi " SYMBOL_NAME_STR(wake) \
: \
: "r" (ptr) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
})
/*
({ \
__asm__ __volatile__( \
"@ down_op_write\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
\
" ldr lr, [%0]\n" \
" subs lr, lr, %1\n" \
" str lr, [%0]\n" \
\
-" orreq r0, r0, #0x40000000 @ set Z \n"\
-" teqp r0, #0\n" \
-" movne r0, %0\n" \
+" orreq ip, ip, #0x40000000 @ set Z \n"\
+" teqp ip, #0\n" \
+" movne ip, %0\n" \
" blne " SYMBOL_NAME_STR(fail) \
: \
: "r" (ptr), "I" (RW_LOCK_BIAS) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
})
/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
({ \
__asm__ __volatile__( \
"@ up_op_read\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
\
" ldr lr, [%0]\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
" adds lr, lr, %1\n" \
" str lr, [%0]\n" \
\
-" orrcs r0, r0, #0x20000000 @ set C\n" \
-" teqp r0, #0\n" \
-" movcs r0, %0\n" \
+" orrcs ip, ip, #0x20000000 @ set C\n" \
+" teqp ip, #0\n" \
+" movcs ip, %0\n" \
" blcs " SYMBOL_NAME_STR(wake) \
: \
: "r" (ptr), "I" (RW_LOCK_BIAS) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
})
#define __down_op_read(ptr,fail) \
({ \
__asm__ __volatile__( \
"@ up_op_read\n" \
-" mov r0, pc\n" \
-" orr lr, r0, #0x08000000\n" \
+" mov ip, pc\n" \
+" orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \
\
" ldr lr, [%0]\n" \
-" and r0, r0, #0x0c000003\n" \
+" and ip, ip, #0x0c000003\n" \
" adds lr, lr, %1\n" \
" str lr, [%0]\n" \
\
-" orreq r0, r0, #0x40000000 @ Set Z \n" \
-" teqp r0, #0\n" \
-" moveq r0, %0\n" \
+" orreq ip, ip, #0x40000000 @ Set Z \n" \
+" teqp ip, #0\n" \
+" moveq ip, %0\n" \
" bleq " SYMBOL_NAME_STR(wake) \
: \
: "r" (ptr), "I" (1) \
- : "r0", "lr", "cc"); \
+ : "ip", "lr", "cc"); \
})
#endif
.macro restore_irqs, oldcpsr
msr cpsr_c, \oldcpsr
.endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do. On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+ .macro save_lr
+ .endm
+
+ .macro restore_pc
+ mov pc, lr
+ .endm
+
+#define USER(x...) \
+9999: x; \
+ .section __ex_table,"a"; \
+ .align 3; \
+ .long 9999b,9001f; \
+ .previous
+
+
: "memory"); \
})
+/*
+ * Enable FIQs
+ */
+#define __stf() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ stf\n" \
+" bic %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory"); \
+ })
+
+/*
+ * Disable FIQs
+ */
+#define __clf() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ clf\n" \
+" orr %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory"); \
+ })
+
/*
* save current IRQ & FIQ state
*/
#include <asm/proc/ptrace.h>
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-
#ifndef __ASSEMBLY__
#define pc_pointer(v) \
((v) & ~PCMASK)
(pc_pointer((regs)->ARM_pc))
#ifdef __KERNEL__
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
extern void show_regs(struct pt_regs *);
#define predicate(x) (x & 0xf0000000)
#ifndef _ASMARM_SCATTERLIST_H
#define _ASMARM_SCATTERLIST_H
+#include <asm/types.h>
+
struct scatterlist {
- char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
- unsigned int length;
+ char *address; /* virtual address */
+ char *alt_address; /* indirect dma address, or NULL */
+ dma_addr_t dma_address; /* dma address */
+ unsigned int length; /* length */
};
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
#define ISA_DMA_THRESHOLD (0xffffffff)
#endif /* _ASMARM_SCATTERLIST_H */
#include <asm/proc/shmparam.h>
+/*
+ * This should be the size of the virtually indexed cache/ways,
+ * or page size, whichever is greater since the cache aliases
+ * every size/ways bytes.
+ */
#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
#endif /* _ASMARM_SHMPARAM_H */
* amount of physical memory you can use to about 950MB.
*
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
- * amd CONFIG_HIGHMEM64G options in the kernel configuration.
+ * and CONFIG_HIGHMEM64G options in the kernel configuration.
*/
#define __PAGE_OFFSET (0xC0000000)
* I expect future Intel CPU's to have a weaker ordering,
* but I'd also expect them to finally get their act together
* and add some real memory barriers if so.
+ *
+ * The Pentium III does add a real memory barrier with the
+ * sfence instruction, so we use that where appropriate.
*/
+#ifndef CONFIG_X86_XMM
#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#else
+#define mb() __asm__ __volatile__ ("sfence": : :"memory")
+#endif
#define rmb() mb()
#define wmb() __asm__ __volatile__ ("": : :"memory")
#define set_mb(var, value) do { xchg(&var, value); } while (0)
int generic_block_bmap(struct address_space *, long, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
+int block_zero_page(struct address_space *mapping, loff_t, unsigned);
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
struct signal_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
- struct sigpending pending;
spinlock_t siglock;
};
#define INIT_SIGNALS { \
ATOMIC_INIT(1), \
{ {{0,}}, }, \
- { NULL, &init_signals.pending.head, }, \
SPIN_LOCK_UNLOCKED }
/*
* Re-calculate pending state from the set of locally pending
* signals, globally pending signals, and blocked signals.
*/
-static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *blocked)
+static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
{
unsigned long ready;
long i;
switch (_NSIG_WORDS) {
default:
for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;)
- ready |= (p1->sig[i] | p2->sig[i]) &~ blocked->sig[i];
+ ready |= signal->sig[i] &~ blocked->sig[i];
break;
- case 4: ready = (p1->sig[3] | p2->sig[3]) &~ blocked->sig[3];
- ready |= (p1->sig[2] | p2->sig[2]) &~ blocked->sig[2];
- ready |= (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1];
- ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
+ case 4: ready = signal->sig[3] &~ blocked->sig[3];
+ ready |= signal->sig[2] &~ blocked->sig[2];
+ ready |= signal->sig[1] &~ blocked->sig[1];
+ ready |= signal->sig[0] &~ blocked->sig[0];
break;
- case 2: ready = (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1];
- ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
+ case 2: ready = signal->sig[1] &~ blocked->sig[1];
+ ready |= signal->sig[0] &~ blocked->sig[0];
break;
- case 1: ready = (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0];
+ case 1: ready = signal->sig[0] &~ blocked->sig[0];
}
return ready != 0;
}
static inline void recalc_sigpending(struct task_struct *t)
{
- t->sigpending = has_pending_signals(&t->pending.signal, &t->sig->pending.signal, &t->blocked);
+ t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked);
}
/* True if we are on the alternate signal stack. */
sig->tail = &sig->head;
}
+extern long do_sigpending(void *, unsigned long);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SIGNAL_H */
return -1;
spin_lock_init(&sig->siglock);
atomic_set(&sig->count, 1);
-
- init_sigpending(&sig->pending);
-
memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
return 0;
}
EXPORT_SYMBOL(block_sync_page);
EXPORT_SYMBOL(cont_prepare_write);
EXPORT_SYMBOL(generic_commit_write);
+EXPORT_SYMBOL(block_zero_page);
EXPORT_SYMBOL(generic_block_bmap);
EXPORT_SYMBOL(generic_file_read);
EXPORT_SYMBOL(do_generic_file_read);
static int
next_signal(struct task_struct *tsk, sigset_t *mask)
{
- unsigned long i, *s1, *s2, *m, x;
+ unsigned long i, *s, *m, x;
int sig = 0;
- s1 = tsk->pending.signal.sig;
- s2 = tsk->sig->pending.signal.sig;
+ s = tsk->pending.signal.sig;
m = mask->sig;
switch (_NSIG_WORDS) {
default:
- for (i = 0; i < _NSIG_WORDS; ++i, ++s1, ++s2, ++m)
- if ((x = (*s1 | *s2) &~ *m) != 0) {
+ for (i = 0; i < _NSIG_WORDS; ++i, ++s, ++m)
+ if ((x = *s &~ *m) != 0) {
sig = ffz(~x) + i*_NSIG_BPW + 1;
break;
}
break;
- case 2: if ((x = (s1[0] | s2[0]) &~ m[0]) != 0)
+ case 2: if ((x = s[0] &~ m[0]) != 0)
sig = 1;
- else if ((x = (s1[1] | s2[1]) &~ m[1]) != 0)
+ else if ((x = s[1] &~ m[1]) != 0)
sig = _NSIG_BPW + 1;
else
break;
sig += ffz(~x);
break;
- case 1: if ((x = (*s1 | *s2) &~ *m) != 0)
+ case 1: if ((x = *s &~ *m) != 0)
sig = ffz(~x) + 1;
break;
}
{
t->sigpending = 0;
flush_sigqueue(&t->pending);
- flush_sigqueue(&t->pending);
}
void exit_sighand(struct task_struct *tsk)
spin_lock_irq(&tsk->sigmask_lock);
if (sig) {
tsk->sig = NULL;
- if (atomic_dec_and_test(&sig->count)) {
- flush_sigqueue(&sig->pending);
+ if (atomic_dec_and_test(&sig->count))
kmem_cache_free(sigact_cachep, sig);
- }
}
tsk->sigpending = 0;
flush_sigqueue(&tsk->pending);
if (sig) {
if (!collect_signal(sig, ¤t->pending, info))
- if (!collect_signal(sig, ¤t->sig->pending, info))
- sig = 0;
+ sig = 0;
/* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
we need to xchg out the timer overrun values. */
*/
static int rm_sig_from_queue(int sig, struct task_struct *t)
{
- return rm_from_queue(sig, &t->pending) | rm_from_queue(sig, &t->sig->pending);
+ return rm_from_queue(sig, &t->pending);
}
/*
#endif /* CONFIG_SMP */
}
-/*
- * Send a thread-group-wide signal.
- *
- * Just add it to the shared signal queue. And
- * make sure to inform everybody.
- */
-static int send_tg_sig_info(int sig, struct siginfo *info, struct task_struct *p)
-{
- int retval, type;
- struct task_struct *tsk;
-
- if (sig < 0 || sig > _NSIG)
- return -EINVAL;
-
- if (bad_signal(sig, info, p))
- return -EPERM;
-
- if (!sig || !p->sig)
- return 0;
-
- /* Have we already delivered this non-queued signal? */
- if (sig < SIGRTMIN && sigismember(&p->sig->pending.signal, sig))
- return 0;
-
- /* Add the signal to the global queue */
- retval = send_signal(sig, info, &p->sig->pending);
- if (retval < 0)
- return retval;
-
- type = signal_type(sig, p->sig);
-
- /* Inform all threads about it.. */
- tsk = p;
- do {
- unsigned long flags;
-
- /* Zombie? Ignore */
- if (!tsk->sig)
- continue;
-
- spin_lock_irqsave(&tsk->sigmask_lock, flags);
- handle_stop_signal(sig, tsk);
-
- /* Blocked? */
- if (sigismember(&tsk->blocked, sig))
- goto next;
-
- /* Is the signal ignored by this thread? */
- switch (type) {
- case 0:
- goto next;
- case -1: /* affects all threads? */
- sigaddset(&tsk->pending.signal, sig);
- }
-
- /* Go, girl, go! */
- signal_wake_up(tsk);
-next:
- spin_unlock_irqrestore(&tsk->sigmask_lock, flags);
- } while ((tsk = next_thread(tsk)) != p);
- return 0;
-}
-
static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
{
int retval = send_signal(sig, info, &t->pending);
}
-/*
- * Send a signal to a thread group..
- *
- * If the pid is the thread group ID, we consider this
- * a "thread group" signal. Otherwise it degenerates into
- * a thread-specific signal.
- */
-static int kill_tg_info(int sig, struct siginfo *info, pid_t pid)
-{
- int error;
- struct task_struct *p;
-
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- error = -ESRCH;
- if (p) {
- /* Is it the leader? Otherwise it degenerates into a per-thread thing */
- if (p->tgid == pid) {
- spin_lock(&p->sig->siglock);
- error = send_tg_sig_info(sig, info, p);
- spin_unlock(&p->sig->siglock);
- } else
- error = send_sig_info(sig, info, p);
- }
- read_unlock(&tasklist_lock);
- return error;
-}
-
/*
* kill_something_info() interprets pid in interesting ways just like kill(2).
*
} else if (pid < 0) {
return kill_pg_info(sig, info, -pid);
} else {
- return kill_tg_info(sig, info, pid);
+ return kill_proc_info(sig, info, pid);
}
}
return error;
}
-asmlinkage long
-sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
+long do_sigpending(void *set, unsigned long sigsetsize)
{
- int error = -EINVAL;
+ long error = -EINVAL;
sigset_t pending;
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
+ if (sigsetsize > sizeof(sigset_t))
goto out;
spin_lock_irq(¤t->sigmask_lock);
- sigorsets(&pending, ¤t->pending.signal, ¤t->sig->pending.signal);
- sigandsets(&pending, ¤t->blocked, &pending);
+ sigandsets(&pending, ¤t->blocked, ¤t->pending.signal);
spin_unlock_irq(¤t->sigmask_lock);
error = -EFAULT;
- if (!copy_to_user(set, &pending, sizeof(*set)))
+ if (!copy_to_user(set, &pending, sigsetsize))
error = 0;
out:
return error;
+}
+
+asmlinkage long
+sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
+{
+ return do_sigpending(set, sigsetsize);
}
asmlinkage long
info.si_signo = sig;
/* POSIX.1b doesn't mention process groups. */
- return kill_tg_info(sig, &info, pid);
+ return kill_proc_info(sig, &info, pid);
}
int
return error;
}
+asmlinkage long
+sys_sigpending(old_sigset_t *set)
+{
+ return do_sigpending(set, sizeof(*set));
+}
+
#if !defined(__alpha__)
/* Alpha has its own versions with special arguments. */
return error;
}
-asmlinkage long
-sys_sigpending(old_sigset_t *set)
-{
- int error;
- old_sigset_t pending;
-
- spin_lock_irq(¤t->sigmask_lock);
- pending = current->blocked.sig[0] & (current->pending.signal.sig[0] | current->sig->pending.signal.sig[0]);
- spin_unlock_irq(¤t->sigmask_lock);
-
- error = -EFAULT;
- if (!copy_to_user(set, &pending, sizeof(*set)))
- error = 0;
- return error;
-}
-
#ifndef __sparc__
asmlinkage long
sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
if (sk != NULL) {
if (sk->stamp.tv_sec == 0)
return -ENOENT;
- return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) : -EFAULT : 0;
- }
+ return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
+ }
return -EINVAL;
case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */