diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 442024af26fc4d72e9332c2838486f702b721bfb..be0683352e513359ac7243576391acc02fdb1321 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -13,7 +13,7 @@ AWK := awk export AWK -OBJCOPYFLAGS := --strip-all +OBJCOPYFLAGS := --strip-all LDFLAGS_vmlinux := -static -T arch/$(ARCH)/vmlinux.lds AFLAGS_KERNEL := -mconstant-gp EXTRA = diff --git a/arch/ia64/boot/Makefile b/arch/ia64/boot/Makefile index 50c6bff505cf70edc093c3ce19e6929e0f6dcd50..ba9772cf5194ff4dcd6939bdaa96c6513872088f 100644 --- a/arch/ia64/boot/Makefile +++ b/arch/ia64/boot/Makefile @@ -12,8 +12,10 @@ LINKFLAGS = -static -T bootloader.lds OBJECTS = bootloader.o -targets-$(CONFIG_IA64_HP_SIM) += bootloader -targets-$(CONFIG_IA64_GENERIC) += bootloader +targets-$(CONFIG_IA64_HP_SIM) += bootloader +targets-$(CONFIG_IA64_GENERIC) += bootloader + +CFLAGS := $(CFLAGS) $(CFLAGS_KERNEL) all: $(targets-y) diff --git a/arch/ia64/config.in b/arch/ia64/config.in index 41f62de88c1e5d93de6462731448ffcb732f4742..4b5fd8aec96592c070581526efc7e4ce119d987c 100644 --- a/arch/ia64/config.in +++ b/arch/ia64/config.in @@ -102,7 +102,6 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then source drivers/acpi/Config.in - bool 'PCI support' CONFIG_PCI source drivers/pci/Config.in @@ -124,18 +123,26 @@ if [ "$CONFIG_NET" = "y" ]; then fi 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 + mainmenu_option next_comment + comment 'ATA/ATAPI/MFM/RLL support' + tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE - - - - - - - - - + if [ "$CONFIG_IDE" != "n" ]; then + source drivers/ide/Config.in + else + define_bool CONFIG_BLK_DEV_HD n + fi + endmenu +fi mainmenu_option next_comment comment 'SCSI support' @@ -157,43 +164,55 @@ if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then source drivers/net/Config.in fi endmenu + fi + source net/ax25/Config.in + source drivers/isdn/Config.in + mainmenu_option next_comment + comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)' - - - - - - - + bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI + if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then + source drivers/cdrom/Config.in fi -bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI -fi # !HP_SIM - -# -# input before char - char/joystick depends on it. As does USB. -# -source drivers/input/Config.in -source drivers/char/Config.in + endmenu -#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/media/Config.in + #source drivers/misc/Config.in -source fs/Config.in + source drivers/media/Config.in +else # HP_SIM -if [ "$CONFIG_VT" = "y" ]; then mainmenu_option next_comment - comment 'Console drivers' - bool 'VGA text console' CONFIG_VGA_CONSOLE - source drivers/video/Config.in - if [ "$CONFIG_FB" = "y" ]; then - define_bool CONFIG_PCI_CONSOLE y + 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 +fi # HP_SIM + +source fs/Config.in if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then + if [ "$CONFIG_VT" = "y" ]; then + mainmenu_option next_comment + comment 'Console drivers' + bool 'VGA text console' CONFIG_VGA_CONSOLE + source drivers/video/Config.in + if [ "$CONFIG_FB" = "y" ]; then + define_bool CONFIG_PCI_CONSOLE y + fi + endmenu + fi mainmenu_option next_comment comment 'Sound' @@ -210,10 +229,9 @@ if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then fi # !HP_SIM 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 - mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index d892b42b05e6bed6549ab6489072f2dc4682ae2a..13a6f5391d82e1a8d76974ff431e5bbbfaa7bdbe 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c @@ -1,18 +1,19 @@ /* * Platform dependent support for HP simulator. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co + * David Mosberger-Tang <davidm@hpl.hp.com> * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com> */ +#include <linux/console.h> #include <linux/init.h> +#include <linux/kdev_t.h> #include <linux/kernel.h> +#include <linux/major.h> #include <linux/param.h> +#include <linux/root_dev.h> #include <linux/string.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/irq.h> @@ -55,5 +56,5 @@ hpsim_setup (char **cmdline_p) { ROOT_DEV = Root_SDA1; /* default to first SCSI drive */ - register_console (&hpsim_cons); + register_console(&hpsim_cons); } diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index e44fa800457b59e6259bb595db17dc44ac2d9bf9..2d060d7679a39e7aaec000c28b7b14459300952f 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -62,7 +62,9 @@ struct disk_stat { 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 { Scsi_Cmnd *sc; @@ -148,9 +150,9 @@ simscsi_biosparam (Disk *disk, struct block_device *n, int ip[]) { int size = disk->capacity; - ip[0] = 64; - ip[1] = 32; - ip[2] = size >> 11; + ip[0] = 64; /* heads */ + ip[1] = 32; /* sectors */ + ip[2] = size >> 11; /* cylinders */ return 0; } @@ -229,6 +231,29 @@ simscsi_readwrite6 (Scsi_Cmnd *sc, int mode) 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 simscsi_readwrite10 (Scsi_Cmnd *sc, int mode) @@ -247,6 +272,7 @@ int simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) { char fname[MAX_ROOT_LEN+16]; + size_t disk_size; char *buf; #if DEBUG_SIMSCSI register long sp asm ("sp"); @@ -258,15 +284,15 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) sc->result = DID_BAD_TARGET << 16; sc->scsi_done = done; - if (sc->target <= 7 && sc->lun == 0) { + if (sc->target <= 15 && sc->lun == 0) { switch (sc->cmnd[0]) { case INQUIRY: if (sc->request_bufflen < 35) { break; } sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target); - desc[sc->target] = ia64_ssc (__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS, - 0, 0, SSC_OPEN); + desc[sc->target] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS, + 0, 0, SSC_OPEN); if (desc[sc->target] < 0) { /* disk doesn't exist... */ break; @@ -319,11 +345,13 @@ simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) } buf = sc->request_buffer; + disk_size = simscsi_get_disk_size(desc[sc->target]); + /* pretend to be a 1GB disk (partition table contains real stuff): */ - buf[0] = 0x00; - buf[1] = 0x1f; - buf[2] = 0xff; - buf[3] = 0xff; + buf[0] = (disk_size >> 24) & 0xff; + buf[1] = (disk_size >> 16) & 0xff; + buf[2] = (disk_size >> 8) & 0xff; + buf[3] = (disk_size >> 0) & 0xff; /* set block size of 512 bytes: */ buf[4] = 0; buf[5] = 0; diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index e31a96f129273d984753aeddfb6653988f5a9b63..a7a447b2ca25df84809b711c1911e83dfc5d59d8 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -13,6 +13,7 @@ * * 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. + * 07/30/02 D. Mosberger Replace sti()/cli() with explicit spinlocks & local irq masking */ #include <linux/config.h> @@ -62,6 +63,7 @@ extern void ia64_ssc_connect_irq (long intr, long irq); static char *serial_name = "SimSerial driver"; 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 @@ -233,14 +235,14 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch) 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) { - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); return; } info->xmit.buf[info->xmit.head] = ch; 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) @@ -248,7 +250,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) int count; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&serial_lock, flags); if (info->x_char) { char c = info->x_char; @@ -291,7 +293,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) info->xmit.tail += count; } out: - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); } static void rs_flush_chars(struct tty_struct *tty) @@ -315,7 +317,6 @@ static int rs_write(struct tty_struct * tty, int from_user, if (!tty || !info->xmit.buf || !tmp_buf) return 0; - save_flags(flags); if (from_user) { down(&tmp_buf_sem); while (1) { @@ -332,21 +333,26 @@ static int rs_write(struct tty_struct * tty, int from_user, ret = -EFAULT; break; } - cli(); - c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - restore_flags(flags); + + spin_lock_irqsave(&serial_lock, flags); + { + c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, + SERIAL_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + } + spin_unlock_irqrestore(&serial_lock, flags); + buf += c; count -= c; ret += c; } up(&tmp_buf_sem); } else { - cli(); + spin_lock_irqsave(&serial_lock, flags); while (1) { c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); if (count < c) @@ -361,7 +367,7 @@ static int rs_write(struct tty_struct * tty, int from_user, count -= c; ret += c; } - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); } /* * Hey, we transmit directly from here in our case @@ -392,9 +398,9 @@ static void rs_flush_buffer(struct tty_struct *tty) struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; - save_flags(flags); cli(); + spin_lock_irqsave(&serial_lock, flags); info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); wake_up_interruptible(&tty->write_wait); @@ -567,44 +573,45 @@ static void shutdown(struct async_struct * info) state->irq); #endif - save_flags(flags); cli(); /* Disable interrupts */ + spin_lock_irqsave(&serial_lock, flags); + { + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; + /* + * Free the IRQ, if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, NULL); + retval = request_irq(state->irq, rs_interrupt_single, + IRQ_T(info), "serial", NULL); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, NULL); + } - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, NULL); - retval = request_irq(state->irq, rs_interrupt_single, - IRQ_T(info), "serial", NULL); + if (info->xmit.buf) { + free_page((unsigned long) info->xmit.buf); + info->xmit.buf = 0; + } - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, NULL); - } + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - if (info->xmit.buf) { - free_page((unsigned long) info->xmit.buf); - info->xmit.buf = 0; + info->flags &= ~ASYNC_INITIALIZED; } - - if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); } /* @@ -627,14 +634,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp) state = info->state; - save_flags(flags); cli(); - + spin_lock_irqsave(&serial_lock, flags); if (tty_hung_up_p(filp)) { #ifdef SIMSERIAL_DEBUG printk("rs_close: hung_up\n"); #endif MOD_DEC_USE_COUNT; - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); return; } #ifdef SIMSERIAL_DEBUG @@ -659,11 +665,11 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } if (state->count) { MOD_DEC_USE_COUNT; - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); return; } 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 @@ -771,7 +777,7 @@ startup(struct async_struct *info) if (!page) return -ENOMEM; - save_flags(flags); cli(); + spin_lock_irqsave(&serial_lock, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); @@ -852,11 +858,11 @@ startup(struct async_struct *info) } info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); return 0; errout: - restore_flags(flags); + spin_unlock_irqrestore(&serial_lock, flags); return retval; } diff --git a/arch/ia64/hp/zx1/hpzx1_misc.c b/arch/ia64/hp/zx1/hpzx1_misc.c index 5dc34d51dbbefa3f74df2a6f5d2c312aab7807b6..7b35a90369e07a30908f240277e67b67ede334ed 100644 --- a/arch/ia64/hp/zx1/hpzx1_misc.c +++ b/arch/ia64/hp/zx1/hpzx1_misc.c @@ -27,6 +27,7 @@ #include "../drivers/acpi/include/acstruct.h" #include "../drivers/acpi/include/acnamesp.h" #include "../drivers/acpi/include/acutils.h" +#include "../drivers/acpi/acpi_bus.h" #define PFX "hpzx1: " @@ -109,7 +110,7 @@ static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \ \ switch (where) { \ case PCI_BASE_ADDRESS_0: \ - if (value == ~0) \ + if (value == (u##bits) ~0) \ fake_dev->sizing = 1; \ break; \ default: \ @@ -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 * 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; } @@ -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))) printk(KERN_INFO PFX "%s LBA at 0x%lx, _BBN 0x%02x; " "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)); return AE_OK; diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c index bb162650842f5e7258f5faf856fdf0fd7e4f71d5..9527d3a6eaa4e8e44bb8672f09e4ced78db84549 100644 --- a/arch/ia64/ia32/ia32_ioctl.c +++ b/arch/ia64/ia32/ia32_ioctl.c @@ -30,6 +30,8 @@ #include <asm/ia32.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)) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index a9fcd6084f49caa536367cb963003f5df6be8571..966c70490899e142de1f17e20c7beebb473ed3f1 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -62,12 +62,13 @@ const char * acpi_get_sysname (void) { #ifdef CONFIG_IA64_GENERIC - unsigned long rsdp_phys = 0; + unsigned long rsdp_phys; struct acpi20_table_rsdp *rsdp; struct acpi_table_xsdt *xsdt; struct acpi_table_header *hdr; - if ((0 != acpi_find_rsdp(&rsdp_phys)) || !rsdp_phys) { + rsdp_phys = acpi_find_rsdp(); + if (!rsdp_phys) { printk("ACPI 2.0 RSDP not found, default to \"dig\"\n"); return "dig"; } @@ -101,6 +102,8 @@ acpi_get_sysname (void) return "sn2"; # elif defined (CONFIG_IA64_DIG) return "dig"; +# elif defined (CONFIG_IA64_HP_ZX1) + return "hpzx1"; # else # error Unknown platform. Fix acpi.c. # endif @@ -132,9 +135,7 @@ acpi_get_crs (acpi_handle obj, acpi_buffer *buf) if (!buf->pointer) return -ENOMEM; - result = acpi_get_current_resources(obj, buf); - - return result; + return acpi_get_current_resources(obj, buf); } acpi_resource * @@ -177,6 +178,8 @@ acpi_dispose_crs (acpi_buffer *buf) /* Array to record platform interrupt vectors for generic interrupt routing. */ int platform_irq_list[ACPI_MAX_PLATFORM_IRQS] = { [0 ... ACPI_MAX_PLATFORM_IRQS - 1] = -1 }; +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC; + /* * Interrupt routing API for device drivers. Provides interrupt vector for * a generic platform event. Currently only CPEI is implemented. @@ -191,10 +194,14 @@ acpi_request_vector (u32 int_type) vector = platform_irq_list[int_type]; } else printk("acpi_request_vector(): invalid interrupt type\n"); - return vector; } +char * +__acpi_map_table (unsigned long phys_addr, unsigned long size) +{ + return __va(phys_addr); +} /* -------------------------------------------------------------------------- Boot-time Table Parsing @@ -220,7 +227,6 @@ acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header) iounmap((void *) ipi_base_addr); ipi_base_addr = (unsigned long) ioremap(lapic->address, 0); } - return 0; } @@ -273,7 +279,6 @@ acpi_parse_lapic_nmi (acpi_table_entry_header *header) acpi_table_print_madt_entry(header); /* TBD: Support lapic_nmi entries */ - return 0; } @@ -282,10 +287,10 @@ static int __init acpi_find_iosapic (int global_vector, u32 *irq_base, char **iosapic_address) { struct acpi_table_iosapic *iosapic; - int ver = 0; - int max_pin = 0; - char *p = 0; - char *end = 0; + int ver; + int max_pin; + char *p; + char *end; if (!irq_base || !iosapic_address) return -ENODEV; @@ -341,9 +346,9 @@ static int __init acpi_parse_plat_int_src (acpi_table_entry_header *header) { struct acpi_table_plat_int_src *plintsrc; - int vector = 0; - u32 irq_base = 0; - char *iosapic_address = NULL; + int vector; + u32 irq_base; + char *iosapic_address; plintsrc = (struct acpi_table_plat_int_src *) header; if (!plintsrc) @@ -356,7 +361,7 @@ acpi_parse_plat_int_src (acpi_table_entry_header *header) return -ENODEV; } - if (0 != acpi_find_iosapic(plintsrc->global_irq, &irq_base, &iosapic_address)) { + if (acpi_find_iosapic(plintsrc->global_irq, &irq_base, &iosapic_address)) { printk(KERN_WARNING PREFIX "IOSAPIC not found\n"); return -ENODEV; } @@ -365,15 +370,15 @@ acpi_parse_plat_int_src (acpi_table_entry_header *header) * Get vector assignment for this IRQ, set attributes, and program the * IOSAPIC routing table. */ - vector = iosapic_register_platform_irq (plintsrc->type, - plintsrc->global_irq, - plintsrc->iosapic_vector, - plintsrc->eid, - plintsrc->id, - (plintsrc->flags.polarity == 1) ? 1 : 0, - (plintsrc->flags.trigger == 1) ? 1 : 0, - irq_base, - iosapic_address); + vector = iosapic_register_platform_irq(plintsrc->type, + plintsrc->global_irq, + plintsrc->iosapic_vector, + plintsrc->eid, + plintsrc->id, + (plintsrc->flags.polarity == 1) ? 1 : 0, + (plintsrc->flags.trigger == 1) ? 1 : 0, + irq_base, + iosapic_address); platform_irq_list[plintsrc->type] = vector; return 0; @@ -396,9 +401,8 @@ acpi_parse_int_src_ovr (acpi_table_entry_header *header) return 0; iosapic_register_legacy_irq(p->bus_irq, p->global_irq, - (p->flags.polarity == 1) ? 1 : 0, - (p->flags.trigger == 1) ? 1 : 0); - + (p->flags.polarity == 1) ? 1 : 0, + (p->flags.trigger == 1) ? 1 : 0); return 0; } @@ -415,7 +419,6 @@ acpi_parse_nmi_src (acpi_table_entry_header *header) acpi_table_print_madt_entry(header); /* TBD: Support nimsrc entries */ - return 0; } @@ -431,15 +434,12 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size) /* Get base address of IPI Message Block */ if (acpi_madt->lapic_address) - ipi_base_addr = (unsigned long) - ioremap(acpi_madt->lapic_address, 0); + ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0); printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr); - return 0; } - static int __init acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { @@ -461,22 +461,16 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size) return 0; } - -int __init -acpi_find_rsdp (unsigned long *rsdp_phys) +unsigned long __init +acpi_find_rsdp (void) { - if (!rsdp_phys) - return -EINVAL; + unsigned long rsdp_phys = 0; - if (efi.acpi20) { - (*rsdp_phys) = __pa(efi.acpi20); - return 0; - } - else if (efi.acpi) { + if (efi.acpi20) + rsdp_phys = __pa(efi.acpi20); + else if (efi.acpi) printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n"); - } - - return -ENODEV; + return rsdp_phys; } @@ -515,28 +509,27 @@ acpi_parse_spcr (unsigned long phys_addr, unsigned long size) if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) && (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) { - u32 irq_base = 0; - char *iosapic_address = NULL; - int vector = 0; + u32 irq_base; + char *iosapic_address; + int vector; /* We have a UART in memory space with an SAPIC interrupt */ - global_int = ( (spcr->global_int[3] << 24) | - (spcr->global_int[2] << 16) | - (spcr->global_int[1] << 8) | - (spcr->global_int[0]) ); + global_int = ((spcr->global_int[3] << 24) | + (spcr->global_int[2] << 16) | + (spcr->global_int[1] << 8) | + (spcr->global_int[0]) ); /* Which iosapic does this IRQ belong to? */ - if (0 == acpi_find_iosapic(global_int, &irq_base, &iosapic_address)) { - vector = iosapic_register_irq (global_int, 1, 1, - irq_base, iosapic_address); - } + if (!acpi_find_iosapic(global_int, &irq_base, &iosapic_address)) + vector = iosapic_register_irq(global_int, 1, 1, + irq_base, iosapic_address); } return 0; } -#endif /*CONFIG_SERIAL_ACPI*/ +#endif /* CONFIG_SERIAL_ACPI */ int __init @@ -564,38 +557,31 @@ acpi_boot_init (char *cmdline) /* Local APIC */ - if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, - acpi_parse_lapic_addr_ovr) < 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, - acpi_parse_lsapic) < 1) + if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1) printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); - if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, - acpi_parse_lapic_nmi) < 0) + if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0) printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* I/O APIC */ - if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, - acpi_parse_iosapic) < 1) - printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n"); + if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1) + printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); /* System-Level Interrupt Routing */ - if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, - acpi_parse_plat_int_src) < 0) + if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0) printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, - acpi_parse_int_src_ovr) < 0) + if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0) printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, - acpi_parse_nmi_src) < 0) + if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0) printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); -skip_madt: + skip_madt: /* FADT says whether a legacy keyboard controller is present. */ if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1) @@ -620,7 +606,6 @@ acpi_boot_init (char *cmdline) #endif /* Make boot-up look pretty */ printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); - return 0; } @@ -643,14 +628,14 @@ acpi_get_prt (struct pci_vector_struct **vectors, int *count) *vectors = NULL; *count = 0; - if (acpi_prts.count <= 0) { + if (acpi_prt.count < 0) { printk(KERN_ERR PREFIX "No PCI IRQ routing entries\n"); return -ENODEV; } /* Allocate vectors */ - *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prts.count, GFP_KERNEL); + *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL); if (!(*vectors)) return -ENOMEM; @@ -658,15 +643,15 @@ acpi_get_prt (struct pci_vector_struct **vectors, int *count) vector = *vectors; - list_for_each(node, &acpi_prts.entries) { + list_for_each(node, &acpi_prt.entries) { entry = (struct acpi_prt_entry *)node; vector[i].bus = entry->id.bus; - vector[i].pci_id = ((u32) entry->id.dev << 16) | 0xffff; - vector[i].pin = entry->id.pin; - vector[i].irq = entry->source.index; + vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff; + vector[i].pin = entry->pin; + vector[i].irq = entry->link.index; i++; } - *count = acpi_prts.count; + *count = acpi_prt.count; return 0; } @@ -678,8 +663,7 @@ acpi_get_interrupt_model (int *type) if (!type) return -EINVAL; - *type = ACPI_INT_MODEL_IOSAPIC; - + *type = ACPI_IRQ_MODEL_IOSAPIC; return 0; } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index b4d3155afe030bfe18579e86b680b1c68a91713b..8180008ed9c031a62b9f841fbd020b1f7ffd837d 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -175,6 +175,7 @@ GLOBAL_ENTRY(ia64_switch_to) (p6) srlz.d ld8 sp=[r21] // load kernel stack pointer of new task mov IA64_KR(CURRENT)=r20 // update "current" application register + mov r8=r13 // return pointer to previously running task mov r13=in0 // set "current" pointer ;; DO_LOAD_SWITCH_STACK diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index d7caf841505c2b82935e7726dac9d144a36a702a..d7e8085dcaadee26f72ece1f09fb80b9c2e97af9 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -88,12 +88,6 @@ EXPORT_SYMBOL(ia64_cpu_to_sapicid); #include <asm/smplock.h> 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 */ EXPORT_SYMBOL(__flush_tlb_all); diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index fbfa43d15d9d9d93eaf06e26a6db2340b4274927..951609fb1b49ef3d0642d4cf16e45356fbac5955 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -422,6 +422,7 @@ register_irq (u32 global_vector, int vector, int pin, unsigned char delivery, irq_desc_t *idesc; struct hw_interrupt_type *irq_type; + gsi_to_vector(global_vector) = vector; iosapic_irq[vector].pin = pin; iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW; iosapic_irq[vector].dmode = delivery; @@ -640,7 +641,7 @@ iosapic_init_pci_irq (void) unsigned int irq; 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; for (i = 0; i < pci_irq.num_routes; i++) { diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 5772707363b20acfa5f926e662474af7844ce5e6..ad10f49069b0b1731b2a7a21bc617a897ffbbca4 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -200,277 +200,12 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } - -/* - * 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) +#if CONFIG_SMP +inline void synchronize_irq(unsigned int irq) { - switch (flags) { - case 0: - __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]); - } + while (irq_desc(irq)->status & IRQ_INPROGRESS) + cpu_relax(); } - #endif /* @@ -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 status; - - local_irq_enter(irq); - - status = 1; /* Force the "do bottom halves" bit */ + int status = 1; /* Force the "do bottom halves" bit */ if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); @@ -500,11 +231,16 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * add_interrupt_randomness(irq); local_irq_disable(); - local_irq_exit(irq); - 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 * @irq: Interrupt to disable @@ -546,14 +282,7 @@ inline void disable_irq_nosync(unsigned int irq) void disable_irq(unsigned int irq) { disable_irq_nosync(irq); - -#ifdef CONFIG_SMP - if (!really_local_irq_count()) { - do { - barrier(); - } while (irq_desc(irq)->status & IRQ_INPROGRESS); - } -#endif + synchronize_irq(irq); } /** @@ -616,6 +345,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) struct irqaction * action; unsigned int status; + irq_enter(); kstat.irqs[cpu][irq]++; if (desc->status & IRQ_PER_CPU) { @@ -682,6 +412,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) desc->handler->end(irq); spin_unlock(&desc->lock); } + irq_exit(); return 1; } @@ -811,7 +542,7 @@ void free_irq(unsigned int irq, void *dev_id) #ifdef CONFIG_SMP /* Wait to make sure it's not being used on another CPU */ while (desc->status & IRQ_INPROGRESS) - barrier(); + synchronize_irq(irq); #endif kfree(action); return; @@ -864,7 +595,7 @@ unsigned long probe_irq_on(void) /* Wait for longstanding interrupts to trigger. */ for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) - /* about 20ms delay */ synchronize_irq(); + /* about 20ms delay */ barrier(); /* * enable any unassigned irqs @@ -887,7 +618,7 @@ unsigned long probe_irq_on(void) * Wait for spurious interrupts to trigger */ 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 diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index eb4047e312e05155f412c3c699d15e2484f406ab..e980509d4269b0356a5ade1d9c3ae64578cc5ee5 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -54,6 +54,11 @@ __u8 isa_irq_to_vector_map[16] = { 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21 }; +/* + * GSI to IA-64 vector translation table. + */ +__u8 gsi_to_vector_map[255]; + int ia64_alloc_irq (void) { diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 112ac8ba66978d919c751f0307234feeb9480e54..82cf7becd0d1a265293e07479bf42b9eb4d1dc31 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -626,9 +626,12 @@ ia64_mca_wakeup_all(void) void 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 */ - save_and_cli(flags); +#warning XXX fix me: this used to be: save_and_cli(flags); + local_irq_save(flags); #ifdef CONFIG_SMP 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) ia64_mca_wakeup_ipi_wait(); /* Enable all interrupts */ - restore_flags(flags); + local_irq_restore(flags); } diff --git a/arch/ia64/kernel/pci.c b/arch/ia64/kernel/pci.c index 60b8fbcb024e292ac4a2099ba70e8bd8d97a2b76..a9a3d16520917f5d74aa73b75f29ae8756cc7b3c 100644 --- a/arch/ia64/kernel/pci.c +++ b/arch/ia64/kernel/pci.c @@ -165,7 +165,7 @@ struct pci_ops pci_sal_ops = { */ struct pci_bus * -pcibios_scan_root(int seg, int bus) +pcibios_scan_root(int bus) { struct list_head *list = NULL; struct pci_bus *pci_bus = NULL; @@ -174,12 +174,12 @@ pcibios_scan_root(int seg, int bus) pci_bus = pci_bus_b(list); if (pci_bus->number == bus) { /* Already scanned */ - printk("PCI: Bus (%02x:%02x) already probed\n", seg, bus); + printk("PCI: Bus (%02x) already probed\n", 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); } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 973bc2bcd2dc162d9abb7286034a91279ae84fd5..ab016306c428c73e603b9798cbfe6c3d9fbe64d6 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -616,7 +616,7 @@ pfm_remove_smpl_mapping(struct task_struct *task) 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); if (r !=0) { diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index ecac5ba7c5b0e596473c441a6996f7cd2dd96f2f..579538d1e31406242b836c3637384e6b9b83a683 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -1,10 +1,14 @@ /* * 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/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]; #define DEBUG_ITC_SYNC 0 -extern void __init calibrate_delay(void); -extern void start_ap(void); +extern void __init calibrate_delay (void); +extern void start_ap (void); extern unsigned long ia64_iobase; int cpucount; task_t *task_for_booting_cpu; -/* Setup configured maximum number of CPUs to activate */ -static int max_cpus = -1; - /* Bitmask of currently online CPUs */ volatile unsigned long cpu_online_map; +unsigned long phys_cpu_present_map; /* which logical CPU number maps to which CPU (physical APIC ID) */ volatile int ia64_cpu_to_sapicid[NR_CPUS]; @@ -86,44 +88,12 @@ static volatile unsigned long cpu_callin_map; 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 */ char __initdata no_int_routing; 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 nointroute (char *str) { @@ -299,7 +269,7 @@ smp_setup_percpu_timer (void) static volatile atomic_t smp_commenced = ATOMIC_INIT(0); -void __init +static void __init smp_commence (void) { /* @@ -308,7 +278,7 @@ smp_commence (void) Dprintk("Setting commenced=1, go go go\n"); wmb(); - atomic_set(&smp_commenced,1); + atomic_set(&smp_commenced, 1); } @@ -405,6 +375,9 @@ do_boot_cpu (int sapicid) int timeout, cpu; cpu = ++cpucount; + + set_bit(cpu, &phys_cpu_present_map); + /* * We can't use kernel_thread since we must avoid to * reschedule the child. @@ -466,8 +439,8 @@ smp_tune_scheduling (void) /* * Cycle through the APs sending Wakeup IPIs to boot each. */ -void __init -smp_boot_cpus (void) +static void __init +smp_boot_cpus (unsigned int max_cpus) { int sapicid, cpu; int boot_cpu_id = hard_smp_processor_id(); @@ -486,13 +459,13 @@ smp_boot_cpus (void) */ set_bit(0, &cpu_online_map); set_bit(0, &cpu_callin_map); + set_bit(0, &phys_cpu_present_map); local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[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; smp_tune_scheduling(); @@ -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 * SoftSDV/Lion, that would be ACPI. @@ -571,9 +567,6 @@ init_smp_config(void) ap_startup = (struct fptr *) start_ap; sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0); - if (sal_ret < 0) { - printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n", - ia64_sal_strerror(sal_ret)); - max_cpus = 0; - } + if (sal_ret < 0) + printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n", ia64_sal_strerror(sal_ret)); } diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index fa230acc7cffee77d1f76771653c697fc5e1e6d5..fe0c33613c951d68f07e6fe3e6e7b8442a9f33b6 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -82,7 +82,6 @@ asmlinkage unsigned long ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6, long arg7, long stack) { - extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr); struct pt_regs *regs = (struct pt_regs *) &stack; unsigned long raddr; int retval; @@ -120,7 +119,7 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, /* Always allow shrinking brk. */ if (brk <= mm->brk) { - if (!do_munmap(mm, newbrk, oldbrk-newbrk)) + if (!do_munmap(mm, newbrk, oldbrk-newbrk, 1)) goto set_brk; goto out; } @@ -138,10 +137,6 @@ ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) goto out; - /* Check if we have enough memory.. */ - if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) - goto out; - /* Ok, looks good - let it rip. */ if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) goto out; diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e6e3f0049cdf95912d28d4e4e014a49cfc246531..75dbfcadd121e1ae1b42183023abf90cfcb7d85a 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -62,27 +62,26 @@ trap_init (void) void bust_spinlocks (int yes) { + int loglevel_save = console_loglevel; + spin_lock_init(&timerlist_lock); if (yes) { oops_in_progress = 1; -#ifdef CONFIG_SMP - global_irq_lock = 0; /* Many serial drivers do __global_cli() */ -#endif - } else { - int loglevel_save = console_loglevel; + return; + } + #ifdef CONFIG_VT - unblank_screen(); + unblank_screen(); #endif - oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() without - * oops_in_progress set so that printk will give klogd a poke. Hold onto - * your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; - } + oops_in_progress = 0; + /* + * OK, the message is on the console. Now we call printk() without + * oops_in_progress set so that printk will give klogd a poke. Hold onto + * your hats... + */ + console_loglevel = 15; /* NMI oopser may have shut the console up */ + printk(" "); + console_loglevel = loglevel_save; } void diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 2ed56ea6c2f4147f9aac8c85ecfcbfb61f0fb716..293cb6d710bcac0fd06dbc9d93b59044eaf2b903 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -6,43 +6,51 @@ L_TARGET = lib.a export-objs := io.o swiotlb.o -obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ - __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ - checksum.o clear_page.o csum_partial_copy.o copy_page.o \ +obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ + __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ + checksum.o clear_page.o csum_partial_copy.o copy_page.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 \ memset.o strlen.o swiotlb.o -obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o -obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o +obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o +obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.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 - $(CC) $(AFLAGS) -c -o $@ $< + $(cmd_as_o_S) __udivdi3.o: idiv64.S - $(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< + $(cmd_as_o_S) __moddi3.o: idiv64.S - $(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< + $(cmd_as_o_S) __umoddi3.o: idiv64.S - $(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< + $(cmd_as_o_S) __divsi3.o: idiv32.S - $(CC) $(AFLAGS) -c -o $@ $< + $(cmd_as_o_S) __udivsi3.o: idiv32.S - $(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< + $(cmd_as_o_S) __modsi3.o: idiv32.S - $(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< + $(cmd_as_o_S) __umodsi3.o: idiv32.S - $(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< - -include $(TOPDIR)/Rules.make + $(cmd_as_o_S) diff --git a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c index 5c2bc63e1da2d215281f38a760bd12058ee834bb..d06543fafbf86baf32e6f127ffd5fcd7778eff82 100644 --- a/arch/ia64/lib/swiotlb.c +++ b/arch/ia64/lib/swiotlb.c @@ -425,7 +425,8 @@ swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int d addr = SG_ENT_VIRT_ADDRESS(sg); pci_addr = virt_to_phys(addr); if ((pci_addr & ~hwdev->dma_mask) != 0) - sg->dma_address = map_single(hwdev, addr, sg->length, direction); + sg->dma_address = (dma_addr_t) + map_single(hwdev, addr, sg->length, direction); else sg->dma_address = pci_addr; sg->dma_length = sg->length; @@ -447,7 +448,7 @@ swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int for (i = 0; i < nelems; i++, sg++) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) - unmap_single(hwdev, sg->dma_address, sg->dma_length, direction); + unmap_single(hwdev, (void *) sg->dma_address, sg->dma_length, direction); else if (direction == PCI_DMA_FROMDEVICE) mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } @@ -469,7 +470,7 @@ swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int for (i = 0; i < nelems; i++, sg++) if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) - sync_single(hwdev, sg->dma_address, sg->dma_length, direction); + sync_single(hwdev, (void *) sg->dma_address, sg->dma_length, direction); } unsigned long diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 3cf17c4dd0a0ca66796d4d9272f791bedd4e6696..eb3267ec34e2d64990fd14c540ba42f5458554aa 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -41,6 +41,8 @@ struct ia64_ctx ia64_ctx = { .max_ctx = ~0U }; +u8 ia64_need_tlb_flush __per_cpu_data; + /* * Acquire the ia64_ctx.lock before calling this function! */ @@ -79,7 +81,7 @@ wrap_mmu_context (struct mm_struct *mm) } read_unlock(&tasklist_lock); /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */ - for (i = 0; i < smp_num_cpus; ++i) + for (i = 0; i < NR_CPUS; ++i) if (i != smp_processor_id()) per_cpu(ia64_need_tlb_flush, i) = 1; __flush_tlb_all(); diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile index af5123c9b28a7f303bff4fff029e81c6994b8292..018c9a3c7594921430ba92bd58388400a6010e17 100644 --- a/arch/ia64/tools/Makefile +++ b/arch/ia64/tools/Makefile @@ -4,7 +4,9 @@ TARGET = $(TOPDIR)/include/asm-ia64/offsets.h all: -mrproper: +fastdep: + +mrproper: clean clean: rm -f print_offsets.s print_offsets offsets.h diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S index f10d01c4ff348370bcd9d668b64524556e24629d..0e456c3e4543d0d19c372e7235d0032b9f26816e 100644 --- a/arch/ia64/vmlinux.lds.S +++ b/arch/ia64/vmlinux.lds.S @@ -41,9 +41,6 @@ SECTIONS /* Read-only data */ - . = ALIGN(16); - __gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */ - /* Global data */ _data = .; @@ -146,6 +143,9 @@ SECTIONS .data : AT(ADDR(.data) - PAGE_OFFSET) { *(.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.plt) *(.got) } /* We want the small data sections together, so single-instruction offsets diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h index 663a568d97673f8e5dcbc2baa0c049dab51656cc..8e39b4fe8691e097d49c5da41c2511c9f9d391bf 100644 --- a/include/asm-ia64/acpi.h +++ b/include/asm-ia64/acpi.h @@ -30,11 +30,74 @@ #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); int acpi_boot_init (char *cdline); -int acpi_find_rsdp (unsigned long *phys_addr); int acpi_request_vector (u32 int_type); int acpi_get_prt (struct pci_vector_struct **vectors, int *count); int acpi_get_interrupt_model(int *type); diff --git a/include/asm-ia64/cacheflush.h b/include/asm-ia64/cacheflush.h index 025398be93bc28edbadfce45a38aad1e018b3887..51c4780d875ab50f207137a7ddb15ece46c70886 100644 --- a/include/asm-ia64/cacheflush.h +++ b/include/asm-ia64/cacheflush.h @@ -6,6 +6,8 @@ * David Mosberger-Tang <davidm@hpl.hp.com> */ +#include <linux/page-flags.h> + #include <asm/bitops.h> #include <asm/page.h> @@ -23,7 +25,7 @@ #define flush_dcache_page(page) \ do { \ - clear_bit(PG_arch_1, &page->flags); \ + clear_bit(PG_arch_1, &(page)->flags); \ } while (0) extern void flush_icache_range (unsigned long start, unsigned long end); diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index 823d3e8ce20f49d683b7d8305798afd75fb7c13d..f723d5eedf623d7542c94f8d628d3ef5a5499cd1 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h @@ -2,10 +2,11 @@ #define _ASM_IA64_HW_IRQ_H /* - * Copyright (C) 2001 Hewlett-Packard Co - * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com> + * Copyright (C) 2001-2002 Hewlett-Packard Co + * David Mosberger-Tang <davidm@hpl.hp.com> */ +#include <linux/interrupt.h> #include <linux/sched.h> #include <linux/types.h> @@ -67,6 +68,8 @@ enum { extern __u8 isa_irq_to_vector_map[16]; #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; diff --git a/include/asm-ia64/kregs.h b/include/asm-ia64/kregs.h index 2383b9148e3a9cc1c61bea38c8e87b03a12341a3..173777837e5581952c766e9e846f15d13453000e 100644 --- a/include/asm-ia64/kregs.h +++ b/include/asm-ia64/kregs.h @@ -64,7 +64,7 @@ #define IA64_PSR_RI_BIT 41 #define IA64_PSR_ED_BIT 43 #define IA64_PSR_BN_BIT 44 -#define IA64_PSR_IA (__IA64_UL(1) << IA64_PSR_IA_BIT) +#define IA64_PSR_IA_BIT 45 /* A mask of PSR bits that we generally don't want to inherit across a clone2() or an execve(). Only list flags here that need to be cleared/set for BOTH clone2() and @@ -94,6 +94,7 @@ #define IA64_PSR_TB (__IA64_UL(1) << IA64_PSR_TB_BIT) #define IA64_PSR_RT (__IA64_UL(1) << IA64_PSR_RT_BIT) /* The following are not affected by save_flags()/restore_flags(): */ +#define IA64_PSR_CPL (__IA64_UL(3) << IA64_PSR_CPL0_BIT) #define IA64_PSR_IS (__IA64_UL(1) << IA64_PSR_IS_BIT) #define IA64_PSR_MC (__IA64_UL(1) << IA64_PSR_MC_BIT) #define IA64_PSR_IT (__IA64_UL(1) << IA64_PSR_IT_BIT) @@ -104,6 +105,7 @@ #define IA64_PSR_RI (__IA64_UL(3) << IA64_PSR_RI_BIT) #define IA64_PSR_ED (__IA64_UL(1) << IA64_PSR_ED_BIT) #define IA64_PSR_BN (__IA64_UL(1) << IA64_PSR_BN_BIT) +#define IA64_PSR_IA (__IA64_UL(1) << IA64_PSR_IA_BIT) /* User mask bits: */ #define IA64_PSR_UM (IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | IA64_PSR_MFH) diff --git a/include/asm-ia64/param.h b/include/asm-ia64/param.h index dc82a64fc40ecf2bfaa9aed6b444923e277e0033..eaee5da9a787befcd097bb3b428d836a5e2ad6e4 100644 --- a/include/asm-ia64/param.h +++ b/include/asm-ia64/param.h @@ -4,8 +4,8 @@ /* * Fundamental kernel parameters. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co + * David Mosberger-Tang <davidm@hpl.hp.com> */ #include <linux/config.h> @@ -33,6 +33,7 @@ #define MAXHOSTNAMELEN 64 /* max length of hostname */ #ifdef __KERNEL__ +# define USER_HZ HZ # define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ #endif diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index 2aaaab2b28790dac6a308774fefbcda053228ea7..7ec7f24575e1eb3f64955e01b99d0563f50ad225 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -21,7 +21,7 @@ #define PCIBIOS_MIN_MEM 0x10000000 void pcibios_config_init(void); -struct pci_bus * pcibios_scan_root(int seg, int bus); +struct pci_bus * pcibios_scan_root(int bus); extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value); extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value); diff --git a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h index c919520f9bcccb976e084efc52e5d7cc419d0d32..493406169337095e842738ce31bd3a1d0f452c87 100644 --- a/include/asm-ia64/pgalloc.h +++ b/include/asm-ia64/pgalloc.h @@ -15,9 +15,10 @@ #include <linux/config.h> +#include <linux/compiler.h> #include <linux/mm.h> +#include <linux/page-flags.h> #include <linux/threads.h> -#include <linux/compiler.h> #include <asm/mmu_context.h> #include <asm/processor.h> diff --git a/include/asm-ia64/rmap.h b/include/asm-ia64/rmap.h index 6738fe9e228f8e415bc5c8b61eca6451974fd840..179c565dd7d60d778f6b1c23c263e65544b2cfee 100644 --- a/include/asm-ia64/rmap.h +++ b/include/asm-ia64/rmap.h @@ -1,7 +1,7 @@ -#ifndef _IA64_RMAP_H -#define _IA64_RMAP_H +#ifndef _ASM_IA64_RMAP_H +#define _ASM_IA64_RMAP_H /* nothing to see, move along */ #include <asm-generic/rmap.h> -#endif +#endif /* _ASM_IA64_RMAP_H */ diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h index 76698ee6028fc015410596fe72f7dacdb456e7e8..45811e953c596a53e461f41726e3b88482cb1141 100644 --- a/include/asm-ia64/smp.h +++ b/include/asm-ia64/smp.h @@ -17,6 +17,7 @@ #include <linux/threads.h> #include <linux/kernel.h> +#include <asm/bitops.h> #include <asm/io.h> #include <asm/param.h> #include <asm/processor.h> @@ -36,6 +37,7 @@ extern struct smp_boot_data { extern char no_int_routing __initdata; +extern unsigned long phys_cpu_present_map; extern volatile unsigned long cpu_online_map; extern unsigned long ipi_base_addr; extern unsigned char smp_int_redirect; @@ -45,23 +47,26 @@ extern volatile int ia64_cpu_to_sapicid[]; extern unsigned long ap_wakeup_vector; -#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) -extern inline unsigned int num_online_cpus(void) +#define cpu_possible(cpu) (phys_cpu_present_map & (1UL << (cpu))) +#define cpu_online(cpu) (cpu_online_map & (1UL << (cpu))) + +static inline unsigned int +num_online_cpus (void) { return hweight64(cpu_online_map); } -extern inline int any_online_cpu(unsigned int mask) +static inline int +any_online_cpu (unsigned int mask) { if (mask & cpu_online_map) return __ffs(mask & cpu_online_map); - return -1; } /* - * Function to map hard smp processor id to logical id. Slow, so - * don't use this in performance-critical code. + * Function to map hard smp processor id to logical id. Slow, so don't use this in + * performance-critical code. */ static inline int cpu_logical_id (int cpuid) @@ -120,11 +125,9 @@ hard_smp_processor_id (void) } /* Upping and downing of CPUs */ -extern int __cpu_disable(void); -extern void __cpu_die(unsigned int cpu); -extern int __cpu_up(unsigned int cpu); - -#define NO_PROC_ID 0xffffffff /* no processor magic marker */ +extern int __cpu_disable (void); +extern void __cpu_die (unsigned int cpu); +extern int __cpu_up (unsigned int cpu); extern void __init init_smp_config (void); extern void smp_do_timer (struct pt_regs *regs); diff --git a/include/asm-ia64/smplock.h b/include/asm-ia64/smplock.h index d5b5222b344bf7289b0c36f3f38cc10dd2433a0d..103185f86e30842c9da43993f73ddbbc13d55dfc 100644 --- a/include/asm-ia64/smplock.h +++ b/include/asm-ia64/smplock.h @@ -14,11 +14,6 @@ extern spinlock_t kernel_flag; #ifdef CONFIG_SMP # define kernel_locked() spin_is_locked(&kernel_flag) -# define check_irq_holder(cpu) \ -do { \ - if (global_irq_holder == (cpu)) \ - BUG(); \ -} while (0) #else # define kernel_locked() (1) #endif @@ -26,12 +21,10 @@ do { \ /* * Release global kernel lock and global interrupt lock */ -#define release_kernel_lock(task, cpu) \ +#define release_kernel_lock(task) \ do { \ - if (unlikely(task->lock_depth >= 0)) { \ + if (unlikely(task->lock_depth >= 0)) \ spin_unlock(&kernel_flag); \ - check_irq_holder(cpu); \ - } \ } while (0) /* diff --git a/include/asm-ia64/softirq.h b/include/asm-ia64/softirq.h index 5f129aaacc05b62f111dd60fcc64d62559d5d040..a50f2d240aac39494de5316f508a7156d0a1f5bd 100644 --- a/include/asm-ia64/softirq.h +++ b/include/asm-ia64/softirq.h @@ -4,23 +4,23 @@ #include <linux/compiler.h> /* - * Copyright (C) 1998-2001 Hewlett-Packard Co + * Copyright (C) 1998-2002 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> */ -#include <asm/hardirq.h> #include <linux/compiler.h> +#include <linux/preempt.h> -#define __local_bh_enable() do { barrier(); really_local_bh_count()--; } while (0) - -#define local_bh_disable() do { really_local_bh_count()++; barrier(); } while (0) -#define local_bh_enable() \ -do { \ - __local_bh_enable(); \ - if (unlikely(local_softirq_pending()) && really_local_bh_count() == 0) \ - do_softirq(); \ -} while (0) +#include <asm/hardirq.h> +#define __local_bh_enable() do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) -#define in_softirq() (really_local_bh_count() != 0) +#define local_bh_disable() do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define local_bh_enable() \ +do { \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && local_softirq_pending())) \ + do_softirq(); \ + preempt_check_resched(); \ +} while (0) #endif /* _ASM_IA64_SOFTIRQ_H */ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index b56387ef185e0e286645d72ee2cd9a803091e163..4a944ee66020cd6dab43817e95933e6dd551e6d3 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -17,6 +17,7 @@ #include <asm/kregs.h> #include <asm/page.h> +#include <asm/pal.h> #define KERNEL_START (PAGE_OFFSET + 68*1024*1024) @@ -103,6 +104,8 @@ ia64_insn_group_barrier (void) #define set_mb(var, value) do { (var) = (value); mb(); } while (0) #define set_wmb(var, value) do { (var) = (value); mb(); } while (0) +#define safe_halt() ia64_pal_halt(1) /* PAL_HALT */ + /* * The group barrier in front of the rsm & ssm are necessary to ensure * that none of the previous instructions in the same group are @@ -169,27 +172,7 @@ do { \ #endif /* !CONFIG_IA64_DEBUG_IRQ */ #define local_irq_enable() __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory") - -#define local_irq_disable() local_irq_disable () #define local_save_flags(flags) __asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory") -#define local_irq_save(flags) local_irq_save(flags) -#define save_and_cli(flags) local_irq_save(flags) - -#ifdef CONFIG_SMP - extern void __global_cli (void); - extern void __global_sti (void); - extern unsigned long __global_save_flags (void); - extern void __global_restore_flags (unsigned long); -# define cli() __global_cli() -# define sti() __global_sti() -# define save_flags(flags) ((flags) = __global_save_flags()) -# define restore_flags(flags) __global_restore_flags(flags) -#else /* !CONFIG_SMP */ -# define cli() local_irq_disable() -# define sti() local_irq_enable() -# define save_flags(flags) local_save_flags(flags) -# define restore_flags(flags) local_irq_restore(flags) -#endif /* !CONFIG_SMP */ /* * Force an unresolved reference if someone tries to use @@ -377,7 +360,7 @@ static inline void ia32_load_state(struct task_struct *t __attribute__((unused)) * newly created thread returns directly to * ia64_ret_from_syscall_clear_r8. */ -extern void ia64_switch_to (void *next_task); +extern struct task_struct *ia64_switch_to (void *next_task); struct task_struct; @@ -391,14 +374,14 @@ extern void ia64_load_extra (struct task_struct *task); # define PERFMON_IS_SYSWIDE() (0) #endif -#define __switch_to(prev,next) do { \ +#define __switch_to(prev,next,last) do { \ if (((prev)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) \ || IS_IA32_PROCESS(ia64_task_regs(prev)) || PERFMON_IS_SYSWIDE()) \ ia64_save_extra(prev); \ if (((next)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) \ || IS_IA32_PROCESS(ia64_task_regs(next)) || PERFMON_IS_SYSWIDE()) \ ia64_load_extra(next); \ - ia64_switch_to((next)); \ + (last) = ia64_switch_to((next)); \ } while (0) #ifdef CONFIG_SMP @@ -413,19 +396,19 @@ extern void ia64_load_extra (struct task_struct *task); * task->thread.fph, avoiding the complication of having to fetch * the latest fph state from another CPU. */ -# define switch_to(prev,next) do { \ +# define switch_to(prev,next,last) do { \ if (ia64_psr(ia64_task_regs(prev))->mfh) { \ ia64_psr(ia64_task_regs(prev))->mfh = 0; \ (prev)->thread.flags |= IA64_THREAD_FPH_VALID; \ __ia64_save_fpu((prev)->thread.fph); \ } \ ia64_psr(ia64_task_regs(prev))->dfh = 1; \ - __switch_to(prev,next); \ + __switch_to(prev,next,last); \ } while (0) #else -# define switch_to(prev,next) do { \ +# define switch_to(prev,next,last) do { \ ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next)); \ - __switch_to(prev,next); \ + __switch_to(prev,next,last); \ } while (0) #endif diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h index de038b9d1f4244cca1e7ad316a461b699d88a9b5..dbe71b298f7c9ed6449113aa3120400829713ceb 100644 --- a/include/asm-ia64/tlb.h +++ b/include/asm-ia64/tlb.h @@ -22,7 +22,7 @@ * unmapping a portion of the virtual address space, these hooks are called according to * the following template: * - * tlb <- tlb_gather_mmu(mm); // start unmap for address space MM + * tlb <- tlb_gather_mmu(mm, full_mm_flush); // start unmap for address space MM * { * for each vma that needs a shootdown do { * tlb_start_vma(tlb, vma); @@ -45,7 +45,7 @@ #ifdef CONFIG_SMP # define FREE_PTE_NR 2048 -# define tlb_fast_mode(tlb) ((tlb)->nr == ~0UL) +# define tlb_fast_mode(tlb) ((tlb)->nr == ~0U) #else # define FREE_PTE_NR 0 # define tlb_fast_mode(tlb) (1) @@ -53,7 +53,8 @@ typedef struct { struct mm_struct *mm; - unsigned long nr; /* == ~0UL => fast mode */ + unsigned int nr; /* == ~0U => fast mode */ + unsigned int fullmm; /* non-zero means full mm flush */ unsigned long freed; /* number of pages freed */ unsigned long start_addr; unsigned long end_addr; @@ -70,10 +71,17 @@ extern mmu_gather_t mmu_gathers[NR_CPUS]; static inline void ia64_tlb_flush_mmu (mmu_gather_t *tlb, unsigned long start, unsigned long end) { - unsigned long nr; + unsigned int nr; - if (unlikely (end - start >= 1024*1024*1024*1024UL - || rgn_index(start) != rgn_index(end - 1))) + if (tlb->fullmm) { + /* + * Tearing down the entire address space. This happens both as a result + * of exit() and execve(). The latter case necessitates the call to + * flush_tlb_mm() here. + */ + flush_tlb_mm(tlb->mm); + } else if (unlikely (end - start >= 1024*1024*1024*1024UL + || REGION_NUMBER(start) != REGION_NUMBER(end - 1))) { /* * If we flush more than a tera-byte or across regions, we're probably @@ -110,16 +118,21 @@ ia64_tlb_flush_mmu (mmu_gather_t *tlb, unsigned long start, unsigned long end) * Return a pointer to an initialized mmu_gather_t. */ static inline mmu_gather_t * -tlb_gather_mmu (struct mm_struct *mm) +tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush) { mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()]; tlb->mm = mm; + tlb->nr = 0; + if (full_mm_flush || num_online_cpus() == 1) + /* + * Use fast mode if only 1 CPU is online or if we're tearing down the + * entire address space. + */ + tlb->nr = ~0U; + tlb->fullmm = full_mm_flush; tlb->freed = 0; tlb->start_addr = ~0UL; - - /* Use fast mode if only one CPU is online */ - tlb->nr = smp_num_cpus > 1 ? 0UL : ~0UL; return tlb; } @@ -152,7 +165,7 @@ tlb_finish_mmu (mmu_gather_t *tlb, unsigned long start, unsigned long end) * PTE, not just those pointing to (normal) physical memory. */ static inline void -tlb_remove_tlb_entry (mmu_gather_t *tlb, pte_t pte, unsigned long address) +tlb_remove_tlb_entry (mmu_gather_t *tlb, pte_t *ptep, unsigned long address) { if (tlb->start_addr == ~0UL) tlb->start_addr = address;