aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-03-31 00:29:06 -0800
committerTony Luck <tony.luck@intel.com>2005-03-31 00:29:06 -0800
commit662756c753b13231d437e4bc78032b5891c9d4ea (patch)
tree1fca1f1fe737081c13d88443f7cd645897941033
parent1a89e511e152998311f49c60e55b21d48d1b8973 (diff)
parent8d7c763253b85b5598e5975a5c88b896fefe2110 (diff)
downloadhistory-662756c753b13231d437e4bc78032b5891c9d4ea.tar.gz
Merge intel.com:/data/home/aegl/BK/work/1
into intel.com:/data/home/aegl/BK/linux-ia64-release-2.6.12
-rw-r--r--arch/ia64/kernel/unaligned.c16
-rw-r--r--arch/ia64/pci/pci.c134
-rw-r--r--arch/ia64/sn/kernel/setup.c28
-rw-r--r--include/asm-ia64/sn/addrs.h7
-rw-r--r--include/asm-ia64/sn/arch.h24
-rw-r--r--include/asm-ia64/sn/pda.h15
-rw-r--r--include/asm-ia64/sn/sn_cpuid.h5
-rw-r--r--include/asm-ia64/sn/sn_sal.h50
8 files changed, 174 insertions, 105 deletions
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 46dad0d215a3dc..43b45b65ee5a9d 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1380,6 +1380,10 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
* - ldX.spill
* - stX.spill
* Reason: RNATs are based on addresses
+ * - ld16
+ * - st16
+ * Reason: ld16 and st16 are supposed to occur in a single
+ * memory op
*
* synchronization:
* - cmpxchg
@@ -1401,6 +1405,10 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
switch (opcode) {
case LDS_OP:
case LDSA_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case LDS_IMM_OP:
case LDSA_IMM_OP:
case LDFS_OP:
@@ -1425,6 +1433,10 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
case LDCCLR_OP:
case LDCNC_OP:
case LDCCLRACQ_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case LD_IMM_OP:
case LDA_IMM_OP:
case LDBIAS_IMM_OP:
@@ -1437,6 +1449,10 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
case ST_OP:
case STREL_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case ST_IMM_OP:
case STREL_IMM_OP:
ret = emulate_store_int(ifa, u.insn, regs);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 61d8dd3c9c93a0..88641e5095b5f9 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -178,30 +178,6 @@ alloc_pci_controller (int seg)
return controller;
}
-static int __devinit
-alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end,
- unsigned long flags)
-{
- struct resource *res;
-
- res = kmalloc(sizeof(*res), GFP_KERNEL);
- if (!res)
- return -ENOMEM;
-
- memset(res, 0, sizeof(*res));
- res->name = name;
- res->start = start;
- res->end = end;
- res->flags = flags;
-
- if (insert_resource(root, res)) {
- kfree(res);
- return -EBUSY;
- }
-
- return 0;
-}
-
static u64 __devinit
add_io_space (struct acpi_resource_address64 *addr)
{
@@ -254,10 +230,9 @@ struct pci_root_info {
char *name;
};
-static acpi_status __devinit
-add_window (struct acpi_resource *res, void *data)
+static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{
- struct pci_root_info *info = (struct pci_root_info *) data;
+ struct pci_root_info *info = data;
struct pci_window *window;
struct acpi_resource_address64 addr;
acpi_status status;
@@ -265,45 +240,71 @@ add_window (struct acpi_resource *res, void *data)
struct resource *root;
status = acpi_resource_to_address64(res, &addr);
- if (ACPI_SUCCESS(status)) {
- if (!addr.address_length)
- return AE_OK;
-
- if (addr.resource_type == ACPI_MEMORY_RANGE) {
- flags = IORESOURCE_MEM;
- root = &iomem_resource;
- offset = addr.address_translation_offset;
- } else if (addr.resource_type == ACPI_IO_RANGE) {
- flags = IORESOURCE_IO;
- root = &ioport_resource;
- offset = add_io_space(&addr);
- if (offset == ~0)
- return AE_OK;
- } else
+ if (!ACPI_SUCCESS(status))
+ return AE_OK;
+
+ if (!addr.address_length)
+ return AE_OK;
+
+ if (addr.resource_type == ACPI_MEMORY_RANGE) {
+ flags = IORESOURCE_MEM;
+ root = &iomem_resource;
+ offset = addr.address_translation_offset;
+ } else if (addr.resource_type == ACPI_IO_RANGE) {
+ flags = IORESOURCE_IO;
+ root = &ioport_resource;
+ offset = add_io_space(&addr);
+ if (offset == ~0)
return AE_OK;
-
- window = &info->controller->window[info->controller->windows++];
- window->resource.flags = flags;
- window->resource.start = addr.min_address_range;
- window->resource.end = addr.max_address_range;
- window->offset = offset;
-
- if (alloc_resource(info->name, root, addr.min_address_range + offset,
- addr.max_address_range + offset, flags))
- printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n",
- addr.min_address_range + offset, addr.max_address_range + offset,
- root->name, info->name);
+ } else
+ return AE_OK;
+
+ window = &info->controller->window[info->controller->windows++];
+ window->resource.name = info->name;
+ window->resource.flags = flags;
+ window->resource.start = addr.min_address_range + offset;
+ window->resource.end = addr.max_address_range + offset;
+ window->resource.child = NULL;
+ window->offset = offset;
+
+ if (insert_resource(root, &window->resource)) {
+ printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n",
+ window->resource.start, window->resource.end,
+ root->name, info->name);
}
return AE_OK;
}
+static void __devinit
+pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
+{
+ int i, j;
+
+ j = 0;
+ for (i = 0; i < ctrl->windows; i++) {
+ struct resource *res = &ctrl->window[i].resource;
+ /* HP's firmware has a hack to work around a Windows bug.
+ * Ignore these tiny memory ranges */
+ if ((res->flags & IORESOURCE_MEM) &&
+ (res->end - res->start < 16))
+ continue;
+ if (j >= PCI_BUS_NUM_RESOURCES) {
+ printk("Ignoring range [%lx-%lx] (%lx)\n", res->start,
+ res->end, res->flags);
+ continue;
+ }
+ bus->resource[j++] = res;
+ }
+}
+
struct pci_bus * __devinit
-pci_acpi_scan_root (struct acpi_device *device, int domain, int bus)
+pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
{
struct pci_root_info info;
struct pci_controller *controller;
unsigned int windows = 0;
+ struct pci_bus *pbus;
char *name;
controller = alloc_pci_controller(domain);
@@ -312,8 +313,10 @@ pci_acpi_scan_root (struct acpi_device *device, int domain, int bus)
controller->acpi_handle = device->handle;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, &windows);
- controller->window = kmalloc(sizeof(*controller->window) * windows, GFP_KERNEL);
+ acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
+ &windows);
+ controller->window = kmalloc(sizeof(*controller->window) * windows,
+ GFP_KERNEL);
if (!controller->window)
goto out2;
@@ -324,9 +327,14 @@ pci_acpi_scan_root (struct acpi_device *device, int domain, int bus)
sprintf(name, "PCI Bus %04x:%02x", domain, bus);
info.controller = controller;
info.name = name;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info);
+ acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
+ &info);
+
+ pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+ if (pbus)
+ pcibios_setup_root_windows(pbus, controller);
- return pci_scan_bus(bus, &pci_root_ops, controller);
+ return pbus;
out3:
kfree(controller->window);
@@ -347,9 +355,9 @@ void pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_window *window = &controller->window[i];
if (!(window->resource.flags & res->flags))
continue;
- if (window->resource.start > res->start - window->offset)
+ if (window->resource.start > res->start)
continue;
- if (window->resource.end < res->end - window->offset)
+ if (window->resource.end < res->end)
continue;
offset = window->offset;
break;
@@ -371,9 +379,9 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
struct pci_window *window = &controller->window[i];
if (!(window->resource.flags & res->flags))
continue;
- if (window->resource.start > region->start)
+ if (window->resource.start - window->offset > region->start)
continue;
- if (window->resource.end < region->end)
+ if (window->resource.end - window->offset < region->end)
continue;
offset = window->offset;
break;
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a852077940fe03..f0306b516afba5 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -67,15 +67,27 @@ extern void snidle(int);
extern unsigned char acpi_kbd_controller_present;
unsigned long sn_rtc_cycles_per_second;
-
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
+DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
+EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
+
partid_t sn_partid = -1;
EXPORT_SYMBOL(sn_partid);
char sn_system_serial_number_string[128];
EXPORT_SYMBOL(sn_system_serial_number_string);
u64 sn_partition_serial_number;
EXPORT_SYMBOL(sn_partition_serial_number);
+u8 sn_partition_id;
+EXPORT_SYMBOL(sn_partition_id);
+u8 sn_system_size;
+EXPORT_SYMBOL(sn_system_size);
+u8 sn_sharing_domain_size;
+EXPORT_SYMBOL(sn_sharing_domain_size);
+u8 sn_coherency_id;
+EXPORT_SYMBOL(sn_coherency_id);
+u8 sn_region_size;
+EXPORT_SYMBOL(sn_region_size);
short physical_node_map[MAX_PHYSNODE_ID];
@@ -232,7 +244,7 @@ static void __init sn_check_for_wars(void)
} else {
for_each_online_node(cnode) {
if (is_shub_1_1(cnodeid_to_nasid(cnode)))
- shub_1_1_found = 1;
+ sn_hub_info->shub_1_1_found = 1;
}
}
}
@@ -424,16 +436,14 @@ void __init sn_cpu_init(void)
int slice;
int cnode;
int i;
- u64 shubtype, nasid_bitmask, nasid_shift;
static int wars_have_been_checked;
memset(pda, 0, sizeof(pda));
- if (ia64_sn_get_hub_info(0, &shubtype, &nasid_bitmask, &nasid_shift))
+ if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
+ &sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
+ &sn_coherency_id, &sn_region_size))
BUG();
- pda->shub2 = (u8)shubtype;
- pda->nasid_bitmask = (u16)nasid_bitmask;
- pda->nasid_shift = (u8)nasid_shift;
- pda->as_shift = pda->nasid_shift - 2;
+ sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
/*
* The boot cpu makes this call again after platform initialization is
@@ -482,7 +492,7 @@ void __init sn_cpu_init(void)
sn_check_for_wars();
wars_have_been_checked = 1;
}
- pda->shub_1_1_found = shub_1_1_found;
+ sn_hub_info->shub_1_1_found = shub_1_1_found;
/*
* Set up addresses of PIO/MEM write status registers.
diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
index 3ce60976d474b8..c916bd22767a14 100644
--- a/include/asm-ia64/sn/addrs.h
+++ b/include/asm-ia64/sn/addrs.h
@@ -11,6 +11,7 @@
#include <asm/percpu.h>
#include <asm/sn/types.h>
+#include <asm/sn/arch.h>
#include <asm/sn/pda.h>
/*
@@ -57,9 +58,9 @@
/*
* Define basic shift & mask constants for manipulating NASIDs and AS values.
*/
-#define NASID_BITMASK (pda->nasid_bitmask)
-#define NASID_SHIFT (pda->nasid_shift)
-#define AS_SHIFT (pda->as_shift)
+#define NASID_BITMASK (sn_hub_info->nasid_bitmask)
+#define NASID_SHIFT (sn_hub_info->nasid_shift)
+#define AS_SHIFT (sn_hub_info->as_shift)
#define AS_BITMASK 0x3UL
#define NASID_MASK ((u64)NASID_BITMASK << NASID_SHIFT)
diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
index bfc922a0ab7179..7c349f07916a1b 100644
--- a/include/asm-ia64/sn/arch.h
+++ b/include/asm-ia64/sn/arch.h
@@ -12,10 +12,34 @@
#define _ASM_IA64_SN_ARCH_H
#include <asm/types.h>
+#include <asm/percpu.h>
#include <asm/sn/types.h>
#include <asm/sn/sn_cpuid.h>
/*
+ * The following defines attributes of the HUB chip. These attributes are
+ * frequently referenced. They are kept in the per-cpu data areas of each cpu.
+ * They are kept together in a struct to minimize cache misses.
+ */
+struct sn_hub_info_s {
+ u8 shub2;
+ u8 nasid_shift;
+ u8 as_shift;
+ u8 shub_1_1_found;
+ u16 nasid_bitmask;
+};
+DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
+#define sn_hub_info (&__get_cpu_var(__sn_hub_info))
+#define is_shub2() (sn_hub_info->shub2)
+#define is_shub1() (sn_hub_info->shub2 == 0)
+
+/*
+ * Use this macro to test if shub 1.1 wars should be enabled
+ */
+#define enable_shub_wars_1_1() (sn_hub_info->shub_1_1_found)
+
+
+/*
* This is the maximum number of nodes that can be part of a kernel.
* Effectively, it's the maximum number of compact node ids (cnodeid_t).
* This is not necessarily the same as MAX_NASIDS.
diff --git a/include/asm-ia64/sn/pda.h b/include/asm-ia64/sn/pda.h
index 6465e8ab2bccd3..e940d3647c8043 100644
--- a/include/asm-ia64/sn/pda.h
+++ b/include/asm-ia64/sn/pda.h
@@ -37,11 +37,6 @@ typedef struct pda_s {
* Support for SN LEDs
*/
volatile short *led_address;
- u16 nasid_bitmask;
- u8 shub2;
- u8 nasid_shift;
- u8 as_shift;
- u8 shub_1_1_found;
u8 led_state;
u8 hb_state; /* supports blinking heartbeat leds */
unsigned int hb_count;
@@ -53,8 +48,6 @@ typedef struct pda_s {
unsigned long pio_write_status_val;
volatile unsigned long *pio_shub_war_cam_addr;
- struct bteinfo_s *cpu_bte_if[BTES_PER_NODE]; /* cpu interface order */
-
unsigned long sn_soft_irr[4];
unsigned long sn_in_service_ivecs[4];
short cnodeid_to_nasid_table[MAX_NUMNODES];
@@ -84,12 +77,4 @@ DECLARE_PER_CPU(struct pda_s, pda_percpu);
#define pdacpu(cpu) (&per_cpu(pda_percpu, cpu))
-/*
- * Use this macro to test if shub 1.1 wars should be enabled
- */
-#define enable_shub_wars_1_1() (pda->shub_1_1_found)
-
-#define is_shub2() (pda->shub2)
-#define is_shub1() (pda->shub2 == 0)
-
#endif /* _ASM_IA64_SN_PDA_H */
diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
index 749f45042cdcc1..685435af170d8d 100644
--- a/include/asm-ia64/sn/sn_cpuid.h
+++ b/include/asm-ia64/sn/sn_cpuid.h
@@ -135,9 +135,10 @@ extern int nasid_slice_to_cpuid(int, int);
#define nasid_to_cnodeid(nasid) (physical_node_map[nasid])
/*
- * partition_coherence_id - cget the coherence ID of the current partition
+ * partition_coherence_id - get the coherence ID of the current partition
*/
-#define partition_coherence_id() (get_nasid() >> 9)
+extern u8 sn_coherency_id;
+#define partition_coherence_id() (sn_coherency_id)
#endif /* _ASM_IA64_SN_SN_CPUID_H */
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index 4ecc05e8ad5772..88c31b53dc0974 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -18,6 +18,7 @@
#include <asm/sn/arch.h>
#include <asm/sn/geo.h>
#include <asm/sn/nodepda.h>
+#include <asm/sn/shub_mmr.h>
// SGI Specific Calls
#define SN_SAL_POD_MODE 0x02000001
@@ -34,7 +35,7 @@
#define SN_SAL_PRINT_ERROR 0x02000012
#define SN_SAL_SET_ERROR_HANDLING_FEATURES 0x0200001a // reentrant
#define SN_SAL_GET_FIT_COMPT 0x0200001b // reentrant
-#define SN_SAL_GET_HUB_INFO 0x0200001c
+#define SN_SAL_GET_SN_INFO 0x0200001c
#define SN_SAL_GET_SAPIC_INFO 0x0200001d
#define SN_SAL_CONSOLE_PUTC 0x02000021
#define SN_SAL_CONSOLE_GETC 0x02000022
@@ -935,15 +936,24 @@ ia64_sn_get_sapic_info(int sapicid, int *nasid, int *subnode, int *slice)
/*
* Returns information about the HUB/SHUB.
* In:
- * arg0 - SN_SAL_GET_HUB_INFO
+ * arg0 - SN_SAL_GET_SN_INFO
* arg1 - 0 (other values reserved for future use)
* Out:
- * v0 - shub type (0=shub1, 1=shub2)
- * v1 - masid mask (ex., 0x7ff for 11 bit nasid)
- * v2 - bit position of low nasid bit
+ * v0
+ * [7:0] - shub type (0=shub1, 1=shub2)
+ * [15:8] - Log2 max number of nodes in entire system (includes
+ * C-bricks, I-bricks, etc)
+ * [23:16] - Log2 of nodes per sharing domain
+ * [31:24] - partition ID
+ * [39:32] - coherency_id
+ * [47:40] - regionsize
+ * v1
+ * [15:0] - nasid mask (ex., 0x7ff for 11 bit nasid)
+ * [23:15] - bit position of low nasid bit
*/
static inline u64
-ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3)
+ia64_sn_get_sn_info(int fc, u8 *shubtype, u16 *nasid_bitmask, u8 *nasid_shift,
+ u8 *systemsize, u8 *sharing_domain_size, u8 *partid, u8 *coher, u8 *reg)
{
struct ia64_sal_retval ret_stuff;
@@ -951,13 +961,22 @@ ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3)
ret_stuff.v0 = 0;
ret_stuff.v1 = 0;
ret_stuff.v2 = 0;
- SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_HUB_INFO, fc, 0, 0, 0, 0, 0, 0);
+ SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
/***** BEGIN HACK - temp til old proms no longer supported ********/
if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
- if (arg1) *arg1 = 0;
- if (arg2) *arg2 = 0x7ff;
- if (arg3) *arg3 = 38;
+ int nasid = get_sapicid() & 0xfff;;
+#define SH_SHUB_ID_NODES_PER_BIT_MASK 0x001f000000000000UL
+#define SH_SHUB_ID_NODES_PER_BIT_SHFT 48
+ if (shubtype) *shubtype = 0;
+ if (nasid_bitmask) *nasid_bitmask = 0x7ff;
+ if (nasid_shift) *nasid_shift = 38;
+ if (systemsize) *systemsize = 11;
+ if (sharing_domain_size) *sharing_domain_size = 9;
+ if (partid) *partid = ia64_sn_sysctl_partition_get(nasid);
+ if (coher) *coher = nasid >> 9;
+ if (reg) *reg = (HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_SHUB_ID)) & SH_SHUB_ID_NODES_PER_BIT_MASK) >>
+ SH_SHUB_ID_NODES_PER_BIT_SHFT;
return 0;
}
/***** END HACK *******/
@@ -965,9 +984,14 @@ ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3)
if (ret_stuff.status < 0)
return ret_stuff.status;
- if (arg1) *arg1 = ret_stuff.v0;
- if (arg2) *arg2 = ret_stuff.v1;
- if (arg3) *arg3 = ret_stuff.v2;
+ if (shubtype) *shubtype = ret_stuff.v0 & 0xff;
+ if (systemsize) *systemsize = (ret_stuff.v0 >> 8) & 0xff;
+ if (sharing_domain_size) *sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
+ if (partid) *partid = (ret_stuff.v0 >> 24) & 0xff;
+ if (coher) *coher = (ret_stuff.v0 >> 32) & 0xff;
+ if (reg) *reg = (ret_stuff.v0 >> 40) & 0xff;
+ if (nasid_bitmask) *nasid_bitmask = (ret_stuff.v1 & 0xffff);
+ if (nasid_shift) *nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
return 0;
}