Commit b26fe855 authored by David Mosberger's avatar David Mosberger Committed by David Mosberger

ia64: More 2.5.xx syncing.

parent 9f1e5eef
......@@ -245,7 +245,14 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Disable VHPT' CONFIG_DISABLE_VHPT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool ' Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
bool ' Early printk support' CONFIG_IA64_EARLY_PRINTK
if [ "$CONFIG_IA64_EARLY_PRINTK" != "n" ]; then
bool ' Early printk on MMIO serial port' CONFIG_IA64_EARLY_PRINTK_UART
if [ "$CONFIG_IA64_EARLY_PRINTK_UART" != "n" ]; then
hex ' UART MMIO base address' CONFIG_IA64_EARLY_PRINTK_UART_BASE ff5e0000
fi
bool ' Early printk on VGA' CONFIG_IA64_EARLY_PRINTK_VGA
fi
bool ' Debug memory allocations' CONFIG_DEBUG_SLAB
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
......
......@@ -450,7 +450,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
** We need the alignment to invalidate I/O TLB using
** SBA HW features in the unmap path.
*/
unsigned long o = 1 << get_order(bits_wanted << IOVP_SHIFT);
unsigned long o = 1UL << get_order(bits_wanted << IOVP_SHIFT);
uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
unsigned long mask;
......@@ -1005,7 +1005,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg,
** Prepare for first/next DMA stream
*/
dma_len = sba_sg_len(startsg);
dma_offset = sba_sg_address(startsg);
dma_offset = (unsigned long) sba_sg_address(startsg);
startsg++;
nents--;
......@@ -1016,7 +1016,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg,
** to take advantage of the block IO TLB flush.
*/
while (nents) {
unsigned int end_offset = dma_offset + dma_len;
unsigned long end_offset = dma_offset + dma_len;
/* prev entry must end on a page boundary */
if (end_offset & IOVP_MASK)
......@@ -1114,9 +1114,9 @@ int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
#endif
/* Fast path single entry scatterlists. */
if (nents == 1) {
sba_sg_iova(sglist) = (char *)sba_map_single(dev,
sba_sg_iova(sglist),
sba_sg_len(sglist), direction);
sba_sg_iova(sglist) = sba_map_single(dev,
(void *) sba_sg_iova(sglist),
sba_sg_len(sglist), direction);
sba_sg_iova_len(sglist) = sba_sg_len(sglist);
#ifdef CONFIG_PROC_FS
/*
......@@ -1455,7 +1455,7 @@ sba_common_init(struct sba_device *sba_dev)
sba_dev->ioc[i].pdir_base[0] = 0x8000badbadc0ffeeULL;
for (reserved_iov = 0xA0000 ; reserved_iov < 0xC0000 ; reserved_iov += IOVP_SIZE) {
u64 *res_ptr = sba_dev->ioc[i].res_map;
u64 *res_ptr = (u64 *) sba_dev->ioc[i].res_map;
int index = PDIR_INDEX(reserved_iov);
int res_word;
u64 mask;
......@@ -1586,8 +1586,8 @@ void __init sba_init(void)
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
if (pci_resource_flags(device, i) == IORESOURCE_MEM) {
hpa = ioremap(pci_resource_start(device, i),
pci_resource_len(device, i));
hpa = (u64) ioremap(pci_resource_start(device, i),
pci_resource_len(device, i));
break;
}
}
......@@ -1595,7 +1595,7 @@ void __init sba_init(void)
func_id = READ_REG(hpa + SBA_FUNC_ID);
if (func_id == ZX1_FUNC_ID_VALUE) {
(void)strcpy(sba_rev, "zx1");
strcpy(sba_rev, "zx1");
func_offset = zx1_func_offsets;
} else {
return;
......
......@@ -12,112 +12,65 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include <asm/iosapic.h>
#include <asm/dma.h>
#include <asm/efi.h>
#include <asm/iosapic.h>
#include "../drivers/acpi/include/platform/acgcc.h"
#include "../drivers/acpi/include/actypes.h"
#include "../drivers/acpi/include/acexcep.h"
#include "../drivers/acpi/include/acpixf.h"
#include "../drivers/acpi/include/actbl.h"
#include "../drivers/acpi/include/acconfig.h"
#include "../drivers/acpi/include/acmacros.h"
#include "../drivers/acpi/include/aclocal.h"
#include "../drivers/acpi/include/acobject.h"
#include "../drivers/acpi/include/acstruct.h"
#include "../drivers/acpi/include/acnamesp.h"
#include "../drivers/acpi/include/acutils.h"
#include "../drivers/acpi/acpi_bus.h"
extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *,
unsigned long *);
#define PFX "hpzx1: "
static int hpzx1_devices;
struct fake_pci_dev {
struct fake_pci_dev *next;
unsigned char bus;
unsigned int devfn;
int sizing; // in middle of BAR sizing operation?
unsigned long csr_base;
unsigned int csr_size;
unsigned long csr_size;
unsigned long mapped_csrs; // ioremapped
int sizing; // in middle of BAR sizing operation?
};
static struct fake_pci_dev *fake_pci_head, **fake_pci_tail = &fake_pci_head;
static struct pci_ops *orig_pci_ops;
static inline struct fake_pci_dev *
fake_pci_find_slot(unsigned char bus, unsigned int devfn)
{
struct fake_pci_dev *dev;
for (dev = fake_pci_head; dev; dev = dev->next)
if (dev->bus == bus && dev->devfn == devfn)
return dev;
return NULL;
}
static struct fake_pci_dev *
alloc_fake_pci_dev(void)
{
struct fake_pci_dev *dev;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
memset(dev, 0, sizeof(*dev));
*fake_pci_tail = dev;
fake_pci_tail = &dev->next;
return dev;
}
#define HP_CFG_RD(sz, bits, name) \
static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
{ \
struct fake_pci_dev *fake_dev; \
if (!(fake_dev = fake_pci_find_slot(dev->bus->number, dev->devfn))) \
return orig_pci_ops->name(dev, where, value); \
\
switch (where) { \
case PCI_COMMAND: \
*value = read##sz(fake_dev->mapped_csrs + where); \
*value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \
break; \
case PCI_BASE_ADDRESS_0: \
if (fake_dev->sizing) \
*value = ~(fake_dev->csr_size - 1); \
else \
*value = (fake_dev->csr_base & \
PCI_BASE_ADDRESS_MEM_MASK) | \
PCI_BASE_ADDRESS_SPACE_MEMORY; \
fake_dev->sizing = 0; \
break; \
default: \
*value = read##sz(fake_dev->mapped_csrs + where); \
break; \
} \
return PCIBIOS_SUCCESSFUL; \
#define HP_CFG_RD(sz, bits, name) \
static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
{ \
struct fake_pci_dev *fake_dev; \
if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
return orig_pci_ops->name(dev, where, value); \
\
if (where == PCI_BASE_ADDRESS_0) { \
if (fake_dev->sizing) \
*value = ~(fake_dev->csr_size - 1); \
else \
*value = (fake_dev->csr_base & \
PCI_BASE_ADDRESS_MEM_MASK) | \
PCI_BASE_ADDRESS_SPACE_MEMORY; \
fake_dev->sizing = 0; \
return PCIBIOS_SUCCESSFUL; \
} \
*value = read##sz(fake_dev->mapped_csrs + where); \
if (where == PCI_COMMAND) \
*value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \
return PCIBIOS_SUCCESSFUL; \
}
#define HP_CFG_WR(sz, bits, name) \
static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
{ \
struct fake_pci_dev *fake_dev; \
if (!(fake_dev = fake_pci_find_slot(dev->bus->number, dev->devfn))) \
return orig_pci_ops->name(dev, where, value); \
\
switch (where) { \
case PCI_BASE_ADDRESS_0: \
if (value == (u##bits) ~0) \
fake_dev->sizing = 1; \
break; \
default: \
write##sz(value, fake_dev->mapped_csrs + where); \
break; \
} \
return PCIBIOS_SUCCESSFUL; \
#define HP_CFG_WR(sz, bits, name) \
static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
{ \
struct fake_pci_dev *fake_dev; \
\
if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
return orig_pci_ops->name(dev, where, value); \
\
if (where == PCI_BASE_ADDRESS_0) { \
if (value == (u##bits) ~0) \
fake_dev->sizing = 1; \
return PCIBIOS_SUCCESSFUL; \
} else \
write##sz(value, fake_dev->mapped_csrs + where); \
return PCIBIOS_SUCCESSFUL; \
}
HP_CFG_RD(b, 8, read_byte)
......@@ -136,51 +89,86 @@ static struct pci_ops hp_pci_conf = {
hp_cfg_writel,
};
/*
* Assume we'll never have a physical slot higher than 0x10, so we can
* use slots above that for "fake" PCI devices to represent things
* that only show up in the ACPI namespace.
*/
#define HP_MAX_SLOT 0x10
static struct fake_pci_dev *
hpzx1_fake_pci_dev(unsigned long addr, unsigned int bus, unsigned int size)
static void
hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size)
{
struct fake_pci_dev *dev;
int slot;
struct fake_pci_dev *fake;
int slot, ret;
struct pci_dev *dev;
struct pci_bus *b, *bus = NULL;
u8 hdr;
fake = kmalloc(sizeof(*fake), GFP_KERNEL);
if (!fake) {
printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name, (void *) addr);
return;
}
memset(fake, 0, sizeof(*fake));
fake->csr_base = addr;
fake->csr_size = size;
fake->mapped_csrs = (unsigned long) ioremap(addr, size);
fake->sizing = 0;
// Note: lspci thinks 0x1f is invalid
for (slot = 0x1e; slot > HP_MAX_SLOT; slot--) {
if (!fake_pci_find_slot(bus, PCI_DEVFN(slot, 0)))
pci_for_each_bus(b)
if (busnum == b->number) {
bus = b;
break;
}
if (!bus) {
printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n",
busnum, name, (void *) addr);
kfree(fake);
return;
}
if (slot == HP_MAX_SLOT) {
printk(KERN_ERR PFX
"no slot space for device (0x%p) on bus 0x%02x\n",
(void *) addr, bus);
return NULL;
for (slot = 0x1e; slot; slot--)
if (!pci_find_slot(busnum, PCI_DEVFN(slot, 0)))
break;
if (slot < 0) {
printk(KERN_ERR PFX "No space for %s (0x%p) on bus 0x%02x\n",
name, (void *) addr, busnum);
kfree(fake);
return;
}
dev = alloc_fake_pci_dev();
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
printk(KERN_ERR PFX
"no memory for device (0x%p) on bus 0x%02x\n",
(void *) addr, bus);
return NULL;
printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name, (void *) addr);
kfree(fake);
return;
}
bus->ops = &hp_pci_conf; // replace pci ops for this bus
memset(dev, 0, sizeof(*dev));
dev->bus = bus;
dev->sysdata = fake;
dev->dev.parent = bus->dev;
dev->dev.bus = &pci_bus_type;
dev->devfn = PCI_DEVFN(slot, 0);
dev->csr_base = addr;
dev->csr_size = size;
pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr);
dev->hdr_type = hdr & 0x7f;
/*
* Drivers should ioremap what they need, but we have to do
* it here, too, so PCI config accesses work.
*/
dev->mapped_csrs = (unsigned long) ioremap(dev->csr_base, dev->csr_size);
pci_setup_device(dev);
return dev;
// pci_insert_device() without running /sbin/hotplug
list_add_tail(&dev->bus_list, &bus->devices);
list_add_tail(&dev->global_list, &pci_devices);
strcpy(dev->dev.name, dev->name);
strcpy(dev->dev.bus_id, dev->slot_name);
ret = device_register(&dev->dev);
if (ret < 0)
printk(KERN_INFO PFX "fake device registration failed (%d)\n", ret);
printk(KERN_INFO PFX "%s at 0x%lx; pci dev %s\n", name, addr, dev->slot_name);
hpzx1_devices++;
}
typedef struct {
......@@ -190,10 +178,10 @@ typedef struct {
u8 csr_length[8];
} acpi_hp_vendor_long;
#define HP_CCSR_LENGTH 0x21
#define HP_CCSR_TYPE 0x2
#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \
0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
#define HP_CCSR_LENGTH 0x21
#define HP_CCSR_TYPE 0x2
#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \
0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
extern acpi_status acpi_get_crs(acpi_handle, acpi_buffer *);
extern acpi_resource *acpi_get_crs_next(acpi_buffer *, int *);
......@@ -214,7 +202,7 @@ hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
*csr_length = 0;
status = acpi_get_crs(obj, &buf);
if (status != AE_OK) {
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PFX "Unable to get _CRS data on object\n");
return status;
}
......@@ -255,13 +243,12 @@ static acpi_status
hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
{
u64 csr_base = 0, csr_length = 0;
char *name = context;
struct fake_pci_dev *dev;
acpi_status status;
char *name = context;
char fullname[16];
status = hp_csr_space(obj, &csr_base, &csr_length);
if (status != AE_OK)
if (ACPI_FAILURE(status))
return status;
/*
......@@ -269,14 +256,10 @@ hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
* includes both SBA and IOC. Make SBA and IOC show up
* separately in PCI space.
*/
if ((dev = hpzx1_fake_pci_dev(csr_base, 0, 0x1000)))
printk(KERN_INFO PFX "%s SBA at 0x%lx; pci dev %02x:%02x.%d\n",
name, csr_base, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
if ((dev = hpzx1_fake_pci_dev(csr_base + 0x1000, 0, 0x1000)))
printk(KERN_INFO PFX "%s IOC at 0x%lx; pci dev %02x:%02x.%d\n",
name, csr_base + 0x1000, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
sprintf(fullname, "%s SBA", name);
hpzx1_fake_pci_dev(fullname, 0, csr_base, 0x1000);
sprintf(fullname, "%s IOC", name);
hpzx1_fake_pci_dev(fullname, 0, csr_base + 0x1000, 0x1000);
return AE_OK;
}
......@@ -284,28 +267,24 @@ hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
static acpi_status
hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
{
acpi_status status;
u64 csr_base = 0, csr_length = 0;
acpi_status status;
NATIVE_UINT busnum;
char *name = context;
NATIVE_UINT busnum = 0;
struct fake_pci_dev *dev;
char fullname[32];
status = hp_csr_space(obj, &csr_base, &csr_length);
if (status != AE_OK)
if (ACPI_FAILURE(status))
return status;
status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PFX "evaluate _BBN fail=0x%x\n", status);
printk(KERN_WARNING PFX "evaluate _BBN fail=0x%x\n", status);
busnum = 0; // no _BBN; stick it on bus 0
}
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, (unsigned int) busnum, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
sprintf(fullname, "%s _BBN 0x%02x", name, (unsigned int) busnum);
hpzx1_fake_pci_dev(fullname, busnum, csr_base, csr_length);
return AE_OK;
}
......@@ -315,6 +294,8 @@ hpzx1_acpi_dev_init(void)
{
extern struct pci_ops *pci_root_ops;
orig_pci_ops = pci_root_ops;
/*
* Make fake PCI devices for the following hardware in the
* ACPI namespace. This makes it more convenient for drivers
......@@ -329,10 +310,10 @@ hpzx1_acpi_dev_init(void)
*/
acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL);
#ifdef CONFIG_IA64_HP_PROTO
if (fake_pci_tail != &fake_pci_head) {
if (hpzx1_devices) {
#endif
acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002", NULL);
acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003", NULL);
acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002 PCI LBA", NULL);
acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003 AGP LBA", NULL);
#ifdef CONFIG_IA64_HP_PROTO
}
......@@ -343,48 +324,25 @@ hpzx1_acpi_dev_init(void)
* if we didn't find anything, add the things we know are
* there.
*/
if (fake_pci_tail == &fake_pci_head) {
if (hpzx1_devices == 0) {
u64 hpa, csr_base;
struct fake_pci_dev *dev;
csr_base = 0xfed00000UL;
hpa = (u64) ioremap(csr_base, 0x1000);
hpa = (u64) ioremap(csr_base, 0x2000);
if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) {
if ((dev = hpzx1_fake_pci_dev(csr_base, 0, 0x1000)))
printk(KERN_INFO PFX "HWP0001 SBA at 0x%lx; "
"pci dev %02x:%02x.%d\n", csr_base,
dev->bus, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
if ((dev = hpzx1_fake_pci_dev(csr_base + 0x1000, 0,
0x1000)))
printk(KERN_INFO PFX "HWP0001 IOC at 0x%lx; "
"pci dev %02x:%02x.%d\n",
csr_base + 0x1000,
dev->bus, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
hpzx1_fake_pci_dev("HWP0001 SBA", 0, csr_base, 0x1000);
hpzx1_fake_pci_dev("HWP0001 IOC", 0, csr_base + 0x1000,
0x1000);
csr_base = 0xfed24000UL;
iounmap(hpa);
hpa = (u64) ioremap(csr_base, 0x1000);
if ((dev = hpzx1_fake_pci_dev(csr_base, 0x40, 0x1000)))
printk(KERN_INFO PFX "HWP0003 AGP LBA at "
"0x%lx; pci dev %02x:%02x.%d\n",
csr_base,
dev->bus, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
hpzx1_fake_pci_dev("HWP0003 AGP LBA", 0x40, csr_base,
0x1000);
}
iounmap(hpa);
}
#endif
if (fake_pci_tail == &fake_pci_head)
return;
/*
* Replace PCI ops, but only if we made fake devices.
*/
orig_pci_ops = pci_root_ops;
pci_root_ops = &hp_pci_conf;
}
extern void sba_init(void);
......@@ -392,9 +350,16 @@ extern void sba_init(void);
void
hpzx1_pci_fixup (int phase)
{
if (phase == 0)
hpzx1_acpi_dev_init();
iosapic_pci_fixup(phase);
if (phase == 1)
switch (phase) {
case 0:
/* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */
MAX_DMA_ADDRESS = ~0UL;
break;
case 1:
hpzx1_acpi_dev_init();
sba_init();
break;
}
}
......@@ -474,7 +474,7 @@ acpi_find_rsdp (void)
}
#ifdef CONFIG_SERIAL_ACPI
#ifdef CONFIG_SERIAL_8250_ACPI
#include <linux/acpi_serial.h>
......@@ -529,7 +529,7 @@ acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
return 0;
}
#endif /* CONFIG_SERIAL_ACPI */
#endif /* CONFIG_SERIAL_8250_ACPI */
int __init
......@@ -587,7 +587,7 @@ acpi_boot_init (char *cmdline)
if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
printk(KERN_ERR PREFIX "Can't find FADT\n");
#ifdef CONFIG_SERIAL_ACPI
#ifdef CONFIG_SERIAL_8250_ACPI
/*
* TBD: Need phased approach to table parsing (only do those absolutely
* required during boot-up). Recommend expanding concept of fix-
......
......@@ -446,6 +446,9 @@ efi_init (void)
} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
efi.sal_systab = __va(config_tables[i].table);
printk(" SALsystab=0x%lx", config_tables[i].table);
} else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
efi.hcdp = __va(config_tables[i].table);
printk(" HCDP=0x%lx", config_tables[i].table);
}
}
printk("\n");
......
......@@ -160,6 +160,10 @@ set_rte (unsigned int vector, unsigned long dest)
int pin;
char redir;
#ifdef DEBUG_IRQ_ROUTING
printk(KERN_DEBUG "set_rte: routing vector 0x%02x to 0x%lx\n", vector, dest);
#endif
pin = iosapic_irq[vector].pin;
if (pin < 0)
return; /* not an IOSAPIC interrupt */
......@@ -406,7 +410,7 @@ iosapic_reassign_vector (int vector)
|| iosapic_irq[vector].polarity || iosapic_irq[vector].trigger)
{
new_vector = ia64_alloc_irq();
printk("Reassigning Vector 0x%x to 0x%x\n", vector, new_vector);
printk("Reassigning vector 0x%x to 0x%x\n", vector, new_vector);
memcpy (&iosapic_irq[new_vector], &iosapic_irq[vector],
sizeof(struct iosapic_irq));
memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq));
......@@ -757,10 +761,11 @@ iosapic_pci_fixup (int phase)
if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
static int cpu_index = 0;
set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
while (!cpu_online(cpu_index))
if (++cpu_index >= NR_CPUS)
cpu_index = 0;
for (cpu_index++; !cpu_online(cpu_index % NR_CPUS); cpu_index++);
cpu_index %= NR_CPUS;
set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
} else {
/*
* Direct the interrupt vector to the current cpu,
......
......@@ -368,7 +368,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
* use the action we have.
*/
action = NULL;
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
action = desc->action;
status &= ~IRQ_PENDING; /* we commit to handling */
status |= IRQ_INPROGRESS; /* we are handling it */
......@@ -381,7 +381,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
* a different instance of this same irq, the other processor
* will take care of it.
*/
if (!action)
if (unlikely(!action))
goto out;
/*
......@@ -403,8 +403,8 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
break;
desc->status &= ~IRQ_PENDING;
}
desc->status &= ~IRQ_INPROGRESS;
out:
desc->status &= ~IRQ_INPROGRESS;
/*
* The ->end() handler has to deal with interrupts which got
* disabled while the handler was running.
......
......@@ -347,6 +347,14 @@ setup_arch (char **cmdline_p)
#ifdef CONFIG_ACPI_BOOT
acpi_boot_init(*cmdline_p);
#endif
#ifdef CONFIG_SERIAL_HCDP
if (efi.hcdp) {
void setup_serial_hcdp(void *);
/* Setup the serial ports described by HCDP */
setup_serial_hcdp(efi.hcdp);
}
#endif
#ifdef CONFIG_VT
# if defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
......
......@@ -130,6 +130,8 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
siginfo_t siginfo;
int sig, code;
die_if_kernel("bad break", regs, break_num);
/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
siginfo.si_imm = break_num;
......
......@@ -108,7 +108,7 @@ free_initmem (void)
addr = (unsigned long) &__init_begin;
for (; addr < (unsigned long) &__init_end; addr += PAGE_SIZE) {
clear_bit(PG_reserved, &virt_to_page(addr)->flags);
ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1);
free_page(addr);
++totalram_pages;
......@@ -162,9 +162,9 @@ free_initrd_mem (unsigned long start, unsigned long end)
if (!virt_addr_valid(start))
continue;
page = virt_to_page(start);
clear_bit(PG_reserved, &page->flags);
ClearPageReserved(page);
set_page_count(page, 1);
__free_page(page);
free_page(page);
++totalram_pages;
}
}
......
#ifndef AGP_H
#define AGP_H 1
#ifndef _ASM_IA64_AGP_H
#define _ASM_IA64_AGP_H
/* dummy for now */
/*
* IA-64 specific AGP definitions.
*
* Copyright (C) 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#define map_page_into_agp(page)
#define unmap_page_from_agp(page)
#define flush_agp_mappings()
#define flush_agp_cache() mb()
/*
* To avoid memory-attribute aliasing issues, we require that the AGPGART engine operate
* in coherent mode, which lets us map the AGP memory as normal (write-back) memory
* (unlike x86, where it gets mapped "write-coalescing").
*/
#define map_page_into_agp(page) /* nothing */
#define unmap_page_from_agp(page) /* nothing */
#define flush_agp_mappings() /* nothing */
#define flush_agp_cache() mb()
#endif
#endif /* _ASM_IA64_AGP_H */
......@@ -190,6 +190,9 @@ typedef void efi_reset_system_t (int reset_type, efi_status_t status,
#define SAL_SYSTEM_TABLE_GUID \
EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
#define HCDP_TABLE_GUID \
EFI_GUID( 0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
typedef struct {
efi_guid_t guid;
u64 table;
......@@ -225,6 +228,7 @@ extern struct efi {
void *smbios; /* SM BIOS table */
void *sal_systab; /* SAL system table */
void *boot_info; /* boot info table */
void *hcdp; /* HCDP table */
efi_get_time_t *get_time;
efi_set_time_t *set_time;
efi_get_wakeup_time_t *get_wakeup_time;
......
......@@ -2,7 +2,7 @@
#define _ASM_IA64_ELF_H
/*
* ELF archtecture specific definitions.
* ELF-specific definitions.
*
* Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
......
......@@ -87,7 +87,12 @@ typedef union ia64_va {
#define REGION_SIZE REGION_NUMBER(1)
#define REGION_KERNEL 7
#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define ia64_abort() __builtin_trap()
#else
# define ia64_abort() (*(volatile int *) 0 = 0)
#endif
#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
#define PAGE_BUG(page) do { BUG(); } while (0)
static __inline__ int
......
/*
* include/asm-ia64/serial.h
*
*
* Derived from the i386 version.
*/
......@@ -35,7 +35,7 @@
#else
#define RS_TABLE_SIZE
#endif
/*
* The following define the access methods for the HUB6 card. All
* access is through two ports for all 24 possible chips. The card is
......@@ -115,21 +115,8 @@
#define HUB6_SERIAL_PORT_DFNS
#endif
#ifdef CONFIG_MCA
#define MCA_SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, 0x3220, 3, STD_COM_FLAGS }, \
{ 0, BASE_BAUD, 0x3228, 3, STD_COM_FLAGS }, \
{ 0, BASE_BAUD, 0x4220, 3, STD_COM_FLAGS }, \
{ 0, BASE_BAUD, 0x4228, 3, STD_COM_FLAGS }, \
{ 0, BASE_BAUD, 0x5220, 3, STD_COM_FLAGS }, \
{ 0, BASE_BAUD, 0x5228, 3, STD_COM_FLAGS },
#else
#define MCA_SERIAL_PORT_DFNS
#endif
#define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS \
HUB6_SERIAL_PORT_DFNS \
MCA_SERIAL_PORT_DFNS
HUB6_SERIAL_PORT_DFNS
......@@ -123,13 +123,20 @@ 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;
/*
* Use fast mode if only 1 CPU is online.
*
* It would be tempting to turn on fast-mode for full_mm_flush as well. But this
* doesn't work because of speculative accesses and software prefetching: the page
* table of "mm" may (and usually is) the currently active page table and even
* though the kernel won't do any user-space accesses during the TLB shoot down, a
* compiler might use speculation or lfetch.fault on what happens to be a valid
* user-space address. This in turn could trigger a TLB miss fault (or a VHPT
* walk) and re-insert a TLB entry we just removed. Slow mode avoids such
* problems. (We could make fast-mode work by switching the current task to a
* different "mm" during the shootdown.) --davidm 08/02/2002
*/
tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
tlb->fullmm = full_mm_flush;
tlb->freed = 0;
tlb->start_addr = ~0UL;
......
......@@ -60,6 +60,8 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
#else
if (vma->vm_mm == current->active_mm)
asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory");
else
vma->vm_mm->context = 0;
#endif
}
......
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