Skip to content

Commit

Permalink
[IA64-SGI] Altix SN topology support for new chipsets and pci topology
Browse files Browse the repository at this point in the history
please accept this patch to the Altix SN platform topology export
interface to support new chipsets and to export PCI topology.

This follows on top of Jack Steiner's patch dated March 1st
("New chipset support for SN platform").

Signed-off-by: Mark Goodwin <markgw@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
  • Loading branch information
Mark Goodwin authored and Tony Luck committed Apr 25, 2005
1 parent 30325d1 commit 4a5c13c
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 9 deletions.
133 changes: 124 additions & 9 deletions arch/ia64/sn/kernel/sn2/sn_hwperf.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/vmalloc.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/utsname.h>
#include <linux/cpumask.h>
#include <linux/smp_lock.h>
#include <linux/nodemask.h>
Expand All @@ -43,6 +44,7 @@
#include <asm/sn/module.h>
#include <asm/sn/geo.h>
#include <asm/sn/sn2/sn_hwperf.h>
#include <asm/sn/addrs.h>

static void *sn_hwperf_salheap = NULL;
static int sn_hwperf_obj_cnt = 0;
Expand Down Expand Up @@ -81,26 +83,45 @@ static int sn_hwperf_enum_objects(int *nobj, struct sn_hwperf_object_info **ret)
return e;
}

static int sn_hwperf_location_to_bpos(char *location,
int *rack, int *bay, int *slot, int *slab)
{
char type;

/* first scan for an old style geoid string */
if (sscanf(location, "%03d%c%02d#%d",
rack, &type, bay, slab) == 4)
*slot = 0;
else /* scan for a new bladed geoid string */
if (sscanf(location, "%03d%c%02d^%02d#%d",
rack, &type, bay, slot, slab) != 5)
return -1;
/* success */
return 0;
}

static int sn_hwperf_geoid_to_cnode(char *location)
{
int cnode;
geoid_t geoid;
moduleid_t module_id;
char type;
int rack, slot, slab;
int this_rack, this_slot, this_slab;
int rack, bay, slot, slab;
int this_rack, this_bay, this_slot, this_slab;

if (sscanf(location, "%03d%c%02d#%d", &rack, &type, &slot, &slab) != 4)
if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab))
return -1;

for (cnode = 0; cnode < numionodes; cnode++) {
geoid = cnodeid_get_geoid(cnode);
module_id = geo_module(geoid);
this_rack = MODULE_GET_RACK(module_id);
this_slot = MODULE_GET_BPOS(module_id);
this_bay = MODULE_GET_BPOS(module_id);
this_slot = 0; /* XXX */
this_slab = geo_slab(geoid);
if (rack == this_rack && slot == this_slot && slab == this_slab)
if (rack == this_rack && bay == this_bay &&
slot == this_slot && slab == this_slab) {
break;
}
}

return cnode < numionodes ? cnode : -1;
Expand Down Expand Up @@ -153,11 +174,29 @@ static const char *sn_hwperf_get_slabname(struct sn_hwperf_object_info *obj,
return slabname;
}

static void print_pci_topology(struct seq_file *s,
struct sn_hwperf_object_info *obj, int *ordinal,
char *pci_topo_buf, int len)
{
char *p1;
char *p2;

for (p1=pci_topo_buf; *p1 && p1 < pci_topo_buf + len;) {
if (!(p2 = strchr(p1, '\n')))
break;
*p2 = '\0';
seq_printf(s, "pcibus %d %s-%s\n",
*ordinal, obj->location, p1);
(*ordinal)++;
p1 = p2 + 1;
}
}

static int sn_topology_show(struct seq_file *s, void *d)
{
int sz;
int pt;
int e;
int e = 0;
int i;
int j;
const char *slabname;
Expand All @@ -169,19 +208,54 @@ static int sn_topology_show(struct seq_file *s, void *d)
struct sn_hwperf_object_info *p;
struct sn_hwperf_object_info *obj = d; /* this object */
struct sn_hwperf_object_info *objs = s->private; /* all objects */
int rack, bay, slot, slab;
u8 shubtype;
u8 system_size;
u8 sharing_size;
u8 partid;
u8 coher;
u8 nasid_shift;
u8 region_size;
u16 nasid_mask;
int nasid_msb;
char *pci_topo_buf;
int pci_bus_ordinal = 0;
static int pci_topo_buf_len = 256;

if (obj == objs) {
seq_printf(s, "# sn_topology version 1\n");
seq_printf(s, "# sn_topology version 2\n");
seq_printf(s, "# objtype ordinal location partition"
" [attribute value [, ...]]\n");

if (ia64_sn_get_sn_info(0,
&shubtype, &nasid_mask, &nasid_shift, &system_size,
&sharing_size, &partid, &coher, &region_size))
BUG();
for (nasid_msb=63; nasid_msb > 0; nasid_msb--) {
if (((u64)nasid_mask << nasid_shift) & (1ULL << nasid_msb))
break;
}
seq_printf(s, "partition %u %s local "
"shubtype %s, "
"nasid_mask 0x%016lx, "
"nasid_bits %d:%d, "
"system_size %d, "
"sharing_size %d, "
"coherency_domain %d, "
"region_size %d\n",

partid, system_utsname.nodename,
shubtype ? "shub2" : "shub1",
(u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
system_size, sharing_size, coher, region_size);
}

if (SN_HWPERF_FOREIGN(obj)) {
/* private in another partition: not interesting */
return 0;
}

for (i = 0; obj->name[i]; i++) {
for (i = 0; i < SN_HWPERF_MAXSTRING && obj->name[i]; i++) {
if (obj->name[i] == ' ')
obj->name[i] = '_';
}
Expand Down Expand Up @@ -221,6 +295,43 @@ static int sn_topology_show(struct seq_file *s, void *d)
seq_putc(s, '\n');
}
}

/*
* PCI busses attached to this node, if any
*/
do {
if (!(pci_topo_buf = vmalloc(pci_topo_buf_len))) {
printk("sn_topology_show: kmalloc failed\n");
break;
}

if (sn_hwperf_location_to_bpos(obj->location,
&rack, &bay, &slot, &slab) != 0)
continue;

e = ia64_sn_ioif_get_pci_topology(rack, bay, slot, slab,
pci_topo_buf, pci_topo_buf_len);

switch (e) {
case SALRET_NOT_IMPLEMENTED:
case SALRET_INVALID_ARG:
/* ignore, don't print anything */
e = SN_HWPERF_OP_OK;
break;

case SALRET_ERROR:
/* retry with a bigger buffer */
pci_topo_buf_len += 256;
break;

case SN_HWPERF_OP_OK:
/* export pci bus info */
print_pci_topology(s, obj, &pci_bus_ordinal,
pci_topo_buf, pci_topo_buf_len);
break;
}
vfree(pci_topo_buf);
} while (e != SN_HWPERF_OP_OK && pci_topo_buf_len < 0x200000);
}

if (obj->ports) {
Expand Down Expand Up @@ -397,6 +508,9 @@ static int sn_hwperf_map_err(int hwperf_err)
break;

case SN_HWPERF_OP_BUSY:
e = -EBUSY;
break;

case SN_HWPERF_OP_RECONFIGURE:
e = -EAGAIN;
break;
Expand Down Expand Up @@ -549,6 +663,7 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
r = sn_hwperf_op_cpu(&op_info);
if (r) {
r = sn_hwperf_map_err(r);
a.v0 = v0;
goto error;
}
break;
Expand Down
11 changes: 11 additions & 0 deletions include/asm-ia64/sn/sn_sal.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056
#define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057
#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058
#define SN_SAL_IOIF_GET_PCI_TOPOLOGY 0x02000059

#define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060

Expand Down Expand Up @@ -1012,4 +1013,14 @@ ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2,
return (int) rv.status;
}

static inline int
ia64_sn_ioif_get_pci_topology(u64 rack, u64 bay, u64 slot, u64 slab,
char *buf, u64 len)
{
struct ia64_sal_retval rv;
SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY,
rack, bay, slot, slab, buf, len, 0);
return (int) rv.status;
}

#endif /* _ASM_IA64_SN_SN_SAL_H */

0 comments on commit 4a5c13c

Please sign in to comment.