Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 502
b: refs/heads/master
c: 4a5c13c
h: refs/heads/master
v: v3
  • Loading branch information
Mark Goodwin authored and Tony Luck committed Apr 25, 2005
1 parent 5d4948d commit 3c32bb6
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 30325d17715302a60c9afdaacaafaeb056b7e880
refs/heads/master: 4a5c13c7eb0d55bfd2cf3100c55f1e3d8df37576
133 changes: 124 additions & 9 deletions trunk/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 trunk/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 3c32bb6

Please sign in to comment.