Commit d1a75a97 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/davem/BK/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 2c66151c 4be8d601
...@@ -59,6 +59,9 @@ endmenu ...@@ -59,6 +59,9 @@ endmenu
mainmenu_option next_comment mainmenu_option next_comment
comment 'Console drivers' comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE bool 'PROM console' CONFIG_PROM_CONSOLE
if [ "$CONFIG_PROM_CONSOLE" != "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
fi
source drivers/video/Config.in source drivers/video/Config.in
endmenu endmenu
...@@ -214,6 +217,8 @@ if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then ...@@ -214,6 +217,8 @@ if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
fi fi
endmenu endmenu
source drivers/input/Config.in
source fs/Config.in source fs/Config.in
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
......
This diff is collapsed.
...@@ -13,7 +13,7 @@ export-objs := sparc_ksyms.o ...@@ -13,7 +13,7 @@ export-objs := sparc_ksyms.o
IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o
obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \
process.o signal.o ioport.o setup.o idprom.o \ process.o signal.o ioport.o setup.o idprom.o \
sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \ sys_sparc.o sunos_asm.o systbls.o \
time.o windows.o cpu.o devices.o sclow.o \ time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \
unaligned.o muldiv.o pcic.o semaphore.o sparc_ksyms.o unaligned.o muldiv.o pcic.o semaphore.o sparc_ksyms.o
......
...@@ -11,8 +11,7 @@ case $1 in ...@@ -11,8 +11,7 @@ case $1 in
echo " sizeof(struct $2_struct)," >> $4 echo " sizeof(struct $2_struct)," >> $4
;; ;;
-ints) -ints)
sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3 sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.global.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3 ;;
;;
*) *)
exit 1 exit 1
;; ;;
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
struct linux_ebus *ebus_chain = 0; struct linux_ebus *ebus_chain = 0;
extern void rs_init(void);
/* We are together with pcic.c under CONFIG_PCI. */ /* We are together with pcic.c under CONFIG_PCI. */
extern unsigned int pcic_pin_to_irq(unsigned int, char *name); extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
...@@ -361,6 +359,4 @@ void __init ebus_init(void) ...@@ -361,6 +359,4 @@ void __init ebus_init(void)
ebus->next = 0; ebus->next = 0;
++num_ebus; ++num_ebus;
} }
rs_init();
} }
...@@ -53,6 +53,7 @@ in_trap_handler: ...@@ -53,6 +53,7 @@ in_trap_handler:
.text .text
.align 4 .align 4
#if 0 /* kgdb is dropped from 2.5.33 */
! This function is called when any SPARC trap (except window overflow or ! This function is called when any SPARC trap (except window overflow or
! underflow) occurs. It makes sure that the invalid register window is still ! underflow) occurs. It makes sure that the invalid register window is still
! available before jumping into C code. It will also restore the world if you ! available before jumping into C code. It will also restore the world if you
...@@ -119,7 +120,7 @@ C_LABEL(trap_low): ...@@ -119,7 +120,7 @@ C_LABEL(trap_low):
STORE_PT_PRIV(sp, l0, l1, l2) STORE_PT_PRIV(sp, l0, l1, l2)
RESTORE_ALL RESTORE_ALL
#endif
#ifdef CONFIG_BLK_DEV_FD #ifdef CONFIG_BLK_DEV_FD
.text .text
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
static struct fs_struct init_fs = INIT_FS; static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES; static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS; static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm); struct mm_struct init_mm = INIT_MM(init_mm);
struct task_struct init_task = INIT_TASK(init_task); struct task_struct init_task = INIT_TASK(init_task);
......
/* $Id: pcic.c,v 1.23 2002/01/23 14:33:55 davem Exp $ /*
* pcic.c: Sparc/PCI controller support * pcic.c: MicroSPARC-IIep PCI controller support
* *
* Copyright (C) 1998 V. Roganov and G. Raiko * Copyright (C) 1998 V. Roganov and G. Raiko
* *
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jiffies.h>
#include <asm/ebus.h> #include <asm/ebus.h>
#include <asm/sbus.h> /* for sanity check... */ #include <asm/sbus.h> /* for sanity check... */
...@@ -193,48 +194,26 @@ static void pci_do_settimeofday(struct timeval *tv); ...@@ -193,48 +194,26 @@ static void pci_do_settimeofday(struct timeval *tv);
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3)) #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
static int pcic_read_config(struct pci_bus *bus, unsigned int devfn, static int pcic_read_config_dword(unsigned int busno, unsigned int devfn,
int where, int size, u32 *value) int where, u32 *value)
{ {
unsigned int v;
unsigned char busnum = bus->number;
struct linux_pcic *pcic; struct linux_pcic *pcic;
unsigned long flags; unsigned long flags;
/* unsigned char where; */
switch (size) {
case 1:
pcic_read_config(bus, devfn, where&~3, 4, &v);
*value = 0xff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
case 2:
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
pcic_read_config(bus, devfn, where&~3, 4, &v);
*value = 0xffff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
}
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0; pcic = &pcic0;
save_and_cli(flags); local_irq_save(flags);
#if 0 /* does not fail here */ #if 0 /* does not fail here */
pcic_speculative = 1; pcic_speculative = 1;
pcic_trapped = 0; pcic_trapped = 0;
#endif #endif
writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr); writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
#if 0 /* does not fail here */ #if 0 /* does not fail here */
nop(); nop();
if (pcic_trapped) { if (pcic_trapped) {
restore_flags(flags); local_irq_restore(flags);
*value = ~0; *value = ~0;
return PCIBIOS_SUCCESSFUL; return 0;
} }
#endif #endif
pcic_speculative = 2; pcic_speculative = 2;
...@@ -243,50 +222,77 @@ static int pcic_read_config(struct pci_bus *bus, unsigned int devfn, ...@@ -243,50 +222,77 @@ static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
nop(); nop();
if (pcic_trapped) { if (pcic_trapped) {
pcic_speculative = 0; pcic_speculative = 0;
restore_flags(flags); local_irq_restore(flags);
*value = ~0; *value = ~0;
return PCIBIOS_SUCCESSFUL; return 0;
} }
pcic_speculative = 0; pcic_speculative = 0;
restore_flags(flags); local_irq_restore(flags);
return PCIBIOS_SUCCESSFUL; return 0;
} }
static int pcic_write_config(struct pci_bus *bus, unsigned int devfn, static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value) int where, int size, u32 *val)
{ {
unsigned int v; unsigned int v;
unsigned char busnum = bus->number;
struct linux_pcic *pcic;
unsigned long flags;
if (bus->number != 0) return -EINVAL;
switch (size) { switch (size) {
case 1: case 1:
pcic_read_config(bus, devfn, where&~3, 4, &v); pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xff << (8*(where&3)))) | *val = 0xff & (v >> (8*(where & 3)));
((0xff&(unsigned)value) << (8*(where&3))); return 0;
return pcic_write_config(bus, devfn, where&~3, 4, v);
break;
case 2: case 2:
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER; if (where&1) return -EINVAL;
pcic_read_config(bus, devfn, where&~3, 4, &v); pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xffff << (8*(where&3)))) | *val = 0xffff & (v >> (8*(where & 3)));
((0xffff&(unsigned)value) << (8*(where&3))); return 0;
return pcic_write_config(bus, devfn, where&~3, 4, v); case 4:
break; if (where&3) return -EINVAL;
pcic_read_config_dword(bus->number, devfn, where&~3, val);
return 0;
} }
return -EINVAL;
}
static int pcic_write_config_dword(unsigned int busno, unsigned int devfn,
int where, u32 value)
{
struct linux_pcic *pcic;
unsigned long flags;
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0; pcic = &pcic0;
save_and_cli(flags); local_irq_save(flags);
writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr); writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
writel(value, pcic->pcic_config_space_data + (where&4)); writel(value, pcic->pcic_config_space_data + (where&4));
restore_flags(flags); local_irq_restore(flags);
return PCIBIOS_SUCCESSFUL; return 0;
}
static int pcic_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
unsigned int v;
if (bus->number != 0) return -EINVAL;
switch (size) {
case 1:
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xff << (8*(where&3)))) |
((0xff&val) << (8*(where&3)));
return pcic_write_config_dword(bus->number, devfn, where&~3, v);
case 2:
if (where&1) return -EINVAL;
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xffff << (8*(where&3)))) |
((0xffff&val) << (8*(where&3)));
return pcic_write_config_dword(bus->number, devfn, where&~3, v);
case 4:
if (where&3) return -EINVAL;
return pcic_write_config_dword(bus->number, devfn, where, val);
}
return -EINVAL;
} }
static struct pci_ops pcic_ops = { static struct pci_ops pcic_ops = {
...@@ -420,7 +426,7 @@ static void __init pcic_pbm_scan_bus(struct linux_pcic *pcic) ...@@ -420,7 +426,7 @@ static void __init pcic_pbm_scan_bus(struct linux_pcic *pcic)
/* /*
* Main entry point from the PCI subsystem. * Main entry point from the PCI subsystem.
*/ */
static int __init pcibios_init(void) static int __init pcic_init(void)
{ {
struct linux_pcic *pcic; struct linux_pcic *pcic;
...@@ -623,7 +629,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -623,7 +629,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
{ {
struct list_head *walk; struct list_head *walk;
int i, has_io, has_mem; int i, has_io, has_mem;
unsigned short cmd; unsigned int cmd;
struct linux_pcic *pcic; struct linux_pcic *pcic;
/* struct linux_pbm_info* pbm = &pcic->pbm; */ /* struct linux_pbm_info* pbm = &pcic->pbm; */
int node; int node;
...@@ -663,19 +669,21 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -663,19 +669,21 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
} else if (f & IORESOURCE_MEM) } else if (f & IORESOURCE_MEM)
has_mem = 1; has_mem = 1;
} }
pcic_read_config_word(dev, PCI_COMMAND, &cmd); pcic_read_config(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
if (has_io && !(cmd & PCI_COMMAND_IO)) { if (has_io && !(cmd & PCI_COMMAND_IO)) {
printk("PCIC: Enabling I/O for device %02x:%02x\n", printk("PCIC: Enabling I/O for device %02x:%02x\n",
dev->bus->number, dev->devfn); dev->bus->number, dev->devfn);
cmd |= PCI_COMMAND_IO; cmd |= PCI_COMMAND_IO;
pcic_write_config_word(dev, PCI_COMMAND, cmd); pcic_write_config(dev->bus, dev->devfn,
PCI_COMMAND, 2, cmd);
} }
if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) { if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
printk("PCIC: Enabling memory for device %02x:%02x\n", printk("PCIC: Enabling memory for device %02x:%02x\n",
dev->bus->number, dev->devfn); dev->bus->number, dev->devfn);
cmd |= PCI_COMMAND_MEMORY; cmd |= PCI_COMMAND_MEMORY;
pcic_write_config_word(dev, PCI_COMMAND, cmd); pcic_write_config(dev->bus, dev->devfn,
} PCI_COMMAND, 2, cmd);
}
node = pdev_to_pnode(&pcic->pbm, dev); node = pdev_to_pnode(&pcic->pbm, dev);
if(node == 0) if(node == 0)
...@@ -785,46 +793,54 @@ static __inline__ unsigned long do_gettimeoffset(void) ...@@ -785,46 +793,54 @@ static __inline__ unsigned long do_gettimeoffset(void)
return offset + count; return offset + count;
} }
extern volatile unsigned long wall_jiffies; extern unsigned long wall_jiffies;
extern rwlock_t xtime_lock;
static void pci_do_gettimeofday(struct timeval *tv) static void pci_do_gettimeofday(struct timeval *tv)
{ {
unsigned long flags; unsigned long flags;
unsigned long usec, sec;
save_and_cli(flags);
*tv = xtime;
tv->tv_usec += do_gettimeoffset();
/* read_lock_irqsave(&xtime_lock, flags);
* xtime is atomically updated in timer_bh. The difference usec = do_gettimeoffset();
* between jiffies and wall_jiffies is nonzero if the timer {
* bottom half hasnt executed yet. unsigned long lost = jiffies - wall_jiffies;
*/ if (lost)
if ((jiffies - wall_jiffies) != 0) usec += lost * (1000000 / HZ);
tv->tv_usec += USECS_PER_JIFFY; }
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
restore_flags(flags); while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
if (tv->tv_usec >= 1000000) { tv->tv_sec = sec;
tv->tv_usec -= 1000000; tv->tv_usec = usec;
tv->tv_sec++;
}
} }
static void pci_do_settimeofday(struct timeval *tv) static void pci_do_settimeofday(struct timeval *tv)
{ {
cli(); /*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) { tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000; tv->tv_usec += 1000000;
tv->tv_sec--; tv->tv_sec--;
} }
xtime = *tv; xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */ time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC; time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT; time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT;
sti();
} }
#if 0 #if 0
...@@ -853,7 +869,7 @@ void pcibios_align_resource(void *data, struct resource *res, ...@@ -853,7 +869,7 @@ void pcibios_align_resource(void *data, struct resource *res,
{ {
} }
int pcibios_enable_device(struct pci_dev *pdev) int pcibios_enable_device(struct pci_dev *pdev, int mask)
{ {
return 0; return 0;
} }
...@@ -898,9 +914,9 @@ static void pcic_disable_irq(unsigned int irq_nr) ...@@ -898,9 +914,9 @@ static void pcic_disable_irq(unsigned int irq_nr)
unsigned long mask, flags; unsigned long mask, flags;
mask = get_irqmask(irq_nr); mask = get_irqmask(irq_nr);
save_and_cli(flags); local_irq_save(flags);
writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET); writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
restore_flags(flags); local_irq_restore(flags);
} }
static void pcic_enable_irq(unsigned int irq_nr) static void pcic_enable_irq(unsigned int irq_nr)
...@@ -908,9 +924,9 @@ static void pcic_enable_irq(unsigned int irq_nr) ...@@ -908,9 +924,9 @@ static void pcic_enable_irq(unsigned int irq_nr)
unsigned long mask, flags; unsigned long mask, flags;
mask = get_irqmask(irq_nr); mask = get_irqmask(irq_nr);
save_and_cli(flags); local_irq_save(flags);
writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR); writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
restore_flags(flags); local_irq_restore(flags);
} }
static void pcic_clear_profile_irq(int cpu) static void pcic_clear_profile_irq(int cpu)
...@@ -1021,4 +1037,4 @@ void insl(unsigned long addr, void *dst, unsigned long count) { ...@@ -1021,4 +1037,4 @@ void insl(unsigned long addr, void *dst, unsigned long count) {
#endif #endif
subsys_initcall(pcibios_init); subsys_initcall(pcic_init);
...@@ -94,7 +94,7 @@ int cpu_idle(void) ...@@ -94,7 +94,7 @@ int cpu_idle(void)
extern unsigned long sun4c_kernel_faults; extern unsigned long sun4c_kernel_faults;
extern void sun4c_grow_kernel_ring(void); extern void sun4c_grow_kernel_ring(void);
save_and_cli(flags); local_irq_save(flags);
now = jiffies; now = jiffies;
count -= (now - last_jiffies); count -= (now - last_jiffies);
last_jiffies = now; last_jiffies = now;
...@@ -110,7 +110,7 @@ int cpu_idle(void) ...@@ -110,7 +110,7 @@ int cpu_idle(void)
sun4c_grow_kernel_ring(); sun4c_grow_kernel_ring();
} }
} }
restore_flags(flags); local_irq_restore(flags);
} }
while((!need_resched()) && pm_idle) { while((!need_resched()) && pm_idle) {
...@@ -144,8 +144,6 @@ int cpu_idle(void) ...@@ -144,8 +144,6 @@ int cpu_idle(void)
extern char reboot_command []; extern char reboot_command [];
extern int serial_console;
extern void (*prom_palette)(int); extern void (*prom_palette)(int);
void machine_halt(void) void machine_halt(void)
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/kgdb.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -67,8 +66,6 @@ struct screen_info screen_info = { ...@@ -67,8 +66,6 @@ struct screen_info screen_info = {
*/ */
extern unsigned long trapbase; extern unsigned long trapbase;
extern int serial_console;
extern void breakpoint(void);
void (*prom_palette)(int); void (*prom_palette)(int);
asmlinkage void sys_sync(void); /* it's really int */ asmlinkage void sys_sync(void); /* it's really int */
...@@ -105,28 +102,15 @@ void prom_sync_me(void) ...@@ -105,28 +102,15 @@ void prom_sync_me(void)
return; return;
} }
extern void rs_kgdb_hook(int tty_num); /* sparc/serial.c */
unsigned int boot_flags __initdata = 0; unsigned int boot_flags __initdata = 0;
#define BOOTME_DEBUG 0x1 #define BOOTME_DEBUG 0x1
#define BOOTME_SINGLE 0x2 #define BOOTME_SINGLE 0x2
#define BOOTME_KGDBA 0x4
#define BOOTME_KGDBB 0x8
#define BOOTME_KGDB 0xc
static int console_fb __initdata = 0; static int console_fb __initdata = 0;
/* Exported for mm/init.c:paging_init. */ /* Exported for mm/init.c:paging_init. */
unsigned long cmdline_memory_size __initdata = 0; unsigned long cmdline_memory_size __initdata = 0;
void kernel_enter_debugger(void)
{
if (boot_flags & BOOTME_KGDB) {
printk("KGDB: Entered\n");
breakpoint();
}
}
static void static void
prom_console_write(struct console *con, const char *s, unsigned n) prom_console_write(struct console *con, const char *s, unsigned n)
{ {
...@@ -142,11 +126,6 @@ static struct console prom_debug_console = { ...@@ -142,11 +126,6 @@ static struct console prom_debug_console = {
int obp_system_intr(void) int obp_system_intr(void)
{ {
if (boot_flags & BOOTME_KGDB) {
printk("KGDB: system interrupted\n");
breakpoint();
return 1;
}
if (boot_flags & BOOTME_DEBUG) { if (boot_flags & BOOTME_DEBUG) {
printk("OBP: system interrupted\n"); printk("OBP: system interrupted\n");
prom_halt(); prom_halt();
...@@ -196,24 +175,6 @@ static void __init boot_flags_init(char *commands) ...@@ -196,24 +175,6 @@ static void __init boot_flags_init(char *commands)
commands++; commands++;
while (*commands && *commands != ' ') while (*commands && *commands != ' ')
process_switch(*commands++); process_switch(*commands++);
} else if (strlen(commands) >= 9
&& !strncmp(commands, "kgdb=tty", 8)) {
switch (commands[8]) {
#ifdef CONFIG_SUN_SERIAL
case 'a':
boot_flags |= BOOTME_KGDBA;
prom_printf("KGDB: Using serial line /dev/ttya.\n");
break;
case 'b':
boot_flags |= BOOTME_KGDBB;
prom_printf("KGDB: Using serial line /dev/ttyb.\n");
break;
#endif
default:
printk("KGDB: Unknown tty line.\n");
break;
}
commands += 9;
} else { } else {
if (!strncmp(commands, "console=", 8)) { if (!strncmp(commands, "console=", 8)) {
commands += 8; commands += 8;
...@@ -378,65 +339,48 @@ void __init setup_arch(char **cmdline_p) ...@@ -378,65 +339,48 @@ void __init setup_arch(char **cmdline_p)
prom_setsync(prom_sync_me); prom_setsync(prom_sync_me);
{ #ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */
#if !CONFIG_SUN_SERIAL serial_console = 0;
serial_console = 0;
#else #else
switch (console_fb) { switch (console_fb) {
case 0: /* Let get our io devices from prom */ case 0: /* Let get our io devices from prom */
{ {
int idev = prom_query_input_device(); int idev = prom_query_input_device();
int odev = prom_query_output_device(); int odev = prom_query_output_device();
if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
serial_console = 0; serial_console = 0;
} else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
serial_console = 1; serial_console = 1;
} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
serial_console = 2; serial_console = 2;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) { } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
prom_printf("MrCoffee ttya\n"); prom_printf("MrCoffee ttya\n");
serial_console = 1; serial_console = 1;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) { } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
serial_console = 0; serial_console = 0;
prom_printf("MrCoffee keyboard\n"); prom_printf("MrCoffee keyboard\n");
} else { } else {
prom_printf("Inconsistent or unknown console\n"); prom_printf("Inconsistent or unknown console\n");
prom_printf("You cannot mix serial and non serial input/output devices\n"); prom_printf("You cannot mix serial and non serial input/output devices\n");
prom_halt(); prom_halt();
}
} }
break;
case 1: serial_console = 0; break; /* Force one of the framebuffers as console */
case 2: serial_console = 1; break; /* Force ttya as console */
case 3: serial_console = 2; break; /* Force ttyb as console */
} }
#endif break;
} case 1: serial_console = 0; break; /* Force one of the framebuffers as console */
case 2: serial_console = 1; break; /* Force ttya as console */
if ((boot_flags & BOOTME_KGDBA)) { case 3: serial_console = 2; break; /* Force ttyb as console */
rs_kgdb_hook(0);
}
if ((boot_flags & BOOTME_KGDBB)) {
rs_kgdb_hook(1);
} }
#endif
if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) && if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) &&
((*(short *)linux_dbvec) != -1)) { ((*(short *)linux_dbvec) != -1)) {
printk("Booted under KADB. Syncing trap table.\n"); printk("Booted under KADB. Syncing trap table.\n");
(*(linux_dbvec->teach_debugger))(); (*(linux_dbvec->teach_debugger))();
} }
if((boot_flags & BOOTME_KGDB)) {
set_debug_traps();
prom_printf ("Breakpoint!\n");
breakpoint();
}
init_mm.context = (unsigned long) NO_CONTEXT; init_mm.context = (unsigned long) NO_CONTEXT;
init_task.thread.kregs = &fake_swapper_regs; init_task.thread.kregs = &fake_swapper_regs;
if (serial_console)
conswitchp = NULL;
paging_init(); paging_init();
} }
...@@ -514,3 +458,19 @@ struct seq_operations cpuinfo_op = { ...@@ -514,3 +458,19 @@ struct seq_operations cpuinfo_op = {
.stop = c_stop, .stop = c_stop,
.show = show_cpuinfo, .show = show_cpuinfo,
}; };
extern int stop_a_enabled;
void sun_do_break(void)
{
if (!stop_a_enabled)
return;
printk("\n");
flush_user_windows();
prom_cmdline();
}
int serial_console;
int stop_a_enabled = 1;
...@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr); ...@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int restart_syscall); unsigned long orig_o0, int restart_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* Signal frames: the original one (compatible with SunOS): /* Signal frames: the original one (compatible with SunOS):
* *
* Set up a signal frame... Make the stack look the way SunOS * Set up a signal frame... Make the stack look the way SunOS
...@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old ...@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
synchronize_user_stack(); synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ); sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){ if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that /* Don't change signal code and address, so that
* post mortem debuggers can have a look. * post mortem debuggers can have a look.
*/ */
...@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size)) if (invalid_frame_pointer (sf, sigframe_size))
goto sigill_and_return; goto sigill_and_return;
if (current->thread.w_saved != 0) { if (current->thread.w_saved != 0)
#ifdef DEBUG_SIGNALS
printk ("%s [%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill_and_return; goto sigill_and_return;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs)); err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs));
...@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
synchronize_user_stack(); synchronize_user_stack();
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ); sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){ if (invalid_frame_pointer (sfp, sizeof (*sfp)))
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
goto sigill_and_return; goto sigill_and_return;
}
/* Start with a clean frame pointer and fill it */ /* Start with a clean frame pointer and fill it */
err = __clear_user(sfp, sizeof (*sfp)); err = __clear_user(sfp, sizeof (*sfp));
...@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->pc = (unsigned long) sa->sa_handler; regs->pc = (unsigned long) sa->sa_handler;
regs->npc = (regs->pc + 4); regs->npc = (regs->pc + 4);
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
#endif
/* Arguments passed to signal handler */ /* Arguments passed to signal handler */
if (regs->u_regs [14]){ if (regs->u_regs [14]){
struct reg_window *rw = (struct reg_window *) regs->u_regs [14]; struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
...@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -1152,7 +1074,6 @@ static inline void read_maps (void) ...@@ -1152,7 +1074,6 @@ static inline void read_maps (void)
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
struct k_sigaction *ka; struct k_sigaction *ka;
siginfo_t info; siginfo_t info;
...@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
oldset = &current->blocked; oldset = &current->blocked;
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
restart_syscall = 0; restart_syscall = 0;
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
/* This happens to be SMP safe so no need to /* This happens to be SMP safe so no need to
* grab master kernel lock even in this case. * grab master kernel lock even in this case.
...@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (is_orphaned_pgrp(current->pgrp)) if (is_orphaned_pgrp(current->pgrp))
continue; continue;
case SIGSTOP: case SIGSTOP: {
if (current->ptrace & PT_PTRACED) struct signal_struct *sig;
continue; set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig;
/* notify_parent() is SMP safe */ if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
if(!(current->parent->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
continue; continue;
}
case SIGQUIT: case SIGILL: case SIGTRAP: case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sigaddset(&current->pending.signal, signr); sig_exit(signr, exit_code, &info);
recalc_sigpending();
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOT REACHED */ /* NOT REACHED */
} }
} }
......
...@@ -188,22 +188,16 @@ static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest) ...@@ -188,22 +188,16 @@ static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
/* Initialize the kgdb_savettable so that debugging can commence */ /* Initialize the kgdb_savettable so that debugging can commence */
static void eh_init(void) static void eh_init(void)
{ {
int i, flags; int i;
save_and_cli(flags);
for(i=0; i < 256; i++) for(i=0; i < 256; i++)
copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]); copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
restore_flags(flags);
} }
/* Install an exception handler for kgdb */ /* Install an exception handler for kgdb */
static void exceptionHandler(int tnum, trapfunc_t trap_entry) static void exceptionHandler(int tnum, trapfunc_t trap_entry)
{ {
unsigned long te_addr = (unsigned long) trap_entry; unsigned long te_addr = (unsigned long) trap_entry;
int flags;
/* We are dorking with a live trap table, all irqs off */
save_and_cli(flags);
/* Make new vector */ /* Make new vector */
sparc_ttable[tnum].inst_one = sparc_ttable[tnum].inst_one =
...@@ -212,8 +206,6 @@ static void exceptionHandler(int tnum, trapfunc_t trap_entry) ...@@ -212,8 +206,6 @@ static void exceptionHandler(int tnum, trapfunc_t trap_entry)
sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0; sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
sparc_ttable[tnum].inst_three = SPARC_NOP; sparc_ttable[tnum].inst_three = SPARC_NOP;
sparc_ttable[tnum].inst_four = SPARC_NOP; sparc_ttable[tnum].inst_four = SPARC_NOP;
restore_flags(flags);
} }
/* Convert ch from a hex digit to an int */ /* Convert ch from a hex digit to an int */
...@@ -406,7 +398,7 @@ set_debug_traps(void) ...@@ -406,7 +398,7 @@ set_debug_traps(void)
struct hard_trap_info *ht; struct hard_trap_info *ht;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
#if 0 #if 0
/* Have to sort this out. This cannot be done after initialization. */ /* Have to sort this out. This cannot be done after initialization. */
BTFIXUPSET_CALL(flush_cache_all, flush_cache_all_nop, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(flush_cache_all, flush_cache_all_nop, BTFIXUPCALL_NOP);
...@@ -438,7 +430,7 @@ set_debug_traps(void) ...@@ -438,7 +430,7 @@ set_debug_traps(void)
#endif #endif
initialized = 1; /* connect! */ initialized = 1; /* connect! */
restore_flags(flags); local_irq_restore(flags);
} }
/* Convert the SPARC hardware trap type code to a unix signal number. */ /* Convert the SPARC hardware trap type code to a unix signal number. */
......
...@@ -55,7 +55,7 @@ sys_call_table: ...@@ -55,7 +55,7 @@ sys_call_table:
/*170*/ .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents /*170*/ .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
/*175*/ .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*175*/ .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
/*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
/*190*/ .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask /*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
......
...@@ -56,6 +56,9 @@ static void clk_slow(void) ...@@ -56,6 +56,9 @@ static void clk_slow(void)
"g2", "g3", "g4", "g5"); "g2", "g3", "g4", "g5");
} }
/*
* Tadpole is guaranteed to be UP, using local_irq_save.
*/
static void tsu_clockstop(void) static void tsu_clockstop(void)
{ {
unsigned int mcsr; unsigned int mcsr;
...@@ -64,28 +67,28 @@ static void tsu_clockstop(void) ...@@ -64,28 +67,28 @@ static void tsu_clockstop(void)
if (!clk_ctrl) if (!clk_ctrl)
return; return;
if (!(clk_state & CLOCK_INIT_DONE)) { if (!(clk_state & CLOCK_INIT_DONE)) {
save_and_cli(flags); local_irq_save(flags);
clk_init(); clk_init();
clk_state |= CLOCK_INIT_DONE; /* all done */ clk_state |= CLOCK_INIT_DONE; /* all done */
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
if (!(clk_ctrl[2] & 1)) if (!(clk_ctrl[2] & 1))
return; /* no speed up yet */ return; /* no speed up yet */
save_and_cli(flags); local_irq_save(flags);
/* if SCSI DMA in progress, don't slow clock */ /* if SCSI DMA in progress, don't slow clock */
mcsr = ldphys(MACIO_SCSI_CSR_ADDR); mcsr = ldphys(MACIO_SCSI_CSR_ADDR);
if ((mcsr&MACIO_EN_DMA) != 0) { if ((mcsr&MACIO_EN_DMA) != 0) {
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
/* TODO... the minimum clock setting ought to increase the /* TODO... the minimum clock setting ought to increase the
* memory refresh interval.. * memory refresh interval..
*/ */
clk_slow(); clk_slow();
restore_flags(flags); local_irq_restore(flags);
} }
static void swift_clockstop(void) static void swift_clockstop(void)
......
...@@ -29,32 +29,30 @@ extern unsigned long lvl14_save[5]; ...@@ -29,32 +29,30 @@ extern unsigned long lvl14_save[5];
static unsigned long *linux_lvl14 = NULL; static unsigned long *linux_lvl14 = NULL;
static unsigned long obp_lvl14[4]; static unsigned long obp_lvl14[4];
/*
* Call with timer IRQ closed.
* First time we do it with disable_irq, later prom code uses spin_lock_irq().
*/
void install_linux_ticker(void) void install_linux_ticker(void)
{ {
unsigned long flags;
if (!linux_lvl14) if (!linux_lvl14)
return; return;
save_and_cli(flags);
linux_lvl14[0] = lvl14_save[0]; linux_lvl14[0] = lvl14_save[0];
linux_lvl14[1] = lvl14_save[1]; linux_lvl14[1] = lvl14_save[1];
linux_lvl14[2] = lvl14_save[2]; linux_lvl14[2] = lvl14_save[2];
linux_lvl14[3] = lvl14_save[3]; linux_lvl14[3] = lvl14_save[3];
restore_flags(flags);
} }
void install_obp_ticker(void) void install_obp_ticker(void)
{ {
unsigned long flags;
if (!linux_lvl14) if (!linux_lvl14)
return; return;
save_and_cli(flags);
linux_lvl14[0] = obp_lvl14[0]; linux_lvl14[0] = obp_lvl14[0];
linux_lvl14[1] = obp_lvl14[1]; linux_lvl14[1] = obp_lvl14[1];
linux_lvl14[2] = obp_lvl14[2]; linux_lvl14[2] = obp_lvl14[2];
linux_lvl14[3] = obp_lvl14[3]; linux_lvl14[3] = obp_lvl14[3];
restore_flags(flags);
} }
void claim_ticker14(void (*handler)(int, void *, struct pt_regs *), void claim_ticker14(void (*handler)(int, void *, struct pt_regs *),
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
extern rwlock_t xtime_lock; extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
u64 jiffies_64; u64 jiffies_64;
enum sparc_clock_type sp_clock_typ; enum sparc_clock_type sp_clock_typ;
...@@ -114,6 +116,9 @@ __volatile__ unsigned int *master_l10_limit; ...@@ -114,6 +116,9 @@ __volatile__ unsigned int *master_l10_limit;
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
*/ */
#define TICK_SIZE (tick_nsec / 1000)
void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{ {
/* last time the cmos clock got updated */ /* last time the cmos clock got updated */
...@@ -142,8 +147,8 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) ...@@ -142,8 +147,8 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* Determine when to update the Mostek clock. */ /* Determine when to update the Mostek clock. */
if ((time_status & STA_UNSYNC) == 0 && if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 && xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0) if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec; last_rtc_update = xtime.tv_sec;
else else
...@@ -400,7 +405,7 @@ void __init sbus_time_init(void) ...@@ -400,7 +405,7 @@ void __init sbus_time_init(void)
mon = MSTK_REG_MONTH(mregs); mon = MSTK_REG_MONTH(mregs);
year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) ); year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0; xtime.tv_nsec = 0;
mregs->creg &= ~MSTK_CREG_READ; mregs->creg &= ~MSTK_CREG_READ;
spin_unlock_irq(&mostek_lock); spin_unlock_irq(&mostek_lock);
#ifdef CONFIG_SUN4 #ifdef CONFIG_SUN4
...@@ -431,7 +436,7 @@ void __init sbus_time_init(void) ...@@ -431,7 +436,7 @@ void __init sbus_time_init(void)
intersil_start(iregs); intersil_start(iregs);
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0; xtime.tv_nsec = 0;
printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec); printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
} }
#endif #endif
...@@ -467,48 +472,33 @@ extern __inline__ unsigned long do_gettimeoffset(void) ...@@ -467,48 +472,33 @@ extern __inline__ unsigned long do_gettimeoffset(void)
return offset + count; return offset + count;
} }
/* This need not obtain the xtime_lock as it is coded in /* Ok, my cute asm atomicity trick doesn't work anymore.
* an implicitly SMP safe way already. * There are just too many variables that need to be protected
* now (both members of xtime, wall_jiffies, et al.)
*/ */
void do_gettimeofday(struct timeval *tv) void do_gettimeofday(struct timeval *tv)
{ {
/* Load doubles must be used on xtime so that what we get unsigned long flags;
* is guarenteed to be atomic, this is why we can run this unsigned long usec, sec;
* with interrupts on full blast. Don't touch this... -DaveM
*/ read_lock_irqsave(&xtime_lock, flags);
__asm__ __volatile__( usec = do_gettimeoffset();
"sethi %hi(master_l10_counter), %o1\n\t" {
"ld [%o1 + %lo(master_l10_counter)], %g3\n\t" unsigned long lost = jiffies - wall_jiffies;
"sethi %hi(xtime), %g2\n" if (lost)
"1:\n\t" usec += lost * (1000000 / HZ);
"ldd [%g2 + %lo(xtime)], %o4\n\t" }
"ld [%g3], %o1\n\t" sec = xtime.tv_sec;
"ldd [%g2 + %lo(xtime)], %o2\n\t" usec += (xtime.tv_nsec / 1000);
"xor %o4, %o2, %o2\n\t" read_unlock_irqrestore(&xtime_lock, flags);
"xor %o5, %o3, %o3\n\t"
"orcc %o2, %o3, %g0\n\t" while (usec >= 1000000) {
"bne 1b\n\t" usec -= 1000000;
" cmp %o1, 0\n\t" sec++;
"bge 1f\n\t" }
" srl %o1, 0xa, %o1\n\t"
"sethi %hi(tick), %o3\n\t" tv->tv_sec = sec;
"ld [%o3 + %lo(tick)], %o3\n\t" tv->tv_usec = usec;
"sethi %hi(0x1fffff), %o2\n\t"
"or %o2, %lo(0x1fffff), %o2\n\t"
"add %o5, %o3, %o5\n\t"
"and %o1, %o2, %o1\n"
"1:\n\t"
"add %o5, %o1, %o5\n\t"
"sethi %hi(1000000), %o2\n\t"
"or %o2, %lo(1000000), %o2\n\t"
"cmp %o5, %o2\n\t"
"bl,a 1f\n\t"
" st %o4, [%o0 + 0x0]\n\t"
"add %o4, 0x1, %o4\n\t"
"sub %o5, %o2, %o5\n\t"
"st %o4, [%o0 + 0x0]\n"
"1:\n\t"
"st %o5, [%o0 + 0x4]\n");
} }
void do_settimeofday(struct timeval *tv) void do_settimeofday(struct timeval *tv)
...@@ -520,12 +510,20 @@ void do_settimeofday(struct timeval *tv) ...@@ -520,12 +510,20 @@ void do_settimeofday(struct timeval *tv)
static void sbus_do_settimeofday(struct timeval *tv) static void sbus_do_settimeofday(struct timeval *tv)
{ {
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) { tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000; tv->tv_usec += 1000000;
tv->tv_sec--; tv->tv_sec--;
} }
xtime = *tv; xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */ time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC; time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT; time_maxerror = NTP_PHASE_LIMIT;
......
...@@ -506,9 +506,18 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) ...@@ -506,9 +506,18 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
break; break;
case both: case both:
#if 0 /* unsupported */
do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
(unsigned long *) addr, (unsigned long *) addr,
user_unaligned_trap_fault); user_unaligned_trap_fault);
#else
/*
* This was supported in 2.4. However, we question
* the value of SWAP instruction across word boundaries.
*/
printk("Unaligned SWAP unsupported.\n");
goto kill_user;
#endif
break; break;
default: default:
......
...@@ -1212,7 +1212,6 @@ extern int linux_num_cpus; ...@@ -1212,7 +1212,6 @@ extern int linux_num_cpus;
void (*poke_srmmu)(void) __initdata = NULL; void (*poke_srmmu)(void) __initdata = NULL;
extern unsigned long bootmem_init(unsigned long *pages_avail); extern unsigned long bootmem_init(unsigned long *pages_avail);
extern void sun_serial_setup(void);
void __init srmmu_paging_init(void) void __init srmmu_paging_init(void)
{ {
...@@ -1281,13 +1280,6 @@ void __init srmmu_paging_init(void) ...@@ -1281,13 +1280,6 @@ void __init srmmu_paging_init(void)
flush_cache_all(); flush_cache_all();
flush_tlb_all(); flush_tlb_all();
/*
* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
sparc_context_init(num_contexts); sparc_context_init(num_contexts);
kmap_init(); kmap_init();
......
...@@ -2001,7 +2001,6 @@ extern void sparc_context_init(int); ...@@ -2001,7 +2001,6 @@ extern void sparc_context_init(int);
extern unsigned long end; extern unsigned long end;
extern unsigned long bootmem_init(unsigned long *pages_avail); extern unsigned long bootmem_init(unsigned long *pages_avail);
extern unsigned long last_valid_pfn; extern unsigned long last_valid_pfn;
extern void sun_serial_setup(void);
void __init sun4c_paging_init(void) void __init sun4c_paging_init(void)
{ {
...@@ -2018,12 +2017,6 @@ void __init sun4c_paging_init(void) ...@@ -2018,12 +2017,6 @@ void __init sun4c_paging_init(void)
last_valid_pfn = bootmem_init(&pages_avail); last_valid_pfn = bootmem_init(&pages_avail);
end_pfn = last_valid_pfn; end_pfn = last_valid_pfn;
/* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
sun4c_probe_mmu(); sun4c_probe_mmu();
invalid_segment = (num_segmaps - 1); invalid_segment = (num_segmaps - 1);
sun4c_init_mmu_entry_pool(); sun4c_init_mmu_entry_pool();
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <asm/openprom.h> #include <asm/openprom.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/auxio.h> #include <asm/auxio.h>
#include <asm/system.h>
extern void restore_current(void); extern void restore_current(void);
...@@ -47,7 +48,6 @@ prom_feval(char *fstring) ...@@ -47,7 +48,6 @@ prom_feval(char *fstring)
/* We want to do this more nicely some day. */ /* We want to do this more nicely some day. */
extern void (*prom_palette)(int); extern void (*prom_palette)(int);
extern int serial_console;
/* Drop into the prom, with the chance to continue with the 'go' /* Drop into the prom, with the chance to continue with the 'go'
* prom command. * prom command.
...@@ -55,20 +55,18 @@ extern int serial_console; ...@@ -55,20 +55,18 @@ extern int serial_console;
void void
prom_cmdline(void) prom_cmdline(void)
{ {
extern void kernel_enter_debugger(void);
extern void install_obp_ticker(void); extern void install_obp_ticker(void);
extern void install_linux_ticker(void); extern void install_linux_ticker(void);
unsigned long flags; unsigned long flags;
kernel_enter_debugger();
if(!serial_console && prom_palette) if(!serial_console && prom_palette)
prom_palette (1); prom_palette (1);
install_obp_ticker();
spin_lock_irqsave(&prom_lock, flags); spin_lock_irqsave(&prom_lock, flags);
install_obp_ticker();
(*(romvec->pv_abort))(); (*(romvec->pv_abort))();
restore_current(); restore_current();
spin_unlock_irqrestore(&prom_lock, flags);
install_linux_ticker(); install_linux_ticker();
spin_unlock_irqrestore(&prom_lock, flags);
#ifdef CONFIG_SUN_AUXIO #ifdef CONFIG_SUN_AUXIO
TURN_ON_LED; TURN_ON_LED;
#endif #endif
......
...@@ -204,6 +204,8 @@ CONFIG_BLK_DEV_IDE=y ...@@ -204,6 +204,8 @@ CONFIG_BLK_DEV_IDE=y
# #
# Please see Documentation/ide.txt for help/info on IDE drives # Please see Documentation/ide.txt for help/info on IDE drives
# #
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_IDEDISK_STROKE is not set # CONFIG_IDEDISK_STROKE is not set
...@@ -218,7 +220,7 @@ CONFIG_BLK_DEV_IDEDISK=y ...@@ -218,7 +220,7 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDECD_BAILOUT is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASK_IOCTL is not set
...@@ -229,8 +231,8 @@ CONFIG_BLK_DEV_IDECD=y ...@@ -229,8 +231,8 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_OFFBOARD is not set
...@@ -239,29 +241,29 @@ CONFIG_IDEDMA_PCI_AUTO=y ...@@ -239,29 +241,29 @@ CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_IDEDMA_ONLYDISK=y CONFIG_IDEDMA_ONLYDISK=y
CONFIG_BLK_DEV_IDEDMA=y CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_AEC62XX_TUNING is not set
CONFIG_BLK_DEV_ALI15X3=y CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_AMD74XX_OVERRIDE is not set
CONFIG_BLK_DEV_CMD64X=y CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_CMD680 is not set
# CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set # CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_NFORCE is not set
CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_ADMA100 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set # CONFIG_PDC202XX_BURST is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_PDC202XX_FORCE is not set # CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_RZ1000 is not set # CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set # CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_TRM290 is not set
...@@ -954,7 +956,7 @@ CONFIG_USB_AUERSWALD=m ...@@ -954,7 +956,7 @@ CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m CONFIG_USB_RIO500=m
# CONFIG_USB_BRLVGER is not set # CONFIG_USB_BRLVGER is not set
CONFIG_USB_LCD=m CONFIG_USB_LCD=m
CONFIG_USB_SPEEDTOUCH=m # CONFIG_USB_SPEEDTOUCH is not set
# #
# Bluetooth support # Bluetooth support
......
...@@ -1795,69 +1795,3 @@ __flushw_user: ...@@ -1795,69 +1795,3 @@ __flushw_user:
restore %g0, %g0, %g0 restore %g0, %g0, %g0
2: retl 2: retl
nop nop
/* This need not obtain the xtime_lock as it is coded in
* an implicitly SMP safe way already.
*/
.align 64
.globl do_gettimeofday
do_gettimeofday: /* %o0 = timevalp */
/* Load doubles must be used on xtime so that what we get
* is guarenteed to be atomic, this is why we can run this
* with interrupts on full blast. Don't touch this... -DaveM
*
* Note with time_t changes to the timeval type, I must now use
* nucleus atomic quad 128-bit loads.
*
* If xtime was stored recently, I've seen crap from the
* quad load on Cheetah. Putting a membar SYNC before
* the quad load seems to make the problem go away. -DaveM
* (we should nop out workarounds like this on spitfire)
*/
sethi %hi(timer_tick_offset), %g3
sethi %hi(xtime), %g2
sethi %hi(timer_tick_compare), %g1
ldx [%g3 + %lo(timer_tick_offset)], %g3
or %g2, %lo(xtime), %g2
or %g1, %lo(timer_tick_compare), %g1
1: membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4
BRANCH_IF_ANY_CHEETAH(o2,o1,2f)
ba,pt %xcc, 3f
rd %tick, %o1
2: ba,pt %xcc, 3f
rd %asr24, %o1
3: ldx [%g1], %g7
membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2
xor %o4, %o2, %o2
xor %o5, %o3, %o3
orcc %o2, %o3, %g0
bne,pn %xcc, 1b
sethi %hi(wall_jiffies), %o2
sethi %hi(jiffies), %o3
ldx [%o2 + %lo(wall_jiffies)], %o2
ldx [%o3 + %lo(jiffies)], %o3
sub %o3, %o2, %o2
sethi %hi(timer_ticks_per_usec_quotient), %o3
add %g3, %o1, %o1
ldx [%o3 + %lo(timer_ticks_per_usec_quotient)], %o3
sub %o1, %g7, %o1
mulx %o3, %o1, %o1
brz,pt %o2, 1f
srlx %o1, 32, %o1
sethi %hi(10000), %g2
or %g2, %lo(10000), %g2
add %o1, %g2, %o1
1: sethi %hi(1000000), %o2
srlx %o5, 32, %o5
or %o2, %lo(1000000), %o2
add %o5, %o1, %o5
cmp %o5, %o2
bl,a,pn %xcc, 1f
stx %o4, [%o0 + 0x0]
add %o4, 0x1, %o4
sub %o5, %o2, %o5
stx %o4, [%o0 + 0x0]
1: retl
st %o5, [%o0 + 0x8]
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
static struct fs_struct init_fs = INIT_FS; static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES; static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS; static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm); struct mm_struct init_mm = INIT_MM(init_mm);
/* .text section in head.S is aligned at 2 page boundry and this gets linked /* .text section in head.S is aligned at 2 page boundry and this gets linked
......
...@@ -365,7 +365,7 @@ void pcibios_align_resource(void *data, struct resource *res, ...@@ -365,7 +365,7 @@ void pcibios_align_resource(void *data, struct resource *res,
{ {
} }
int pcibios_enable_device(struct pci_dev *pdev) int pcibios_enable_device(struct pci_dev *pdev, int mask)
{ {
return 0; return 0;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/system.h>
#include <asm/ebus.h> #include <asm/ebus.h>
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
...@@ -37,8 +38,6 @@ extern void machine_halt(void); ...@@ -37,8 +38,6 @@ extern void machine_halt(void);
extern void machine_alt_power_off(void); extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off; static void (*poweroff_method)(void) = machine_alt_power_off;
extern int serial_console;
void machine_power_off(void) void machine_power_off(void)
{ {
if (!serial_console) { if (!serial_console) {
......
...@@ -110,7 +110,6 @@ int cpu_idle(void) ...@@ -110,7 +110,6 @@ int cpu_idle(void)
extern char reboot_command []; extern char reboot_command [];
extern void (*prom_palette)(int); extern void (*prom_palette)(int);
extern int serial_console;
extern void (*prom_keyboard)(void); extern void (*prom_keyboard)(void);
void machine_halt(void) void machine_halt(void)
......
...@@ -314,12 +314,9 @@ int prom_callback(long *args) ...@@ -314,12 +314,9 @@ int prom_callback(long *args)
return 0; return 0;
} }
extern void rs_kgdb_hook(int tty_num); /* sparc/serial.c */
unsigned int boot_flags = 0; unsigned int boot_flags = 0;
#define BOOTME_DEBUG 0x1 #define BOOTME_DEBUG 0x1
#define BOOTME_SINGLE 0x2 #define BOOTME_SINGLE 0x2
#define BOOTME_KGDB 0x4
static int console_fb __initdata = 0; static int console_fb __initdata = 0;
...@@ -389,26 +386,6 @@ static void __init boot_flags_init(char *commands) ...@@ -389,26 +386,6 @@ static void __init boot_flags_init(char *commands)
commands++; commands++;
while (*commands && *commands != ' ') while (*commands && *commands != ' ')
process_switch(*commands++); process_switch(*commands++);
} else if (strlen(commands) >= 9
&& !strncmp(commands, "kgdb=tty", 8)) {
boot_flags |= BOOTME_KGDB;
switch (commands[8]) {
#ifdef CONFIG_SUN_SERIAL
case 'a':
rs_kgdb_hook(0);
prom_printf("KGDB: Using serial line /dev/ttya.\n");
break;
case 'b':
rs_kgdb_hook(1);
prom_printf("KGDB: Using serial line /dev/ttyb.\n");
break;
#endif
default:
printk("KGDB: Unknown tty line.\n");
boot_flags &= ~BOOTME_KGDB;
break;
}
commands += 9;
} else { } else {
if (!strncmp(commands, "console=", 8)) { if (!strncmp(commands, "console=", 8)) {
commands += 8; commands += 8;
...@@ -484,7 +461,6 @@ extern void paging_init(void); ...@@ -484,7 +461,6 @@ extern void paging_init(void);
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
extern int serial_console; /* in console.c, of course */
unsigned long highest_paddr; unsigned long highest_paddr;
int i; int i;
...@@ -568,7 +544,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -568,7 +544,6 @@ void __init setup_arch(char **cmdline_p)
} }
#endif #endif
#ifdef CONFIG_SUN_SERIAL
switch (console_fb) { switch (console_fb) {
case 0: /* Let's get our io devices from prom */ case 0: /* Let's get our io devices from prom */
{ {
...@@ -597,10 +572,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -597,10 +572,7 @@ void __init setup_arch(char **cmdline_p)
case 3: /* Force ttyb as console */ case 3: /* Force ttyb as console */
serial_console = 2; serial_console = 2;
break; break;
} };
#else
serial_console = 0;
#endif
if (serial_console) if (serial_console)
conswitchp = NULL; conswitchp = NULL;
......
...@@ -36,11 +36,6 @@ ...@@ -36,11 +36,6 @@
static int do_signal(sigset_t *oldset, struct pt_regs * regs, static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int ret_from_syscall); unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{ {
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
...@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, ...@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size)) if (invalid_frame_pointer (sf, sigframe_size))
goto sigill; goto sigill;
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
err = copy_to_user(&sf->regs, regs, sizeof (*regs)); err = copy_to_user(&sf->regs, regs, sizeof (*regs));
...@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, ...@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -694,7 +628,6 @@ static inline void read_maps (void) ...@@ -694,7 +628,6 @@ static inline void read_maps (void)
static int do_signal(sigset_t *oldset, struct pt_regs * regs, static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
siginfo_t info; siginfo_t info;
struct k_sigaction *ka; struct k_sigaction *ka;
...@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
} }
#endif #endif
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
...@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
...@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug the dynamic linker */
printk ("Sig %d going...\n", (int)signr);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
unsigned long ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sig_exit(signr, exit_code, &info); sig_exit(signr, exit_code, &info);
/* NOT REACHED */ /* NOT REACHED */
......
...@@ -34,12 +34,6 @@ ...@@ -34,12 +34,6 @@
int do_signal32(sigset_t *oldset, struct pt_regs *regs, int do_signal32(sigset_t *oldset, struct pt_regs *regs,
unsigned long orig_o0, int ret_from_syscall); unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* #define DEBUG_SIGNALS_TLB 1 */
/* Signal frames: the original one (compatible with SunOS): /* Signal frames: the original one (compatible with SunOS):
* *
* Set up a signal frame... Make the stack look the way SunOS * Set up a signal frame... Make the stack look the way SunOS
...@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o ...@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ); sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){ if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%016lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that /* Don't change signal code and address, so that
* post mortem debuggers can have a look. * post mortem debuggers can have a look.
*/ */
...@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg ...@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) { if (invalid_frame_pointer (sf, sigframe_size))
#ifdef DEBUG_SIGNALS
printk("new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
goto sigill; goto sigill;
}
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { if (test_thread_flag(TIF_32BIT)) {
...@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED); sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){ if (invalid_frame_pointer (sfp, sizeof (*sfp)))
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
do_exit(SIGILL); do_exit(SIGILL);
}
/* Start with a clean frame pointer and fill it */ /* Start with a clean frame pointer and fill it */
err = clear_user(sfp, sizeof (*sfp)); err = clear_user(sfp, sizeof (*sfp));
...@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, ...@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->tnpc &= 0xffffffff; regs->tnpc &= 0xffffffff;
} }
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc);
#endif
/* Arguments passed to signal handler */ /* Arguments passed to signal handler */
if (regs->u_regs [14]){ if (regs->u_regs [14]){
struct reg_window32 *rw = (struct reg_window32 *) struct reg_window32 *rw = (struct reg_window32 *)
...@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) ...@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
synchronize_user_stack(); synchronize_user_stack();
save_and_clear_fpu(); save_and_clear_fpu();
if (get_thread_wsaved()) { if (get_thread_wsaved())
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is not zero (%d)\n", (int) get_thread_wsaved());
#endif
do_exit (SIGSEGV); do_exit (SIGSEGV);
}
err = clear_user(uc, sizeof (*uc)); err = clear_user(uc, sizeof (*uc));
/* Setup convenience variables */ /* Setup convenience variables */
...@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) ...@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
*/ */
flush_user_windows(); flush_user_windows();
if (get_thread_wsaved()) { if (get_thread_wsaved())
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is: 0x%x\n", get_thread_wsaved());
#endif
goto sigsegv; goto sigsegv;
}
if (((unsigned long) c) & 3){ if (((unsigned long) c) & 3){
printk ("Unaligned structure passed\n"); printk ("Unaligned structure passed\n");
goto sigsegv; goto sigsegv;
...@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) ...@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
gr = &c->mcontext.greg; gr = &c->mcontext.greg;
err = __get_user(pc, &((*gr)[SVR4_PC])); err = __get_user(pc, &((*gr)[SVR4_PC]));
err |= __get_user(npc, &((*gr)[SVR4_NPC])); err |= __get_user(npc, &((*gr)[SVR4_NPC]));
if ((pc | npc) & 3) { if ((pc | npc) & 3)
#ifdef DEBUG_SIGNALS
printk ("setcontext, PC or nPC were bogus\n");
#endif
goto sigsegv; goto sigsegv;
}
/* Retrieve information from passed ucontext */ /* Retrieve information from passed ucontext */
/* note that nPC is ored a 1, this is used to inform entry.S */ /* note that nPC is ored a 1, this is used to inform entry.S */
...@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs ...@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) { if (invalid_frame_pointer (sf, sigframe_size))
#ifdef DEBUG_SIGNALS
printk("rt_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
goto sigill; goto sigill;
}
if (get_thread_wsaved() != 0) { if (get_thread_wsaved() != 0)
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
goto sigill; goto sigill;
}
/* 2. Save the current process state */ /* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) { if (test_thread_flag(TIF_32BIT)) {
...@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs ...@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
} }
} }
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't /* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by * want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake. * mistake.
...@@ -1380,16 +1275,27 @@ static inline void read_maps (void) ...@@ -1380,16 +1275,27 @@ static inline void read_maps (void)
int do_signal32(sigset_t *oldset, struct pt_regs * regs, int do_signal32(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall) unsigned long orig_i0, int restart_syscall)
{ {
unsigned long signr;
struct k_sigaction *ka; struct k_sigaction *ka;
siginfo_t info; siginfo_t info;
int svr4_signal = current->personality == PER_SVR4; int svr4_signal = current->personality == PER_SVR4;
for (;;) { for (;;) {
spin_lock_irq(&current->sigmask_lock); sigset_t *mask = &current->blocked;
signr = dequeue_signal(&current->blocked, &info); unsigned long signr = 0;
spin_unlock_irq(&current->sigmask_lock);
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr) if (!signr)
break; break;
...@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
} }
current->exit_code = signr; current->exit_code = signr;
current->state = TASK_STOPPED; set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
if (!(signr = current->exit_code)) if (!(signr = current->exit_code))
...@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: { case SIGSTOP: {
struct signal_struct *sig; struct signal_struct *sig;
set_current_state(TASK_STOPPED);
current->state = TASK_STOPPED;
current->exit_code = signr; current->exit_code = signr;
sig = current->parent->sig; sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
...@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, regs))
exit_code |= 0x80; exit_code |= 0x80;
#ifdef DEBUG_SIGNALS /* FALLTHRU */
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
/* On SMP we are only interested in the current
* CPU's registers.
*/
__show_regs (regs);
#ifdef DEBUG_SIGNALS_TLB
do {
extern void sparc_ultra_dump_itlb(void);
extern void sparc_ultra_dump_dtlb(void);
sparc_ultra_dump_dtlb();
sparc_ultra_dump_itlb();
} while (0);
#endif
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window32 *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
default: default:
sig_exit(signr, exit_code, &info); sig_exit(signr, exit_code, &info);
/* NOT REACHED */ /* NOT REACHED */
......
...@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, ...@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
return -EINVAL; return -EINVAL;
} }
spin_lock_irq(&current->sigmask_lock); spin_lock_irq(&current->sig->siglock);
sig = dequeue_signal(&these, &info); spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
if (!sig) { if (!sig) {
/* None ready -- temporarily unblock those we're interested
in so that we'll be awakened when they arrive. */
sigset_t oldblocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
timeout = MAX_SCHEDULE_TIMEOUT; timeout = MAX_SCHEDULE_TIMEOUT;
if (uts) if (uts)
timeout = (timespec_to_jiffies(&ts) timeout = (timespec_to_jiffies(&ts)
+ (ts.tv_sec || ts.tv_nsec)); + (ts.tv_sec || ts.tv_nsec));
current->state = TASK_INTERRUPTIBLE; if (timeout) {
timeout = schedule_timeout(timeout); /* None ready -- temporarily unblock those we're
* interested while we are sleeping in so that we'll
spin_lock_irq(&current->sigmask_lock); * be awakened when they arrive. */
sig = dequeue_signal(&these, &info); current->real_blocked = current->blocked;
current->blocked = oldblocked; sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending(); recalc_sigpending();
spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
spin_lock_irq(&current->sig->siglock);
spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
current->blocked = current->real_blocked;
siginitset(&current->real_blocked, 0);
recalc_sigpending();
}
} }
spin_unlock_irq(&current->sigmask_lock); spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
if (sig) { if (sig) {
ret = sig; ret = sig;
......
...@@ -56,7 +56,7 @@ sys_call_table32: ...@@ -56,7 +56,7 @@ sys_call_table32:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir /*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
...@@ -115,7 +115,7 @@ sys_call_table: ...@@ -115,7 +115,7 @@ sys_call_table:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
......
...@@ -44,6 +44,8 @@ unsigned long mstk48t02_regs = 0UL; ...@@ -44,6 +44,8 @@ unsigned long mstk48t02_regs = 0UL;
unsigned long ds1287_regs = 0UL; unsigned long ds1287_regs = 0UL;
#endif #endif
extern unsigned long wall_jiffies;
u64 jiffies_64; u64 jiffies_64;
static unsigned long mstk48t08_regs = 0UL; static unsigned long mstk48t08_regs = 0UL;
...@@ -61,6 +63,8 @@ unsigned long timer_tick_offset; ...@@ -61,6 +63,8 @@ unsigned long timer_tick_offset;
unsigned long timer_tick_compare; unsigned long timer_tick_compare;
unsigned long timer_ticks_per_usec_quotient; unsigned long timer_ticks_per_usec_quotient;
#define TICK_SIZE (tick_nsec / 1000)
static __inline__ void timer_check_rtc(void) static __inline__ void timer_check_rtc(void)
{ {
/* last time the cmos clock got updated */ /* last time the cmos clock got updated */
...@@ -69,8 +73,8 @@ static __inline__ void timer_check_rtc(void) ...@@ -69,8 +73,8 @@ static __inline__ void timer_check_rtc(void)
/* Determine when to update the Mostek clock. */ /* Determine when to update the Mostek clock. */
if ((time_status & STA_UNSYNC) == 0 && if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 && xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0) if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec; last_rtc_update = xtime.tv_sec;
else else
...@@ -390,7 +394,7 @@ static void __init set_system_time(void) ...@@ -390,7 +394,7 @@ static void __init set_system_time(void)
} }
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0; xtime.tv_nsec = 0;
if (mregs) { if (mregs) {
tmp = mostek_read(mregs + MOSTEK_CREG); tmp = mostek_read(mregs + MOSTEK_CREG);
...@@ -428,7 +432,7 @@ void __init clock_probe(void) ...@@ -428,7 +432,7 @@ void __init clock_probe(void)
(unsigned int) (long) &unix_tod); (unsigned int) (long) &unix_tod);
prom_feval(obp_gettod); prom_feval(obp_gettod);
xtime.tv_sec = unix_tod; xtime.tv_sec = unix_tod;
xtime.tv_usec = 0; xtime.tv_nsec = 0;
return; return;
} }
...@@ -658,22 +662,58 @@ void do_settimeofday(struct timeval *tv) ...@@ -658,22 +662,58 @@ void do_settimeofday(struct timeval *tv)
return; return;
write_lock_irq(&xtime_lock); write_lock_irq(&xtime_lock);
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) { tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000; tv->tv_usec += 1000000;
tv->tv_sec--; tv->tv_sec--;
} }
xtime = *tv; xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */ time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC; time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT; time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT;
write_unlock_irq(&xtime_lock); write_unlock_irq(&xtime_lock);
} }
/* Ok, my cute asm atomicity trick doesn't work anymore.
* There are just too many variables that need to be protected
* now (both members of xtime, wall_jiffies, et al.)
*/
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
static int set_rtc_mmss(unsigned long nowtime) static int set_rtc_mmss(unsigned long nowtime)
{ {
int real_seconds, real_minutes, chip_minutes; int real_seconds, real_minutes, chip_minutes;
......
...@@ -1515,14 +1515,6 @@ void __init paging_init(void) ...@@ -1515,14 +1515,6 @@ void __init paging_init(void)
pages_avail = 0; pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail); last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
#ifdef CONFIG_SUN_SERIAL
/* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
#endif
/* Inherit non-locked OBP mappings. */ /* Inherit non-locked OBP mappings. */
inherit_prom_mappings(); inherit_prom_mappings();
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/openprom.h> #include <asm/openprom.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/system.h>
/* Reset and reboot the machine with the command 'bcommand'. */ /* Reset and reboot the machine with the command 'bcommand'. */
void prom_reboot(char *bcommand) void prom_reboot(char *bcommand)
...@@ -33,7 +34,6 @@ void prom_feval(char *fstring) ...@@ -33,7 +34,6 @@ void prom_feval(char *fstring)
/* We want to do this more nicely some day. */ /* We want to do this more nicely some day. */
extern void (*prom_palette)(int); extern void (*prom_palette)(int);
extern int serial_console;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
extern void smp_capture(void); extern void smp_capture(void);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/serio.h> #include <linux/serio.h>
#endif #endif
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -1019,6 +1020,8 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1019,6 +1020,8 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (!up->port_node || !up->su_type) if (!up->port_node || !up->su_type)
return; return;
up->port.iotype = SERIAL_IO_MEM;
/* /*
* First we look for Ebus-bases su's * First we look for Ebus-bases su's
*/ */
......
...@@ -382,13 +382,6 @@ static void sunzilog_receive_chars(struct uart_sunzilog_port *up, ...@@ -382,13 +382,6 @@ static void sunzilog_receive_chars(struct uart_sunzilog_port *up,
sun_do_break(); sun_do_break();
return; return;
} }
#ifndef CONFIG_SPARC64
/* Look for kgdb 'stop' character. */
if (ZS_IS_KGDB(up) && (ch == '\003')) {
breakpoint();
return;
}
#endif
/* A real serial line, record the character and status. */ /* A real serial line, record the character and status. */
*tty->flip.char_buf_ptr = ch; *tty->flip.char_buf_ptr = ch;
...@@ -1152,11 +1145,11 @@ static struct zilog_layout * __init get_zs_sun4u(int chip) ...@@ -1152,11 +1145,11 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
static struct zilog_layout * __init get_zs_sun4cmd(int chip) static struct zilog_layout * __init get_zs_sun4cmd(int chip)
{ {
struct linux_prom_irqs irq_info[2]; struct linux_prom_irqs irq_info[2];
unsigned long mapped_addr; unsigned long mapped_addr = 0;
int zsnode, chipid, cpunode; int zsnode, chipid, cpunode, bbnode;
if (sparc_cpu_model == sun4d) { if (sparc_cpu_model == sun4d) {
int bbnode, walk, no; int walk, no;
zsnode = 0; zsnode = 0;
bbnode = 0; bbnode = 0;
...@@ -1249,7 +1242,7 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip) ...@@ -1249,7 +1242,7 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip)
} else if (zilog_irq != irq_info[0].pri) { } else if (zilog_irq != irq_info[0].pri) {
prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n", prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
chip); chip);
promt_halt(); prom_halt();
} }
break; break;
} }
...@@ -1290,7 +1283,7 @@ static struct zilog_layout * __init get_zs(int chip) ...@@ -1290,7 +1283,7 @@ static struct zilog_layout * __init get_zs(int chip)
zilog_irq = 12; zilog_irq = 12;
res.end = (res.start + (8 - 1)); res.end = (res.start + (8 - 1));
res.flags = IORESOURCE_IO; res.flags = IORESOURCE_IO;
return sbus_ioremap(&res, 0, 8, "SunZilog"); return (struct zilog_layout *) sbus_ioremap(&res, 0, 8, "SunZilog");
} }
return get_zs_sun4cmd(chip); return get_zs_sun4cmd(chip);
...@@ -1649,13 +1642,10 @@ static int __init sunzilog_init(void) ...@@ -1649,13 +1642,10 @@ static int __init sunzilog_init(void)
/* Sun4 Zilog setup is hard coded, no probing to do. */ /* Sun4 Zilog setup is hard coded, no probing to do. */
if (sparc_cpu_model == sun4) { if (sparc_cpu_model == sun4) {
NUM_SUNZILOG = 2; NUM_SUNZILOG = 2;
goto no_probe; } else if (sparc_cpu_model == sun4d) {
}
node = prom_getchild(prom_root_node);
if (sparc_cpu_model == sun4d) {
int bbnode; int bbnode;
node = prom_getchild(prom_root_node);
NUM_SUNZILOG = 0; NUM_SUNZILOG = 0;
while (node && while (node &&
(node = prom_searchsiblings(node, "cpu-unit"))) { (node = prom_searchsiblings(node, "cpu-unit"))) {
...@@ -1664,7 +1654,6 @@ static int __init sunzilog_init(void) ...@@ -1664,7 +1654,6 @@ static int __init sunzilog_init(void)
NUM_SUNZILOG += 2; NUM_SUNZILOG += 2;
node = prom_getsibling(node); node = prom_getsibling(node);
} }
goto no_probe;
} else if (sparc_cpu_model == sun4u) { } else if (sparc_cpu_model == sun4u) {
int central_node; int central_node;
...@@ -1675,27 +1664,28 @@ static int __init sunzilog_init(void) ...@@ -1675,27 +1664,28 @@ static int __init sunzilog_init(void)
if (central_node != 0 && central_node != -1) if (central_node != 0 && central_node != -1)
node = prom_searchsiblings(prom_getchild(central_node), "fhc"); node = prom_searchsiblings(prom_getchild(central_node), "fhc");
else else
node = prom_searchsiblings(node, "sbus"); node = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
if (node != 0 && node != -1) if (node != 0 && node != -1)
node = prom_getchild(node); node = prom_getchild(node);
if (node == 0 || node == -1) if (node == 0 || node == -1)
return -ENODEV; return -ENODEV;
node = prom_searchsiblings(node, "zs");
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
} else { } else {
node = prom_getchild(prom_root_node);
node = prom_searchsiblings(node, "obio"); node = prom_searchsiblings(node, "obio");
if (node) if (node)
node = prom_getchild(node); node = prom_getchild(node);
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2; NUM_SUNZILOG = 2;
goto no_probe;
} }
node = prom_searchsiblings(node, "zs");
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
no_probe:
sunzilog_alloc_tables(); sunzilog_alloc_tables();
sunzilog_ports_init(); sunzilog_ports_init();
......
...@@ -39,8 +39,8 @@ typedef struct { ...@@ -39,8 +39,8 @@ typedef struct {
* - ( bit 26 is the PREEMPT_ACTIVE flag. ) * - ( bit 26 is the PREEMPT_ACTIVE flag. )
* *
* PREEMPT_MASK: 0x000000ff * PREEMPT_MASK: 0x000000ff
* HARDIRQ_MASK: 0x0000ff00 * SOFTIRQ_MASK: 0x0000ff00
* SOFTIRQ_MASK: 0x00ff0000 * HARDIRQ_MASK: 0x00ff0000
*/ */
#define PREEMPT_BITS 8 #define PREEMPT_BITS 8
...@@ -90,8 +90,10 @@ typedef struct { ...@@ -90,8 +90,10 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#if CONFIG_PREEMPT #if CONFIG_PREEMPT
# define in_atomic() (preempt_count() != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else #else
# define in_atomic() (preempt_count() != 0)
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif #endif
#define irq_exit() \ #define irq_exit() \
...@@ -121,7 +123,7 @@ do { \ ...@@ -121,7 +123,7 @@ do { \
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
#define synchronize_irq() barrier() #define synchronize_irq(irq) barrier()
#else /* (CONFIG_SMP) */ #else /* (CONFIG_SMP) */
......
...@@ -148,6 +148,19 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) ...@@ -148,6 +148,19 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
dec_preempt_count(); dec_preempt_count();
} }
static inline struct page *kmap_atomic_to_page(void *ptr)
{
unsigned long idx, vaddr = (unsigned long)ptr;
pte_t *pte;
if (vaddr < FIX_KMAP_BEGIN)
return virt_to_page(ptr);
idx = ((vaddr - FIX_KMAP_BEGIN) >> PAGE_SHIFT);
pte = kmap_pte + idx;
return pte_page(*pte);
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */ #endif /* _ASM_HIGHMEM_H */
...@@ -81,92 +81,30 @@ static __inline__ void ide_init_default_hwifs(void) ...@@ -81,92 +81,30 @@ static __inline__ void ide_init_default_hwifs(void)
* The following are not needed for the non-m68k ports * The following are not needed for the non-m68k ports
*/ */
#define ide_ack_intr(hwif) (1) #define ide_ack_intr(hwif) (1)
#define ide_fix_driveid(id) do {} while (0)
#define ide_release_lock(lock) do {} while (0) #define ide_release_lock(lock) do {} while (0)
#define ide_get_lock(lock, hdlr, data) do {} while (0) #define ide_get_lock(lock, hdlr, data) do {} while (0)
/* From m68k code... */ /* XXX Known to be broken. Axboe will fix the problems this
* XXX has by making seperate IN/OUT macros for IDE_DATA
#ifdef insl * XXX register and rest of IDE regs and also using
#undef insl * XXX ide_ioreg_t instead of u32 for ports. -DaveM
#endif */
#ifdef outsl
#undef outsl
#endif
#ifdef insw
#undef insw
#endif
#ifdef outsw
#undef outsw
#endif
#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
#define insw(port, buf, nr) ide_insw((port), (buf), (nr))
#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
static __inline__ void ide_insw(unsigned long port,
void *dst,
unsigned long count)
{
volatile unsigned short *data_port;
/* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */
u16 *ps = dst;
u32 *pi;
data_port = (volatile unsigned short *)port;
if(((unsigned long)ps) & 0x2) {
*ps++ = *data_port;
count--;
}
pi = (u32 *)ps;
while(count >= 2) {
u32 w;
w = (*data_port) << 16;
w |= (*data_port);
*pi++ = w;
count -= 2;
}
ps = (u16 *)pi;
if(count)
*ps++ = *data_port;
/* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
}
static __inline__ void ide_outsw(unsigned long port,
const void *src,
unsigned long count)
{
volatile unsigned short *data_port;
/* unsigned long end = (unsigned long)src + (count << 1); */
const u16 *ps = src;
const u32 *pi;
data_port = (volatile unsigned short *)port;
if(((unsigned long)src) & 0x2) {
*data_port = *ps++;
count--;
}
pi = (const u32 *)ps;
while(count >= 2) {
u32 w;
w = *pi++;
*data_port = (w >> 16);
*data_port = w;
count -= 2;
}
ps = (const u16 *)pi;
if(count)
*data_port = *ps;
/* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */ #define HAVE_ARCH_IN_BYTE
} #define IN_BYTE(p) (*((volatile u8 *)(p)))
#define IN_WORD(p) (*((volatile u16 *)(p)))
#define IN_LONG(p) (*((volatile u32 *)(p)))
#define IN_BYTE_P IN_BYTE
#define IN_WORD_P IN_WORD
#define IN_LONG_P IN_LONG
#define HAVE_ARCH_OUT_BYTE
#define OUT_BYTE(b,p) ((*((volatile u8 *)(p))) = (b))
#define OUT_WORD(w,p) ((*((volatile u16 *)(p))) = (w))
#define OUT_LONG(l,p) ((*((volatile u32 *)(p))) = (l))
#define OUT_BYTE_P OUT_BYTE
#define OUT_WORD_P OUT_WORD
#define OUT_LONG_P OUT_LONG
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -21,6 +21,8 @@ BTFIXUPDEF_CALL(char *, __irq_itoa, unsigned int) ...@@ -21,6 +21,8 @@ BTFIXUPDEF_CALL(char *, __irq_itoa, unsigned int)
#define NR_IRQS 15 #define NR_IRQS 15
#define irq_cannonicalize(irq) (irq)
/* Dave Redman (djhr@tadpole.co.uk) /* Dave Redman (djhr@tadpole.co.uk)
* changed these to function pointers.. it saves cycles and will allow * changed these to function pointers.. it saves cycles and will allow
* the irq dependencies to be split into different files at a later date * the irq dependencies to be split into different files at a later date
......
...@@ -11,6 +11,8 @@ enum km_type { ...@@ -11,6 +11,8 @@ enum km_type {
KM_BIO_DST_IRQ, KM_BIO_DST_IRQ,
KM_PTE0, KM_PTE0,
KM_PTE1, KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_TYPE_NR KM_TYPE_NR
}; };
......
...@@ -42,6 +42,7 @@ typedef struct _rwlock_debug rwlock_t; ...@@ -42,6 +42,7 @@ typedef struct _rwlock_debug rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} } #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} }
#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) #define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
#define rwlock_is_locked(lp) ((lp)->lock != 0)
extern void _do_read_lock(rwlock_t *rw, char *str); extern void _do_read_lock(rwlock_t *rw, char *str);
extern void _do_read_unlock(rwlock_t *rw, char *str); extern void _do_read_unlock(rwlock_t *rw, char *str);
...@@ -141,6 +142,7 @@ typedef struct { volatile unsigned int lock; } rwlock_t; ...@@ -141,6 +142,7 @@ typedef struct { volatile unsigned int lock; } rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 } #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) #define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0)
#define rwlock_is_locked(lp) ((lp)->lock != 0)
/* Sort of like atomic_t's on Sparc, but even more clever. /* Sort of like atomic_t's on Sparc, but even more clever.
......
...@@ -56,6 +56,17 @@ extern unsigned long empty_zero_page; ...@@ -56,6 +56,17 @@ extern unsigned long empty_zero_page;
extern struct linux_romvec *romvec; extern struct linux_romvec *romvec;
#define halt() romvec->pv_halt() #define halt() romvec->pv_halt()
extern void sun_do_break(void);
extern int serial_console;
extern int stop_a_enabled;
static __inline__ int con_is_present(void)
{
return serial_console ? 0 : 1;
}
extern struct pt_regs *kbd_pt_regs;
/* When a context switch happens we must flush all user windows so that /* When a context switch happens we must flush all user windows so that
* the windows of the current process are flushed onto its stack. This * the windows of the current process are flushed onto its stack. This
* way the windows are all clean for the next process and the stack * way the windows are all clean for the next process and the stack
...@@ -113,6 +124,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, ...@@ -113,6 +124,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
"restore; restore; restore; restore; restore; restore; restore"); \ "restore; restore; restore; restore; restore; restore; restore"); \
} while(0) } while(0)
#define finish_arch_switch(rq, next) do{ }while(0) #define finish_arch_switch(rq, next) do{ }while(0)
#define task_running(rq, p) ((rq)->curr == (p))
/* Much care has gone into this code, do not touch it. /* Much care has gone into this code, do not touch it.
* *
...@@ -263,6 +275,15 @@ extern __inline__ unsigned long read_psr_and_cli(void) ...@@ -263,6 +275,15 @@ extern __inline__ unsigned long read_psr_and_cli(void)
#define local_irq_save(flags) ((flags) = read_psr_and_cli()) #define local_irq_save(flags) ((flags) = read_psr_and_cli())
#define local_irq_restore(flags) setipl((flags)) #define local_irq_restore(flags) setipl((flags))
/* On sparc32 IRQ flags are the PSR register in the PSR_PIL
* field.
*/
#define irqs_disabled() \
({ unsigned long flags; \
local_save_flags(flags);\
(flags & PSR_PIL) != 0; \
})
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
extern unsigned char global_irq_holder; extern unsigned char global_irq_holder;
...@@ -282,9 +303,6 @@ extern void __global_restore_flags(unsigned long flags); ...@@ -282,9 +303,6 @@ extern void __global_restore_flags(unsigned long flags);
#define cli() local_irq_disable() #define cli() local_irq_disable()
#define sti() local_irq_enable() #define sti() local_irq_enable()
#define save_flags(x) local_save_flags(x)
#define restore_flags(x) local_irq_restore(x)
#define save_and_cli(x) local_irq_save(x)
#endif #endif
......
...@@ -203,7 +203,7 @@ ...@@ -203,7 +203,7 @@
#define __NR_setpgid 185 /* Common */ #define __NR_setpgid 185 /* Common */
#define __NR_fremovexattr 186 /* SunOS: pathconf */ #define __NR_fremovexattr 186 /* SunOS: pathconf */
#define __NR_tkill 187 /* SunOS: fpathconf */ #define __NR_tkill 187 /* SunOS: fpathconf */
/* #define __NR_sysconf 188 SunOS Specific */ #define __NR_exit_group 188 /* Linux specific, sysconf undef SunOS */
#define __NR_uname 189 /* Linux Specific */ #define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* Linux Specific */ #define __NR_init_module 190 /* Linux Specific */
#define __NR_personality 191 /* Linux Specific */ #define __NR_personality 191 /* Linux Specific */
......
...@@ -85,8 +85,10 @@ typedef struct { ...@@ -85,8 +85,10 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
#if CONFIG_PREEMPT #if CONFIG_PREEMPT
# define in_atomic() (preempt_count() != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else #else
# define in_atomic() (preempt_count() != 0)
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif #endif
#define irq_exit() \ #define irq_exit() \
......
...@@ -78,112 +78,63 @@ static __inline__ void ide_init_default_hwifs(void) ...@@ -78,112 +78,63 @@ static __inline__ void ide_init_default_hwifs(void)
* The following are not needed for the non-m68k ports * The following are not needed for the non-m68k ports
*/ */
#define ide_ack_intr(hwif) (1) #define ide_ack_intr(hwif) (1)
#define ide_fix_driveid(id) do {} while (0)
#define ide_release_lock(lock) do {} while (0) #define ide_release_lock(lock) do {} while (0)
#define ide_get_lock(lock, hdlr, data) do {} while (0) #define ide_get_lock(lock, hdlr, data) do {} while (0)
/* From m68k code... */ /* XXX Known to be broken. Axboe will fix the problems this
* XXX has by making seperate IN/OUT macros for IDE_DATA
#ifdef insl * XXX register and rest of IDE regs and also using
#undef insl * XXX ide_ioreg_t instead of u32 for ports. -DaveM
#endif */
#ifdef outsl
#undef outsl
#endif
#ifdef insw
#undef insw
#endif
#ifdef outsw
#undef outsw
#endif
#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
#define insw(port, buf, nr) ide_insw((port), (buf), (nr))
#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
static __inline__ unsigned int inw_be(unsigned long addr)
{
unsigned int ret;
__asm__ __volatile__("lduha [%1] %2, %0" #define HAVE_ARCH_IN_BYTE
static __inline__ u8 IN_BYTE(ide_ioreg_t addr)
{ u8 ret;
__asm__ __volatile__("lduba [%1] %2, %0\t/* ide_in_byte */"
: "=r" (ret) : "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret; return ret;
} }
static __inline__ u16 IN_WORD(ide_ioreg_t addr)
{ u16 ret;
__asm__ __volatile__("lduha [%1] %2, %0\t/* ide_in_word */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
static __inline__ u16 IN_LONG(ide_ioreg_t addr)
{ u32 ret;
__asm__ __volatile__("lduwa [%1] %2, %0\t/* ide_in_long */"
: "=r" (ret)
: "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
return ret;
}
#define IN_BYTE_P IN_BYTE
#define IN_WORD_P IN_WORD
#define IN_LONG_P IN_LONG
static __inline__ void ide_insw(unsigned long port, #define HAVE_ARCH_OUT_BYTE
void *dst, static __inline__ void OUT_BYTE(u8 byte, ide_ioreg_t addr)
unsigned long count)
{ {
#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ __asm__ __volatile__("stba %r0, [%1] %2\t/* ide_out_byte */"
unsigned long end = (unsigned long)dst + (count << 1); : /* no outputs */
#endif : "Jr" (byte), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
u16 *ps = dst;
u32 *pi;
if(((u64)ps) & 0x2) {
*ps++ = inw_be(port);
count--;
}
pi = (u32 *)ps;
while(count >= 2) {
u32 w;
w = inw_be(port) << 16;
w |= inw_be(port);
*pi++ = w;
count -= 2;
}
ps = (u16 *)pi;
if(count)
*ps++ = inw_be(port);
#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */
__flush_dcache_range((unsigned long)dst, end);
#endif
} }
static __inline__ void OUT_WORD(u16 word, ide_ioreg_t addr)
static __inline__ void outw_be(unsigned short w, unsigned long addr)
{ {
__asm__ __volatile__("stha %0, [%1] %2" __asm__ __volatile__("stha %r0, [%1] %2\t/* ide_out_word */"
: /* no outputs */ : /* no outputs */
: "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); : "Jr" (word), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
} }
static __inline__ void OUT_LONG(u32 _long, ide_ioreg_t addr)
static __inline__ void ide_outsw(unsigned long port,
const void *src,
unsigned long count)
{ {
#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ __asm__ __volatile__("stwa %r0, [%1] %2\t/* ide_out_long */"
unsigned long end = (unsigned long)src + (count << 1); : /* no outputs */
#endif : "Jr" (_long), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
const u16 *ps = src;
const u32 *pi;
if(((u64)src) & 0x2) {
outw_be(*ps++, port);
count--;
}
pi = (const u32 *)ps;
while(count >= 2) {
u32 w;
w = *pi++;
outw_be((w >> 16), port);
outw_be(w, port);
count -= 2;
}
ps = (const u16 *)pi;
if(count)
outw_be(*ps, port);
#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */
__flush_dcache_range((unsigned long)src, end);
#endif
} }
#define OUT_BYTE_P OUT_BYTE
#define OUT_WORD_P OUT_WORD
#define OUT_LONG_P OUT_LONG
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -112,6 +112,7 @@ extern int _spin_trylock (spinlock_t *lock); ...@@ -112,6 +112,7 @@ extern int _spin_trylock (spinlock_t *lock);
typedef unsigned int rwlock_t; typedef unsigned int rwlock_t;
#define RW_LOCK_UNLOCKED 0 #define RW_LOCK_UNLOCKED 0
#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
#define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
extern void __read_lock(rwlock_t *); extern void __read_lock(rwlock_t *);
extern void __read_unlock(rwlock_t *); extern void __read_unlock(rwlock_t *);
...@@ -132,6 +133,7 @@ typedef struct { ...@@ -132,6 +133,7 @@ typedef struct {
} rwlock_t; } rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { 0, 0, 0, 0 } } #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { 0, 0, 0, 0 } }
#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
#define rwlock_is_locked(x) ((x)->lock != 0)
extern void _do_read_lock(rwlock_t *rw, char *str); extern void _do_read_lock(rwlock_t *rw, char *str);
extern void _do_read_unlock(rwlock_t *rw, char *str); extern void _do_read_unlock(rwlock_t *rw, char *str);
......
...@@ -203,7 +203,7 @@ ...@@ -203,7 +203,7 @@
#define __NR_setpgid 185 /* Common */ #define __NR_setpgid 185 /* Common */
#define __NR_fremovexattr 186 /* SunOS: pathconf */ #define __NR_fremovexattr 186 /* SunOS: pathconf */
#define __NR_tkill 187 /* SunOS: fpathconf */ #define __NR_tkill 187 /* SunOS: fpathconf */
/* #define __NR_sysconf 188 SunOS Specific */ #define __NR_exit_group 188 /* Linux specific, sysconf undef SunOS */
#define __NR_uname 189 /* Linux Specific */ #define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* Linux Specific */ #define __NR_init_module 190 /* Linux Specific */
#define __NR_personality 191 /* Linux Specific */ #define __NR_personality 191 /* Linux Specific */
......
...@@ -73,12 +73,21 @@ int max_queued_signals = 1024; ...@@ -73,12 +73,21 @@ int max_queued_signals = 1024;
---------------------------------------------------------- ----------------------------------------------------------
*/ */
/* Some systems do not have a SIGSTKFLT and the kernel never
* generates such signals anyways.
*/
#ifdef SIGSTKFLT
#define M_SIGSTKFLT M(SIGSTKFLT)
#else
#define M_SIGSTKFLT 0
#endif
#define M(sig) (1UL << (sig)) #define M(sig) (1UL << (sig))
#define SIG_USER_SPECIFIC_MASK (\ #define SIG_USER_SPECIFIC_MASK (\
M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | M(SIGBUS) | \ M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | M(SIGBUS) | \
M(SIGFPE) | M(SIGSEGV) | M(SIGPIPE) | M(SIGXFSZ) | \ M(SIGFPE) | M(SIGSEGV) | M(SIGPIPE) | M(SIGXFSZ) | \
M(SIGPROF) | M(SIGSYS) | M(SIGSTKFLT) | M(SIGCONT) ) M(SIGPROF) | M(SIGSYS) | M_SIGSTKFLT | M(SIGCONT) )
#define SIG_USER_LOAD_BALANCE_MASK (\ #define SIG_USER_LOAD_BALANCE_MASK (\
M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGUSR1) | \ M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGUSR1) | \
...@@ -95,7 +104,7 @@ int max_queued_signals = 1024; ...@@ -95,7 +104,7 @@ int max_queued_signals = 1024;
M(SIGKILL) | M(SIGUSR1) | M(SIGSEGV) | M(SIGUSR2) | \ M(SIGKILL) | M(SIGUSR1) | M(SIGSEGV) | M(SIGUSR2) | \
M(SIGPIPE) | M(SIGALRM) | M(SIGTERM) | M(SIGXCPU) | \ M(SIGPIPE) | M(SIGALRM) | M(SIGTERM) | M(SIGXCPU) | \
M(SIGXFSZ) | M(SIGVTALRM) | M(SIGPROF) | M(SIGPOLL) | \ M(SIGXFSZ) | M(SIGVTALRM) | M(SIGPROF) | M(SIGPOLL) | \
M(SIGSYS) | M(SIGSTKFLT) | M(SIGPWR) | M(SIGCONT) | \ M(SIGSYS) | M_SIGSTKFLT | M(SIGPWR) | M(SIGCONT) | \
M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) ) M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) )
#define SIG_KERNEL_ONLY_MASK (\ #define SIG_KERNEL_ONLY_MASK (\
......
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