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 ...@@ -245,7 +245,14 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Disable VHPT' CONFIG_DISABLE_VHPT bool ' Disable VHPT' CONFIG_DISABLE_VHPT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ 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 ' Debug memory allocations' CONFIG_DEBUG_SLAB
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG 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) ...@@ -450,7 +450,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
** We need the alignment to invalidate I/O TLB using ** We need the alignment to invalidate I/O TLB using
** SBA HW features in the unmap path. ** 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); uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
unsigned long mask; unsigned long mask;
...@@ -1005,7 +1005,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, ...@@ -1005,7 +1005,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg,
** Prepare for first/next DMA stream ** Prepare for first/next DMA stream
*/ */
dma_len = sba_sg_len(startsg); dma_len = sba_sg_len(startsg);
dma_offset = sba_sg_address(startsg); dma_offset = (unsigned long) sba_sg_address(startsg);
startsg++; startsg++;
nents--; nents--;
...@@ -1016,7 +1016,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, ...@@ -1016,7 +1016,7 @@ sba_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg,
** to take advantage of the block IO TLB flush. ** to take advantage of the block IO TLB flush.
*/ */
while (nents) { 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 */ /* prev entry must end on a page boundary */
if (end_offset & IOVP_MASK) if (end_offset & IOVP_MASK)
...@@ -1114,8 +1114,8 @@ int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, ...@@ -1114,8 +1114,8 @@ int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
#endif #endif
/* Fast path single entry scatterlists. */ /* Fast path single entry scatterlists. */
if (nents == 1) { if (nents == 1) {
sba_sg_iova(sglist) = (char *)sba_map_single(dev, sba_sg_iova(sglist) = sba_map_single(dev,
sba_sg_iova(sglist), (void *) sba_sg_iova(sglist),
sba_sg_len(sglist), direction); sba_sg_len(sglist), direction);
sba_sg_iova_len(sglist) = sba_sg_len(sglist); sba_sg_iova_len(sglist) = sba_sg_len(sglist);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
...@@ -1455,7 +1455,7 @@ sba_common_init(struct sba_device *sba_dev) ...@@ -1455,7 +1455,7 @@ sba_common_init(struct sba_device *sba_dev)
sba_dev->ioc[i].pdir_base[0] = 0x8000badbadc0ffeeULL; sba_dev->ioc[i].pdir_base[0] = 0x8000badbadc0ffeeULL;
for (reserved_iov = 0xA0000 ; reserved_iov < 0xC0000 ; reserved_iov += IOVP_SIZE) { 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 index = PDIR_INDEX(reserved_iov);
int res_word; int res_word;
u64 mask; u64 mask;
...@@ -1586,7 +1586,7 @@ void __init sba_init(void) ...@@ -1586,7 +1586,7 @@ void __init sba_init(void)
for (i = 0; i < PCI_NUM_RESOURCES; i++) { for (i = 0; i < PCI_NUM_RESOURCES; i++) {
if (pci_resource_flags(device, i) == IORESOURCE_MEM) { if (pci_resource_flags(device, i) == IORESOURCE_MEM) {
hpa = ioremap(pci_resource_start(device, i), hpa = (u64) ioremap(pci_resource_start(device, i),
pci_resource_len(device, i)); pci_resource_len(device, i));
break; break;
} }
...@@ -1595,7 +1595,7 @@ void __init sba_init(void) ...@@ -1595,7 +1595,7 @@ void __init sba_init(void)
func_id = READ_REG(hpa + SBA_FUNC_ID); func_id = READ_REG(hpa + SBA_FUNC_ID);
if (func_id == ZX1_FUNC_ID_VALUE) { if (func_id == ZX1_FUNC_ID_VALUE) {
(void)strcpy(sba_rev, "zx1"); strcpy(sba_rev, "zx1");
func_offset = zx1_func_offsets; func_offset = zx1_func_offsets;
} else { } else {
return; return;
......
...@@ -12,80 +12,35 @@ ...@@ -12,80 +12,35 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <asm/iosapic.h>
#include <asm/dma.h>
#include <asm/efi.h> #include <asm/efi.h>
#include <asm/iosapic.h>
#include "../drivers/acpi/include/platform/acgcc.h" extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *,
#include "../drivers/acpi/include/actypes.h" unsigned long *);
#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"
#define PFX "hpzx1: " #define PFX "hpzx1: "
static int hpzx1_devices;
struct fake_pci_dev { 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 long csr_base;
unsigned int csr_size; unsigned long csr_size;
unsigned long mapped_csrs; // ioremapped 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 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) \ #define HP_CFG_RD(sz, bits, name) \
static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \ static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
{ \ { \
struct fake_pci_dev *fake_dev; \ struct fake_pci_dev *fake_dev; \
if (!(fake_dev = fake_pci_find_slot(dev->bus->number, dev->devfn))) \ if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
return orig_pci_ops->name(dev, where, value); \ return orig_pci_ops->name(dev, where, value); \
\ \
switch (where) { \ if (where == PCI_BASE_ADDRESS_0) { \
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) \ if (fake_dev->sizing) \
*value = ~(fake_dev->csr_size - 1); \ *value = ~(fake_dev->csr_size - 1); \
else \ else \
...@@ -93,11 +48,11 @@ static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \ ...@@ -93,11 +48,11 @@ static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
PCI_BASE_ADDRESS_MEM_MASK) | \ PCI_BASE_ADDRESS_MEM_MASK) | \
PCI_BASE_ADDRESS_SPACE_MEMORY; \ PCI_BASE_ADDRESS_SPACE_MEMORY; \
fake_dev->sizing = 0; \ fake_dev->sizing = 0; \
break; \ return PCIBIOS_SUCCESSFUL; \
default: \
*value = read##sz(fake_dev->mapped_csrs + where); \
break; \
} \ } \
*value = read##sz(fake_dev->mapped_csrs + where); \
if (where == PCI_COMMAND) \
*value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \
return PCIBIOS_SUCCESSFUL; \ return PCIBIOS_SUCCESSFUL; \
} }
...@@ -105,18 +60,16 @@ static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \ ...@@ -105,18 +60,16 @@ static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \ static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
{ \ { \
struct fake_pci_dev *fake_dev; \ struct fake_pci_dev *fake_dev; \
if (!(fake_dev = fake_pci_find_slot(dev->bus->number, dev->devfn))) \ \
if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
return orig_pci_ops->name(dev, where, value); \ return orig_pci_ops->name(dev, where, value); \
\ \
switch (where) { \ if (where == PCI_BASE_ADDRESS_0) { \
case PCI_BASE_ADDRESS_0: \
if (value == (u##bits) ~0) \ if (value == (u##bits) ~0) \
fake_dev->sizing = 1; \ fake_dev->sizing = 1; \
break; \ return PCIBIOS_SUCCESSFUL; \
default: \ } else \
write##sz(value, fake_dev->mapped_csrs + where); \ write##sz(value, fake_dev->mapped_csrs + where); \
break; \
} \
return PCIBIOS_SUCCESSFUL; \ return PCIBIOS_SUCCESSFUL; \
} }
...@@ -136,51 +89,86 @@ static struct pci_ops hp_pci_conf = { ...@@ -136,51 +89,86 @@ static struct pci_ops hp_pci_conf = {
hp_cfg_writel, hp_cfg_writel,
}; };
/* static void
* Assume we'll never have a physical slot higher than 0x10, so we can hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size)
* 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)
{ {
struct fake_pci_dev *dev; struct fake_pci_dev *fake;
int slot; 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;
}
// Note: lspci thinks 0x1f is invalid memset(fake, 0, sizeof(*fake));
for (slot = 0x1e; slot > HP_MAX_SLOT; slot--) { fake->csr_base = addr;
if (!fake_pci_find_slot(bus, PCI_DEVFN(slot, 0))) fake->csr_size = size;
fake->mapped_csrs = (unsigned long) ioremap(addr, size);
fake->sizing = 0;
pci_for_each_bus(b)
if (busnum == b->number) {
bus = b;
break; break;
} }
if (slot == HP_MAX_SLOT) {
printk(KERN_ERR PFX if (!bus) {
"no slot space for device (0x%p) on bus 0x%02x\n", printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n",
(void *) addr, bus); busnum, name, (void *) addr);
return NULL; kfree(fake);
return;
}
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) { if (!dev) {
printk(KERN_ERR PFX printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name, (void *) addr);
"no memory for device (0x%p) on bus 0x%02x\n", kfree(fake);
(void *) addr, bus); return;
return NULL;
} }
bus->ops = &hp_pci_conf; // replace pci ops for this bus
memset(dev, 0, sizeof(*dev));
dev->bus = bus; dev->bus = bus;
dev->sysdata = fake;
dev->dev.parent = bus->dev;
dev->dev.bus = &pci_bus_type;
dev->devfn = PCI_DEVFN(slot, 0); dev->devfn = PCI_DEVFN(slot, 0);
dev->csr_base = addr; pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
dev->csr_size = size; pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr);
dev->hdr_type = hdr & 0x7f;
/* pci_setup_device(dev);
* Drivers should ioremap what they need, but we have to do
* it here, too, so PCI config accesses work. // pci_insert_device() without running /sbin/hotplug
*/ list_add_tail(&dev->bus_list, &bus->devices);
dev->mapped_csrs = (unsigned long) ioremap(dev->csr_base, dev->csr_size); 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);
return dev; hpzx1_devices++;
} }
typedef struct { typedef struct {
...@@ -214,7 +202,7 @@ hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) ...@@ -214,7 +202,7 @@ hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
*csr_length = 0; *csr_length = 0;
status = acpi_get_crs(obj, &buf); 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"); printk(KERN_ERR PFX "Unable to get _CRS data on object\n");
return status; return status;
} }
...@@ -255,13 +243,12 @@ static acpi_status ...@@ -255,13 +243,12 @@ static acpi_status
hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret) hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
{ {
u64 csr_base = 0, csr_length = 0; u64 csr_base = 0, csr_length = 0;
char *name = context;
struct fake_pci_dev *dev;
acpi_status status; acpi_status status;
char *name = context;
char fullname[16];
status = hp_csr_space(obj, &csr_base, &csr_length); status = hp_csr_space(obj, &csr_base, &csr_length);
if (ACPI_FAILURE(status))
if (status != AE_OK)
return status; return status;
/* /*
...@@ -269,14 +256,10 @@ hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret) ...@@ -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 * includes both SBA and IOC. Make SBA and IOC show up
* separately in PCI space. * separately in PCI space.
*/ */
if ((dev = hpzx1_fake_pci_dev(csr_base, 0, 0x1000))) sprintf(fullname, "%s SBA", name);
printk(KERN_INFO PFX "%s SBA at 0x%lx; pci dev %02x:%02x.%d\n", hpzx1_fake_pci_dev(fullname, 0, csr_base, 0x1000);
name, csr_base, dev->bus, sprintf(fullname, "%s IOC", name);
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); hpzx1_fake_pci_dev(fullname, 0, csr_base + 0x1000, 0x1000);
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));
return AE_OK; return AE_OK;
} }
...@@ -284,28 +267,24 @@ hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret) ...@@ -284,28 +267,24 @@ hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
static acpi_status static acpi_status
hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret) hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
{ {
acpi_status status;
u64 csr_base = 0, csr_length = 0; u64 csr_base = 0, csr_length = 0;
acpi_status status;
NATIVE_UINT busnum;
char *name = context; char *name = context;
NATIVE_UINT busnum = 0; char fullname[32];
struct fake_pci_dev *dev;
status = hp_csr_space(obj, &csr_base, &csr_length); status = hp_csr_space(obj, &csr_base, &csr_length);
if (ACPI_FAILURE(status))
if (status != AE_OK)
return status; return status;
status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum); status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum);
if (ACPI_FAILURE(status)) { 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 busnum = 0; // no _BBN; stick it on bus 0
} }
if ((dev = hpzx1_fake_pci_dev(csr_base, busnum, csr_length))) sprintf(fullname, "%s _BBN 0x%02x", name, (unsigned int) busnum);
printk(KERN_INFO PFX "%s LBA at 0x%lx, _BBN 0x%02x; " hpzx1_fake_pci_dev(fullname, busnum, csr_base, csr_length);
"pci dev %02x:%02x.%d\n",
name, csr_base, (unsigned int) busnum, dev->bus,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
return AE_OK; return AE_OK;
} }
...@@ -315,6 +294,8 @@ hpzx1_acpi_dev_init(void) ...@@ -315,6 +294,8 @@ hpzx1_acpi_dev_init(void)
{ {
extern struct pci_ops *pci_root_ops; extern struct pci_ops *pci_root_ops;
orig_pci_ops = pci_root_ops;
/* /*
* Make fake PCI devices for the following hardware in the * Make fake PCI devices for the following hardware in the
* ACPI namespace. This makes it more convenient for drivers * ACPI namespace. This makes it more convenient for drivers
...@@ -329,10 +310,10 @@ hpzx1_acpi_dev_init(void) ...@@ -329,10 +310,10 @@ hpzx1_acpi_dev_init(void)
*/ */
acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL); acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL);
#ifdef CONFIG_IA64_HP_PROTO #ifdef CONFIG_IA64_HP_PROTO
if (fake_pci_tail != &fake_pci_head) { if (hpzx1_devices) {
#endif #endif
acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002", NULL); acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002 PCI LBA", NULL);
acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003", NULL); acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003 AGP LBA", NULL);
#ifdef CONFIG_IA64_HP_PROTO #ifdef CONFIG_IA64_HP_PROTO
} }
...@@ -343,48 +324,25 @@ hpzx1_acpi_dev_init(void) ...@@ -343,48 +324,25 @@ hpzx1_acpi_dev_init(void)
* if we didn't find anything, add the things we know are * if we didn't find anything, add the things we know are
* there. * there.
*/ */
if (fake_pci_tail == &fake_pci_head) { if (hpzx1_devices == 0) {
u64 hpa, csr_base; u64 hpa, csr_base;
struct fake_pci_dev *dev;
csr_base = 0xfed00000UL; csr_base = 0xfed00000UL;
hpa = (u64) ioremap(csr_base, 0x1000); hpa = (u64) ioremap(csr_base, 0x2000);
if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) { if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) {
if ((dev = hpzx1_fake_pci_dev(csr_base, 0, 0x1000))) hpzx1_fake_pci_dev("HWP0001 SBA", 0, csr_base, 0x1000);
printk(KERN_INFO PFX "HWP0001 SBA at 0x%lx; " hpzx1_fake_pci_dev("HWP0001 IOC", 0, csr_base + 0x1000,
"pci dev %02x:%02x.%d\n", csr_base, 0x1000);
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));
csr_base = 0xfed24000UL; csr_base = 0xfed24000UL;
iounmap(hpa); iounmap(hpa);
hpa = (u64) ioremap(csr_base, 0x1000); hpa = (u64) ioremap(csr_base, 0x1000);
if ((dev = hpzx1_fake_pci_dev(csr_base, 0x40, 0x1000))) hpzx1_fake_pci_dev("HWP0003 AGP LBA", 0x40, csr_base,
printk(KERN_INFO PFX "HWP0003 AGP LBA at " 0x1000);
"0x%lx; pci dev %02x:%02x.%d\n",
csr_base,
dev->bus, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
} }
iounmap(hpa); iounmap(hpa);
} }
#endif #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); extern void sba_init(void);
...@@ -392,9 +350,16 @@ extern void sba_init(void); ...@@ -392,9 +350,16 @@ extern void sba_init(void);
void void
hpzx1_pci_fixup (int phase) hpzx1_pci_fixup (int phase)
{ {
if (phase == 0)
hpzx1_acpi_dev_init();
iosapic_pci_fixup(phase); 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(); sba_init();
break;
}
} }
...@@ -474,7 +474,7 @@ acpi_find_rsdp (void) ...@@ -474,7 +474,7 @@ acpi_find_rsdp (void)
} }
#ifdef CONFIG_SERIAL_ACPI #ifdef CONFIG_SERIAL_8250_ACPI
#include <linux/acpi_serial.h> #include <linux/acpi_serial.h>
...@@ -529,7 +529,7 @@ acpi_parse_spcr (unsigned long phys_addr, unsigned long size) ...@@ -529,7 +529,7 @@ acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
return 0; return 0;
} }
#endif /* CONFIG_SERIAL_ACPI */ #endif /* CONFIG_SERIAL_8250_ACPI */
int __init int __init
...@@ -587,7 +587,7 @@ acpi_boot_init (char *cmdline) ...@@ -587,7 +587,7 @@ acpi_boot_init (char *cmdline)
if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1) if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
printk(KERN_ERR PREFIX "Can't find FADT\n"); 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 * TBD: Need phased approach to table parsing (only do those absolutely
* required during boot-up). Recommend expanding concept of fix- * required during boot-up). Recommend expanding concept of fix-
......
...@@ -446,6 +446,9 @@ efi_init (void) ...@@ -446,6 +446,9 @@ efi_init (void)
} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) { } else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
efi.sal_systab = __va(config_tables[i].table); efi.sal_systab = __va(config_tables[i].table);
printk(" SALsystab=0x%lx", 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"); printk("\n");
......
...@@ -160,6 +160,10 @@ set_rte (unsigned int vector, unsigned long dest) ...@@ -160,6 +160,10 @@ set_rte (unsigned int vector, unsigned long dest)
int pin; int pin;
char redir; 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; pin = iosapic_irq[vector].pin;
if (pin < 0) if (pin < 0)
return; /* not an IOSAPIC interrupt */ return; /* not an IOSAPIC interrupt */
...@@ -406,7 +410,7 @@ iosapic_reassign_vector (int vector) ...@@ -406,7 +410,7 @@ iosapic_reassign_vector (int vector)
|| iosapic_irq[vector].polarity || iosapic_irq[vector].trigger) || iosapic_irq[vector].polarity || iosapic_irq[vector].trigger)
{ {
new_vector = ia64_alloc_irq(); 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], memcpy (&iosapic_irq[new_vector], &iosapic_irq[vector],
sizeof(struct iosapic_irq)); sizeof(struct iosapic_irq));
memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq)); memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq));
...@@ -757,10 +761,11 @@ iosapic_pci_fixup (int phase) ...@@ -757,10 +761,11 @@ iosapic_pci_fixup (int phase)
if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
static int cpu_index = 0; 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++); set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
cpu_index %= NR_CPUS;
} else { } else {
/* /*
* Direct the interrupt vector to the current cpu, * Direct the interrupt vector to the current cpu,
......
...@@ -368,7 +368,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -368,7 +368,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
* use the action we have. * use the action we have.
*/ */
action = NULL; action = NULL;
if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
action = desc->action; action = desc->action;
status &= ~IRQ_PENDING; /* we commit to handling */ status &= ~IRQ_PENDING; /* we commit to handling */
status |= IRQ_INPROGRESS; /* we are handling it */ status |= IRQ_INPROGRESS; /* we are handling it */
...@@ -381,7 +381,7 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -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 * a different instance of this same irq, the other processor
* will take care of it. * will take care of it.
*/ */
if (!action) if (unlikely(!action))
goto out; goto out;
/* /*
...@@ -403,8 +403,8 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -403,8 +403,8 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
break; break;
desc->status &= ~IRQ_PENDING; desc->status &= ~IRQ_PENDING;
} }
desc->status &= ~IRQ_INPROGRESS;
out: out:
desc->status &= ~IRQ_INPROGRESS;
/* /*
* The ->end() handler has to deal with interrupts which got * The ->end() handler has to deal with interrupts which got
* disabled while the handler was running. * disabled while the handler was running.
......
...@@ -347,6 +347,14 @@ setup_arch (char **cmdline_p) ...@@ -347,6 +347,14 @@ setup_arch (char **cmdline_p)
#ifdef CONFIG_ACPI_BOOT #ifdef CONFIG_ACPI_BOOT
acpi_boot_init(*cmdline_p); acpi_boot_init(*cmdline_p);
#endif #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 #ifdef CONFIG_VT
# if defined(CONFIG_DUMMY_CONSOLE) # if defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con; conswitchp = &dummy_con;
......
...@@ -130,6 +130,8 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) ...@@ -130,6 +130,8 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
siginfo_t siginfo; siginfo_t siginfo;
int sig, code; int sig, code;
die_if_kernel("bad break", regs, break_num);
/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
siginfo.si_imm = break_num; siginfo.si_imm = break_num;
......
...@@ -108,7 +108,7 @@ free_initmem (void) ...@@ -108,7 +108,7 @@ free_initmem (void)
addr = (unsigned long) &__init_begin; addr = (unsigned long) &__init_begin;
for (; addr < (unsigned long) &__init_end; addr += PAGE_SIZE) { 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); set_page_count(virt_to_page(addr), 1);
free_page(addr); free_page(addr);
++totalram_pages; ++totalram_pages;
...@@ -162,9 +162,9 @@ free_initrd_mem (unsigned long start, unsigned long end) ...@@ -162,9 +162,9 @@ free_initrd_mem (unsigned long start, unsigned long end)
if (!virt_addr_valid(start)) if (!virt_addr_valid(start))
continue; continue;
page = virt_to_page(start); page = virt_to_page(start);
clear_bit(PG_reserved, &page->flags); ClearPageReserved(page);
set_page_count(page, 1); set_page_count(page, 1);
__free_page(page); free_page(page);
++totalram_pages; ++totalram_pages;
} }
} }
......
#ifndef AGP_H #ifndef _ASM_IA64_AGP_H
#define AGP_H 1 #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) * To avoid memory-attribute aliasing issues, we require that the AGPGART engine operate
#define flush_agp_mappings() * 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() #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, ...@@ -190,6 +190,9 @@ typedef void efi_reset_system_t (int reset_type, efi_status_t status,
#define SAL_SYSTEM_TABLE_GUID \ #define SAL_SYSTEM_TABLE_GUID \
EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) 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 { typedef struct {
efi_guid_t guid; efi_guid_t guid;
u64 table; u64 table;
...@@ -225,6 +228,7 @@ extern struct efi { ...@@ -225,6 +228,7 @@ extern struct efi {
void *smbios; /* SM BIOS table */ void *smbios; /* SM BIOS table */
void *sal_systab; /* SAL system table */ void *sal_systab; /* SAL system table */
void *boot_info; /* boot info table */ void *boot_info; /* boot info table */
void *hcdp; /* HCDP table */
efi_get_time_t *get_time; efi_get_time_t *get_time;
efi_set_time_t *set_time; efi_set_time_t *set_time;
efi_get_wakeup_time_t *get_wakeup_time; efi_get_wakeup_time_t *get_wakeup_time;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _ASM_IA64_ELF_H #define _ASM_IA64_ELF_H
/* /*
* ELF archtecture specific definitions. * ELF-specific definitions.
* *
* Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com> * David Mosberger-Tang <davidm@hpl.hp.com>
......
...@@ -87,7 +87,12 @@ typedef union ia64_va { ...@@ -87,7 +87,12 @@ typedef union ia64_va {
#define REGION_SIZE REGION_NUMBER(1) #define REGION_SIZE REGION_NUMBER(1)
#define REGION_KERNEL 7 #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) #define PAGE_BUG(page) do { BUG(); } while (0)
static __inline__ int static __inline__ int
......
...@@ -115,21 +115,8 @@ ...@@ -115,21 +115,8 @@
#define HUB6_SERIAL_PORT_DFNS #define HUB6_SERIAL_PORT_DFNS
#endif #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 \ #define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \ STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS \ EXTRA_SERIAL_PORT_DEFNS \
HUB6_SERIAL_PORT_DFNS \ HUB6_SERIAL_PORT_DFNS
MCA_SERIAL_PORT_DFNS
...@@ -123,13 +123,20 @@ tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush) ...@@ -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()]; mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()];
tlb->mm = mm; 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 * Use fast mode if only 1 CPU is online.
* entire address space. *
* 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 = ~0U; tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
tlb->fullmm = full_mm_flush; tlb->fullmm = full_mm_flush;
tlb->freed = 0; tlb->freed = 0;
tlb->start_addr = ~0UL; tlb->start_addr = ~0UL;
......
...@@ -60,6 +60,8 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr) ...@@ -60,6 +60,8 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
#else #else
if (vma->vm_mm == current->active_mm) if (vma->vm_mm == current->active_mm)
asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory"); asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory");
else
vma->vm_mm->context = 0;
#endif #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