Commit 3db9dee5 authored by Linus Torvalds's avatar Linus Torvalds

- pre3:

    - 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
parent e6c596f3
...@@ -833,7 +833,7 @@ sys_call_table: ...@@ -833,7 +833,7 @@ sys_call_table:
.quad alpha_ni_syscall .quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */ .quad alpha_ni_syscall /* 50 */
.quad sys_acct .quad sys_acct
.quad osf_sigpending .quad sys_sigpending
.quad alpha_ni_syscall .quad alpha_ni_syscall
.quad sys_ioctl .quad sys_ioctl
.quad alpha_ni_syscall /* 55 */ .quad alpha_ni_syscall /* 55 */
......
...@@ -170,18 +170,6 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, ...@@ -170,18 +170,6 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
return ret; return ret;
} }
asmlinkage int
osf_sigpending(old_sigset_t *set)
{
sigset_t pending;
spin_lock_irq(&current->sigmask_lock);
sigandsets(&pending, &current->blocked, &current->signal);
spin_unlock_irq(&current->sigmask_lock);
return copy_to_user(set, &pending, sizeof(*set));
}
/* /*
* Atomically swap in the new signal mask, and wait for a signal. * Atomically swap in the new signal mask, and wait for a signal.
*/ */
...@@ -729,7 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, ...@@ -729,7 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
default: default:
lock_kernel(); lock_kernel();
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
/* NOTREACHED */ /* NOTREACHED */
......
...@@ -32,21 +32,21 @@ endif ...@@ -32,21 +32,21 @@ endif
GZFLAGS = -9 GZFLAGS = -9
# Ensure this is ld "2.9.4" or later # 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.' dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
@echo '*** Please upgrade your binutils to 2.9.5.' @echo '*** Please upgrade your binutils to 2.9.5.'
@false @false
endif endif
# GCC 2.7 uses different options to later compilers; sort out which we have # 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 # select flags depending on the compiler
# #
ifeq ($(NEW_GCC),y) ifneq ($(NEW_GCC),0)
CFLAGS += -mshort-load-bytes CFLAGS += -mshort-load-bytes
CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os
CFLAGS_PROC_CPU_32v3 := -march=armv3 CFLAGS_PROC_CPU_32v3 := -march=armv3
...@@ -54,6 +54,7 @@ CFLAGS_PROC_CPU_32v4 := -march=armv4 ...@@ -54,6 +54,7 @@ CFLAGS_PROC_CPU_32v4 := -march=armv4
CFLAGS_ARM6 := -mtune=arm6 CFLAGS_ARM6 := -mtune=arm6
CFLAGS_ARM7 := -mtune=arm7 CFLAGS_ARM7 := -mtune=arm7
CFLAGS_ARM720 := -mtune=arm7tdmi CFLAGS_ARM720 := -mtune=arm7tdmi
CFLAGS_ARM920 := -mtune=arm9tdmi
CFLAGS_SA110 := -mtune=strongarm110 CFLAGS_SA110 := -mtune=strongarm110
else else
CFLAGS += -DNO_TEXT_SECTIONS CFLAGS += -DNO_TEXT_SECTIONS
...@@ -63,6 +64,7 @@ CFLAGS_PROC_CPU_32v4 := ...@@ -63,6 +64,7 @@ CFLAGS_PROC_CPU_32v4 :=
CFLAGS_ARM6 := -m6 CFLAGS_ARM6 := -m6
CFLAGS_ARM7 := -m6 CFLAGS_ARM7 := -m6
CFLAGS_ARM720 := -m6 CFLAGS_ARM720 := -m6
CFLAGS_ARM920 := -m6
CFLAGS_SA110 := -m6 CFLAGS_SA110 := -m6
endif endif
...@@ -98,6 +100,9 @@ ifeq ($(CONFIG_CPU_32),y) ...@@ -98,6 +100,9 @@ ifeq ($(CONFIG_CPU_32),y)
ifeq ($(CONFIG_CPU_ARM720),y) ifeq ($(CONFIG_CPU_ARM720),y)
CFLAGS += $(CFLAGS_ARM720) CFLAGS += $(CFLAGS_ARM720)
else else
ifeq ($(CONFIG_CPU_ARM920),y)
CFLAGS += $(CFLAGS_ARM920)
else
ifeq ($(CONFIG_CPU_SA110),y) ifeq ($(CONFIG_CPU_SA110),y)
CFLAGS += $(CFLAGS_SA110) CFLAGS += $(CFLAGS_SA110)
else else
...@@ -108,6 +113,7 @@ ifeq ($(CONFIG_CPU_32),y) ...@@ -108,6 +113,7 @@ ifeq ($(CONFIG_CPU_32),y)
endif endif
endif endif
endif endif
endif
endif endif
LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
...@@ -116,51 +122,60 @@ export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS ...@@ -116,51 +122,60 @@ export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
ifeq ($(CONFIG_ARCH_ARCA5K),y) ifeq ($(CONFIG_ARCH_ARCA5K),y)
MACHINE = arc MACHINE = arc
ARCHDIR = arc
endif endif
ifeq ($(CONFIG_ARCH_RPC),y) ifeq ($(CONFIG_ARCH_RPC),y)
MACHINE = rpc MACHINE = rpc
ARCHDIR = rpc
endif endif
ifeq ($(CONFIG_ARCH_EBSA110),y) ifeq ($(CONFIG_ARCH_EBSA110),y)
MACHINE = ebsa110 MACHINE = ebsa110
ARCHDIR = ebsa110
endif endif
ifeq ($(CONFIG_ARCH_CLPS7500),y) ifeq ($(CONFIG_ARCH_CLPS7500),y)
MACHINE = clps7500 MACHINE = clps7500
ARCHDIR = cl7500 INCDIR = cl7500
endif endif
ifeq ($(CONFIG_FOOTBRIDGE),y) ifeq ($(CONFIG_FOOTBRIDGE),y)
MACHINE = footbridge MACHINE = footbridge
ARCHDIR = ebsa285 INCDIR = ebsa285
endif endif
ifeq ($(CONFIG_ARCH_CO285),y) ifeq ($(CONFIG_ARCH_CO285),y)
TEXTADDR = 0x60008000 TEXTADDR = 0x60008000
MACHINE = footbridge
INCDIR = ebsa285
endif endif
ifeq ($(CONFIG_ARCH_NEXUSPCI),y) ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
MACHINE = nexuspci MACHINE = nexuspci
ARCHDIR = nexuspci
endif endif
ifeq ($(CONFIG_ARCH_SHARK),y) ifeq ($(CONFIG_ARCH_SHARK),y)
MACHINE = shark MACHINE = shark
ARCHDIR = shark
endif endif
ifeq ($(CONFIG_ARCH_SA1100),y) ifeq ($(CONFIG_ARCH_SA1100),y)
MACHINE = sa1100 MACHINE = sa1100
ARCHDIR = sa1100
endif endif
ifeq ($(CONFIG_ARCH_L7200),y) ifeq ($(CONFIG_ARCH_L7200),y)
MACHINE = l7200 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 endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
...@@ -193,36 +208,30 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot ...@@ -193,36 +208,30 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
# to date before starting compilation # to date before starting compilation
$(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \ $(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \
constants \
include/asm-arm/mach-types.h include/asm-arm/mach-types.h
include/asm-arm/mach-types.h: \ $(patsubst %, _dir_%, $(SUBDIRS)) : constants
arch/arm/tools/mach-types \
arch/arm/tools/gen-mach-types 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 > $@ @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 @$(MAKE) -C arch/arm/lib constants.h
symlinks: archsymlinks symlinks: archsymlinks
archsymlinks: archsymlinks:
$(RM) include/asm-arm/arch include/asm-arm/proc $(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 vmlinux: arch/arm/vmlinux.lds
arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@ @sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
arch/arm/kernel: dummy arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
arch/arm/mm: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm
arch/arm/lib: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib
bzImage zImage zinstall Image bootpImage install: vmlinux bzImage zImage zinstall Image bootpImage install: vmlinux
@$(MAKEBOOT) $@ @$(MAKEBOOT) $@
...@@ -235,7 +244,7 @@ archclean: ...@@ -235,7 +244,7 @@ archclean:
$(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds $(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds
$(RM) include/asm-arm/mach-types.h $(RM) include/asm-arm/mach-types.h
archdep: symlinks archdep: archsymlinks
@$(MAKEBOOT) dep @$(MAKEBOOT) dep
# My testing targets (that short circuit a few dependencies) # My testing targets (that short circuit a few dependencies)
...@@ -252,7 +261,7 @@ CFGS= a5k_config ebsa110_config \ ...@@ -252,7 +261,7 @@ CFGS= a5k_config ebsa110_config \
brutus_config victor_config \ brutus_config victor_config \
empeg_config thinclient_config \ empeg_config thinclient_config \
assabet_config lart_config \ assabet_config lart_config \
cerf_config cerf_config lusl7200_config
$(CFGS): $(CFGS):
@( \ @( \
...@@ -266,7 +275,3 @@ $(CFGS): ...@@ -266,7 +275,3 @@ $(CFGS):
echo "$$CFG does not exist"; \ echo "$$CFG does not exist"; \
fi; \ fi; \
) )
l7200_config:
$(RM) arch/arm/defconfig
cp arch/arm/def-configs/lusl7200 arch/arm/defconfig
...@@ -105,10 +105,10 @@ initrd: ...@@ -105,10 +105,10 @@ initrd:
@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1) @test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
install: $(CONFIGURE) Image 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 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: clean:
$(RM) Image zImage bootpImage $(RM) Image zImage bootpImage
......
...@@ -23,4 +23,4 @@ initrd.o: $(INITRD) ...@@ -23,4 +23,4 @@ initrd.o: $(INITRD)
.PHONY: $(INITRD) $(ZSYSTEM) .PHONY: $(INITRD) $(ZSYSTEM)
clean:; $(RM) bootp bootp.lds clean:; $(RM) bootp
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) }
}
/*
* 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 */
/*
* 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
...@@ -85,7 +85,7 @@ start: ...@@ -85,7 +85,7 @@ start:
.word 0x016f2818 @ Magic numbers to help the loader .word 0x016f2818 @ Magic numbers to help the loader
.word start .word start
1: mov r7, r1 @ save architecture ID 1: mov r7, r1 @ save architecture ID
mov r8, r0 @ save r0 mov r8, #0 @ save r0
#ifdef CONFIG_ANGELBOOT #ifdef CONFIG_ANGELBOOT
/* /*
* Booting from Angel - need to enter SVC mode and disable * Booting from Angel - need to enter SVC mode and disable
...@@ -198,9 +198,10 @@ cache_on: ldr r1, proc_sa110_type ...@@ -198,9 +198,10 @@ cache_on: ldr r1, proc_sa110_type
1: 1:
sub r3, r4, #16384 @ Page directory size sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer 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 r0, r3
mov r8, r0, lsr #18 mov r8, r0, lsr #18
...@@ -217,6 +218,20 @@ cache_on: ldr r1, proc_sa110_type ...@@ -217,6 +218,20 @@ cache_on: ldr r1, proc_sa110_type
add r1, r1, #1048576 add r1, r1, #1048576
teq r0, r2 teq r0, r2
bne 1b 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 mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
......
...@@ -45,6 +45,12 @@ SCR_loc: .long SYMBOL_NAME(SCR_value) ...@@ -45,6 +45,12 @@ SCR_loc: .long SYMBOL_NAME(SCR_value)
#define GPIO_2_9 0x3fc #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 ); * void sa1100_setup( int arch_id );
* *
...@@ -138,7 +144,7 @@ skip_uart: ...@@ -138,7 +144,7 @@ skip_uart:
@ The machine type is passed in r0 @ The machine type is passed in r0
mov r0, r3 mov r0, r3
#ifdef CONFIG_SA1100_NANOENGINE #ifdef CONFIG_SA1100_NANOENGINE
teq r0, #32 @ MACH_TYPE_NANOENGINE teq r0, #MACH_TYPE_NANOENGINE
beq SYMBOL_NAME(bse_setup) beq SYMBOL_NAME(bse_setup)
#endif #endif
......
...@@ -10,16 +10,14 @@ ...@@ -10,16 +10,14 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/page.h> /* for BUG() */
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/pci.h>
#include "bios32.h"
static int debug_pci; static int debug_pci;
int have_isa_bridge; int have_isa_bridge;
extern void hw_init(void);
void pcibios_report_status(u_int status_mask, int warn) void pcibios_report_status(u_int status_mask, int warn)
{ {
struct pci_dev *dev; struct pci_dev *dev;
...@@ -157,6 +155,14 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev) ...@@ -157,6 +155,14 @@ static void __init pci_fixup_ide_bases(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[] = { struct pci_fixup pcibios_fixups[] = {
{ {
PCI_FIXUP_HEADER, PCI_FIXUP_HEADER,
...@@ -174,6 +180,10 @@ struct pci_fixup pcibios_fixups[] = { ...@@ -174,6 +180,10 @@ struct pci_fixup pcibios_fixups[] = {
PCI_FIXUP_HEADER, PCI_FIXUP_HEADER,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
pci_fixup_ide_bases pci_fixup_ide_bases
}, {
PCI_FIXUP_HEADER,
PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
pci_fixup_dec21142
}, { 0 } }, { 0 }
}; };
...@@ -277,12 +287,11 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -277,12 +287,11 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
* SERR and PERR reporting - this chip doesn't drive the * SERR and PERR reporting - this chip doesn't drive the
* parity line correctly. * parity line correctly.
*/ */
#if 1 /* !testing */
if (dev->vendor == PCI_VENDOR_ID_INTERG && if (dev->vendor == PCI_VENDOR_ID_INTERG &&
dev->device == PCI_DEVICE_ID_INTERG_2000) dev->device == PCI_DEVICE_ID_INTERG_2000)
busdata->features &= ~(PCI_COMMAND_SERR | busdata->features &= ~(PCI_COMMAND_SERR |
PCI_COMMAND_PARITY); PCI_COMMAND_PARITY);
#endif
/* /*
* Calculate the maximum devsel latency. * Calculate the maximum devsel latency.
*/ */
...@@ -318,18 +327,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -318,18 +327,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
u16 cmd; u16 cmd;
u8 min_gnt, latency; 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. * Calculate this masters latency timer value.
* This is rather primitive - it does not take * This is rather primitive - it does not take
...@@ -372,184 +369,23 @@ pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *rang ...@@ -372,184 +369,23 @@ pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *rang
ranges->mem_end -= bus->resource[1]->start; 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; return 0;
} }
/* ebsa285 host-specific stuff */ extern struct hw_pci ebsa285_pci;
extern struct hw_pci cats_pci;
#ifdef CONFIG_ARCH_EBSA285 extern struct hw_pci netwinder_pci;
static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; extern struct hw_pci personal_server_pci;
extern struct hw_pci ftv_pci;
static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) extern struct hw_pci integrator_pci;
{
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
void __init pcibios_init(void) void __init pcibios_init(void)
{ {
struct hw_pci *hw_pci = NULL; struct hw_pci *hw_pci = NULL;
struct arm_pci_sysdata sysdata;
int i;
do { do {
#ifdef CONFIG_ARCH_EBSA285 #ifdef CONFIG_ARCH_EBSA285
...@@ -582,15 +418,28 @@ void __init pcibios_init(void) ...@@ -582,15 +418,28 @@ void __init pcibios_init(void)
break; break;
} }
#endif #endif
} while (0); #ifdef CONFIG_ARCH_INTEGRATOR
if (machine_is_integrator()) {
hw_pci = &integrator_pci;
break;
}
#endif
} while (0);
if (hw_pci == NULL) if (hw_pci == NULL)
return; 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. * 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? * Other architectures don't seem to do this... should we?
...@@ -598,8 +447,7 @@ void __init pcibios_init(void) ...@@ -598,8 +447,7 @@ void __init pcibios_init(void)
pcibios_claim_resources(); pcibios_claim_resources();
/* /*
* Assign any unassigned resources. Note that we really ought to * Assign any unassigned resources.
* have min/max stuff here - max mem address is 0x0fffffff
*/ */
pci_assign_unassigned_resources(); pci_assign_unassigned_resources();
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system.h> #include <asm/system.h>
#include "bios32.h" #include <asm/mach/pci.h>
#define MAX_SLOTS 21 #define MAX_SLOTS 21
...@@ -252,7 +252,7 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -252,7 +252,7 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
add_timer(timer); add_timer(timer);
} }
void __init dc21285_init(void) void __init dc21285_init(struct arm_pci_sysdata *sysdata)
{ {
unsigned long cntl; unsigned long cntl;
unsigned int mem_size; unsigned int mem_size;
...@@ -279,19 +279,26 @@ void __init dc21285_init(void) ...@@ -279,19 +279,26 @@ void __init dc21285_init(void)
"central function" : "addin"); "central function" : "addin");
if (cfn_mode) { if (cfn_mode) {
static struct resource csrmem, csrio; static struct resource csrmem, csrio, busmem, busmempf;
struct arm_pci_sysdata sysdata; struct pci_bus *bus;
int i;
csrio.flags = IORESOURCE_IO; csrio.flags = IORESOURCE_IO;
csrio.name = "DC21285"; csrio.name = "Footbridge";
csrmem.flags = IORESOURCE_MEM; 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, allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL); 0xff00, 0xffff, 128, NULL, NULL);
allocate_resource(&iomem_resource, &csrmem, 128, allocate_resource(&iomem_resource, &csrmem, 128,
0xf4000000, 0xf8000000, 128, NULL, NULL); 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 * Map our SDRAM at a known address in PCI space, just in case
...@@ -302,24 +309,24 @@ void __init dc21285_init(void) ...@@ -302,24 +309,24 @@ void __init dc21285_init(void)
*CSR_PCICACHELINESIZE = 0x00002008; *CSR_PCICACHELINESIZE = 0x00002008;
*CSR_PCICSRBASE = csrmem.start; *CSR_PCICSRBASE = csrmem.start;
*CSR_PCICSRIOBASE = csrio.start; *CSR_PCICSRIOBASE = csrio.start;
*CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0; *CSR_PCIROMBASE = 0;
*CSR_PCICMD = pci_cmd | *CSR_PCICMD = pci_cmd |
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
for (i = 0; i < MAX_NR_BUS; i++) { bus = pci_scan_bus(0, &dc21285_ops, sysdata);
sysdata.bus[i].features = PCI_COMMAND_FAST_BACK | /*
PCI_COMMAND_SERR | * bus->resource[0] is the IO resource for this bus
PCI_COMMAND_PARITY; * bus->resource[1] is the mem resource for this bus
sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST; * bus->resource[2] is the prefetch mem resource for this bus
} */
bus->resource[1] = &busmem;
pci_scan_bus(0, &dc21285_ops, &sysdata); 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", 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"); "en" : "dis");
/* /*
......
...@@ -318,7 +318,7 @@ ecard_task(void * unused) ...@@ -318,7 +318,7 @@ ecard_task(void * unused)
* We don't want /any/ signals, not even SIGKILL * We don't want /any/ signals, not even SIGKILL
*/ */
sigfillset(&tsk->blocked); sigfillset(&tsk->blocked);
sigemptyset(&tsk->signal); sigemptyset(&tsk->pending.signal);
recalc_sigpending(tsk); recalc_sigpending(tsk);
strcpy(tsk->comm, "kecardd"); strcpy(tsk->comm, "kecardd");
...@@ -335,7 +335,7 @@ ecard_task(void * unused) ...@@ -335,7 +335,7 @@ ecard_task(void * unused)
req = xchg(&ecard_req, NULL); req = xchg(&ecard_req, NULL);
if (req == NULL) { if (req == NULL) {
sigemptyset(&tsk->signal); sigemptyset(&tsk->pending.signal);
interruptible_sleep_on(&ecard_wait); interruptible_sleep_on(&ecard_wait);
} }
} while (req == NULL); } while (req == NULL);
......
...@@ -72,6 +72,7 @@ detect_arch_type: ...@@ -72,6 +72,7 @@ detect_arch_type:
mov pc, lr mov pc, lr
detect_proc_type: detect_proc_type:
mov ip, lr
mov r2, #0xea000000 @ Point undef instr to continuation mov r2, #0xea000000 @ Point undef instr to continuation
adr r0, continue - 12 adr r0, continue - 12
orr r0, r2, r0, lsr #2 orr r0, r2, r0, lsr #2
...@@ -80,8 +81,9 @@ detect_proc_type: ...@@ -80,8 +81,9 @@ detect_proc_type:
ldr r0, arm2_id ldr r0, arm2_id
swp r2, r2, [r1] @ check for swp (ARM2 can't) swp r2, r2, [r1] @ check for swp (ARM2 can't)
ldr r0, arm250_id 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 continue: mov r2, #0xeb000000 @ Make undef vector loop
sub r2, r2, #2 sub r2, r2, #2
str r2, [r1, #4] str r2, [r1, #4]
mov pc, lr mov pc, ip
...@@ -280,8 +280,8 @@ void exit_thread(void) ...@@ -280,8 +280,8 @@ void exit_thread(void)
void flush_thread(void) void flush_thread(void)
{ {
memset(&current->thread.debug, 0, sizeof(current->thread.debug)); memset(&current->thread.debug, 0, sizeof(struct debug_info));
memset(&current->thread.fpstate, 0, sizeof(current->thread.fpstate)); memset(&current->thread.fpstate, 0, sizeof(union fp_state));
current->used_math = 0; current->used_math = 0;
current->flags &= ~PF_USEDFPU; current->flags &= ~PF_USEDFPU;
} }
...@@ -326,19 +326,21 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp) ...@@ -326,19 +326,21 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
*/ */
void dump_thread(struct pt_regs * regs, struct user * dump) void dump_thread(struct pt_regs * regs, struct user * dump)
{ {
struct task_struct *tsk = current;
dump->magic = CMAGIC; 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->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
dump->u_tsize = (current->mm->end_code - current->mm->start_code) >> PAGE_SHIFT; dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0; dump->u_ssize = 0;
dump->u_debugreg[0] = current->thread.debug.bp[0].address; dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
dump->u_debugreg[1] = current->thread.debug.bp[1].address; dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
dump->u_debugreg[2] = current->thread.debug.bp[0].insn; dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
dump->u_debugreg[3] = current->thread.debug.bp[1].insn; dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
dump->u_debugreg[4] = current->thread.debug.nsaved; dump->u_debugreg[4] = tsk->thread.debug.nsaved;
if (dump->start_stack < 0x04000000) if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
......
...@@ -61,9 +61,18 @@ static inline long get_stack_long(struct task_struct *task, int offset) ...@@ -61,9 +61,18 @@ static inline long get_stack_long(struct task_struct *task, int offset)
static inline int static inline int
put_stack_long(struct task_struct *task, int offset, long data) 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 static inline int
...@@ -406,7 +415,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -406,7 +415,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break; break;
if (addr < sizeof (struct pt_regs)) if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, (int)addr >> 2, data); ret = put_stack_long(child, (int)addr >> 2, data);
break; break;
...@@ -499,12 +508,19 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -499,12 +508,19 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
* Set all gp regs in the child. * Set all gp regs in the child.
*/ */
case PTRACE_SETREGS: { case PTRACE_SETREGS: {
struct pt_regs *regs = get_user_regs(child); struct pt_regs newregs;
ret = 0; ret = -EFAULT;
if (copy_from_user(regs, (void *)data, if (copy_from_user(&newregs, (void *)data,
sizeof(struct pt_regs))) sizeof(struct pt_regs)) == 0) {
ret = -EFAULT; struct pt_regs *regs = get_user_regs(child);
ret = -EINVAL;
if (valid_user_regs(&newregs)) {
*regs = newregs;
ret = 0;
}
}
break; break;
} }
......
...@@ -587,7 +587,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -587,7 +587,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -9,9 +9,9 @@ USE_STANDARD_AS_RULE := true ...@@ -9,9 +9,9 @@ USE_STANDARD_AS_RULE := true
L_TARGET := lib.a L_TARGET := lib.a
L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \ L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \ csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \
memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \ memchr.o memcpy.o memset.o memzero.o setbit.o \
strrchr.o testchangebit.o testclearbit.o testsetbit.o \ strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \
uaccess.o testchangebit.o testclearbit.o testsetbit.o uaccess.o
O_TARGET := lib.o O_TARGET := lib.o
O_OBJS := backtrace.o delay.o O_OBJS := backtrace.o delay.o
......
...@@ -10,26 +10,26 @@ ...@@ -10,26 +10,26 @@
#include <asm/assembler.h> #include <asm/assembler.h>
#include "constants.h" #include "constants.h"
.text .text
.align 5
/* /*
* StrongARM optimised copy_page routine * StrongARM optimised copy_page routine
* now 1.72bytes/cycle, was 1.60 bytes/cycle * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s)
* (50MHz bus -> 86MB/s) * Note that we probably achieve closer to the 100MB/s target with
* the core clock switching.
*/ */
ENTRY(copy_page) ENTRY(copy_page)
stmfd sp!, {r4, lr} @ 2 stmfd sp!, {r4, lr} @ 2
mov r2, #PAGE_SZ/64 @ 1 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 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 ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4 stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1 ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4 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 bne 1b @ 1
LOADREGS(fd, sp!, {r4, pc}) @ 3 LOADREGS(fd, sp!, {r4, pc}) @ 3
...@@ -40,4 +40,3 @@ ENTRY(__delay) ...@@ -40,4 +40,3 @@ ENTRY(__delay)
subs r0, r0, #1 subs r0, r0, #1
bcs SYMBOL_NAME(__delay) bcs SYMBOL_NAME(__delay)
RETINSTR(mov,pc,lr) RETINSTR(mov,pc,lr)
/* /*
* linux/arch/arm/lib/memchr.S * linux/arch/arm/lib/memchr.S
* *
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-2000 Russell King
* *
* ASM optimised string functions * ASM optimised string functions
*
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include "constants.h"
.text .text
.align 5
ENTRY(memchr) ENTRY(memchr)
str lr, [sp, #-4]! 1: ldrb r3, [r0], #1
1: ldrb r3, [r0], #1 teq r3, r1
teq r3, r1 beq 2f
beq 2f subs r2, r2, #1
subs r2, r2, #1 bpl 1b
bpl 1b 2: movne r0, #0
2: movne r0, #0 subeq r0, r0, #1
subeq r0, r0, #1 RETINSTR(mov,pc,lr)
LOADREGS(fd, sp!, {pc})
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-1999 Russell King
* *
* ASM optimised string functions * ASM optimised string functions
*
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
...@@ -314,5 +313,3 @@ ENTRY(memmove) ...@@ -314,5 +313,3 @@ ENTRY(memmove)
b 24b b 24b
.align .align
/* /*
* linux/arch/arm/lib/memset.S * linux/arch/arm/lib/memset.S
* *
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-2000 Russell King
* *
* ASM optimised string functions * ASM optimised string functions
*
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include "constants.h"
.text .text
.align 5 .align 5
ENTRY(memset) .word 0
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})
4: movs ip, r2, lsr #3 1: subs r2, r2, #4 @ 1 do we have enough
beq 3b blt 5f @ 1 bytes to align with?
sub r2, r2, ip, lsl #3 cmp r3, #2 @ 1
str lr, [sp, #-4]! strltb r1, [r0], #1 @ 1
mov lr, r1 strleb r1, [r0], #1 @ 1
subs ip, ip, #4 strb r1, [r0], #1 @ 1
5: stmgeia r3!, {r1, lr} add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
stmgeia r3!, {r1, lr} /*
stmgeia r3!, {r1, lr} * The pointer is now aligned and the length is adjusted. Try doing the
stmgeia r3!, {r1, lr} * memzero again.
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
6: subs r2, r2, #1 ENTRY(memset)
strgeb r1, [r3], #1 ands r3, r0, #3 @ 1 unaligned?
bgt 6b bne 1b @ 1
RETINSTR(mov, pc, lr) /*
* 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 * linux/arch/arm/lib/memzero.S
* *
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-2000 Russell King
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.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) ENTRY(__memzero)
mov r2, #0 @ 1 mov r2, #0 @ 1
cmp r1, #4 @ 1 ands r3, r0, #3 @ 1 unaligned?
blt 4f @ 1 @ = 3 bne 1b @ 1
/*
@ r1 >= 4 * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
*/
ands ip, r0, #3 @ 1 cmp r1, #16 @ 1 we can skip this chunk if we
bne 1b @ 1 @ = 5 blt 4f @ 1 have < 16 bytes
/*
2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11 * We need an extra register for this loop - save the return address and
* use the LR
str lr, [sp, #-4]! @ 1 */
mov r3, #0 @ 1 str lr, [sp, #-4]! @ 1
mov ip, #0 @ 1 mov ip, r2 @ 1
mov lr, #0 @ 1 mov lr, r2 @ 1
@ 4 <= r1 <= 32 @ = 9 or 15 3: subs r1, r1, #64 @ 1 write 32 bytes out per loop
stmgeia r0!, {r2, r3, ip, lr} @ 4
3: subs r1, r1, #32 @ 1 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 stmgeia r0!, {r2, r3, ip, lr} @ 4
bgt 3b @ 1 bgt 3b @ 1
LOADREGS(eqfd, sp!, {pc}) @ 1/2 LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit
/*
@ -28 <= r1 <= -1 * No need to correct the count; we're only testing bits from now on
*/
cmp r1, #-16 @ 1 tst r1, #32 @ 1
stmgeia r0!, {r2, r3, ip, lr} @ 4 stmneia r0!, {r2, r3, ip, lr} @ 4
ldr lr, [sp], #4 @ 1 stmneia r0!, {r2, r3, ip, lr} @ 4
addlts r1, r1, #16 @ 1 tst r1, #16 @ 1 16 bytes or more?
RETINSTR(moveq,pc,lr) @ 1 stmneia r0!, {r2, r3, ip, lr} @ 4
ldr lr, [sp], #4 @ 1
@ -12 <= r1 <= -1
4: tst r1, #8 @ 1 8 bytes or more?
cmp r1, #-8 @ 1 stmneia r0!, {r2, r3} @ 2
stmgeia r0!, {r2, r3} @ 2 tst r1, #4 @ 1 4 bytes or more?
addlts r1, r1, #8 @ 1 strne r2, [r0], #4 @ 1
RETINSTR(moveq,pc,lr) @ 1 /*
* When we get here, we've got less than 4 bytes to zero. We
@ -4 <= r1 <= -1 * may have an unaligned pointer as well.
*/
cmp r1, #-4 @ 1 5: tst r1, #2 @ 1 2 bytes or more?
strge r2, [r0], #4 @ 1 strneb r2, [r0], #1 @ 1
adds r1, r1, #4 @ 1 strneb r2, [r0], #1 @ 1
RETINSTR(moveq,pc,lr) @ 1 tst r1, #1 @ 1 a byte left over
strneb r2, [r0], #1 @ 1
4: @ 1 <= r1 <= 3 RETINSTR(mov,pc,lr) @ 1
cmp r1, #2 @ 1
strgtb r2, [r0], #1 @ 1
strgeb r2, [r0], #1 @ 1
strb r2, [r0], #1 @ 1
RETINSTR(mov,pc,lr) @ 1
/* /*
* linux/arch/arm/lib/strchr.S * linux/arch/arm/lib/strchr.S
* *
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-2000 Russell King
* *
* ASM optimised string functions * ASM optimised string functions
*
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include "constants.h"
.text .text
.align 5
ENTRY(strchr) ENTRY(strchr)
str lr, [sp, #-4]!
mov r3, #0
1: ldrb r2, [r0], #1 1: ldrb r2, [r0], #1
teq r2, r1 teq r2, r1
teqne r2, #0 teqne r2, #0
...@@ -21,6 +18,4 @@ ENTRY(strchr) ...@@ -21,6 +18,4 @@ ENTRY(strchr)
teq r2, #0 teq r2, #0
moveq r0, #0 moveq r0, #0
subne r0, r0, #1 subne r0, r0, #1
LOADREGS(fd, sp!, {pc}) RETINSTR(mov,pc,lr)
/*
* 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
/*
* 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 * linux/arch/arm/lib/strrchr.S
* *
* Copyright (C) 1995-1999 Russell King * Copyright (C) 1995-2000 Russell King
* *
* ASM optimised string functions * ASM optimised string functions
*
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include "constants.h"
.text .text
.align 5
ENTRY(strrchr) ENTRY(strrchr)
str lr, [sp, #-4]!
mov r3, #0 mov r3, #0
1: ldrb r2, [r0], #1 1: ldrb r2, [r0], #1
teq r2, r1 teq r2, r1
...@@ -20,6 +18,4 @@ ENTRY(strrchr) ...@@ -20,6 +18,4 @@ ENTRY(strrchr)
teq r2, #0 teq r2, #0
bne 1b bne 1b
mov r0, r3 mov r0, r3
LOADREGS(fd, sp!, {pc}) RETINSTR(mov,pc,lr)
...@@ -11,13 +11,6 @@ ...@@ -11,13 +11,6 @@
.text .text
#define USER(x...) \
9999: x; \
.section __ex_table,"a"; \
.align 3; \
.long 9999b,9001f; \
.previous
.globl SYMBOL_NAME(uaccess_user) .globl SYMBOL_NAME(uaccess_user)
SYMBOL_NAME(uaccess_user): SYMBOL_NAME(uaccess_user):
.word uaccess_user_put_byte .word uaccess_user_put_byte
......
...@@ -13,13 +13,6 @@ ...@@ -13,13 +13,6 @@
.text .text
#define USER(x...) \
9999: x; \
.section __ex_table,"a"; \
.align 3; \
.long 9999b,9001f; \
.previous
#define PAGE_SHIFT 12 #define PAGE_SHIFT 12
/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) /* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
...@@ -590,62 +583,3 @@ USER( strnebt r2, [r0], #1) ...@@ -590,62 +583,3 @@ USER( strnebt r2, [r0], #1)
9001: LOADREGS(fd,sp!, {r0, pc}) 9001: LOADREGS(fd,sp!, {r0, pc})
.previous .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
#
# 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
/*
* 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
/*
* 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);
/*
* 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,
};
/*
* 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);
/*
* 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,
};
This diff is collapsed.
/*
* 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);
/*
* 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,
};
/*
* 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,
};
...@@ -37,6 +37,11 @@ graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 ...@@ -37,6 +37,11 @@ graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29
xp860 SA1100_XP860 XP860 30 xp860 SA1100_XP860 XP860 30
cerf SA1100_CERF CERF 31 cerf SA1100_CERF CERF 31
nanoengine SA1100_NANOENGINE NANOENGINE 32 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 # The following are unallocated
empeg SA1100_EMPEG EMPEG empeg SA1100_EMPEG EMPEG
......
...@@ -79,9 +79,10 @@ SECTIONS ...@@ -79,9 +79,10 @@ SECTIONS
.bss : { .bss : {
__bss_start = .; /* BSS */ __bss_start = .; /* BSS */
*(.bss) *(.bss)
_end = . ; *(COMMON)
_end = . ;
} }
/* Stabs debugging sections. */ /* Stabs debugging sections. */
......
...@@ -42,8 +42,8 @@ SECTIONS ...@@ -42,8 +42,8 @@ SECTIONS
*(.text.lock) /* out-of-line lock text */ *(.text.lock) /* out-of-line lock text */
*(.rodata) *(.rodata)
*(.kstrtab) *(.kstrtab)
. = ALIGN(16); /* Exception table */ . = ALIGN(16);
__start___ex_table = .; __start___ex_table = .; /* Exception table */
*(__ex_table) *(__ex_table)
__stop___ex_table = .; __stop___ex_table = .;
......
...@@ -279,6 +279,7 @@ static inline int save_i387_fsave( struct _fpstate *buf ) ...@@ -279,6 +279,7 @@ static inline int save_i387_fsave( struct _fpstate *buf )
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
unlazy_fpu( tsk );
tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd; tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
if ( __copy_to_user( buf, &tsk->thread.i387.fsave, if ( __copy_to_user( buf, &tsk->thread.i387.fsave,
sizeof(struct i387_fsave_struct) ) ) sizeof(struct i387_fsave_struct) ) )
...@@ -291,6 +292,8 @@ static inline int save_i387_fxsave( struct _fpstate *buf ) ...@@ -291,6 +292,8 @@ static inline int save_i387_fxsave( struct _fpstate *buf )
struct task_struct *tsk = current; struct task_struct *tsk = current;
int err = 0; int err = 0;
unlazy_fpu( tsk );
if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) ) if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) )
return -1; return -1;
......
...@@ -99,6 +99,11 @@ static int putreg(struct task_struct *child, ...@@ -99,6 +99,11 @@ static int putreg(struct task_struct *child,
case EFL: case EFL:
value &= FLAG_MASK; value &= FLAG_MASK;
value |= get_stack_long(child, EFL_OFFSET) & ~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) if (regno > GS*4)
regno -= 2*4; regno -= 2*4;
......
...@@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) ...@@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -1127,7 +1127,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) ...@@ -1127,7 +1127,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
notes[0].datasz = sizeof(prstatus); notes[0].datasz = sizeof(prstatus);
notes[0].data = &prstatus; notes[0].data = &prstatus;
prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; 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]; prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
......
...@@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
...@@ -429,24 +429,7 @@ irix_sigaction(int sig, const struct sigaction *act, ...@@ -429,24 +429,7 @@ irix_sigaction(int sig, const struct sigaction *act,
asmlinkage int irix_sigpending(irix_sigset_t *set) asmlinkage int irix_sigpending(irix_sigset_t *set)
{ {
int err; return do_sigpending(set, sizeof(*set));
if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0)
return -EFAULT;
/* fill in "set" with signals pending but blocked. */
spin_lock_irq(&current->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(&current->sigmask_lock);
return err;
} }
asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
...@@ -605,7 +588,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, ...@@ -605,7 +588,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
expire = schedule_timeout(expire); expire = schedule_timeout(expire);
for (i=0; i<=4; i++) 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) if (tmp)
break; break;
...@@ -622,7 +605,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, ...@@ -622,7 +605,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
if (sigismember (&kset, sig)) if (sigismember (&kset, sig))
continue; continue;
if (sigismember (&current->signal, sig)) { if (sigismember (&current->pending.signal, sig)) {
/* XXX need more than this... */ /* XXX need more than this... */
if (info) if (info)
info->sig = sig; info->sig = sig;
......
...@@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm); ...@@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm);
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -646,7 +646,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) ...@@ -646,7 +646,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
default: default:
lock_kernel(); lock_kernel();
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
default: default:
lock_kernel(); lock_kernel();
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* FALLTHRU */ /* FALLTHRU */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif #endif
/* fall through */ /* fall through */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif #endif
/* fall through */ /* fall through */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
#endif #endif
/* fall through */ /* fall through */
default: default:
sigaddset(&current->signal, signr); sigaddset(&current->pending.signal, signr);
recalc_sigpending(current); recalc_sigpending(current);
current->flags |= PF_SIGNALED; current->flags |= PF_SIGNALED;
do_exit(exit_code); do_exit(exit_code);
......
...@@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set) ...@@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set)
switch (which) { switch (which) {
case 1: /* sigpending */ case 1: /* sigpending */
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sigmask_lock);
sigandsets(&s, &current->blocked, &current->signal); sigandsets(&s, &current->blocked, &current->pending.signal);
recalc_sigpending(current); recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
break; break;
......
...@@ -794,8 +794,8 @@ void ftape_disable(void) ...@@ -794,8 +794,8 @@ void ftape_disable(void)
i, *ft_buffer[i]->address); i, *ft_buffer[i]->address);
} }
} }
if (sigtestsetmask(&current->signal, _DONT_BLOCK) && if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) &&
!(sigtestsetmask(&current->signal, _NEVER_BLOCK)) && !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) &&
ftape_tape_running) { ftape_tape_running) {
TRACE(ft_t_warn, TRACE(ft_t_warn,
"Interrupted by fatal signal and tape still running"); "Interrupted by fatal signal and tape still running");
......
...@@ -433,7 +433,7 @@ int ftape_dumb_stop(void) ...@@ -433,7 +433,7 @@ int ftape_dumb_stop(void)
result = ftape_ready_wait(ftape_timeout.pause,&status); result = ftape_ready_wait(ftape_timeout.pause,&status);
} }
} while (ftape_tape_running } while (ftape_tape_running
&& !(sigtestsetmask(&current->signal, _NEVER_BLOCK))); && !(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)));
#ifndef TESTING #ifndef TESTING
ft_location.known = 0; ft_location.known = 0;
#endif #endif
...@@ -661,7 +661,7 @@ static int seek_forward(int segment_id, int fast) ...@@ -661,7 +661,7 @@ static int seek_forward(int segment_id, int fast)
* to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!! * to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!!
*/ */
if (ftape_read_id() < 0 || !ft_location.known || if (ftape_read_id() < 0 || !ft_location.known ||
sigtestsetmask(&current->signal, _DONT_BLOCK)) { sigtestsetmask(&current->pending.signal, _DONT_BLOCK)) {
ft_location.known = 0; ft_location.known = 0;
if (!ftape_tape_running || if (!ftape_tape_running ||
++failures > FT_SECTORS_PER_SEGMENT) { ++failures > FT_SECTORS_PER_SEGMENT) {
...@@ -776,7 +776,7 @@ static int skip_reverse(int segment_id, int *pstatus) ...@@ -776,7 +776,7 @@ static int skip_reverse(int segment_id, int *pstatus)
fast_seek(count, 1); fast_seek(count, 1);
logical_forward(); logical_forward();
if (ftape_read_id() < 0 || !ft_location.known || if (ftape_read_id() < 0 || !ft_location.known ||
(sigtestsetmask(&current->signal, _DONT_BLOCK))) { (sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
if ((!ftape_tape_running && !ft_location.known) || if ((!ftape_tape_running && !ft_location.known) ||
++failures > FT_SECTORS_PER_SEGMENT) { ++failures > FT_SECTORS_PER_SEGMENT) {
TRACE_ABORT(-EIO, ft_t_err, TRACE_ABORT(-EIO, ft_t_err,
...@@ -1002,7 +1002,7 @@ int ftape_start_tape(int segment_id, int sector_offset) ...@@ -1002,7 +1002,7 @@ int ftape_start_tape(int segment_id, int sector_offset)
while (result < 0 && while (result < 0 &&
retry++ <= 5 && retry++ <= 5 &&
!ft_failure && !ft_failure &&
!(sigtestsetmask(&current->signal, _DONT_BLOCK))) { !(sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
if (retry && start_offset < 5) { if (retry && start_offset < 5) {
start_offset ++; start_offset ++;
......
...@@ -171,7 +171,7 @@ extern void ftape_trace_log (const char *file, const char *name); ...@@ -171,7 +171,7 @@ extern void ftape_trace_log (const char *file, const char *name);
* but rather into ftape-rw.h (maybe) * but rather into ftape-rw.h (maybe)
*/ */
#define FT_SIGNAL_EXIT(sig_mask) \ #define FT_SIGNAL_EXIT(sig_mask) \
if (sigtestsetmask(&current->signal, sig_mask)) { \ if (sigtestsetmask(&current->pending.signal, sig_mask)) { \
TRACE_ABORT(-EINTR, \ TRACE_ABORT(-EINTR, \
ft_t_warn, \ ft_t_warn, \
"interrupted by non-blockable signal"); \ "interrupted by non-blockable signal"); \
......
...@@ -218,7 +218,7 @@ int copy_to_user(void *to_user, const void *from, unsigned long len) ...@@ -218,7 +218,7 @@ int copy_to_user(void *to_user, const void *from, unsigned long len)
static inline int signal_pending(struct task_struct *p) static inline int signal_pending(struct task_struct *p)
{ {
return (p->signal & (~p->blocked != 0)); return (p->signal & ~p->blocked) != 0;
} }
#else #else
......
...@@ -1721,6 +1721,54 @@ int generic_commit_write(struct file *file, struct page *page, ...@@ -1721,6 +1721,54 @@ int generic_commit_write(struct file *file, struct page *page,
return 0; 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) int block_write_full_page(struct page *page, get_block_t *get_block)
{ {
struct inode *inode = (struct inode*)page->mapping->host; struct inode *inode = (struct inode*)page->mapping->host;
......
...@@ -634,8 +634,8 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp) ...@@ -634,8 +634,8 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp)
if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) { if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) {
/* if this process really wants to die, let it go */ /* if this process really wants to die, let it go */
if ( sigismember(&(current->signal), SIGKILL) || if ( sigismember(&(current->pending.signal), SIGKILL) ||
sigismember(&(current->signal), SIGINT) ) sigismember(&(current->pending.signal), SIGINT) )
break; break;
/* signal is present: after timeout always return /* signal is present: after timeout always return
really smart idea, probably useless ... */ really smart idea, probably useless ... */
......
...@@ -904,6 +904,7 @@ void ext2_truncate (struct inode * inode) ...@@ -904,6 +904,7 @@ void ext2_truncate (struct inode * inode)
int nr = 0; int nr = 0;
int n; int n;
long iblock; long iblock;
unsigned blocksize, tail;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode))) S_ISLNK(inode->i_mode)))
...@@ -913,8 +914,13 @@ void ext2_truncate (struct inode * inode) ...@@ -913,8 +914,13 @@ void ext2_truncate (struct inode * inode)
ext2_discard_prealloc(inode); 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); >> 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); n = ext2_block_to_path(inode, iblock, offsets);
if (n == 0) if (n == 0)
......
...@@ -641,7 +641,7 @@ smb_request(struct smb_sb_info *server) ...@@ -641,7 +641,7 @@ smb_request(struct smb_sb_info *server)
DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]); DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
spin_lock_irqsave(&current->sigmask_lock, flags); spin_lock_irqsave(&current->sigmask_lock, flags);
sigpipe = sigismember(&current->signal, SIGPIPE); sigpipe = sigismember(&current->pending.signal, SIGPIPE);
old_set = current->blocked; old_set = current->blocked;
siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
recalc_sigpending(current); recalc_sigpending(current);
...@@ -659,7 +659,7 @@ smb_request(struct smb_sb_info *server) ...@@ -659,7 +659,7 @@ smb_request(struct smb_sb_info *server)
/* read/write errors are handled by errno */ /* read/write errors are handled by errno */
spin_lock_irqsave(&current->sigmask_lock, flags); spin_lock_irqsave(&current->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe) if (result == -EPIPE && !sigpipe)
sigdelset(&current->signal, SIGPIPE); sigdelset(&current->pending.signal, SIGPIPE);
current->blocked = old_set; current->blocked = old_set;
recalc_sigpending(current); recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags); spin_unlock_irqrestore(&current->sigmask_lock, flags);
...@@ -821,7 +821,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, ...@@ -821,7 +821,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
goto bad_conn; goto bad_conn;
spin_lock_irqsave(&current->sigmask_lock, flags); spin_lock_irqsave(&current->sigmask_lock, flags);
sigpipe = sigismember(&current->signal, SIGPIPE); sigpipe = sigismember(&current->pending.signal, SIGPIPE);
old_set = current->blocked; old_set = current->blocked;
siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP));
recalc_sigpending(current); recalc_sigpending(current);
...@@ -841,7 +841,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, ...@@ -841,7 +841,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
/* read/write errors are handled by errno */ /* read/write errors are handled by errno */
spin_lock_irqsave(&current->sigmask_lock, flags); spin_lock_irqsave(&current->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe) if (result == -EPIPE && !sigpipe)
sigdelset(&current->signal, SIGPIPE); sigdelset(&current->pending.signal, SIGPIPE);
current->blocked = old_set; current->blocked = old_set;
recalc_sigpending(current); recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags); spin_unlock_irqrestore(&current->sigmask_lock, flags);
......
...@@ -168,5 +168,7 @@ static __inline__ void irq_init_irq(void) ...@@ -168,5 +168,7 @@ static __inline__ void irq_init_irq(void)
} }
} }
irq_mask[IRQ_KEYBOARDTX].noautoenable = 1;
init_FIQ(); init_FIQ();
} }
...@@ -46,6 +46,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -46,6 +46,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#endif #endif
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs);
} }
/* /*
......
...@@ -15,20 +15,13 @@ ...@@ -15,20 +15,13 @@
/* Virtual Physical Size /* Virtual Physical Size
* 0xff800000 0x40000000 1MB X-Bus * 0xff800000 0x40000000 1MB X-Bus
* 0xff000000 0x7c000000 1MB PCI I/O space * 0xff000000 0x7c000000 1MB PCI I/O space
*
* 0xfe000000 0x42000000 1MB CSR * 0xfe000000 0x42000000 1MB CSR
* 0xfd000000 0x78000000 1MB Outbound write flush (not supported) * 0xfd000000 0x78000000 1MB Outbound write flush (not supported)
* 0xfc000000 0x79000000 1MB PCI IACK/special space * 0xfc000000 0x79000000 1MB PCI IACK/special space
*
* 0xfb000000 0x7a000000 16MB PCI Config type 1 * 0xfb000000 0x7a000000 16MB PCI Config type 1
* 0xfa000000 0x7b000000 16MB PCI Config type 0 * 0xfa000000 0x7b000000 16MB PCI Config type 0
*
* 0xf9000000 0x50000000 1MB Cache flush * 0xf9000000 0x50000000 1MB Cache flush
* 0xf8000000 0x41000000 16MB Flash memory * 0xf0000000 0x80000000 16MB ISA memory
*
* 0xe1000000 unmapped (to catch bad ISA/PCI)
*
* 0xe0000000 0x80000000 16MB ISA memory
*/ */
#define XBUS_SIZE 0x00100000 #define XBUS_SIZE 0x00100000
#define XBUS_BASE 0xff800000 #define XBUS_BASE 0xff800000
...@@ -54,9 +47,6 @@ ...@@ -54,9 +47,6 @@
#define FLUSH_SIZE 0x00100000 #define FLUSH_SIZE 0x00100000
#define FLUSH_BASE 0xf9000000 #define FLUSH_BASE 0xf9000000
#define FLASH_SIZE 0x01000000
#define FLASH_BASE 0xf8000000
#define PCIMEM_SIZE 0x01000000 #define PCIMEM_SIZE 0x01000000
#define PCIMEM_BASE 0xf0000000 #define PCIMEM_BASE 0xf0000000
...@@ -67,9 +57,6 @@ ...@@ -67,9 +57,6 @@
#define PCIMEM_SIZE 0x80000000 #define PCIMEM_SIZE 0x80000000
#define PCIMEM_BASE 0x80000000 #define PCIMEM_BASE 0x80000000
#define FLASH_SIZE 0x01000000
#define FLASH_BASE 0x7f000000
#define FLUSH_SIZE 0x00100000 #define FLUSH_SIZE 0x00100000
#define FLUSH_BASE 0x7e000000 #define FLUSH_BASE 0x7e000000
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* Copyright (C) 1996-1999 Russell King * Copyright (C) 1996-1999 Russell King
*/ */
#include <asm/mach-types.h>
/* /*
* Note! This could cause problems on the NetWinder * Note! This could cause problems on the NetWinder
......
...@@ -63,4 +63,6 @@ ...@@ -63,4 +63,6 @@
#define INTCONT_LED 0x1a #define INTCONT_LED 0x1a
#define INTCONT_PCI_RESET 0x1c #define INTCONT_PCI_RESET 0x1c
#define UNCACHEABLE_ADDR STATUS_BASE
#endif #endif
...@@ -46,6 +46,7 @@ extern __inline__ void setup_timer(void) ...@@ -46,6 +46,7 @@ extern __inline__ void setup_timer(void)
__raw_writeb(0x10, DUART_BASE + 0x14); __raw_writeb(0x10, DUART_BASE + 0x14);
timer_irq.handler = timer_interrupt; timer_irq.handler = timer_interrupt;
timer_irq.flags = SA_SHIRQ;
setup_arm_irq(IRQ_TIMER, &timer_irq); setup_arm_irq(IRQ_TIMER, &timer_irq);
} }
...@@ -22,8 +22,11 @@ void _ll_write_char(char c) ...@@ -22,8 +22,11 @@ void _ll_write_char(char c)
*/ */
static void puts(const char *s) static void puts(const char *s)
{ {
while (*s) while (*s) {
if (*s == '\n')
_ll_write_char('\r');
_ll_write_char(*(s++)); _ll_write_char(*(s++));
}
} }
/* /*
......
...@@ -152,21 +152,22 @@ static __inline__ void irq_init_irq(void) ...@@ -152,21 +152,22 @@ static __inline__ void irq_init_irq(void)
irq_desc[irq].unmask = rpc_unmask_irq_b; irq_desc[irq].unmask = rpc_unmask_irq_b;
break; break;
case 16 ... 22: case 16 ... 21:
irq_desc[irq].valid = 1; irq_desc[irq].valid = 1;
irq_desc[irq].noautoenable = 1;
irq_desc[irq].mask_ack = rpc_mask_irq_dma; irq_desc[irq].mask_ack = rpc_mask_irq_dma;
irq_desc[irq].mask = rpc_mask_irq_dma; irq_desc[irq].mask = rpc_mask_irq_dma;
irq_desc[irq].unmask = rpc_unmask_irq_dma; irq_desc[irq].unmask = rpc_unmask_irq_dma;
break; break;
case 32 ... 40: case 32 ... 39:
irq_desc[irq].valid = 1; irq_desc[irq].valid = 1;
irq_desc[irq].mask_ack = ecard_disableirq; irq_desc[irq].mask_ack = ecard_disableirq;
irq_desc[irq].mask = ecard_disableirq; irq_desc[irq].mask = ecard_disableirq;
irq_desc[irq].unmask = ecard_enableirq; irq_desc[irq].unmask = ecard_enableirq;
break; break;
case 64 ... 72: case 64 ... 71:
irq_desc[irq].valid = 1; irq_desc[irq].valid = 1;
irq_desc[irq].mask_ack = rpc_mask_irq_fiq; irq_desc[irq].mask_ack = rpc_mask_irq_fiq;
irq_desc[irq].mask = rpc_mask_irq_fiq; irq_desc[irq].mask = rpc_mask_irq_fiq;
...@@ -175,5 +176,7 @@ static __inline__ void irq_init_irq(void) ...@@ -175,5 +176,7 @@ static __inline__ void irq_init_irq(void)
} }
} }
irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
init_FIQ(); init_FIQ();
} }
#ifndef _ASMARM_CURRENT_H #ifndef _ASMARM_CURRENT_H
#define _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 /* Old compilers seem to generate bad code if we allow `current' to be
non volatile. */ non volatile. */
#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90) #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90)
static inline struct task_struct *get_current(void) __attribute__ (( __const__ )); static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
#define __VOLATILE_CURRENT
#else
#define __VOLATILE_CURRENT volatile
#endif #endif
static inline struct task_struct *get_current(void) static inline struct task_struct *get_current(void)
{ {
struct task_struct *ts; register unsigned long sp asm ("sp");
__asm__ __VOLATILE_CURRENT ( return (struct task_struct *)(sp & ~0x1fff);
"bic %0, sp, #0x1f00 @ get_current
bic %0, %0, #0x00ff"
: "=r" (ts));
return ts;
} }
#define current (get_current()) #define current (get_current())
......
...@@ -7,6 +7,7 @@ typedef unsigned int dmach_t; ...@@ -7,6 +7,7 @@ typedef unsigned int dmach_t;
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/scatterlist.h>
#include <asm/arch/dma.h> #include <asm/arch/dma.h>
/* /*
......
/*
* 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
/*
* 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);
/*
* 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);
/*
* linux/include/asm-arm/mach/pci.h
*/
#define MAX_NR_BUS 2 #define MAX_NR_BUS 2
struct arm_bus_sysdata { struct arm_bus_sysdata {
...@@ -22,12 +25,12 @@ struct arm_pci_sysdata { ...@@ -22,12 +25,12 @@ struct arm_pci_sysdata {
}; };
struct hw_pci { struct hw_pci {
void (*init)(void); void (*init)(struct arm_pci_sysdata *);
unsigned long io_start;
unsigned long mem_start;
u8 (*swizzle)(struct pci_dev *dev, u8 *pin); u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
}; };
void __init dc21285_init(void); extern u8 no_swizzle(struct pci_dev *dev, u8 *pin);
void __init plx90x0_init(void);
void __init dc21285_init(struct arm_pci_sysdata *);
void __init plx90x0_init(struct arm_pci_sysdata *);
...@@ -17,9 +17,19 @@ ...@@ -17,9 +17,19 @@
#define destroy_context(mm) do { } while(0) #define destroy_context(mm) do { } while(0)
#define init_new_context(tsk,mm) 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) 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 * This is the actual mm switch as far as the scheduler
* is concerned. No registers are touched. * is concerned. No registers are touched.
......
...@@ -93,8 +93,10 @@ pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int directi ...@@ -93,8 +93,10 @@ pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int directi
{ {
int i; int i;
for (i = 0; i < nents; i++, sg++) for (i = 0; i < nents; i++, sg++) {
consistent_sync(sg->address, sg->length, direction); consistent_sync(sg->address, sg->length, direction);
sg->dma_address = virt_to_bus(sg->address);
}
return nents; return nents;
} }
...@@ -136,7 +138,7 @@ pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int d ...@@ -136,7 +138,7 @@ pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int d
int i; int i;
for (i = 0; i < nelems; i++, sg++) 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 whether the given PCI device DMA address mask can
...@@ -149,15 +151,6 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) ...@@ -149,15 +151,6 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
return 1; 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 /* __KERNEL__ */
#endif #endif
...@@ -13,11 +13,10 @@ ...@@ -13,11 +13,10 @@
*/ */
#include <asm/proc/cache.h> #include <asm/proc/cache.h>
extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, /*
unsigned long start, * ARM processors do not cache TLB tables in RAM.
unsigned long end) */
{ #define flush_tlb_pgtables(mm,start,end) do { } while (0)
}
/* /*
* Page table cache stuff * Page table cache stuff
......
...@@ -78,3 +78,25 @@ ...@@ -78,3 +78,25 @@
.macro restore_irqs, oldcpsr .macro restore_irqs, oldcpsr
@ This be restore_irqs @ This be restore_irqs
.endm .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_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0) #define flush_cache_mm(mm) do { } while (0)
#define flush_cache_range(mm,start,end) do { } while (0) #define flush_cache_range(mm,start,end) do { } while (0)
#define flush_cache_page(vma,vmaddr) do { } while (0) #define flush_cache_page(vma,vmaddr) do { } while (0)
#define flush_page_to_ram(page) 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_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_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 */ /* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */
#define clean_cache_area(_start,_size) do { } while (0) #define clean_cache_area(_start,_size) do { } while (0)
......
...@@ -15,20 +15,20 @@ ...@@ -15,20 +15,20 @@
({ \ ({ \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"@ atomic down operation\n" \ "@ atomic down operation\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
" ldr lr, [%0]\n" \ " ldr lr, [%0]\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
" subs lr, lr, #1\n" \ " subs lr, lr, #1\n" \
" str lr, [%0]\n" \ " str lr, [%0]\n" \
" orrmi r0, r0, #0x80000000 @ set N\n" \ " orrmi ip, ip, #0x80000000 @ set N\n" \
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" movmi r0, %0\n" \ " movmi ip, %0\n" \
" blmi " SYMBOL_NAME_STR(fail) \ " blmi " SYMBOL_NAME_STR(fail) \
: \ : \
: "r" (ptr) \ : "r" (ptr) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
}) })
#define __down_op_ret(ptr,fail) \ #define __down_op_ret(ptr,fail) \
...@@ -36,22 +36,22 @@ ...@@ -36,22 +36,22 @@
unsigned int result; \ unsigned int result; \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
" @ down_op_ret\n" \ " @ down_op_ret\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
" ldr lr, [%1]\n" \ " ldr lr, [%1]\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
" subs lr, lr, #1\n" \ " subs lr, lr, #1\n" \
" str lr, [%1]\n" \ " str lr, [%1]\n" \
" orrmi r0, r0, #0x80000000 @ set N\n" \ " orrmi ip, ip, #0x80000000 @ set N\n" \
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" movmi r0, %1\n" \ " movmi ip, %1\n" \
" movpl r0, #0\n" \ " movpl ip, #0\n" \
" blmi " SYMBOL_NAME_STR(fail) "\n" \ " blmi " SYMBOL_NAME_STR(fail) "\n" \
" mov %0, r0" \ " mov %0, ip" \
: "=&r" (result) \ : "=&r" (result) \
: "r" (ptr) \ : "r" (ptr) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
result; \ result; \
}) })
...@@ -59,20 +59,20 @@ ...@@ -59,20 +59,20 @@
({ \ ({ \
__asm__ __volatile__ ( \ __asm__ __volatile__ ( \
"@ up_op\n" \ "@ up_op\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
" ldr lr, [%0]\n" \ " ldr lr, [%0]\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
" adds lr, lr, #1\n" \ " adds lr, lr, #1\n" \
" str lr, [%0]\n" \ " str lr, [%0]\n" \
" orrle r0, r0, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \ " orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" movmi r0, %0\n" \ " movmi ip, %0\n" \
" blmi " SYMBOL_NAME_STR(wake) \ " blmi " SYMBOL_NAME_STR(wake) \
: \ : \
: "r" (ptr) \ : "r" (ptr) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
}) })
/* /*
...@@ -89,22 +89,22 @@ ...@@ -89,22 +89,22 @@
({ \ ({ \
__asm__ __volatile__( \ __asm__ __volatile__( \
"@ down_op_write\n" \ "@ down_op_write\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
\ \
" ldr lr, [%0]\n" \ " ldr lr, [%0]\n" \
" subs lr, lr, %1\n" \ " subs lr, lr, %1\n" \
" str lr, [%0]\n" \ " str lr, [%0]\n" \
\ \
" orreq r0, r0, #0x40000000 @ set Z \n"\ " orreq ip, ip, #0x40000000 @ set Z \n"\
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" movne r0, %0\n" \ " movne ip, %0\n" \
" blne " SYMBOL_NAME_STR(fail) \ " blne " SYMBOL_NAME_STR(fail) \
: \ : \
: "r" (ptr), "I" (RW_LOCK_BIAS) \ : "r" (ptr), "I" (RW_LOCK_BIAS) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
}) })
/* Increments by RW_LOCK_BIAS, wakes if value >= 0 */ /* Increments by RW_LOCK_BIAS, wakes if value >= 0 */
...@@ -112,22 +112,22 @@ ...@@ -112,22 +112,22 @@
({ \ ({ \
__asm__ __volatile__( \ __asm__ __volatile__( \
"@ up_op_read\n" \ "@ up_op_read\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
\ \
" ldr lr, [%0]\n" \ " ldr lr, [%0]\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
" adds lr, lr, %1\n" \ " adds lr, lr, %1\n" \
" str lr, [%0]\n" \ " str lr, [%0]\n" \
\ \
" orrcs r0, r0, #0x20000000 @ set C\n" \ " orrcs ip, ip, #0x20000000 @ set C\n" \
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" movcs r0, %0\n" \ " movcs ip, %0\n" \
" blcs " SYMBOL_NAME_STR(wake) \ " blcs " SYMBOL_NAME_STR(wake) \
: \ : \
: "r" (ptr), "I" (RW_LOCK_BIAS) \ : "r" (ptr), "I" (RW_LOCK_BIAS) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
}) })
#define __down_op_read(ptr,fail) \ #define __down_op_read(ptr,fail) \
...@@ -137,22 +137,22 @@ ...@@ -137,22 +137,22 @@
({ \ ({ \
__asm__ __volatile__( \ __asm__ __volatile__( \
"@ up_op_read\n" \ "@ up_op_read\n" \
" mov r0, pc\n" \ " mov ip, pc\n" \
" orr lr, r0, #0x08000000\n" \ " orr lr, ip, #0x08000000\n" \
" teqp lr, #0\n" \ " teqp lr, #0\n" \
\ \
" ldr lr, [%0]\n" \ " ldr lr, [%0]\n" \
" and r0, r0, #0x0c000003\n" \ " and ip, ip, #0x0c000003\n" \
" adds lr, lr, %1\n" \ " adds lr, lr, %1\n" \
" str lr, [%0]\n" \ " str lr, [%0]\n" \
\ \
" orreq r0, r0, #0x40000000 @ Set Z \n" \ " orreq ip, ip, #0x40000000 @ Set Z \n" \
" teqp r0, #0\n" \ " teqp ip, #0\n" \
" moveq r0, %0\n" \ " moveq ip, %0\n" \
" bleq " SYMBOL_NAME_STR(wake) \ " bleq " SYMBOL_NAME_STR(wake) \
: \ : \
: "r" (ptr), "I" (1) \ : "r" (ptr), "I" (1) \
: "r0", "lr", "cc"); \ : "ip", "lr", "cc"); \
}) })
#endif #endif
...@@ -47,3 +47,24 @@ ...@@ -47,3 +47,24 @@
.macro restore_irqs, oldcpsr .macro restore_irqs, oldcpsr
msr cpsr_c, \oldcpsr msr cpsr_c, \oldcpsr
.endm .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
...@@ -108,6 +108,36 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -108,6 +108,36 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
: "memory"); \ : "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 * save current IRQ & FIQ state
*/ */
......
...@@ -3,11 +3,6 @@ ...@@ -3,11 +3,6 @@
#include <asm/proc/ptrace.h> #include <asm/proc/ptrace.h>
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#define PTRACE_GETFPREGS 14
#define PTRACE_SETFPREGS 15
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define pc_pointer(v) \ #define pc_pointer(v) \
((v) & ~PCMASK) ((v) & ~PCMASK)
...@@ -16,6 +11,11 @@ ...@@ -16,6 +11,11 @@
(pc_pointer((regs)->ARM_pc)) (pc_pointer((regs)->ARM_pc))
#ifdef __KERNEL__ #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 *); extern void show_regs(struct pt_regs *);
#define predicate(x) (x & 0xf0000000) #define predicate(x) (x & 0xf0000000)
......
#ifndef _ASMARM_SCATTERLIST_H #ifndef _ASMARM_SCATTERLIST_H
#define _ASMARM_SCATTERLIST_H #define _ASMARM_SCATTERLIST_H
#include <asm/types.h>
struct scatterlist { struct scatterlist {
char * address; /* Location data is to be transferred to */ char *address; /* virtual address */
char * alt_address; /* Location of actual if address is a char *alt_address; /* indirect dma address, or NULL */
* dma indirect buffer. NULL otherwise */ dma_addr_t dma_address; /* dma address */
unsigned int length; 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) #define ISA_DMA_THRESHOLD (0xffffffff)
#endif /* _ASMARM_SCATTERLIST_H */ #endif /* _ASMARM_SCATTERLIST_H */
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
#include <asm/proc/shmparam.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 */ #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
#endif /* _ASMARM_SHMPARAM_H */ #endif /* _ASMARM_SHMPARAM_H */
...@@ -75,7 +75,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; ...@@ -75,7 +75,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
* amount of physical memory you can use to about 950MB. * amount of physical memory you can use to about 950MB.
* *
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G * 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) #define __PAGE_OFFSET (0xC0000000)
......
...@@ -267,8 +267,15 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, ...@@ -267,8 +267,15 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
* I expect future Intel CPU's to have a weaker ordering, * I expect future Intel CPU's to have a weaker ordering,
* but I'd also expect them to finally get their act together * but I'd also expect them to finally get their act together
* and add some real memory barriers if so. * 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") #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
#else
#define mb() __asm__ __volatile__ ("sfence": : :"memory")
#endif
#define rmb() mb() #define rmb() mb()
#define wmb() __asm__ __volatile__ ("": : :"memory") #define wmb() __asm__ __volatile__ ("": : :"memory")
#define set_mb(var, value) do { xchg(&var, value); } while (0) #define set_mb(var, value) do { xchg(&var, value); } while (0)
......
...@@ -1162,6 +1162,7 @@ extern int block_sync_page(struct page *); ...@@ -1162,6 +1162,7 @@ extern int block_sync_page(struct page *);
int generic_block_bmap(struct address_space *, long, get_block_t *); int generic_block_bmap(struct address_space *, long, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned); 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 int generic_file_mmap(struct file *, struct vm_area_struct *);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
......
...@@ -234,7 +234,6 @@ struct mm_struct { ...@@ -234,7 +234,6 @@ struct mm_struct {
struct signal_struct { struct signal_struct {
atomic_t count; atomic_t count;
struct k_sigaction action[_NSIG]; struct k_sigaction action[_NSIG];
struct sigpending pending;
spinlock_t siglock; spinlock_t siglock;
}; };
...@@ -242,7 +241,6 @@ struct signal_struct { ...@@ -242,7 +241,6 @@ struct signal_struct {
#define INIT_SIGNALS { \ #define INIT_SIGNALS { \
ATOMIC_INIT(1), \ ATOMIC_INIT(1), \
{ {{0,}}, }, \ { {{0,}}, }, \
{ NULL, &init_signals.pending.head, }, \
SPIN_LOCK_UNLOCKED } SPIN_LOCK_UNLOCKED }
/* /*
...@@ -582,7 +580,7 @@ static inline int signal_pending(struct task_struct *p) ...@@ -582,7 +580,7 @@ static inline int signal_pending(struct task_struct *p)
* Re-calculate pending state from the set of locally pending * Re-calculate pending state from the set of locally pending
* signals, globally pending signals, and blocked signals. * 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; unsigned long ready;
long i; long i;
...@@ -590,20 +588,20 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc ...@@ -590,20 +588,20 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
default: default:
for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;) 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; break;
case 4: ready = (p1->sig[3] | p2->sig[3]) &~ blocked->sig[3]; case 4: ready = signal->sig[3] &~ blocked->sig[3];
ready |= (p1->sig[2] | p2->sig[2]) &~ blocked->sig[2]; ready |= signal->sig[2] &~ blocked->sig[2];
ready |= (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1]; ready |= signal->sig[1] &~ blocked->sig[1];
ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0]; ready |= signal->sig[0] &~ blocked->sig[0];
break; break;
case 2: ready = (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1]; case 2: ready = signal->sig[1] &~ blocked->sig[1];
ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0]; ready |= signal->sig[0] &~ blocked->sig[0];
break; 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; return ready != 0;
} }
...@@ -614,7 +612,7 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc ...@@ -614,7 +612,7 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc
static inline void recalc_sigpending(struct task_struct *t) 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. */ /* True if we are on the alternate signal stack. */
......
...@@ -218,6 +218,8 @@ static inline void init_sigpending(struct sigpending *sig) ...@@ -218,6 +218,8 @@ static inline void init_sigpending(struct sigpending *sig)
sig->tail = &sig->head; sig->tail = &sig->head;
} }
extern long do_sigpending(void *, unsigned long);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_SIGNAL_H */ #endif /* _LINUX_SIGNAL_H */
...@@ -512,9 +512,6 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t ...@@ -512,9 +512,6 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t
return -1; return -1;
spin_lock_init(&sig->siglock); spin_lock_init(&sig->siglock);
atomic_set(&sig->count, 1); atomic_set(&sig->count, 1);
init_sigpending(&sig->pending);
memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action)); memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
return 0; return 0;
} }
......
...@@ -203,6 +203,7 @@ EXPORT_SYMBOL(block_prepare_write); ...@@ -203,6 +203,7 @@ EXPORT_SYMBOL(block_prepare_write);
EXPORT_SYMBOL(block_sync_page); EXPORT_SYMBOL(block_sync_page);
EXPORT_SYMBOL(cont_prepare_write); EXPORT_SYMBOL(cont_prepare_write);
EXPORT_SYMBOL(generic_commit_write); EXPORT_SYMBOL(generic_commit_write);
EXPORT_SYMBOL(block_zero_page);
EXPORT_SYMBOL(generic_block_bmap); EXPORT_SYMBOL(generic_block_bmap);
EXPORT_SYMBOL(generic_file_read); EXPORT_SYMBOL(generic_file_read);
EXPORT_SYMBOL(do_generic_file_read); EXPORT_SYMBOL(do_generic_file_read);
......
...@@ -50,31 +50,30 @@ void __init signals_init(void) ...@@ -50,31 +50,30 @@ void __init signals_init(void)
static int static int
next_signal(struct task_struct *tsk, sigset_t *mask) 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; int sig = 0;
s1 = tsk->pending.signal.sig; s = tsk->pending.signal.sig;
s2 = tsk->sig->pending.signal.sig;
m = mask->sig; m = mask->sig;
switch (_NSIG_WORDS) { switch (_NSIG_WORDS) {
default: default:
for (i = 0; i < _NSIG_WORDS; ++i, ++s1, ++s2, ++m) for (i = 0; i < _NSIG_WORDS; ++i, ++s, ++m)
if ((x = (*s1 | *s2) &~ *m) != 0) { if ((x = *s &~ *m) != 0) {
sig = ffz(~x) + i*_NSIG_BPW + 1; sig = ffz(~x) + i*_NSIG_BPW + 1;
break; break;
} }
break; break;
case 2: if ((x = (s1[0] | s2[0]) &~ m[0]) != 0) case 2: if ((x = s[0] &~ m[0]) != 0)
sig = 1; sig = 1;
else if ((x = (s1[1] | s2[1]) &~ m[1]) != 0) else if ((x = s[1] &~ m[1]) != 0)
sig = _NSIG_BPW + 1; sig = _NSIG_BPW + 1;
else else
break; break;
sig += ffz(~x); sig += ffz(~x);
break; break;
case 1: if ((x = (*s1 | *s2) &~ *m) != 0) case 1: if ((x = *s &~ *m) != 0)
sig = ffz(~x) + 1; sig = ffz(~x) + 1;
break; break;
} }
...@@ -108,7 +107,6 @@ flush_signals(struct task_struct *t) ...@@ -108,7 +107,6 @@ flush_signals(struct task_struct *t)
{ {
t->sigpending = 0; t->sigpending = 0;
flush_sigqueue(&t->pending); flush_sigqueue(&t->pending);
flush_sigqueue(&t->pending);
} }
void exit_sighand(struct task_struct *tsk) void exit_sighand(struct task_struct *tsk)
...@@ -118,10 +116,8 @@ void exit_sighand(struct task_struct *tsk) ...@@ -118,10 +116,8 @@ void exit_sighand(struct task_struct *tsk)
spin_lock_irq(&tsk->sigmask_lock); spin_lock_irq(&tsk->sigmask_lock);
if (sig) { if (sig) {
tsk->sig = NULL; tsk->sig = NULL;
if (atomic_dec_and_test(&sig->count)) { if (atomic_dec_and_test(&sig->count))
flush_sigqueue(&sig->pending);
kmem_cache_free(sigact_cachep, sig); kmem_cache_free(sigact_cachep, sig);
}
} }
tsk->sigpending = 0; tsk->sigpending = 0;
flush_sigqueue(&tsk->pending); flush_sigqueue(&tsk->pending);
...@@ -256,8 +252,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid, ...@@ -256,8 +252,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
if (sig) { if (sig) {
if (!collect_signal(sig, &current->pending, info)) if (!collect_signal(sig, &current->pending, info))
if (!collect_signal(sig, &current->sig->pending, info)) sig = 0;
sig = 0;
/* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER, /* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
we need to xchg out the timer overrun values. */ we need to xchg out the timer overrun values. */
...@@ -303,7 +298,7 @@ static int rm_from_queue(int sig, struct sigpending *s) ...@@ -303,7 +298,7 @@ static int rm_from_queue(int sig, struct sigpending *s)
*/ */
static int rm_sig_from_queue(int sig, struct task_struct *t) 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);
} }
/* /*
...@@ -494,69 +489,6 @@ static inline void signal_wake_up(struct task_struct *t) ...@@ -494,69 +489,6 @@ static inline void signal_wake_up(struct task_struct *t)
#endif /* CONFIG_SMP */ #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) static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
{ {
int retval = send_signal(sig, info, &t->pending); int retval = send_signal(sig, info, &t->pending);
...@@ -715,34 +647,6 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) ...@@ -715,34 +647,6 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
} }
/*
* 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). * kill_something_info() interprets pid in interesting ways just like kill(2).
* *
...@@ -772,7 +676,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) ...@@ -772,7 +676,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
} else if (pid < 0) { } else if (pid < 0) {
return kill_pg_info(sig, info, -pid); return kill_pg_info(sig, info, -pid);
} else { } else {
return kill_tg_info(sig, info, pid); return kill_proc_info(sig, info, pid);
} }
} }
...@@ -975,26 +879,29 @@ sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize) ...@@ -975,26 +879,29 @@ sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize)
return error; return error;
} }
asmlinkage long long do_sigpending(void *set, unsigned long sigsetsize)
sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
{ {
int error = -EINVAL; long error = -EINVAL;
sigset_t pending; 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; goto out;
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sigmask_lock);
sigorsets(&pending, &current->pending.signal, &current->sig->pending.signal); sigandsets(&pending, &current->blocked, &current->pending.signal);
sigandsets(&pending, &current->blocked, &pending);
spin_unlock_irq(&current->sigmask_lock); spin_unlock_irq(&current->sigmask_lock);
error = -EFAULT; error = -EFAULT;
if (!copy_to_user(set, &pending, sizeof(*set))) if (!copy_to_user(set, &pending, sigsetsize))
error = 0; error = 0;
out: out:
return error; return error;
}
asmlinkage long
sys_rt_sigpending(sigset_t *set, size_t sigsetsize)
{
return do_sigpending(set, sigsetsize);
} }
asmlinkage long asmlinkage long
...@@ -1098,7 +1005,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo) ...@@ -1098,7 +1005,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo)
info.si_signo = sig; info.si_signo = sig;
/* POSIX.1b doesn't mention process groups. */ /* POSIX.1b doesn't mention process groups. */
return kill_tg_info(sig, &info, pid); return kill_proc_info(sig, &info, pid);
} }
int int
...@@ -1218,6 +1125,12 @@ do_sigaltstack (const stack_t *uss, stack_t *uoss, unsigned long sp) ...@@ -1218,6 +1125,12 @@ do_sigaltstack (const stack_t *uss, stack_t *uoss, unsigned long sp)
return error; return error;
} }
asmlinkage long
sys_sigpending(old_sigset_t *set)
{
return do_sigpending(set, sizeof(*set));
}
#if !defined(__alpha__) #if !defined(__alpha__)
/* Alpha has its own versions with special arguments. */ /* Alpha has its own versions with special arguments. */
...@@ -1270,22 +1183,6 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset) ...@@ -1270,22 +1183,6 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset)
return error; return error;
} }
asmlinkage long
sys_sigpending(old_sigset_t *set)
{
int error;
old_sigset_t pending;
spin_lock_irq(&current->sigmask_lock);
pending = current->blocked.sig[0] & (current->pending.signal.sig[0] | current->sig->pending.signal.sig[0]);
spin_unlock_irq(&current->sigmask_lock);
error = -EFAULT;
if (!copy_to_user(set, &pending, sizeof(*set)))
error = 0;
return error;
}
#ifndef __sparc__ #ifndef __sparc__
asmlinkage long asmlinkage long
sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment