Commit 9f1e5eef authored by David Mosberger's avatar David Mosberger

Merge wailua.hpl.hp.com:/var/autofs/net/tiger/data1/bk/vanilla/linux-2.5

into wailua.hpl.hp.com:/var/autofs/net/tiger/data1/bk/lia64/to-linus-2.5
parents cd03e0b9 1ebe34c9
...@@ -26,7 +26,7 @@ CFLAGS_KERNEL := -mconstant-gp ...@@ -26,7 +26,7 @@ CFLAGS_KERNEL := -mconstant-gp
GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
ifneq ($(GCC_VERSION),2) ifneq ($(GCC_VERSION),2)
CFLAGS += -frename-registers --param max-inline-insns=2000 CFLAGS += -frename-registers --param max-inline-insns=5000
endif endif
ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y) ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y)
......
...@@ -15,6 +15,8 @@ OBJECTS = bootloader.o ...@@ -15,6 +15,8 @@ OBJECTS = bootloader.o
targets-$(CONFIG_IA64_HP_SIM) += bootloader targets-$(CONFIG_IA64_HP_SIM) += bootloader
targets-$(CONFIG_IA64_GENERIC) += bootloader targets-$(CONFIG_IA64_GENERIC) += bootloader
CFLAGS := $(CFLAGS) $(CFLAGS_KERNEL)
all: $(targets-y) all: $(targets-y)
bootloader: $(OBJECTS) bootloader: $(OBJECTS)
......
...@@ -64,7 +64,8 @@ if [ "$CONFIG_MCKINLEY" = "y" ]; then ...@@ -64,7 +64,8 @@ if [ "$CONFIG_MCKINLEY" = "y" ]; then
fi fi
fi fi
if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ]; then if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ];
then
bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
define_bool CONFIG_PM y define_bool CONFIG_PM y
fi fi
...@@ -99,21 +100,20 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF ...@@ -99,21 +100,20 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
source drivers/acpi/Config.in
source drivers/acpi/Config.in bool 'PCI support' CONFIG_PCI
source drivers/pci/Config.in
bool 'PCI support' CONFIG_PCI bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
source drivers/pci/Config.in if [ "$CONFIG_HOTPLUG" = "y" ]; then
source drivers/hotplug/Config.in
bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
if [ "$CONFIG_HOTPLUG" = "y" ]; then
source drivers/pcmcia/Config.in source drivers/pcmcia/Config.in
else else
define_bool CONFIG_PCMCIA n define_bool CONFIG_PCMCIA n
fi fi
source drivers/parport/Config.in
source drivers/parport/Config.in
fi # !HP_SIM fi # !HP_SIM
endmenu endmenu
...@@ -123,39 +123,26 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -123,39 +123,26 @@ if [ "$CONFIG_NET" = "y" ]; then
fi fi
if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
source drivers/mtd/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
source drivers/ieee1394/Config.in
source drivers/message/i2o/Config.in
source drivers/md/Config.in
source drivers/message/fusion/Config.in
source drivers/mtd/Config.in mainmenu_option next_comment
source drivers/pnp/Config.in comment 'ATA/ATAPI/MFM/RLL support'
source drivers/block/Config.in
source drivers/ieee1394/Config.in
source drivers/message/i2o/Config.in
source drivers/md/Config.in
source drivers/message/fusion/Config.in
mainmenu_option next_comment
comment 'ATA/ATAPI/MFM/RLL support'
tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in source drivers/ide/Config.in
else else
define_bool CONFIG_BLK_DEV_HD n define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
fi fi
endmenu
else # ! HP_SIM
mainmenu_option next_comment
comment 'Block devices'
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
fi
endmenu
fi # !HP_SIM
mainmenu_option next_comment mainmenu_option next_comment
comment 'SCSI support' comment 'SCSI support'
...@@ -168,8 +155,7 @@ fi ...@@ -168,8 +155,7 @@ fi
endmenu endmenu
if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
comment 'Network device support' comment 'Network device support'
...@@ -178,36 +164,46 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -178,36 +164,46 @@ if [ "$CONFIG_NET" = "y" ]; then
source drivers/net/Config.in source drivers/net/Config.in
fi fi
endmenu endmenu
fi fi
source net/ax25/Config.in
source net/ax25/Config.in source drivers/isdn/Config.in
source drivers/isdn/Config.in
mainmenu_option next_comment mainmenu_option next_comment
comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)' comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in source drivers/cdrom/Config.in
fi fi
endmenu endmenu
fi # !HP_SIM #
# input before char - char/joystick depends on it. As does USB.
#
source drivers/input/Config.in
source drivers/char/Config.in
# #source drivers/misc/Config.in
# input before char - char/joystick depends on it. As does USB.
#
source drivers/input/Config.in
source drivers/char/Config.in
#source drivers/misc/Config.in source drivers/media/Config.in
else # HP_SIM
source drivers/media/Config.in mainmenu_option next_comment
comment 'Block devices'
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
fi
endmenu
fi # HP_SIM
source fs/Config.in source fs/Config.in
if [ "$CONFIG_VT" = "y" ]; then if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
comment 'Console drivers' comment 'Console drivers'
bool 'VGA text console' CONFIG_VGA_CONSOLE bool 'VGA text console' CONFIG_VGA_CONSOLE
...@@ -216,32 +212,26 @@ if [ "$CONFIG_VT" = "y" ]; then ...@@ -216,32 +212,26 @@ if [ "$CONFIG_VT" = "y" ]; then
define_bool CONFIG_PCI_CONSOLE y define_bool CONFIG_PCI_CONSOLE y
fi fi
endmenu endmenu
fi fi
if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
mainmenu_option next_comment mainmenu_option next_comment
comment 'Sound' comment 'Sound'
tristate 'Sound card support' CONFIG_SOUND tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then if [ "$CONFIG_SOUND" != "n" ]; then
source sound/Config.in source sound/Config.in
fi fi
endmenu endmenu
source drivers/usb/Config.in
source lib/Config.in
source net/bluetooth/Config.in
source drivers/usb/Config.in
source lib/Config.in
source net/bluetooth/Config.in
fi # !HP_SIM fi # !HP_SIM
if [ "$CONFIG_IA64_HP_SIM" != "n" -o "$CONFIG_IA64_GENERIC" != "n" ]; then if [ "$CONFIG_IA64_HP_SIM" != "n" -o "$CONFIG_IA64_GENERIC" != "n" ]; then
source arch/ia64/hp/Config.in source arch/ia64/hp/sim/Config.in
fi fi
mainmenu_option next_comment mainmenu_option next_comment
comment 'Kernel hacking' comment 'Kernel hacking'
......
This diff is collapsed.
...@@ -30,12 +30,12 @@ static void simcons_write (struct console *, const char *, unsigned); ...@@ -30,12 +30,12 @@ static void simcons_write (struct console *, const char *, unsigned);
static kdev_t simcons_console_device (struct console *); static kdev_t simcons_console_device (struct console *);
struct console hpsim_cons = { struct console hpsim_cons = {
name: "simcons", .name = "simcons",
write: simcons_write, .write = simcons_write,
device: simcons_console_device, .device = simcons_console_device,
setup: simcons_init, .setup = simcons_init,
flags: CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
index: -1, .index = -1,
}; };
static int static int
......
...@@ -22,14 +22,14 @@ hpsim_irq_noop (unsigned int irq) ...@@ -22,14 +22,14 @@ hpsim_irq_noop (unsigned int irq)
} }
static struct hw_interrupt_type irq_type_hp_sim = { static struct hw_interrupt_type irq_type_hp_sim = {
typename: "hpsim", .typename = "hpsim",
startup: hpsim_irq_startup, .startup = hpsim_irq_startup,
shutdown: hpsim_irq_noop, .shutdown = hpsim_irq_noop,
enable: hpsim_irq_noop, .enable = hpsim_irq_noop,
disable: hpsim_irq_noop, .disable = hpsim_irq_noop,
ack: hpsim_irq_noop, .ack = hpsim_irq_noop,
end: hpsim_irq_noop, .end = hpsim_irq_noop,
set_affinity: (void (*)(unsigned int, unsigned long)) hpsim_irq_noop, .set_affinity = (void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
}; };
void __init void __init
......
/* /*
* Platform dependent support for HP simulator. * Platform dependent support for HP simulator.
* *
* Copyright (C) 1998, 1999 Hewlett-Packard Co * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
* Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com> * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
*/ */
#include <linux/console.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/major.h>
#include <linux/param.h> #include <linux/param.h>
#include <linux/root_dev.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/console.h>
#include <linux/root_dev.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -55,5 +56,5 @@ hpsim_setup (char **cmdline_p) ...@@ -55,5 +56,5 @@ hpsim_setup (char **cmdline_p)
{ {
ROOT_DEV = Root_SDA1; /* default to first SCSI drive */ ROOT_DEV = Root_SDA1; /* default to first SCSI drive */
register_console (&hpsim_cons); register_console(&hpsim_cons);
} }
...@@ -62,7 +62,9 @@ struct disk_stat { ...@@ -62,7 +62,9 @@ struct disk_stat {
extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr); extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
static int desc[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; static int desc[16] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
static struct queue_entry { static struct queue_entry {
Scsi_Cmnd *sc; Scsi_Cmnd *sc;
...@@ -148,9 +150,9 @@ simscsi_biosparam (Disk *disk, struct block_device *n, int ip[]) ...@@ -148,9 +150,9 @@ simscsi_biosparam (Disk *disk, struct block_device *n, int ip[])
{ {
int size = disk->capacity; int size = disk->capacity;
ip[0] = 64; ip[0] = 64; /* heads */
ip[1] = 32; ip[1] = 32; /* sectors */
ip[2] = size >> 11; ip[2] = size >> 11; /* cylinders */
return 0; return 0;
} }
...@@ -229,6 +231,29 @@ simscsi_readwrite6 (Scsi_Cmnd *sc, int mode) ...@@ -229,6 +231,29 @@ simscsi_readwrite6 (Scsi_Cmnd *sc, int mode)
simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512); simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
} }
static size_t
simscsi_get_disk_size (int fd)
{
struct disk_stat stat;
size_t bit, sectors = 0;
struct disk_req req;
char buf[512];
/*
* This is a bit kludgey: the simulator doesn't provide a direct way of determining
* the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
*/
for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
req.addr = __pa(&buf);
req.len = sizeof(buf);
ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
stat.fd = fd;
ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
if (stat.count == sizeof(buf))
sectors |= bit;
}
return sectors - 1; /* return last valid sector number */
}
static void static void
simscsi_readwrite10 (Scsi_Cmnd *sc, int mode) simscsi_readwrite10 (Scsi_Cmnd *sc, int mode)
...@@ -247,6 +272,7 @@ int ...@@ -247,6 +272,7 @@ int
simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
{ {
char fname[MAX_ROOT_LEN+16]; char fname[MAX_ROOT_LEN+16];
size_t disk_size;
char *buf; char *buf;
#if DEBUG_SIMSCSI #if DEBUG_SIMSCSI
register long sp asm ("sp"); register long sp asm ("sp");
...@@ -258,14 +284,14 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) ...@@ -258,14 +284,14 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
sc->result = DID_BAD_TARGET << 16; sc->result = DID_BAD_TARGET << 16;
sc->scsi_done = done; sc->scsi_done = done;
if (sc->target <= 7 && sc->lun == 0) { if (sc->target <= 15 && sc->lun == 0) {
switch (sc->cmnd[0]) { switch (sc->cmnd[0]) {
case INQUIRY: case INQUIRY:
if (sc->request_bufflen < 35) { if (sc->request_bufflen < 35) {
break; break;
} }
sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target); sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target);
desc[sc->target] = ia64_ssc (__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS, desc[sc->target] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
0, 0, SSC_OPEN); 0, 0, SSC_OPEN);
if (desc[sc->target] < 0) { if (desc[sc->target] < 0) {
/* disk doesn't exist... */ /* disk doesn't exist... */
...@@ -319,11 +345,13 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) ...@@ -319,11 +345,13 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
} }
buf = sc->request_buffer; buf = sc->request_buffer;
disk_size = simscsi_get_disk_size(desc[sc->target]);
/* pretend to be a 1GB disk (partition table contains real stuff): */ /* pretend to be a 1GB disk (partition table contains real stuff): */
buf[0] = 0x00; buf[0] = (disk_size >> 24) & 0xff;
buf[1] = 0x1f; buf[1] = (disk_size >> 16) & 0xff;
buf[2] = 0xff; buf[2] = (disk_size >> 8) & 0xff;
buf[3] = 0xff; buf[3] = (disk_size >> 0) & 0xff;
/* set block size of 512 bytes: */ /* set block size of 512 bytes: */
buf[4] = 0; buf[4] = 0;
buf[5] = 0; buf[5] = 0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* *
* 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close(). * 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close().
* 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c. * 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c.
* 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include <linux/serialP.h> #include <linux/serialP.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hw_irq.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#ifdef CONFIG_KDB #ifdef CONFIG_KDB
...@@ -61,6 +63,7 @@ extern void ia64_ssc_connect_irq (long intr, long irq); ...@@ -61,6 +63,7 @@ extern void ia64_ssc_connect_irq (long intr, long irq);
static char *serial_name = "SimSerial driver"; static char *serial_name = "SimSerial driver";
static char *serial_version = "0.6"; static char *serial_version = "0.6";
static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
/* /*
* This has been extracted from asm/serial.h. We need one eventually but * This has been extracted from asm/serial.h. We need one eventually but
...@@ -232,14 +235,14 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch) ...@@ -232,14 +235,14 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
if (!tty || !info->xmit.buf) return; if (!tty || !info->xmit.buf) return;
save_flags(flags); cli(); spin_lock_irqsave(&serial_lock, flags);
if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) { if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
return; return;
} }
info->xmit.buf[info->xmit.head] = ch; info->xmit.buf[info->xmit.head] = ch;
info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
} }
static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
...@@ -247,7 +250,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) ...@@ -247,7 +250,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
int count; int count;
unsigned long flags; unsigned long flags;
save_flags(flags); cli(); spin_lock_irqsave(&serial_lock, flags);
if (info->x_char) { if (info->x_char) {
char c = info->x_char; char c = info->x_char;
...@@ -290,7 +293,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) ...@@ -290,7 +293,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
info->xmit.tail += count; info->xmit.tail += count;
} }
out: out:
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
} }
static void rs_flush_chars(struct tty_struct *tty) static void rs_flush_chars(struct tty_struct *tty)
...@@ -314,7 +317,6 @@ static int rs_write(struct tty_struct * tty, int from_user, ...@@ -314,7 +317,6 @@ static int rs_write(struct tty_struct * tty, int from_user,
if (!tty || !info->xmit.buf || !tmp_buf) return 0; if (!tty || !info->xmit.buf || !tmp_buf) return 0;
save_flags(flags);
if (from_user) { if (from_user) {
down(&tmp_buf_sem); down(&tmp_buf_sem);
while (1) { while (1) {
...@@ -331,21 +333,26 @@ static int rs_write(struct tty_struct * tty, int from_user, ...@@ -331,21 +333,26 @@ static int rs_write(struct tty_struct * tty, int from_user,
ret = -EFAULT; ret = -EFAULT;
break; break;
} }
cli();
c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); spin_lock_irqsave(&serial_lock, flags);
{
c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail,
SERIAL_XMIT_SIZE);
if (c1 < c) if (c1 < c)
c = c1; c = c1;
memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
info->xmit.head = ((info->xmit.head + c) & info->xmit.head = ((info->xmit.head + c) &
(SERIAL_XMIT_SIZE-1)); (SERIAL_XMIT_SIZE-1));
restore_flags(flags); }
spin_unlock_irqrestore(&serial_lock, flags);
buf += c; buf += c;
count -= c; count -= c;
ret += c; ret += c;
} }
up(&tmp_buf_sem); up(&tmp_buf_sem);
} else { } else {
cli(); spin_lock_irqsave(&serial_lock, flags);
while (1) { while (1) {
c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
if (count < c) if (count < c)
...@@ -360,7 +367,7 @@ static int rs_write(struct tty_struct * tty, int from_user, ...@@ -360,7 +367,7 @@ static int rs_write(struct tty_struct * tty, int from_user,
count -= c; count -= c;
ret += c; ret += c;
} }
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
} }
/* /*
* Hey, we transmit directly from here in our case * Hey, we transmit directly from here in our case
...@@ -391,9 +398,9 @@ static void rs_flush_buffer(struct tty_struct *tty) ...@@ -391,9 +398,9 @@ static void rs_flush_buffer(struct tty_struct *tty)
struct async_struct *info = (struct async_struct *)tty->driver_data; struct async_struct *info = (struct async_struct *)tty->driver_data;
unsigned long flags; unsigned long flags;
save_flags(flags); cli(); spin_lock_irqsave(&serial_lock, flags);
info->xmit.head = info->xmit.tail = 0; info->xmit.head = info->xmit.tail = 0;
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->write_wait);
...@@ -566,8 +573,8 @@ static void shutdown(struct async_struct * info) ...@@ -566,8 +573,8 @@ static void shutdown(struct async_struct * info)
state->irq); state->irq);
#endif #endif
save_flags(flags); cli(); /* Disable interrupts */ spin_lock_irqsave(&serial_lock, flags);
{
/* /*
* First unlink the serial port from the IRQ chain... * First unlink the serial port from the IRQ chain...
*/ */
...@@ -603,7 +610,8 @@ static void shutdown(struct async_struct * info) ...@@ -603,7 +610,8 @@ static void shutdown(struct async_struct * info)
if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
info->flags &= ~ASYNC_INITIALIZED; info->flags &= ~ASYNC_INITIALIZED;
restore_flags(flags); }
spin_unlock_irqrestore(&serial_lock, flags);
} }
/* /*
...@@ -626,14 +634,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -626,14 +634,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
state = info->state; state = info->state;
save_flags(flags); cli(); spin_lock_irqsave(&serial_lock, flags);
if (tty_hung_up_p(filp)) { if (tty_hung_up_p(filp)) {
#ifdef SIMSERIAL_DEBUG #ifdef SIMSERIAL_DEBUG
printk("rs_close: hung_up\n"); printk("rs_close: hung_up\n");
#endif #endif
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
return; return;
} }
#ifdef SIMSERIAL_DEBUG #ifdef SIMSERIAL_DEBUG
...@@ -658,11 +665,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -658,11 +665,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
} }
if (state->count) { if (state->count) {
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
return; return;
} }
info->flags |= ASYNC_CLOSING; info->flags |= ASYNC_CLOSING;
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
/* /*
* Now we wait for the transmit buffer to clear; and we notify * Now we wait for the transmit buffer to clear; and we notify
...@@ -770,7 +777,7 @@ startup(struct async_struct *info) ...@@ -770,7 +777,7 @@ startup(struct async_struct *info)
if (!page) if (!page)
return -ENOMEM; return -ENOMEM;
save_flags(flags); cli(); spin_lock_irqsave(&serial_lock, flags);
if (info->flags & ASYNC_INITIALIZED) { if (info->flags & ASYNC_INITIALIZED) {
free_page(page); free_page(page);
...@@ -851,11 +858,11 @@ startup(struct async_struct *info) ...@@ -851,11 +858,11 @@ startup(struct async_struct *info)
} }
info->flags |= ASYNC_INITIALIZED; info->flags |= ASYNC_INITIALIZED;
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
return 0; return 0;
errout: errout:
restore_flags(flags); spin_unlock_irqrestore(&serial_lock, flags);
return retval; return retval;
} }
......
#define MACHVEC_PLATFORM_NAME hpzx1 #define MACHVEC_PLATFORM_NAME hpzx1
#include <asm/machvec_init.h> #include <asm/machvec_init.h>
#define MACHVEC_PLATFORM_NAME hpzx1
#include <asm/machvec_init.h>
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "../drivers/acpi/include/acstruct.h" #include "../drivers/acpi/include/acstruct.h"
#include "../drivers/acpi/include/acnamesp.h" #include "../drivers/acpi/include/acnamesp.h"
#include "../drivers/acpi/include/acutils.h" #include "../drivers/acpi/include/acutils.h"
#include "../drivers/acpi/acpi_bus.h"
#define PFX "hpzx1: " #define PFX "hpzx1: "
...@@ -109,7 +110,7 @@ static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \ ...@@ -109,7 +110,7 @@ static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
\ \
switch (where) { \ switch (where) { \
case PCI_BASE_ADDRESS_0: \ case PCI_BASE_ADDRESS_0: \
if (value == ~0) \ if (value == (u##bits) ~0) \
fake_dev->sizing = 1; \ fake_dev->sizing = 1; \
break; \ break; \
default: \ default: \
...@@ -177,7 +178,7 @@ hpzx1_fake_pci_dev(unsigned long addr, unsigned int bus, unsigned int size) ...@@ -177,7 +178,7 @@ hpzx1_fake_pci_dev(unsigned long addr, unsigned int bus, unsigned int size)
* Drivers should ioremap what they need, but we have to do * Drivers should ioremap what they need, but we have to do
* it here, too, so PCI config accesses work. * it here, too, so PCI config accesses work.
*/ */
dev->mapped_csrs = ioremap(dev->csr_base, dev->csr_size); dev->mapped_csrs = (unsigned long) ioremap(dev->csr_base, dev->csr_size);
return dev; return dev;
} }
...@@ -303,7 +304,7 @@ hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret) ...@@ -303,7 +304,7 @@ hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
if ((dev = hpzx1_fake_pci_dev(csr_base, busnum, csr_length))) if ((dev = hpzx1_fake_pci_dev(csr_base, busnum, csr_length)))
printk(KERN_INFO PFX "%s LBA at 0x%lx, _BBN 0x%02x; " printk(KERN_INFO PFX "%s LBA at 0x%lx, _BBN 0x%02x; "
"pci dev %02x:%02x.%d\n", "pci dev %02x:%02x.%d\n",
name, csr_base, busnum, dev->bus, name, csr_base, (unsigned int) busnum, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return AE_OK; return AE_OK;
......
...@@ -67,7 +67,7 @@ ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int ...@@ -67,7 +67,7 @@ ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int
} }
static struct vm_operations_struct ia32_shared_page_vm_ops = { static struct vm_operations_struct ia32_shared_page_vm_ops = {
nopage: ia32_install_shared_page .nopage =ia32_install_shared_page
}; };
void void
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <asm/ia32.h> #include <asm/ia32.h>
#include <../drivers/char/drm/drm.h> #include <../drivers/char/drm/drm.h>
#include <../drivers/char/drm/mga_drm.h>
#include <../drivers/char/drm/i810_drm.h>
#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) #define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
......
This diff is collapsed.
...@@ -125,9 +125,79 @@ efi_gettimeofday (struct timeval *tv) ...@@ -125,9 +125,79 @@ efi_gettimeofday (struct timeval *tv)
tv->tv_usec = tm.nanosecond / 1000; tv->tv_usec = tm.nanosecond / 1000;
} }
static int
is_available_memory (efi_memory_desc_t *md)
{
if (!(md->attribute & EFI_MEMORY_WB))
return 0;
switch (md->type) {
case EFI_LOADER_CODE:
case EFI_LOADER_DATA:
case EFI_BOOT_SERVICES_CODE:
case EFI_BOOT_SERVICES_DATA:
case EFI_CONVENTIONAL_MEMORY:
return 1;
}
return 0;
}
/*
* Trim descriptor MD so its starts at address START_ADDR. If the descriptor covers
* memory that is normally available to the kernel, issue a warning that some memory
* is being ignored.
*/
static void
trim_bottom (efi_memory_desc_t *md, u64 start_addr)
{
u64 num_skipped_pages;
if (md->phys_addr >= start_addr || !md->num_pages)
return;
num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
if (num_skipped_pages > md->num_pages)
num_skipped_pages = md->num_pages;
if (is_available_memory(md))
printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
"at 0x%lx\n", __FUNCTION__,
(num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
md->phys_addr, start_addr - IA64_GRANULE_SIZE);
/*
* NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
* descriptor list to become unsorted. In such a case, md->num_pages will be
* zero, so the Right Thing will happen.
*/
md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
md->num_pages -= num_skipped_pages;
}
static void
trim_top (efi_memory_desc_t *md, u64 end_addr)
{
u64 num_dropped_pages, md_end_addr;
md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
if (md_end_addr <= end_addr || !md->num_pages)
return;
num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
if (num_dropped_pages > md->num_pages)
num_dropped_pages = md->num_pages;
if (is_available_memory(md))
printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
"at 0x%lx\n", __FUNCTION__,
(num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
md->phys_addr, end_addr);
md->num_pages -= num_dropped_pages;
}
/* /*
* Walks the EFI memory map and calls CALLBACK once for each EFI * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
* memory descriptor that has memory that is available for OS use. * has memory that is available for OS use.
*/ */
void void
efi_memmap_walk (efi_freemem_callback_t callback, void *arg) efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
...@@ -137,9 +207,9 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) ...@@ -137,9 +207,9 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
u64 start; u64 start;
u64 end; u64 end;
} prev, curr; } prev, curr;
void *efi_map_start, *efi_map_end, *p; void *efi_map_start, *efi_map_end, *p, *q;
efi_memory_desc_t *md; efi_memory_desc_t *md, *check_md;
u64 efi_desc_size, start, end; u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0;
efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_start = __va(ia64_boot_param->efi_memmap);
efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
...@@ -147,24 +217,56 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) ...@@ -147,24 +217,56 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
md = p; md = p;
switch (md->type) {
case EFI_LOADER_CODE: /* skip over non-WB memory descriptors; that's all we're interested in... */
case EFI_LOADER_DATA:
case EFI_BOOT_SERVICES_CODE:
case EFI_BOOT_SERVICES_DATA:
case EFI_CONVENTIONAL_MEMORY:
if (!(md->attribute & EFI_MEMORY_WB)) if (!(md->attribute & EFI_MEMORY_WB))
continue; continue;
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) {
/*
* Search for the next run of contiguous WB memory. Start search
* at first granule boundary covered by md.
*/
granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1)
& -IA64_GRANULE_SIZE);
first_non_wb_addr = granule_addr;
for (q = p; q < efi_map_end; q += efi_desc_size) {
check_md = q;
if (check_md->attribute & EFI_MEMORY_WB)
trim_bottom(md, granule_addr);
if (check_md->phys_addr < granule_addr)
continue;
if (!(check_md->attribute & EFI_MEMORY_WB))
break; /* hit a non-WB region; stop search */
if (check_md->phys_addr != first_non_wb_addr)
break; /* hit a memory hole; stop search */
first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
}
/* round it down to the previous granule-boundary: */
first_non_wb_addr &= -IA64_GRANULE_SIZE;
if (!(first_non_wb_addr > granule_addr))
continue; /* couldn't find enough contiguous memory */
}
/* BUG_ON((md->phys_addr >> IA64_GRANULE_SHIFT) < first_non_wb_addr); */
trim_top(md, first_non_wb_addr);
if (is_available_memory(md)) {
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) { if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
if (md->phys_addr > mem_limit) if (md->phys_addr > mem_limit)
continue; continue;
md->num_pages = (mem_limit - md->phys_addr) >> EFI_PAGE_SHIFT; md->num_pages = (mem_limit - md->phys_addr) >> EFI_PAGE_SHIFT;
} }
if (md->num_pages == 0) {
printk("efi_memmap_walk: ignoring empty region at 0x%lx", if (md->num_pages == 0)
md->phys_addr);
continue; continue;
}
curr.start = PAGE_OFFSET + md->phys_addr; curr.start = PAGE_OFFSET + md->phys_addr;
curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT); curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
...@@ -187,10 +289,6 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg) ...@@ -187,10 +289,6 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
prev = curr; prev = curr;
} }
} }
break;
default:
continue;
} }
} }
if (prev_valid) { if (prev_valid) {
...@@ -268,8 +366,9 @@ efi_map_pal_code (void) ...@@ -268,8 +366,9 @@ efi_map_pal_code (void)
*/ */
psr = ia64_clear_ic(); psr = ia64_clear_ic();
ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask, ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
pte_val(pfn_pte(md->phys_addr >> PAGE_SHIFT, PAGE_KERNEL)), IA64_GRANULE_SHIFT); pte_val(pfn_pte(md->phys_addr >> PAGE_SHIFT, PAGE_KERNEL)),
ia64_set_psr(psr); IA64_GRANULE_SHIFT);
ia64_set_psr(psr); /* restore psr */
ia64_srlz_i(); ia64_srlz_i();
} }
} }
...@@ -376,7 +475,7 @@ efi_init (void) ...@@ -376,7 +475,7 @@ efi_init (void)
md = p; md = p;
printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n", printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
i, md->type, md->attribute, md->phys_addr, i, md->type, md->attribute, md->phys_addr,
md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
md->num_pages >> (20 - EFI_PAGE_SHIFT)); md->num_pages >> (20 - EFI_PAGE_SHIFT));
} }
} }
......
...@@ -175,6 +175,7 @@ GLOBAL_ENTRY(ia64_switch_to) ...@@ -175,6 +175,7 @@ GLOBAL_ENTRY(ia64_switch_to)
(p6) srlz.d (p6) srlz.d
ld8 sp=[r21] // load kernel stack pointer of new task ld8 sp=[r21] // load kernel stack pointer of new task
mov IA64_KR(CURRENT)=r20 // update "current" application register mov IA64_KR(CURRENT)=r20 // update "current" application register
mov r8=r13 // return pointer to previously running task
mov r13=in0 // set "current" pointer mov r13=in0 // set "current" pointer
;; ;;
DO_LOAD_SWITCH_STACK DO_LOAD_SWITCH_STACK
......
...@@ -88,12 +88,6 @@ EXPORT_SYMBOL(ia64_cpu_to_sapicid); ...@@ -88,12 +88,6 @@ EXPORT_SYMBOL(ia64_cpu_to_sapicid);
#include <asm/smplock.h> #include <asm/smplock.h>
EXPORT_SYMBOL(kernel_flag); EXPORT_SYMBOL(kernel_flag);
/* #include <asm/system.h> */
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
#else /* !CONFIG_SMP */ #else /* !CONFIG_SMP */
EXPORT_SYMBOL(__flush_tlb_all); EXPORT_SYMBOL(__flush_tlb_all);
......
...@@ -34,8 +34,8 @@ union init_thread { ...@@ -34,8 +34,8 @@ union init_thread {
} s; } s;
unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)]; unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
} init_thread_union __attribute__((section(".data.init_task"))) = {{ } init_thread_union __attribute__((section(".data.init_task"))) = {{
task: INIT_TASK(init_thread_union.s.task), .task = INIT_TASK(init_thread_union.s.task),
thread_info: INIT_THREAD_INFO(init_thread_union.s.thread_info) .thread_info = INIT_THREAD_INFO(init_thread_union.s.thread_info)
}}; }};
asm (".global init_task; init_task = init_thread_union"); asm (".global init_task; init_task = init_thread_union");
...@@ -88,7 +88,7 @@ static struct { ...@@ -88,7 +88,7 @@ static struct {
static struct iosapic_irq { static struct iosapic_irq {
char *addr; /* base address of IOSAPIC */ char *addr; /* base address of IOSAPIC */
unsigned char base_irq; /* first irq assigned to this IOSAPIC */ unsigned int base_irq; /* first irq assigned to this IOSAPIC */
char pin; /* IOSAPIC pin (-1 => not an IOSAPIC irq) */ char pin; /* IOSAPIC pin (-1 => not an IOSAPIC irq) */
unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
unsigned char polarity : 1; /* interrupt polarity (see iosapic.h) */ unsigned char polarity : 1; /* interrupt polarity (see iosapic.h) */
...@@ -97,9 +97,9 @@ static struct iosapic_irq { ...@@ -97,9 +97,9 @@ static struct iosapic_irq {
static struct iosapic { static struct iosapic {
char *addr; /* base address of IOSAPIC */ char *addr; /* base address of IOSAPIC */
unsigned char pcat_compat; /* 8259 compatibility flag */ unsigned int base_irq; /* first irq assigned to this IOSAPIC */
unsigned char base_irq; /* first irq assigned to this IOSAPIC */
unsigned short max_pin; /* max input pin supported in this IOSAPIC */ unsigned short max_pin; /* max input pin supported in this IOSAPIC */
unsigned char pcat_compat; /* 8259 compatibility flag */
} iosapic_lists[256] __initdata; } iosapic_lists[256] __initdata;
static int num_iosapic = 0; static int num_iosapic = 0;
...@@ -322,14 +322,14 @@ iosapic_end_level_irq (unsigned int irq) ...@@ -322,14 +322,14 @@ iosapic_end_level_irq (unsigned int irq)
#define iosapic_ack_level_irq nop #define iosapic_ack_level_irq nop
struct hw_interrupt_type irq_type_iosapic_level = { struct hw_interrupt_type irq_type_iosapic_level = {
typename: "IO-SAPIC-level", .typename = "IO-SAPIC-level",
startup: iosapic_startup_level_irq, .startup = iosapic_startup_level_irq,
shutdown: iosapic_shutdown_level_irq, .shutdown = iosapic_shutdown_level_irq,
enable: iosapic_enable_level_irq, .enable = iosapic_enable_level_irq,
disable: iosapic_disable_level_irq, .disable = iosapic_disable_level_irq,
ack: iosapic_ack_level_irq, .ack = iosapic_ack_level_irq,
end: iosapic_end_level_irq, .end = iosapic_end_level_irq,
set_affinity: iosapic_set_affinity .set_affinity = iosapic_set_affinity
}; };
/* /*
...@@ -366,14 +366,14 @@ iosapic_ack_edge_irq (unsigned int irq) ...@@ -366,14 +366,14 @@ iosapic_ack_edge_irq (unsigned int irq)
#define iosapic_end_edge_irq nop #define iosapic_end_edge_irq nop
struct hw_interrupt_type irq_type_iosapic_edge = { struct hw_interrupt_type irq_type_iosapic_edge = {
typename: "IO-SAPIC-edge", .typename = "IO-SAPIC-edge",
startup: iosapic_startup_edge_irq, .startup = iosapic_startup_edge_irq,
shutdown: iosapic_disable_edge_irq, .shutdown = iosapic_disable_edge_irq,
enable: iosapic_enable_edge_irq, .enable = iosapic_enable_edge_irq,
disable: iosapic_disable_edge_irq, .disable = iosapic_disable_edge_irq,
ack: iosapic_ack_edge_irq, .ack = iosapic_ack_edge_irq,
end: iosapic_end_edge_irq, .end = iosapic_end_edge_irq,
set_affinity: iosapic_set_affinity .set_affinity = iosapic_set_affinity
}; };
unsigned int unsigned int
...@@ -422,6 +422,7 @@ register_irq (u32 global_vector, int vector, int pin, unsigned char delivery, ...@@ -422,6 +422,7 @@ register_irq (u32 global_vector, int vector, int pin, unsigned char delivery,
irq_desc_t *idesc; irq_desc_t *idesc;
struct hw_interrupt_type *irq_type; struct hw_interrupt_type *irq_type;
gsi_to_vector(global_vector) = vector;
iosapic_irq[vector].pin = pin; iosapic_irq[vector].pin = pin;
iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW; iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
iosapic_irq[vector].dmode = delivery; iosapic_irq[vector].dmode = delivery;
...@@ -640,7 +641,7 @@ iosapic_init_pci_irq (void) ...@@ -640,7 +641,7 @@ iosapic_init_pci_irq (void)
unsigned int irq; unsigned int irq;
char *addr; char *addr;
if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) if (acpi_get_prt(&pci_irq.route, &pci_irq.num_routes))
return; return;
for (i = 0; i < pci_irq.num_routes; i++) { for (i = 0; i < pci_irq.num_routes; i++) {
...@@ -679,11 +680,10 @@ iosapic_init_pci_irq (void) ...@@ -679,11 +680,10 @@ iosapic_init_pci_irq (void)
pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin, pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin,
iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector); iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector);
#endif #endif
/* /*
* Forget not to program the IOSAPIC RTE per ACPI _PRT * NOTE: The IOSAPIC RTE will be programmed in iosapic_pci_fixup(). It
* needs to be done there to ensure PCI hotplug works right.
*/ */
set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
} }
} }
......
...@@ -200,277 +200,12 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -200,277 +200,12 @@ int show_interrupts(struct seq_file *p, void *v)
return 0; return 0;
} }
#if CONFIG_SMP
/* inline void synchronize_irq(unsigned int irq)
* Global interrupt locks for SMP. Allow interrupts to come in on any
* CPU, yet make cli/sti act globally to protect critical regions..
*/
#ifdef CONFIG_SMP
unsigned int global_irq_holder = NO_PROC_ID;
unsigned volatile long global_irq_lock; /* pedantic: long for set_bit --RR */
extern void show_stack(unsigned long* esp);
static void show(char * str)
{
int i;
int cpu = smp_processor_id();
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: %d [",irqs_running());
for(i=0;i < NR_CPUS;i++)
printk(" %d",irq_count(i));
printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
for(i=0;i < NR_CPUS;i++)
printk(" %d",bh_count(i));
printk(" ]\nStack dumps:");
#if defined(CONFIG_IA64)
/*
* We can't unwind the stack of another CPU without access to
* the registers of that CPU. And sending an IPI when we're
* in a potentially wedged state doesn't sound like a smart
* idea.
*/
#elif defined(CONFIG_X86)
for(i=0;i< NR_CPUS;i++) {
unsigned long esp;
if(i==cpu)
continue;
printk("\nCPU %d:",i);
esp = init_tss[i].esp0;
if(esp==NULL) {
/* tss->esp0 is set to NULL in cpu_init(),
* it's initialized when the cpu returns to user
* space. -- manfreds
*/
printk(" <unknown> ");
continue;
}
esp &= ~(THREAD_SIZE-1);
esp += sizeof(struct task_struct);
show_stack((void*)esp);
}
#else
You lose...
#endif
printk("\nCPU %d:",cpu);
show_stack(NULL);
printk("\n");
}
#define MAXCOUNT 100000000
/*
* I had a lockup scenario where a tight loop doing
* spin_unlock()/spin_lock() on CPU#1 was racing with
* spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
* apparently the spin_unlock() information did not make it
* through to CPU#0 ... nasty, is this by design, do we have to limit
* 'memory update oscillation frequency' artificially like here?
*
* Such 'high frequency update' races can be avoided by careful design, but
* some of our major constructs like spinlocks use similar techniques,
* it would be nice to clarify this issue. Set this define to 0 if you
* want to check whether your system freezes. I suspect the delay done
* by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
* i thought that such things are guaranteed by design, since we use
* the 'LOCK' prefix.
*/
#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
# define SYNC_OTHER_CORES(x) udelay(x+1)
#else
/*
* We have to allow irqs to arrive between local_irq_enable and local_irq_disable
*/
# ifdef CONFIG_IA64
# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop 0")
# else
# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
# endif
#endif
static inline void wait_on_irq(void)
{
int count = MAXCOUNT;
for (;;) {
/*
* Wait until all interrupts are gone. Wait
* for bottom half handlers unless we're
* already executing in one..
*/
if (!irqs_running())
if (really_local_bh_count() || !spin_is_locked(&global_bh_lock))
break;
/* Duh, we have to loop. Release the lock to avoid deadlocks */
smp_mb__before_clear_bit(); /* need barrier before releasing lock... */
clear_bit(0,&global_irq_lock);
for (;;) {
if (!--count) {
show("wait_on_irq");
count = ~0;
}
local_irq_enable();
SYNC_OTHER_CORES(smp_processor_id());
local_irq_disable();
if (irqs_running())
continue;
if (global_irq_lock)
continue;
if (!really_local_bh_count() && spin_is_locked(&global_bh_lock))
continue;
if (!test_and_set_bit(0,&global_irq_lock))
break;
}
}
}
/*
* This is called when we want to synchronize with
* interrupts. We may for example tell a device to
* stop sending interrupts: but to make sure there
* are no interrupts that are executing on another
* CPU we need to call this function.
*/
void synchronize_irq(void)
{
if (irqs_running()) {
/* Stupid approach */
cli();
sti();
}
}
static inline void get_irqlock(void)
{
if (test_and_set_bit(0,&global_irq_lock)) {
/* do we already hold the lock? */
if (smp_processor_id() == global_irq_holder)
return;
/* Uhhuh.. Somebody else got it. Wait.. */
do {
do {
#ifdef CONFIG_X86
rep_nop();
#endif
} while (test_bit(0,&global_irq_lock));
} while (test_and_set_bit(0,&global_irq_lock));
}
/*
* We also to make sure that nobody else is running
* in an interrupt context.
*/
wait_on_irq();
/*
* Ok, finally..
*/
global_irq_holder = smp_processor_id();
}
#define EFLAGS_IF_SHIFT 9
/*
* A global "cli()" while in an interrupt context
* turns into just a local cli(). Interrupts
* should use spinlocks for the (very unlikely)
* case that they ever want to protect against
* each other.
*
* If we already have local interrupts disabled,
* this will not turn a local disable into a
* global one (problems with spinlocks: this makes
* save_flags+cli+sti usable inside a spinlock).
*/
void __global_cli(void)
{
unsigned int flags;
#ifdef CONFIG_IA64
local_save_flags(flags);
if (flags & IA64_PSR_I) {
local_irq_disable();
if (!really_local_irq_count())
get_irqlock();
}
#else
local_save_flags(flags);
if (flags & (1 << EFLAGS_IF_SHIFT)) {
local_irq_disable();
if (!really_local_irq_count())
get_irqlock();
}
#endif
}
void __global_sti(void)
{
if (!really_local_irq_count())
release_irqlock(smp_processor_id());
local_irq_enable();
}
/*
* SMP flags value to restore to:
* 0 - global cli
* 1 - global sti
* 2 - local cli
* 3 - local sti
*/
unsigned long __global_save_flags(void)
{
int retval;
int local_enabled;
unsigned long flags;
int cpu = smp_processor_id();
local_save_flags(flags);
#ifdef CONFIG_IA64
local_enabled = (flags & IA64_PSR_I) != 0;
#else
local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
#endif
/* default to local */
retval = 2 + local_enabled;
/* check for global flags if we're not in an interrupt */
if (!really_local_irq_count()) {
if (local_enabled)
retval = 1;
if (global_irq_holder == cpu)
retval = 0;
}
return retval;
}
void __global_restore_flags(unsigned long flags)
{ {
switch (flags) { while (irq_desc(irq)->status & IRQ_INPROGRESS)
case 0: cpu_relax();
__global_cli();
break;
case 1:
__global_sti();
break;
case 2:
local_irq_disable();
break;
case 3:
local_irq_enable();
break;
default:
printk("global_restore_flags: %08lx (%08lx)\n",
flags, (&flags)[-1]);
}
} }
#endif #endif
/* /*
...@@ -482,11 +217,7 @@ void __global_restore_flags(unsigned long flags) ...@@ -482,11 +217,7 @@ void __global_restore_flags(unsigned long flags)
*/ */
int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
{ {
int status; int status = 1; /* Force the "do bottom halves" bit */
local_irq_enter(irq);
status = 1; /* Force the "do bottom halves" bit */
if (!(action->flags & SA_INTERRUPT)) if (!(action->flags & SA_INTERRUPT))
local_irq_enable(); local_irq_enable();
...@@ -500,11 +231,16 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * ...@@ -500,11 +231,16 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction *
add_interrupt_randomness(irq); add_interrupt_randomness(irq);
local_irq_disable(); local_irq_disable();
local_irq_exit(irq);
return status; return status;
} }
/*
* Generic enable/disable code: this just calls
* down into the PIC-specific version for the actual
* hardware disable after having gotten the irq
* controller lock.
*/
/** /**
* disable_irq_nosync - disable an irq without waiting * disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable * @irq: Interrupt to disable
...@@ -546,14 +282,7 @@ inline void disable_irq_nosync(unsigned int irq) ...@@ -546,14 +282,7 @@ inline void disable_irq_nosync(unsigned int irq)
void disable_irq(unsigned int irq) void disable_irq(unsigned int irq)
{ {
disable_irq_nosync(irq); disable_irq_nosync(irq);
synchronize_irq(irq);
#ifdef CONFIG_SMP
if (!really_local_irq_count()) {
do {
barrier();
} while (irq_desc(irq)->status & IRQ_INPROGRESS);
}
#endif
} }
/** /**
...@@ -616,6 +345,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -616,6 +345,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
struct irqaction * action; struct irqaction * action;
unsigned int status; unsigned int status;
irq_enter();
kstat.irqs[cpu][irq]++; kstat.irqs[cpu][irq]++;
if (desc->status & IRQ_PER_CPU) { if (desc->status & IRQ_PER_CPU) {
...@@ -682,6 +412,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -682,6 +412,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
desc->handler->end(irq); desc->handler->end(irq);
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
} }
irq_exit();
return 1; return 1;
} }
...@@ -811,7 +542,7 @@ void free_irq(unsigned int irq, void *dev_id) ...@@ -811,7 +542,7 @@ void free_irq(unsigned int irq, void *dev_id)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Wait to make sure it's not being used on another CPU */ /* Wait to make sure it's not being used on another CPU */
while (desc->status & IRQ_INPROGRESS) while (desc->status & IRQ_INPROGRESS)
barrier(); synchronize_irq(irq);
#endif #endif
kfree(action); kfree(action);
return; return;
...@@ -864,7 +595,7 @@ unsigned long probe_irq_on(void) ...@@ -864,7 +595,7 @@ unsigned long probe_irq_on(void)
/* Wait for longstanding interrupts to trigger. */ /* Wait for longstanding interrupts to trigger. */
for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
/* about 20ms delay */ synchronize_irq(); /* about 20ms delay */ barrier();
/* /*
* enable any unassigned irqs * enable any unassigned irqs
...@@ -887,7 +618,7 @@ unsigned long probe_irq_on(void) ...@@ -887,7 +618,7 @@ unsigned long probe_irq_on(void)
* Wait for spurious interrupts to trigger * Wait for spurious interrupts to trigger
*/ */
for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
/* about 100ms delay */ synchronize_irq(); /* about 100ms delay */ barrier();
/* /*
* Now filter out any obviously spurious interrupts * Now filter out any obviously spurious interrupts
......
...@@ -36,6 +36,10 @@ ...@@ -36,6 +36,10 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#ifdef CONFIG_PERFMON
# include <asm/perfmon.h>
#endif
#define IRQ_DEBUG 0 #define IRQ_DEBUG 0
/* default base addr of IPI table */ /* default base addr of IPI table */
...@@ -50,6 +54,11 @@ __u8 isa_irq_to_vector_map[16] = { ...@@ -50,6 +54,11 @@ __u8 isa_irq_to_vector_map[16] = {
0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21
}; };
/*
* GSI to IA-64 vector translation table.
*/
__u8 gsi_to_vector_map[255];
int int
ia64_alloc_irq (void) ia64_alloc_irq (void)
{ {
...@@ -144,9 +153,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) ...@@ -144,9 +153,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs); extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
static struct irqaction ipi_irqaction = { static struct irqaction ipi_irqaction = {
handler: handle_IPI, .handler = handle_IPI,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "IPI" .name = "IPI"
}; };
#endif #endif
...@@ -172,6 +181,9 @@ init_IRQ (void) ...@@ -172,6 +181,9 @@ init_IRQ (void)
register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL); register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
#endif
#ifdef CONFIG_PERFMON
perfmon_init_percpu();
#endif #endif
platform_irq_init(); platform_irq_init();
} }
......
...@@ -27,12 +27,12 @@ lsapic_noop (unsigned int irq) ...@@ -27,12 +27,12 @@ lsapic_noop (unsigned int irq)
} }
struct hw_interrupt_type irq_type_ia64_lsapic = { struct hw_interrupt_type irq_type_ia64_lsapic = {
typename: "LSAPIC", .typename = "LSAPIC",
startup: lsapic_noop_startup, .startup = lsapic_noop_startup,
shutdown: lsapic_noop, .shutdown = lsapic_noop,
enable: lsapic_noop, .enable = lsapic_noop,
disable: lsapic_noop, .disable = lsapic_noop,
ack: lsapic_noop, .ack = lsapic_noop,
end: lsapic_noop, .end = lsapic_noop,
set_affinity: (void (*)(unsigned int, unsigned long)) lsapic_noop .set_affinity = (void (*)(unsigned int, unsigned long)) lsapic_noop
}; };
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
struct ia64_machine_vector ia64_mv; struct ia64_machine_vector ia64_mv;
/* /*
* Most platforms use this routine for mapping page frame addresses * Most platforms use this routine for mapping page frame addresses into a memory map
* into a memory map index. * index.
*
* Note: we can't use __pa() because map_nr_dense(X) MUST map to something >= max_mapnr if
* X is outside the identity mapped kernel space.
*/ */
unsigned long unsigned long
map_nr_dense (unsigned long addr) map_nr_dense (unsigned long addr)
{ {
return MAP_NR_DENSE(addr); return (addr - PAGE_OFFSET) >> PAGE_SHIFT;
} }
static struct ia64_machine_vector * static struct ia64_machine_vector *
......
...@@ -82,27 +82,27 @@ extern void ia64_slave_init_handler (void); ...@@ -82,27 +82,27 @@ extern void ia64_slave_init_handler (void);
extern struct hw_interrupt_type irq_type_iosapic_level; extern struct hw_interrupt_type irq_type_iosapic_level;
static struct irqaction cmci_irqaction = { static struct irqaction cmci_irqaction = {
handler: ia64_mca_cmc_int_handler, .handler = ia64_mca_cmc_int_handler,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "cmc_hndlr" .name = "cmc_hndlr"
}; };
static struct irqaction mca_rdzv_irqaction = { static struct irqaction mca_rdzv_irqaction = {
handler: ia64_mca_rendez_int_handler, .handler = ia64_mca_rendez_int_handler,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "mca_rdzv" .name = "mca_rdzv"
}; };
static struct irqaction mca_wkup_irqaction = { static struct irqaction mca_wkup_irqaction = {
handler: ia64_mca_wakeup_int_handler, .handler = ia64_mca_wakeup_int_handler,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "mca_wkup" .name = "mca_wkup"
}; };
static struct irqaction mca_cpe_irqaction = { static struct irqaction mca_cpe_irqaction = {
handler: ia64_mca_cpe_int_handler, .handler = ia64_mca_cpe_int_handler,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "cpe_hndlr" .name = "cpe_hndlr"
}; };
/* /*
...@@ -626,9 +626,12 @@ ia64_mca_wakeup_all(void) ...@@ -626,9 +626,12 @@ ia64_mca_wakeup_all(void)
void void
ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
{ {
int flags, cpu = 0; unsigned long flags;
int cpu = 0;
/* Mask all interrupts */ /* Mask all interrupts */
save_and_cli(flags); #warning XXX fix me: this used to be: save_and_cli(flags);
local_irq_save(flags);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
cpu = cpu_logical_id(hard_smp_processor_id()); cpu = cpu_logical_id(hard_smp_processor_id());
...@@ -646,7 +649,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) ...@@ -646,7 +649,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
ia64_mca_wakeup_ipi_wait(); ia64_mca_wakeup_ipi_wait();
/* Enable all interrupts */ /* Enable all interrupts */
restore_flags(flags); local_irq_restore(flags);
} }
......
...@@ -684,9 +684,9 @@ ia64_os_mca_tlb_error_check: ...@@ -684,9 +684,9 @@ ia64_os_mca_tlb_error_check:
movl r3=SAL_GET_STATE_INFO;; movl r3=SAL_GET_STATE_INFO;;
DATA_VA_TO_PA(r7);; // convert to physical address DATA_VA_TO_PA(r7);; // convert to physical address
ld8 r8=[r7],8;; // get pdesc function pointer ld8 r8=[r7],8;; // get pdesc function pointer
DATA_VA_TO_PA(r8) // convert to physical address dep r8=0,r8,61,3;; // convert SAL VA to PA
ld8 r1=[r7];; // set new (ia64_sal) gp ld8 r1=[r7];; // set new (ia64_sal) gp
DATA_VA_TO_PA(r1) // convert to physical address dep r1=0,r1,61,3;; // convert SAL VA to PA
mov b6=r8 mov b6=r8
alloc r5=ar.pfs,8,0,8,0;; // allocate stack frame for SAL call alloc r5=ar.pfs,8,0,8,0;; // allocate stack frame for SAL call
......
...@@ -165,7 +165,7 @@ struct pci_ops pci_sal_ops = { ...@@ -165,7 +165,7 @@ struct pci_ops pci_sal_ops = {
*/ */
struct pci_bus * struct pci_bus *
pcibios_scan_root(int seg, int bus) pcibios_scan_root(int bus)
{ {
struct list_head *list = NULL; struct list_head *list = NULL;
struct pci_bus *pci_bus = NULL; struct pci_bus *pci_bus = NULL;
...@@ -174,12 +174,12 @@ pcibios_scan_root(int seg, int bus) ...@@ -174,12 +174,12 @@ pcibios_scan_root(int seg, int bus)
pci_bus = pci_bus_b(list); pci_bus = pci_bus_b(list);
if (pci_bus->number == bus) { if (pci_bus->number == bus) {
/* Already scanned */ /* Already scanned */
printk("PCI: Bus (%02x:%02x) already probed\n", seg, bus); printk("PCI: Bus (%02x) already probed\n", bus);
return pci_bus; return pci_bus;
} }
} }
printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus); printk("PCI: Probing PCI hardware on bus (%02x)\n", bus);
return pci_scan_bus(bus, pci_root_ops, NULL); return pci_scan_bus(bus, pci_root_ops, NULL);
} }
...@@ -265,12 +265,37 @@ pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * r ...@@ -265,12 +265,37 @@ pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * r
int int
pcibios_enable_device (struct pci_dev *dev) pcibios_enable_device (struct pci_dev *dev)
{ {
u16 cmd, old_cmd;
int idx;
struct resource *r;
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
/* Not needed, since we enable all devices at startup. */ pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for (idx=0; idx<6; idx++) {
r = &dev->resource[idx];
if (!r->start && r->end) {
printk(KERN_ERR
"PCI: Device %s not available because of resource collisions\n",
dev->slot_name);
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
cmd |= PCI_COMMAND_IO;
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
if (dev->resource[PCI_ROM_RESOURCE].start)
cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name); printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
return 0; return 0;
} }
......
...@@ -106,6 +106,12 @@ ...@@ -106,6 +106,12 @@
#define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0) #define PFM_REG_RETFLAG_SET(flags, val) do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
#ifdef CONFIG_SMP
#define cpu_is_online(i) (cpu_online_map & (1UL << i))
#else
#define cpu_is_online(i) (i==0)
#endif
/* /*
* debugging * debugging
*/ */
...@@ -277,8 +283,8 @@ typedef struct { ...@@ -277,8 +283,8 @@ typedef struct {
typedef struct { typedef struct {
pfm_pmu_reg_type_t type; pfm_pmu_reg_type_t type;
int pm_pos; int pm_pos;
int (*read_check)(struct task_struct *task, unsigned int cnum, unsigned long *val); int (*read_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
int (*write_check)(struct task_struct *task, unsigned int cnum, unsigned long *val); int (*write_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
unsigned long dep_pmd[4]; unsigned long dep_pmd[4];
unsigned long dep_pmc[4]; unsigned long dep_pmc[4];
} pfm_reg_desc_t; } pfm_reg_desc_t;
...@@ -396,7 +402,7 @@ static unsigned long reset_pmcs[IA64_NUM_PMC_REGS]; /* contains PAL reset values ...@@ -396,7 +402,7 @@ static unsigned long reset_pmcs[IA64_NUM_PMC_REGS]; /* contains PAL reset values
static void pfm_vm_close(struct vm_area_struct * area); static void pfm_vm_close(struct vm_area_struct * area);
static struct vm_operations_struct pfm_vm_ops={ static struct vm_operations_struct pfm_vm_ops={
close: pfm_vm_close .close = pfm_vm_close
}; };
/* /*
...@@ -610,7 +616,7 @@ pfm_remove_smpl_mapping(struct task_struct *task) ...@@ -610,7 +616,7 @@ pfm_remove_smpl_mapping(struct task_struct *task)
down_write(&task->mm->mmap_sem); down_write(&task->mm->mmap_sem);
r = do_munmap(task->mm, ctx->ctx_smpl_vaddr, psb->psb_size); r = do_munmap(task->mm, ctx->ctx_smpl_vaddr, psb->psb_size, 0);
up_write(&task->mm->mmap_sem); up_write(&task->mm->mmap_sem);
if (r !=0) { if (r !=0) {
...@@ -902,8 +908,8 @@ pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx) ...@@ -902,8 +908,8 @@ pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
/* /*
* and it must be a valid CPU * and it must be a valid CPU
*/ */
cpu = ffs(pfx->ctx_cpu_mask); cpu = ffz(~pfx->ctx_cpu_mask);
if (!cpu_online(cpu)) { if (cpu_is_online(cpu) == 0) {
DBprintk(("CPU%d is not online\n", cpu)); DBprintk(("CPU%d is not online\n", cpu));
return -EINVAL; return -EINVAL;
} }
...@@ -925,11 +931,12 @@ pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx) ...@@ -925,11 +931,12 @@ pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
DBprintk(("must have notify_pid when blocking for [%d]\n", task->pid)); DBprintk(("must have notify_pid when blocking for [%d]\n", task->pid));
return -EINVAL; return -EINVAL;
} }
#if 0
if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == task->pid) { if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == task->pid) {
DBprintk(("cannot notify self when blocking for [%d]\n", task->pid)); DBprintk(("cannot notify self when blocking for [%d]\n", task->pid));
return -EINVAL; return -EINVAL;
} }
#endif
} }
/* probably more to add here */ /* probably more to add here */
...@@ -968,7 +975,7 @@ pfm_context_create(struct task_struct *task, pfm_context_t *ctx, void *req, int ...@@ -968,7 +975,7 @@ pfm_context_create(struct task_struct *task, pfm_context_t *ctx, void *req, int
if (ctx_flags & PFM_FL_SYSTEM_WIDE) { if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
/* at this point, we know there is at least one bit set */ /* at this point, we know there is at least one bit set */
cpu = ffs(tmp.ctx_cpu_mask) - 1; cpu = ffz(~tmp.ctx_cpu_mask);
DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id())); DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id()));
...@@ -1280,7 +1287,7 @@ pfm_write_pmcs(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun ...@@ -1280,7 +1287,7 @@ pfm_write_pmcs(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun
/* /*
* execute write checker, if any * execute write checker, if any
*/ */
if (PMC_WR_FUNC(cnum)) ret = PMC_WR_FUNC(cnum)(task, cnum, &tmp.reg_value); if (PMC_WR_FUNC(cnum)) ret = PMC_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
abort_mission: abort_mission:
if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL; if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
...@@ -1371,7 +1378,7 @@ pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun ...@@ -1371,7 +1378,7 @@ pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun
/* /*
* execute write checker, if any * execute write checker, if any
*/ */
if (PMD_WR_FUNC(cnum)) ret = PMD_WR_FUNC(cnum)(task, cnum, &tmp.reg_value); if (PMD_WR_FUNC(cnum)) ret = PMD_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
abort_mission: abort_mission:
if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL; if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
...@@ -1394,6 +1401,8 @@ pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun ...@@ -1394,6 +1401,8 @@ pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int coun
/* keep track of what we use */ /* keep track of what we use */
CTX_USED_PMD(ctx, pmu_conf.pmd_desc[(cnum)].dep_pmd[0]); CTX_USED_PMD(ctx, pmu_conf.pmd_desc[(cnum)].dep_pmd[0]);
/* mark this register as used as well */
CTX_USED_PMD(ctx, RDEP(cnum));
/* writes to unimplemented part is ignored, so this is safe */ /* writes to unimplemented part is ignored, so this is safe */
ia64_set_pmd(cnum, tmp.reg_value & pmu_conf.perf_ovfl_val); ia64_set_pmd(cnum, tmp.reg_value & pmu_conf.perf_ovfl_val);
...@@ -1438,7 +1447,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count ...@@ -1438,7 +1447,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count
DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid)); DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
for (i = 0; i < count; i++, req++) { for (i = 0; i < count; i++, req++) {
unsigned long reg_val = ~0UL, ctx_val = ~0UL; unsigned long ctx_val = ~0UL;
if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT; if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
...@@ -1462,7 +1471,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count ...@@ -1462,7 +1471,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count
*/ */
if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){ if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){
ia64_srlz_d(); ia64_srlz_d();
val = reg_val = ia64_get_pmd(cnum); val = ia64_get_pmd(cnum);
DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val)); DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
} else { } else {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -1484,7 +1493,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count ...@@ -1484,7 +1493,7 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count
} }
#endif #endif
/* context has been saved */ /* context has been saved */
val = reg_val = th->pmd[cnum]; val = th->pmd[cnum];
} }
if (PMD_IS_COUNTING(cnum)) { if (PMD_IS_COUNTING(cnum)) {
/* /*
...@@ -1493,8 +1502,6 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count ...@@ -1493,8 +1502,6 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count
val &= pmu_conf.perf_ovfl_val; val &= pmu_conf.perf_ovfl_val;
val += ctx_val = ctx->ctx_soft_pmds[cnum].val; val += ctx_val = ctx->ctx_soft_pmds[cnum].val;
} else {
val = reg_val = ia64_get_pmd(cnum);
} }
tmp.reg_value = val; tmp.reg_value = val;
...@@ -1503,14 +1510,13 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count ...@@ -1503,14 +1510,13 @@ pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count
* execute read checker, if any * execute read checker, if any
*/ */
if (PMD_RD_FUNC(cnum)) { if (PMD_RD_FUNC(cnum)) {
ret = PMD_RD_FUNC(cnum)(task, cnum, &tmp.reg_value); ret = PMD_RD_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
} }
PFM_REG_RETFLAG_SET(tmp.reg_flags, ret); PFM_REG_RETFLAG_SET(tmp.reg_flags, ret);
DBprintk(("read pmd[%u] ret=%d soft_pmd=0x%lx reg=0x%lx pmc=0x%lx\n", DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n",
cnum, ret, ctx_val, reg_val, cnum, ret, val, ia64_get_pmc(cnum)));
ia64_get_pmc(cnum)));
if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT; if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
} }
...@@ -1553,15 +1559,11 @@ pfm_use_debug_registers(struct task_struct *task) ...@@ -1553,15 +1559,11 @@ pfm_use_debug_registers(struct task_struct *task)
*/ */
if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1; if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1;
/*
* XXX: not pretty
*/
LOCK_PFS(); LOCK_PFS();
/* /*
* We only allow the use of debug registers when there is no system * We cannot allow setting breakpoints when system wide monitoring
* wide monitoring * sessions are using the debug registers.
* XXX: we could relax this by
*/ */
if (pfm_sessions.pfs_sys_use_dbregs> 0) if (pfm_sessions.pfs_sys_use_dbregs> 0)
ret = -1; ret = -1;
...@@ -1921,7 +1923,6 @@ typedef union { ...@@ -1921,7 +1923,6 @@ typedef union {
dbr_mask_reg_t dbr; dbr_mask_reg_t dbr;
} dbreg_t; } dbreg_t;
static int static int
pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs) pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs)
{ {
...@@ -1963,8 +1964,8 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru ...@@ -1963,8 +1964,8 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru
if (ctx->ctx_fl_system) { if (ctx->ctx_fl_system) {
/* we mark ourselves as owner of the debug registers */ /* we mark ourselves as owner of the debug registers */
ctx->ctx_fl_using_dbreg = 1; ctx->ctx_fl_using_dbreg = 1;
} else { DBprintk(("system-wide setting fl_using_dbreg for [%d]\n", task->pid));
if (ctx->ctx_fl_using_dbreg == 0) { } else if (first_time) {
ret= -EBUSY; ret= -EBUSY;
if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) { if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) {
DBprintk(("debug registers already in use for [%d]\n", task->pid)); DBprintk(("debug registers already in use for [%d]\n", task->pid));
...@@ -1973,6 +1974,7 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru ...@@ -1973,6 +1974,7 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru
/* we mark ourselves as owner of the debug registers */ /* we mark ourselves as owner of the debug registers */
ctx->ctx_fl_using_dbreg = 1; ctx->ctx_fl_using_dbreg = 1;
DBprintk(("setting fl_using_dbreg for [%d]\n", task->pid));
/* /*
* Given debug registers cannot be used for both debugging * Given debug registers cannot be used for both debugging
* and performance monitoring at the same time, we reuse * and performance monitoring at the same time, we reuse
...@@ -1980,10 +1982,18 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru ...@@ -1980,10 +1982,18 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru
*/ */
memset(task->thread.dbr, 0, sizeof(task->thread.dbr)); memset(task->thread.dbr, 0, sizeof(task->thread.dbr));
memset(task->thread.ibr, 0, sizeof(task->thread.ibr)); memset(task->thread.ibr, 0, sizeof(task->thread.ibr));
}
if (first_time) {
DBprintk(("[%d] clearing ibrs,dbrs\n", task->pid));
/* /*
* clear hardware registers to make sure we don't * clear hardware registers to make sure we don't
* pick up stale state * pick up stale state.
*
* for a system wide session, we do not use
* thread.dbr, thread.ibr because this process
* never leaves the current CPU and the state
* is shared by all processes running on it
*/ */
for (i=0; i < pmu_conf.num_ibrs; i++) { for (i=0; i < pmu_conf.num_ibrs; i++) {
ia64_set_ibr(i, 0UL); ia64_set_ibr(i, 0UL);
...@@ -1994,7 +2004,6 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru ...@@ -1994,7 +2004,6 @@ pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, stru
} }
ia64_srlz_d(); ia64_srlz_d();
} }
}
ret = -EFAULT; ret = -EFAULT;
...@@ -2361,9 +2370,9 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, ...@@ -2361,9 +2370,9 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6,
{ {
struct pt_regs *regs = (struct pt_regs *)&stack; struct pt_regs *regs = (struct pt_regs *)&stack;
struct task_struct *task = current; struct task_struct *task = current;
pfm_context_t *ctx = task->thread.pfm_context; pfm_context_t *ctx;
size_t sz; size_t sz;
int ret = -ESRCH, narg; int ret, narg;
/* /*
* reject any call if perfmon was disabled at initialization time * reject any call if perfmon was disabled at initialization time
...@@ -2393,6 +2402,8 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, ...@@ -2393,6 +2402,8 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6,
if (pid != current->pid) { if (pid != current->pid) {
ret = -ESRCH;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
task = find_task_by_pid(pid); task = find_task_by_pid(pid);
...@@ -2407,10 +2418,11 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, ...@@ -2407,10 +2418,11 @@ sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6,
ret = check_task_state(task); ret = check_task_state(task);
if (ret != 0) goto abort_call; if (ret != 0) goto abort_call;
} }
ctx = task->thread.pfm_context;
} }
} }
ctx = task->thread.pfm_context;
if (PFM_CMD_USE_CTX(cmd)) { if (PFM_CMD_USE_CTX(cmd)) {
ret = -EINVAL; ret = -EINVAL;
if (ctx == NULL) { if (ctx == NULL) {
...@@ -2953,11 +2965,6 @@ perfmon_interrupt (int irq, void *arg, struct pt_regs *regs) ...@@ -2953,11 +2965,6 @@ perfmon_interrupt (int irq, void *arg, struct pt_regs *regs)
static int static int
perfmon_proc_info(char *page) perfmon_proc_info(char *page)
{ {
#ifdef CONFIG_SMP
#define cpu_is_online(i) (cpu_online_map & (1UL << i))
#else
#define cpu_is_online(i) 1
#endif
char *p = page; char *p = page;
int i; int i;
...@@ -4118,9 +4125,9 @@ pfm_cleanup_notifiers(struct task_struct *task) ...@@ -4118,9 +4125,9 @@ pfm_cleanup_notifiers(struct task_struct *task)
} }
static struct irqaction perfmon_irqaction = { static struct irqaction perfmon_irqaction = {
handler: perfmon_interrupt, .handler = perfmon_interrupt,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "perfmon" .name = "perfmon"
}; };
...@@ -4150,11 +4157,6 @@ perfmon_init (void) ...@@ -4150,11 +4157,6 @@ perfmon_init (void)
pal_perf_mon_info_u_t pm_info; pal_perf_mon_info_u_t pm_info;
s64 status; s64 status;
register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
ia64_set_pmv(IA64_PERFMON_VECTOR);
ia64_srlz_d();
pmu_conf.pfm_is_disabled = 1; pmu_conf.pfm_is_disabled = 1;
printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n", printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n",
...@@ -4232,6 +4234,9 @@ __initcall(perfmon_init); ...@@ -4232,6 +4234,9 @@ __initcall(perfmon_init);
void void
perfmon_init_percpu (void) perfmon_init_percpu (void)
{ {
if (smp_processor_id() == 0)
register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
ia64_set_pmv(IA64_PERFMON_VECTOR); ia64_set_pmv(IA64_PERFMON_VECTOR);
ia64_srlz_d(); ia64_srlz_d();
} }
......
/*
* This file contains the Itanium PMU register description tables
* and pmc checker used by perfmon.c.
*
* Copyright (C) 2002 Hewlett Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
*/
#define RDEP(x) (1UL<<(x))
#ifndef CONFIG_ITANIUM
#error "This file is only valid when CONFIG_ITANIUM is defined"
#endif
static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
static pfm_reg_desc_t pmc_desc[256]={
/* pmc0 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc1 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc2 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc3 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc4 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc5 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc6 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc7 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc8 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc9 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc10 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, pfm_ita_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
{ PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
};
static pfm_reg_desc_t pmd_desc[256]={
/* pmd0 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
/* pmd1 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
/* pmd2 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
/* pmd3 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
/* pmd4 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
/* pmd5 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
/* pmd6 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
/* pmd7 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
/* pmd8 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd9 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
{ PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
};
static int
pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
{
pfm_context_t *ctx = task->thread.pfm_context;
int ret;
/*
* we must clear the (instruction) debug registers if pmc13.ta bit is cleared
* before they are written (fl_using_dbreg==0) to avoid picking up stale information.
*/
if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
/* don't mix debug with perfmon */
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
/*
* a count of 0 will mark the debug registers as in use and also
* ensure that they are properly cleared.
*/
ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
if (ret) return ret;
}
/*
* we must clear the (data) debug registers if pmc11.pt bit is cleared
* before they are written (fl_using_dbreg==0) to avoid picking up stale information.
*/
if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
/* don't mix debug with perfmon */
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
/*
* a count of 0 will mark the debug registers as in use and also
* ensure that they are properly cleared.
*/
ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
if (ret) return ret;
}
return 0;
}
/*
* This file contains the McKinley PMU register description tables
* and pmc checker used by perfmon.c.
*
* Copyright (C) 2002 Hewlett Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
*/
#define RDEP(x) (1UL<<(x))
#ifndef CONFIG_MCKINLEY
#error "This file is only valid when CONFIG_MCKINLEY is defined"
#endif
static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
static pfm_reg_desc_t pmc_desc[256]={
/* pmc0 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc1 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc2 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc3 */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc4 */ { PFM_REG_COUNTING, 6, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc5 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc6 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc7 */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc8 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc9 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc10 */ { PFM_REG_MONITOR, 4, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc14 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
/* pmc15 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
{ PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
};
static pfm_reg_desc_t pmd_desc[256]={
/* pmd0 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
/* pmd1 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
/* pmd2 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
/* pmd3 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
/* pmd4 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
/* pmd5 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
/* pmd6 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
/* pmd7 */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
/* pmd8 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd9 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
{ PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
};
static int
pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
{
struct thread_struct *th = &task->thread;
pfm_context_t *ctx = task->thread.pfm_context;
int ret = 0, check_case1 = 0;
unsigned long val8 = 0, val14 = 0, val13 = 0;
/*
* we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled
* before they are written (fl_using_dbreg==0) to avoid picking up stale information.
*/
if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) {
/* don't mix debug with perfmon */
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
/*
* a count of 0 will mark the debug registers as in use and also
* ensure that they are properly cleared.
*/
ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
if (ret) return ret;
}
/*
* we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
* before they are (fl_using_dbreg==0) to avoid picking up stale information.
*/
if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) {
/* don't mix debug with perfmon */
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
/*
* a count of 0 will mark the debug registers as in use and also
* ensure that they are properly cleared.
*/
ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
if (ret) return ret;
}
switch(cnum) {
case 4: *val |= 1UL << 23; /* force power enable bit */
break;
case 8: val8 = *val;
val13 = th->pmc[13];
val14 = th->pmc[14];
check_case1 = 1;
break;
case 13: val8 = th->pmc[8];
val13 = *val;
val14 = th->pmc[14];
check_case1 = 1;
break;
case 14: val8 = th->pmc[13];
val13 = th->pmc[13];
val14 = *val;
check_case1 = 1;
break;
}
/* check illegal configuration which can produce inconsistencies in tagging
* i-side events in L1D and L2 caches
*/
if (check_case1) {
ret = ((val13 >> 45) & 0xf) == 0
&& ((val8 & 0x1) == 0)
&& ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
if (ret) printk("perfmon: failure check_case1\n");
}
return ret ? -EINVAL : 0;
}
...@@ -325,6 +325,11 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -325,6 +325,11 @@ copy_thread (int nr, unsigned long clone_flags,
/* copy parts of thread_struct: */ /* copy parts of thread_struct: */
p->thread.ksp = (unsigned long) child_stack - 16; p->thread.ksp = (unsigned long) child_stack - 16;
/* stop some PSR bits from being inherited: */
child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
& ~IA64_PSR_BITS_TO_CLEAR);
/* /*
* NOTE: The calling convention considers all floating point * NOTE: The calling convention considers all floating point
* registers in the high partition (fph) to be scratch. Since * registers in the high partition (fph) to be scratch. Since
......
...@@ -436,7 +436,7 @@ static void * ...@@ -436,7 +436,7 @@ static void *
c_start (struct seq_file *m, loff_t *pos) c_start (struct seq_file *m, loff_t *pos)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
while (*pos < NR_CPUS && !(cpu_online_map & (1 << *pos))) while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
++*pos; ++*pos;
#endif #endif
return *pos < NR_CPUS ? cpu_data(*pos) : NULL; return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
...@@ -455,10 +455,10 @@ c_stop (struct seq_file *m, void *v) ...@@ -455,10 +455,10 @@ c_stop (struct seq_file *m, void *v)
} }
struct seq_operations cpuinfo_op = { struct seq_operations cpuinfo_op = {
start: c_start, .start = c_start,
next: c_next, .next = c_next,
stop: c_stop, .stop = c_stop,
show: show_cpuinfo .show = show_cpuinfo
}; };
void void
...@@ -542,7 +542,18 @@ cpu_init (void) ...@@ -542,7 +542,18 @@ cpu_init (void)
extern char __per_cpu_end[]; extern char __per_cpu_end[];
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (__per_cpu_end - __per_cpu_start > PAGE_SIZE)
panic("Per-cpu data area too big! (%Zu > %Zu)",
__per_cpu_end - __per_cpu_start, PAGE_SIZE);
/*
* On the BSP, the page allocator isn't initialized by the time we get here. On
* the APs, the bootmem allocator is no longer available...
*/
if (cpu == 0)
my_cpu_data = alloc_bootmem_pages(__per_cpu_end - __per_cpu_start); my_cpu_data = alloc_bootmem_pages(__per_cpu_end - __per_cpu_start);
else
my_cpu_data = (void *) get_free_page(GFP_KERNEL);
memcpy(my_cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); memcpy(my_cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
__per_cpu_offset[cpu] = (char *) my_cpu_data - __per_cpu_start; __per_cpu_offset[cpu] = (char *) my_cpu_data - __per_cpu_start;
my_cpu_info = my_cpu_data + ((char *) &cpu_info - __per_cpu_start); my_cpu_info = my_cpu_data + ((char *) &cpu_info - __per_cpu_start);
......
...@@ -146,6 +146,7 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from) ...@@ -146,6 +146,7 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
if (from->si_code < 0) { if (from->si_code < 0) {
if (__copy_to_user(to, from, sizeof(siginfo_t))) if (__copy_to_user(to, from, sizeof(siginfo_t)))
return -EFAULT; return -EFAULT;
return 0;
} else { } else {
int err; int err;
......
/* /*
* SMP boot-related support * SMP boot-related support
* *
* Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com> * Copyright (C) 1998-2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* *
* 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here. * 01/05/16 Rohit Seth <rohit.seth@intel.com> Moved SMP booting functions from smp.c to here.
* 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code. * 01/04/27 David Mosberger <davidm@hpl.hp.com> Added ITC synching code.
* 02/07/31 David Mosberger <davidm@hpl.hp.com> Switch over to hotplug-CPU boot-sequence.
* smp_boot_cpus()/smp_commence() is replaced by
* smp_prepare_cpus()/__cpu_up()/smp_cpus_done().
*/ */
...@@ -66,18 +70,16 @@ static volatile unsigned long go[SLAVE + 1]; ...@@ -66,18 +70,16 @@ static volatile unsigned long go[SLAVE + 1];
#define DEBUG_ITC_SYNC 0 #define DEBUG_ITC_SYNC 0
extern void __init calibrate_delay(void); extern void __init calibrate_delay (void);
extern void start_ap(void); extern void start_ap (void);
extern unsigned long ia64_iobase; extern unsigned long ia64_iobase;
int cpucount; int cpucount;
task_t *task_for_booting_cpu; task_t *task_for_booting_cpu;
/* Setup configured maximum number of CPUs to activate */
static int max_cpus = -1;
/* Bitmask of currently online CPUs */ /* Bitmask of currently online CPUs */
volatile unsigned long cpu_online_map; volatile unsigned long cpu_online_map;
unsigned long phys_cpu_present_map;
/* which logical CPU number maps to which CPU (physical APIC ID) */ /* which logical CPU number maps to which CPU (physical APIC ID) */
volatile int ia64_cpu_to_sapicid[NR_CPUS]; volatile int ia64_cpu_to_sapicid[NR_CPUS];
...@@ -86,44 +88,12 @@ static volatile unsigned long cpu_callin_map; ...@@ -86,44 +88,12 @@ static volatile unsigned long cpu_callin_map;
struct smp_boot_data smp_boot_data __initdata; struct smp_boot_data smp_boot_data __initdata;
/* Set when the idlers are all forked */
volatile int smp_threads_ready;
unsigned long ap_wakeup_vector = -1; /* External Int use to wakeup APs */ unsigned long ap_wakeup_vector = -1; /* External Int use to wakeup APs */
char __initdata no_int_routing; char __initdata no_int_routing;
unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */ unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
/*
* Setup routine for controlling SMP activation
*
* Command-line option of "nosmp" or "maxcpus=0" will disable SMP
* activation entirely (the MPS table probe still happens, though).
*
* Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
* greater than 0, limits the maximum number of CPUs activated in
* SMP mode to <NUM>.
*/
static int __init
nosmp (char *str)
{
max_cpus = 0;
return 1;
}
__setup("nosmp", nosmp);
static int __init
maxcpus (char *str)
{
get_option(&str, &max_cpus);
return 1;
}
__setup("maxcpus=", maxcpus);
static int __init static int __init
nointroute (char *str) nointroute (char *str)
{ {
...@@ -299,7 +269,7 @@ smp_setup_percpu_timer (void) ...@@ -299,7 +269,7 @@ smp_setup_percpu_timer (void)
static volatile atomic_t smp_commenced = ATOMIC_INIT(0); static volatile atomic_t smp_commenced = ATOMIC_INIT(0);
void __init static void __init
smp_commence (void) smp_commence (void)
{ {
/* /*
...@@ -308,7 +278,7 @@ smp_commence (void) ...@@ -308,7 +278,7 @@ smp_commence (void)
Dprintk("Setting commenced=1, go go go\n"); Dprintk("Setting commenced=1, go go go\n");
wmb(); wmb();
atomic_set(&smp_commenced,1); atomic_set(&smp_commenced, 1);
} }
...@@ -405,6 +375,9 @@ do_boot_cpu (int sapicid) ...@@ -405,6 +375,9 @@ do_boot_cpu (int sapicid)
int timeout, cpu; int timeout, cpu;
cpu = ++cpucount; cpu = ++cpucount;
set_bit(cpu, &phys_cpu_present_map);
/* /*
* We can't use kernel_thread since we must avoid to * We can't use kernel_thread since we must avoid to
* reschedule the child. * reschedule the child.
...@@ -425,7 +398,7 @@ do_boot_cpu (int sapicid) ...@@ -425,7 +398,7 @@ do_boot_cpu (int sapicid)
task_for_booting_cpu = idle; task_for_booting_cpu = idle;
Dprintk("Sending wakeup vector %u to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid); Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
...@@ -466,8 +439,8 @@ smp_tune_scheduling (void) ...@@ -466,8 +439,8 @@ smp_tune_scheduling (void)
/* /*
* Cycle through the APs sending Wakeup IPIs to boot each. * Cycle through the APs sending Wakeup IPIs to boot each.
*/ */
void __init static void __init
smp_boot_cpus (void) smp_boot_cpus (unsigned int max_cpus)
{ {
int sapicid, cpu; int sapicid, cpu;
int boot_cpu_id = hard_smp_processor_id(); int boot_cpu_id = hard_smp_processor_id();
...@@ -486,13 +459,13 @@ smp_boot_cpus (void) ...@@ -486,13 +459,13 @@ smp_boot_cpus (void)
*/ */
set_bit(0, &cpu_online_map); set_bit(0, &cpu_online_map);
set_bit(0, &cpu_callin_map); set_bit(0, &cpu_callin_map);
set_bit(0, &phys_cpu_present_map);
local_cpu_data->loops_per_jiffy = loops_per_jiffy; local_cpu_data->loops_per_jiffy = loops_per_jiffy;
ia64_cpu_to_sapicid[0] = boot_cpu_id; ia64_cpu_to_sapicid[0] = boot_cpu_id;
printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id); printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
global_irq_holder = NO_PROC_ID;
current_thread_info()->cpu = 0; current_thread_info()->cpu = 0;
smp_tune_scheduling(); smp_tune_scheduling();
...@@ -537,11 +510,11 @@ smp_boot_cpus (void) ...@@ -537,11 +510,11 @@ smp_boot_cpus (void)
printk("Before bogomips.\n"); printk("Before bogomips.\n");
if (!cpucount) { if (!cpucount) {
printk(KERN_ERR "Error: only one processor found.\n"); printk(KERN_WARNING "Warning: only one processor found.\n");
} else { } else {
unsigned long bogosum = 0; unsigned long bogosum = 0;
for (cpu = 0; cpu < NR_CPUS; cpu++) for (cpu = 0; cpu < NR_CPUS; cpu++)
if (cpu_online_map & (1<<cpu)) if (cpu_online_map & (1UL << cpu))
bogosum += cpu_data(cpu)->loops_per_jiffy; bogosum += cpu_data(cpu)->loops_per_jiffy;
printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n", printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
...@@ -552,6 +525,29 @@ smp_boot_cpus (void) ...@@ -552,6 +525,29 @@ smp_boot_cpus (void)
; ;
} }
void __init
smp_prepare_cpus (unsigned int max_cpus)
{
smp_boot_cpus(max_cpus);
}
int __devinit
__cpu_up (unsigned int cpu)
{
/*
* Yeah, that's cheesy, but it will do until there is real hotplug support and in
* the meantime, this gives time for the interface changes to settle down...
*/
smp_commence();
return 0;
}
void __init
smp_cpus_done (unsigned int max_cpus)
{
/* nuthing... */
}
/* /*
* Assume that CPU's have been discovered by some platform-dependant interface. For * Assume that CPU's have been discovered by some platform-dependant interface. For
* SoftSDV/Lion, that would be ACPI. * SoftSDV/Lion, that would be ACPI.
...@@ -571,9 +567,6 @@ init_smp_config(void) ...@@ -571,9 +567,6 @@ init_smp_config(void)
ap_startup = (struct fptr *) start_ap; ap_startup = (struct fptr *) start_ap;
sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
__pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0); __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
if (sal_ret < 0) { if (sal_ret < 0)
printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n", printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n", ia64_sal_strerror(sal_ret));
ia64_sal_strerror(sal_ret));
max_cpus = 0;
}
} }
...@@ -82,7 +82,6 @@ asmlinkage unsigned long ...@@ -82,7 +82,6 @@ asmlinkage unsigned long
ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6, ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6,
long arg7, long stack) long arg7, long stack)
{ {
extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr);
struct pt_regs *regs = (struct pt_regs *) &stack; struct pt_regs *regs = (struct pt_regs *) &stack;
unsigned long raddr; unsigned long raddr;
int retval; int retval;
...@@ -120,7 +119,7 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, ...@@ -120,7 +119,7 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3,
/* Always allow shrinking brk. */ /* Always allow shrinking brk. */
if (brk <= mm->brk) { if (brk <= mm->brk) {
if (!do_munmap(mm, newbrk, oldbrk-newbrk)) if (!do_munmap(mm, newbrk, oldbrk-newbrk, 1))
goto set_brk; goto set_brk;
goto out; goto out;
} }
...@@ -138,10 +137,6 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, ...@@ -138,10 +137,6 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3,
if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
goto out; goto out;
/* Check if we have enough memory.. */
if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT))
goto out;
/* Ok, looks good - let it rip. */ /* Ok, looks good - let it rip. */
if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
goto out; goto out;
......
...@@ -41,10 +41,12 @@ do_profile (unsigned long ip) ...@@ -41,10 +41,12 @@ do_profile (unsigned long ip)
extern unsigned long prof_cpu_mask; extern unsigned long prof_cpu_mask;
extern char _stext; extern char _stext;
if (!prof_buffer)
return;
if (!((1UL << smp_processor_id()) & prof_cpu_mask)) if (!((1UL << smp_processor_id()) & prof_cpu_mask))
return; return;
if (prof_buffer && current->pid) {
ip -= (unsigned long) &_stext; ip -= (unsigned long) &_stext;
ip >>= prof_shift; ip >>= prof_shift;
/* /*
...@@ -55,7 +57,6 @@ do_profile (unsigned long ip) ...@@ -55,7 +57,6 @@ do_profile (unsigned long ip)
ip = prof_len - 1; ip = prof_len - 1;
atomic_inc((atomic_t *) &prof_buffer[ip]); atomic_inc((atomic_t *) &prof_buffer[ip]);
}
} }
/* /*
...@@ -285,9 +286,9 @@ ia64_init_itm (void) ...@@ -285,9 +286,9 @@ ia64_init_itm (void)
} }
static struct irqaction timer_irqaction = { static struct irqaction timer_irqaction = {
handler: timer_interrupt, .handler = timer_interrupt,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "timer" .name = "timer"
}; };
void __init void __init
......
...@@ -62,14 +62,14 @@ trap_init (void) ...@@ -62,14 +62,14 @@ trap_init (void)
void void
bust_spinlocks (int yes) bust_spinlocks (int yes)
{ {
int loglevel_save = console_loglevel;
spin_lock_init(&timerlist_lock); spin_lock_init(&timerlist_lock);
if (yes) { if (yes) {
oops_in_progress = 1; oops_in_progress = 1;
#ifdef CONFIG_SMP return;
global_irq_lock = 0; /* Many serial drivers do __global_cli() */ }
#endif
} else {
int loglevel_save = console_loglevel;
#ifdef CONFIG_VT #ifdef CONFIG_VT
unblank_screen(); unblank_screen();
#endif #endif
...@@ -82,7 +82,6 @@ bust_spinlocks (int yes) ...@@ -82,7 +82,6 @@ bust_spinlocks (int yes)
console_loglevel = 15; /* NMI oopser may have shut the console up */ console_loglevel = 15; /* NMI oopser may have shut the console up */
printk(" "); printk(" ");
console_loglevel = loglevel_save; console_loglevel = loglevel_save;
}
} }
void void
...@@ -93,9 +92,9 @@ die (const char *str, struct pt_regs *regs, long err) ...@@ -93,9 +92,9 @@ die (const char *str, struct pt_regs *regs, long err)
int lock_owner; int lock_owner;
int lock_owner_depth; int lock_owner_depth;
} die = { } die = {
lock: SPIN_LOCK_UNLOCKED, .lock = SPIN_LOCK_UNLOCKED,
lock_owner: -1, .lock_owner = -1,
lock_owner_depth: 0 .lock_owner_depth = 0
}; };
if (die.lock_owner != smp_processor_id()) { if (die.lock_owner != smp_processor_id()) {
...@@ -435,7 +434,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -435,7 +434,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
unsigned long code, error = isr; unsigned long code, error = isr;
struct siginfo siginfo; struct siginfo siginfo;
char buf[128]; char buf[128];
int result; int result, sig;
static const char *reason[] = { static const char *reason[] = {
"IA-64 Illegal Operation fault", "IA-64 Illegal Operation fault",
"IA-64 Privileged Operation fault", "IA-64 Privileged Operation fault",
...@@ -479,6 +478,30 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -479,6 +478,30 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
break; break;
case 26: /* NaT Consumption */ case 26: /* NaT Consumption */
if (user_mode(regs)) {
if (((isr >> 4) & 0xf) == 2) {
/* NaT page consumption */
sig = SIGSEGV;
code = SEGV_ACCERR;
} else {
/* register NaT consumption */
sig = SIGILL;
code = ILL_ILLOPN;
}
siginfo.si_signo = sig;
siginfo.si_code = code;
siginfo.si_errno = 0;
siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
siginfo.si_imm = vector;
siginfo.si_flags = __ISR_VALID;
siginfo.si_isr = isr;
force_sig_info(sig, &siginfo, current);
return;
} else if (done_with_exception(regs))
return;
sprintf(buf, "NaT consumption");
break;
case 31: /* Unsupported Data Reference */ case 31: /* Unsupported Data Reference */
if (user_mode(regs)) { if (user_mode(regs)) {
siginfo.si_signo = SIGILL; siginfo.si_signo = SIGILL;
...@@ -491,7 +514,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -491,7 +514,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
force_sig_info(SIGILL, &siginfo, current); force_sig_info(SIGILL, &siginfo, current);
return; return;
} }
sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference"); sprintf(buf, "Unsupported data reference");
break; break;
case 29: /* Debug */ case 29: /* Debug */
...@@ -508,16 +531,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, ...@@ -508,16 +531,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
if (ia64_psr(regs)->is == 0) if (ia64_psr(regs)->is == 0)
ifa = regs->cr_iip; ifa = regs->cr_iip;
#endif #endif
siginfo.si_addr = (void *) ifa;
break; break;
case 35: siginfo.si_code = TRAP_BRANCH; break; case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
case 36: siginfo.si_code = TRAP_TRACE; break; case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
} }
siginfo.si_signo = SIGTRAP; siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0; siginfo.si_errno = 0;
siginfo.si_flags = 0; siginfo.si_flags = 0;
siginfo.si_isr = 0; siginfo.si_isr = 0;
siginfo.si_addr = 0; siginfo.si_addr = (void *) ifa;
siginfo.si_imm = 0; siginfo.si_imm = 0;
force_sig_info(SIGTRAP, &siginfo, current); force_sig_info(SIGTRAP, &siginfo, current);
return; return;
......
...@@ -140,13 +140,13 @@ static struct { ...@@ -140,13 +140,13 @@ static struct {
} stat; } stat;
# endif # endif
} unw = { } unw = {
tables: &unw.kernel_table, .tables = &unw.kernel_table,
lock: SPIN_LOCK_UNLOCKED, .lock = SPIN_LOCK_UNLOCKED,
save_order: { .save_order = {
UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
}, },
preg_index: { .preg_index = {
struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */ struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */
struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */ struct_offset(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */
struct_offset(struct unw_frame_info, bsp_loc)/8, struct_offset(struct unw_frame_info, bsp_loc)/8,
...@@ -189,9 +189,9 @@ static struct { ...@@ -189,9 +189,9 @@ static struct {
struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8, struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8,
struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8, struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8,
}, },
hash : { [0 ... UNW_HASH_SIZE - 1] = -1 }, .hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
#if UNW_DEBUG #if UNW_DEBUG
preg_name: { .preg_name = {
"pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp", "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
"r4", "r5", "r6", "r7", "r4", "r5", "r6", "r7",
"ar.unat", "pr", "ar.lc", "ar.fpsr", "ar.unat", "pr", "ar.lc", "ar.fpsr",
...@@ -634,8 +634,8 @@ alloc_spill_area (unsigned long *offp, unsigned long regsize, ...@@ -634,8 +634,8 @@ alloc_spill_area (unsigned long *offp, unsigned long regsize,
for (reg = hi; reg >= lo; --reg) { for (reg = hi; reg >= lo; --reg) {
if (reg->where == UNW_WHERE_SPILL_HOME) { if (reg->where == UNW_WHERE_SPILL_HOME) {
reg->where = UNW_WHERE_PSPREL; reg->where = UNW_WHERE_PSPREL;
reg->val = 0x10 - *offp; *offp -= regsize;
*offp += regsize; reg->val = *offp;
} }
} }
} }
...@@ -814,7 +814,8 @@ desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *s ...@@ -814,7 +814,8 @@ desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *s
} }
for (i = 0; i < 20; ++i) { for (i = 0; i < 20; ++i) {
if ((frmask & 1) != 0) { if ((frmask & 1) != 0) {
set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME, int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4;
set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
sr->region_start + sr->region_len - 1, 0); sr->region_start + sr->region_len - 1, 0);
sr->any_spills = 1; sr->any_spills = 1;
} }
......
...@@ -9,40 +9,48 @@ export-objs := swiotlb.o ...@@ -9,40 +9,48 @@ export-objs := swiotlb.o
obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \
checksum.o clear_page.o csum_partial_copy.o copy_page.o \ checksum.o clear_page.o csum_partial_copy.o copy_page.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
flush.o io.o ip_fast_csum.o do_csum.o \ flush.o io.o ip_fast_csum.o do_csum.o \
memcpy.o memset.o strlen.o swiotlb.o memset.o strlen.o swiotlb.o
obj-$(CONFIG_ITANIUM) += copy_page.o obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
obj-$(CONFIG_MCKINLEY) += copy_page_mck.o obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
$(L_TARGET): $(obj-y) $(export-objs) include $(TOPDIR)/Rules.make
AFLAGS___divdi3.o =
AFLAGS___udivdi3.o = -DUNSIGNED
AFLAGS___moddi3.o = -DMODULO
AFLAGS___umoddi3.o = -DUNSIGNED -DMODULO
AFLAGS___divsi3.o =
AFLAGS___udivsi3.o = -DUNSIGNED
AFLAGS___modsi3.o = -DMODULO
AFLAGS___umodsi3.o = -DUNSIGNED -DMODULO
__divdi3.o: idiv64.S __divdi3.o: idiv64.S
$(CC) $(AFLAGS) -c -o $@ $< $(cmd_as_o_S)
__udivdi3.o: idiv64.S __udivdi3.o: idiv64.S
$(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< $(cmd_as_o_S)
__moddi3.o: idiv64.S __moddi3.o: idiv64.S
$(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< $(cmd_as_o_S)
__umoddi3.o: idiv64.S __umoddi3.o: idiv64.S
$(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< $(cmd_as_o_S)
__divsi3.o: idiv32.S __divsi3.o: idiv32.S
$(CC) $(AFLAGS) -c -o $@ $< $(cmd_as_o_S)
__udivsi3.o: idiv32.S __udivsi3.o: idiv32.S
$(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< $(cmd_as_o_S)
__modsi3.o: idiv32.S __modsi3.o: idiv32.S
$(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< $(cmd_as_o_S)
__umodsi3.o: idiv32.S __umodsi3.o: idiv32.S
$(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< $(cmd_as_o_S)
include $(TOPDIR)/Rules.make
...@@ -237,15 +237,17 @@ GLOBAL_ENTRY(__copy_user) ...@@ -237,15 +237,17 @@ GLOBAL_ENTRY(__copy_user)
.copy_user_bit##rshift: \ .copy_user_bit##rshift: \
1: \ 1: \
EX(.failure_out,(EPI) st8 [dst1]=tmp,8); \ EX(.failure_out,(EPI) st8 [dst1]=tmp,8); \
(EPI_1) shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift; \ (EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift; \
EX(3f,(p16) ld8 val1[0]=[src1],8); \ EX(3f,(p16) ld8 val1[1]=[src1],8); \
(p16) mov val1[0]=r0; \
br.ctop.dptk 1b; \ br.ctop.dptk 1b; \
;; \ ;; \
br.cond.sptk.many .diff_align_do_tail; \ br.cond.sptk.many .diff_align_do_tail; \
2: \ 2: \
(EPI) st8 [dst1]=tmp,8; \ (EPI) st8 [dst1]=tmp,8; \
(EPI_1) shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift; \ (EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift; \
3: \ 3: \
(p16) mov val1[1]=r0; \
(p16) mov val1[0]=r0; \ (p16) mov val1[0]=r0; \
br.ctop.dptk 2b; \ br.ctop.dptk 2b; \
;; \ ;; \
......
...@@ -87,6 +87,12 @@ ia64_outl (unsigned int val, unsigned long port) ...@@ -87,6 +87,12 @@ ia64_outl (unsigned int val, unsigned long port)
__ia64_outl(val, port); __ia64_outl(val, port);
} }
void
ia64_mmiob (void)
{
__ia64_mmiob();
}
/* define aliases: */ /* define aliases: */
asm (".global __ia64_inb, __ia64_inw, __ia64_inl"); asm (".global __ia64_inb, __ia64_inw, __ia64_inl");
...@@ -99,4 +105,7 @@ asm ("__ia64_outb = ia64_outb"); ...@@ -99,4 +105,7 @@ asm ("__ia64_outb = ia64_outb");
asm ("__ia64_outw = ia64_outw"); asm ("__ia64_outw = ia64_outw");
asm ("__ia64_outl = ia64_outl"); asm ("__ia64_outl = ia64_outl");
asm (".global __ia64_mmiob");
asm ("__ia64_mmiob = ia64_mmiob");
#endif /* CONFIG_IA64_GENERIC */ #endif /* CONFIG_IA64_GENERIC */
This diff is collapsed.
...@@ -415,18 +415,21 @@ int ...@@ -415,18 +415,21 @@ int
swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
{ {
void *addr; void *addr;
unsigned long pci_addr;
int i; int i;
if (direction == PCI_DMA_NONE) if (direction == PCI_DMA_NONE)
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) { for (i = 0; i < nelems; i++, sg++) {
sg->orig_address = SG_ENT_VIRT_ADDRESS(sg); addr = SG_ENT_VIRT_ADDRESS(sg);
if ((SG_ENT_PHYS_ADDRESS(sg) & ~hwdev->dma_mask) != 0) { pci_addr = virt_to_phys(addr);
addr = map_single(hwdev, sg->orig_address, sg->length, direction); if ((pci_addr & ~hwdev->dma_mask) != 0)
sg->page = virt_to_page(addr); sg->dma_address = (dma_addr_t)
sg->offset = (u64) addr & ~PAGE_MASK; map_single(hwdev, addr, sg->length, direction);
} else
sg->dma_address = pci_addr;
sg->dma_length = sg->length;
} }
return nelems; return nelems;
} }
...@@ -444,12 +447,10 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int ...@@ -444,12 +447,10 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg)) { if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
unmap_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction); unmap_single(hwdev, (void *) sg->dma_address, sg->dma_length, direction);
sg->page = virt_to_page(sg->orig_address); else if (direction == PCI_DMA_FROMDEVICE)
sg->offset = (u64) sg->orig_address & ~PAGE_MASK; mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
} else if (direction == PCI_DMA_FROMDEVICE)
mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->length);
} }
/* /*
...@@ -468,14 +469,14 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int ...@@ -468,14 +469,14 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int
BUG(); BUG();
for (i = 0; i < nelems; i++, sg++) for (i = 0; i < nelems; i++, sg++)
if (sg->orig_address != SG_ENT_VIRT_ADDRESS(sg)) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, direction); sync_single(hwdev, (void *) sg->dma_address, sg->dma_length, direction);
} }
unsigned long unsigned long
swiotlb_dma_address (struct scatterlist *sg) swiotlb_dma_address (struct scatterlist *sg)
{ {
return SG_ENT_PHYS_ADDRESS(sg); return sg->dma_address;
} }
/* /*
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/personality.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/swap.h> #include <linux/swap.h>
...@@ -68,10 +69,9 @@ ia64_init_addr_space (void) ...@@ -68,10 +69,9 @@ ia64_init_addr_space (void)
struct vm_area_struct *vma; struct vm_area_struct *vma;
/* /*
* If we're out of memory and kmem_cache_alloc() returns NULL, * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
* we simply ignore the problem. When the process attempts to * the problem. When the process attempts to write to the register backing store
* write to the register backing store for the first time, it * for the first time, it will get a SEGFAULT in this case.
* will get a SEGFAULT in this case.
*/ */
vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (vma) { if (vma) {
...@@ -86,6 +86,19 @@ ia64_init_addr_space (void) ...@@ -86,6 +86,19 @@ ia64_init_addr_space (void)
vma->vm_private_data = NULL; vma->vm_private_data = NULL;
insert_vm_struct(current->mm, vma); insert_vm_struct(current->mm, vma);
} }
/* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
if (!(current->personality & MMAP_PAGE_ZERO)) {
vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (vma) {
memset(vma, 0, sizeof(*vma));
vma->vm_mm = current->mm;
vma->vm_end = PAGE_SIZE;
vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
insert_vm_struct(current->mm, vma);
}
}
} }
void void
......
...@@ -35,12 +35,14 @@ ...@@ -35,12 +35,14 @@
1 << _PAGE_SIZE_4K ) 1 << _PAGE_SIZE_4K )
struct ia64_ctx ia64_ctx = { struct ia64_ctx ia64_ctx = {
lock: SPIN_LOCK_UNLOCKED, .lock = SPIN_LOCK_UNLOCKED,
next: 1, .next = 1,
limit: (1 << 15) - 1, /* start out with the safe (architected) limit */ .limit = (1 << 15) - 1, /* start out with the safe (architected) limit */
max_ctx: ~0U .max_ctx = ~0U
}; };
u8 ia64_need_tlb_flush __per_cpu_data;
/* /*
* Acquire the ia64_ctx.lock before calling this function! * Acquire the ia64_ctx.lock before calling this function!
*/ */
...@@ -49,6 +51,7 @@ wrap_mmu_context (struct mm_struct *mm) ...@@ -49,6 +51,7 @@ wrap_mmu_context (struct mm_struct *mm)
{ {
unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
struct task_struct *tsk; struct task_struct *tsk;
int i;
if (ia64_ctx.next > max_ctx) if (ia64_ctx.next > max_ctx)
ia64_ctx.next = 300; /* skip daemons */ ia64_ctx.next = 300; /* skip daemons */
...@@ -77,7 +80,11 @@ wrap_mmu_context (struct mm_struct *mm) ...@@ -77,7 +80,11 @@ wrap_mmu_context (struct mm_struct *mm)
ia64_ctx.limit = tsk_context; ia64_ctx.limit = tsk_context;
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
flush_tlb_all(); /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
for (i = 0; i < NR_CPUS; ++i)
if (i != smp_processor_id())
per_cpu(ia64_need_tlb_flush, i) = 1;
__flush_tlb_all();
} }
void void
......
...@@ -279,9 +279,9 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file, ...@@ -279,9 +279,9 @@ static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
} }
struct file_operations ifconfig_net_fops = { struct file_operations ifconfig_net_fops = {
ioctl:ifconfig_net_ioctl, /* ioctl */ .ioctl =ifconfig_net_ioctl, /* ioctl */
open:ifconfig_net_open, /* open */ .open =ifconfig_net_open, /* open */
release:ifconfig_net_close /* release */ .release =ifconfig_net_close /* release */
}; };
......
...@@ -210,31 +210,31 @@ static void dump_allocations(struct list_head * dalp); ...@@ -210,31 +210,31 @@ static void dump_allocations(struct list_head * dalp);
/* file operations for each type of node */ /* file operations for each type of node */
static struct file_operations rom_fops = { static struct file_operations rom_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
mmap: rom_mmap, .mmap = rom_mmap,
open: generic_open, .open = generic_open,
release: rom_release .release = rom_release
}; };
static struct file_operations base_fops = { static struct file_operations base_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
mmap: base_mmap, .mmap = base_mmap,
open: generic_open .open = generic_open
}; };
static struct file_operations config_fops = { static struct file_operations config_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
ioctl: config_ioctl, .ioctl = config_ioctl,
open: generic_open .open = generic_open
}; };
static struct file_operations dma_fops = { static struct file_operations dma_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
ioctl: dma_ioctl, .ioctl = dma_ioctl,
mmap: dma_mmap, .mmap = dma_mmap,
open: generic_open .open = generic_open
}; };
......
...@@ -24,7 +24,7 @@ extern void hubni_error_handler(char *, int); /* huberror.c */ ...@@ -24,7 +24,7 @@ extern void hubni_error_handler(char *, int); /* huberror.c */
static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long); static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
struct file_operations hub_mon_fops = { struct file_operations hub_mon_fops = {
ioctl: hubstats_ioctl, .ioctl = hubstats_ioctl,
}; };
#define HUB_CAPTURE_TICKS (2 * HZ) #define HUB_CAPTURE_TICKS (2 * HZ)
......
...@@ -307,22 +307,22 @@ extern void free_pciio_dmamap(pcibr_dmamap_t); ...@@ -307,22 +307,22 @@ extern void free_pciio_dmamap(pcibr_dmamap_t);
* appropriate function name below. * appropriate function name below.
*/ */
struct file_operations pcibr_fops = { struct file_operations pcibr_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
llseek: NULL, .llseek = NULL,
read: NULL, .read = NULL,
write: NULL, .write = NULL,
readdir: NULL, .readdir = NULL,
poll: NULL, .poll = NULL,
ioctl: NULL, .ioctl = NULL,
mmap: NULL, .mmap = NULL,
open: NULL, .open = NULL,
flush: NULL, .flush = NULL,
release: NULL, .release = NULL,
fsync: NULL, .fsync = NULL,
fasync: NULL, .fasync = NULL,
lock: NULL, .lock = NULL,
readv: NULL, .readv = NULL,
writev: NULL .writev = NULL
}; };
extern devfs_handle_t hwgraph_root; extern devfs_handle_t hwgraph_root;
......
...@@ -64,22 +64,22 @@ int pcibr_devflag = D_MP; ...@@ -64,22 +64,22 @@ int pcibr_devflag = D_MP;
* appropriate function name below. * appropriate function name below.
*/ */
struct file_operations pcibr_fops = { struct file_operations pcibr_fops = {
owner: THIS_MODULE, .owner =THIS_MODULE,
llseek: NULL, .llseek = NULL,
read: NULL, .read = NULL,
write: NULL, .write = NULL,
readdir: NULL, .readdir = NULL,
poll: NULL, .poll = NULL,
ioctl: NULL, .ioctl = NULL,
mmap: NULL, .mmap = NULL,
open: NULL, .open = NULL,
flush: NULL, .flush = NULL,
release: NULL, .release = NULL,
fsync: NULL, .fsync = NULL,
fasync: NULL, .fasync = NULL,
lock: NULL, .lock = NULL,
readv: NULL, .readv = NULL,
writev: NULL .writev = NULL
}; };
#ifdef LATER #ifdef LATER
......
...@@ -109,14 +109,14 @@ irqpda_t *irqpdaindr[NR_CPUS]; ...@@ -109,14 +109,14 @@ irqpda_t *irqpdaindr[NR_CPUS];
* VGA color display. * VGA color display.
*/ */
struct screen_info sn1_screen_info = { struct screen_info sn1_screen_info = {
orig_x: 0, .orig_x = 0,
orig_y: 0, .orig_y = 0,
orig_video_mode: 3, .orig_video_mode = 3,
orig_video_cols: 80, .orig_video_cols = 80,
orig_video_ega_bx: 3, .orig_video_ega_bx = 3,
orig_video_lines: 25, .orig_video_lines = 25,
orig_video_isVGA: 1, .orig_video_isVGA = 1,
orig_video_points: 16 .orig_video_points = 16
}; };
/* /*
...@@ -170,9 +170,9 @@ early_sn1_setup(void) ...@@ -170,9 +170,9 @@ early_sn1_setup(void)
#ifdef NOT_YET_CONFIG_IA64_MCA #ifdef NOT_YET_CONFIG_IA64_MCA
extern void ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs); extern void ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs);
static struct irqaction mca_cpe_irqaction = { static struct irqaction mca_cpe_irqaction = {
handler: ia64_mca_cpe_int_handler, .handler = ia64_mca_cpe_int_handler,
flags: SA_INTERRUPT, .flags = SA_INTERRUPT,
name: "cpe_hndlr" .name = "cpe_hndlr"
}; };
#endif #endif
#ifdef CONFIG_IA64_MCA #ifdef CONFIG_IA64_MCA
......
...@@ -4,7 +4,9 @@ TARGET = $(TOPDIR)/include/asm-ia64/offsets.h ...@@ -4,7 +4,9 @@ TARGET = $(TOPDIR)/include/asm-ia64/offsets.h
all: all:
mrproper: fastdep:
mrproper: clean
clean: clean:
rm -f print_offsets.s print_offsets offsets.h rm -f print_offsets.s print_offsets offsets.h
......
...@@ -41,9 +41,6 @@ SECTIONS ...@@ -41,9 +41,6 @@ SECTIONS
/* Read-only data */ /* Read-only data */
. = ALIGN(16);
__gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */
/* Global data */ /* Global data */
_data = .; _data = .;
...@@ -146,6 +143,9 @@ SECTIONS ...@@ -146,6 +143,9 @@ SECTIONS
.data : AT(ADDR(.data) - PAGE_OFFSET) .data : AT(ADDR(.data) - PAGE_OFFSET)
{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS } { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
. = ALIGN(16);
__gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */
.got : AT(ADDR(.got) - PAGE_OFFSET) .got : AT(ADDR(.got) - PAGE_OFFSET)
{ *(.got.plt) *(.got) } { *(.got.plt) *(.got) }
/* We want the small data sections together, so single-instruction offsets /* We want the small data sections together, so single-instruction offsets
......
...@@ -30,11 +30,74 @@ ...@@ -30,11 +30,74 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#define __acpi_map_table(phys_addr, size) __va(phys_addr) #define COMPILER_DEPENDENT_INT64 long
#define COMPILER_DEPENDENT_UINT64 unsigned long
/*
* Calling conventions:
*
* ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads)
* ACPI_EXTERNAL_XFACE - External ACPI interfaces
* ACPI_INTERNAL_XFACE - Internal ACPI interfaces
* ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces
*/
#define ACPI_SYSTEM_XFACE
#define ACPI_EXTERNAL_XFACE
#define ACPI_INTERNAL_XFACE
#define ACPI_INTERNAL_VAR_XFACE
/* Asm macros */
#define ACPI_ASM_MACROS
#define BREAKPOINT3
#define ACPI_DISABLE_IRQS() local_irq_disable()
#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE()
#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
do { \
__asm__ volatile ("1: ld4 r29=%1\n" \
";;\n" \
"mov ar.ccv=r29\n" \
"mov r2=r29\n" \
"shr.u r30=r29,1\n" \
"and r29=-4,r29\n" \
";;\n" \
"add r29=2,r29\n" \
"and r30=1,r30\n" \
";;\n" \
"add r29=r29,r30\n" \
";;\n" \
"cmpxchg4.acq r30=%1,r29,ar.ccv\n" \
";;\n" \
"cmp.eq p6,p7=r2,r30\n" \
"(p7) br.dpnt.few 1b\n" \
"cmp.gt p8,p9=3,r29\n" \
";;\n" \
"(p8) mov %0=-1\n" \
"(p9) mov %0=r0\n" \
:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
} while (0)
#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
do { \
__asm__ volatile ("1: ld4 r29=%1\n" \
";;\n" \
"mov ar.ccv=r29\n" \
"mov r2=r29\n" \
"and r29=-4,r29\n" \
";;\n" \
"cmpxchg4.acq r30=%1,r29,ar.ccv\n" \
";;\n" \
"cmp.eq p6,p7=r2,r30\n" \
"(p7) br.dpnt.few 1b\n" \
"and %0=1,r2\n" \
";;\n" \
:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
} while (0)
const char *acpi_get_sysname (void); const char *acpi_get_sysname (void);
int acpi_boot_init (char *cdline); int acpi_boot_init (char *cdline);
int acpi_find_rsdp (unsigned long *phys_addr);
int acpi_request_vector (u32 int_type); int acpi_request_vector (u32 int_type);
int acpi_get_prt (struct pci_vector_struct **vectors, int *count); int acpi_get_prt (struct pci_vector_struct **vectors, int *count);
int acpi_get_interrupt_model(int *type); int acpi_get_interrupt_model(int *type);
......
...@@ -326,7 +326,7 @@ ia64_fls (unsigned long x) ...@@ -326,7 +326,7 @@ ia64_fls (unsigned long x)
return exp - 0xffff; return exp - 0xffff;
} }
static int static inline int
fls (int x) fls (int x)
{ {
return ia64_fls((unsigned int) x); return ia64_fls((unsigned int) x);
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
*/ */
#include <linux/page-flags.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/page.h> #include <asm/page.h>
...@@ -23,7 +25,7 @@ ...@@ -23,7 +25,7 @@
#define flush_dcache_page(page) \ #define flush_dcache_page(page) \
do { \ do { \
clear_bit(PG_arch_1, &page->flags); \ clear_bit(PG_arch_1, &(page)->flags); \
} while (0) } while (0)
extern void flush_icache_range (unsigned long start, unsigned long end); extern void flush_icache_range (unsigned long start, unsigned long end);
......
...@@ -53,7 +53,7 @@ ia64_get_itc (void) ...@@ -53,7 +53,7 @@ ia64_get_itc (void)
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
#ifdef CONFIG_ITANIUM #ifdef CONFIG_ITANIUM
while (unlikely ((__s32) result == -1) while (unlikely((__s32) result == -1))
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
#endif #endif
return result; return result;
......
This diff is collapsed.
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
#define _ASM_IA64_HW_IRQ_H #define _ASM_IA64_HW_IRQ_H
/* /*
* Copyright (C) 2001 Hewlett-Packard Co * Copyright (C) 2001-2002 Hewlett-Packard Co
* Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
*/ */
#include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -67,6 +68,8 @@ enum { ...@@ -67,6 +68,8 @@ enum {
extern __u8 isa_irq_to_vector_map[16]; extern __u8 isa_irq_to_vector_map[16];
#define isa_irq_to_vector(x) isa_irq_to_vector_map[(x)] #define isa_irq_to_vector(x) isa_irq_to_vector_map[(x)]
extern __u8 gsi_to_vector_map[255];
#define gsi_to_vector(x) gsi_to_vector_map[(x)]
extern unsigned long ipi_base_addr; extern unsigned long ipi_base_addr;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define KEYBOARD_IRQ isa_irq_to_vector(1) #define KEYBOARD_IRQ isa_irq_to_vector(1)
#define DISABLE_KBD_DURING_INTERRUPTS 0 #define DISABLE_KBD_DURING_INTERRUPTS 0
extern unsigned char acpi_kbd_controller_present;
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode); extern int pckbd_getkeycode(unsigned int scancode);
extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
...@@ -26,6 +27,7 @@ extern void pckbd_leds(unsigned char leds); ...@@ -26,6 +27,7 @@ extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void); extern void pckbd_init_hw(void);
extern unsigned char pckbd_sysrq_xlate[128]; extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_controller_present() acpi_kbd_controller_present
#define kbd_setkeycode pckbd_setkeycode #define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode #define kbd_getkeycode pckbd_getkeycode
#define kbd_pretranslate pckbd_pretranslate #define kbd_pretranslate pckbd_pretranslate
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment