summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-05-27 19:00:20 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-05-27 19:00:20 +0000
commit142f545264089ad6a493f097b3c2eefacd6e357c (patch)
treef860ef07f04e88c5b983e0ec7aac55a1f9ed72fc
parent8084c4c5b9de95c18b2f37b49ef0ce54cb12a8d5 (diff)
Rework KL board and component enumeration, to allow it to be used from
drivers with callback routines. While there, skip disabled or failed components.
-rw-r--r--sys/arch/sgi/include/mnode.h50
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c24
-rw-r--r--sys/arch/sgi/sgi/sginode.c285
3 files changed, 227 insertions, 132 deletions
diff --git a/sys/arch/sgi/include/mnode.h b/sys/arch/sgi/include/mnode.h
index 0cf495b37a0..d180632e968 100644
--- a/sys/arch/sgi/include/mnode.h
+++ b/sys/arch/sgi/include/mnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mnode.h,v 1.3 2009/05/06 20:08:44 miod Exp $ */
+/* $OpenBSD: mnode.h,v 1.4 2009/05/27 19:00:15 miod Exp $ */
/*
* Copyright (c) 2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -145,6 +145,7 @@ typedef struct kl_config_hdr {
#define IP27_KLNEXT_BOARD(n, board) \
IP27_UNCAC_ADDR(lboard_t *, n, board->brd_next)
#define MAX_COMPTS_PER_BRD 24
+
typedef struct lboard_s {
klconf_off_t brd_next; /* Next BOARD */
uint8_t struct_type; /* type, local or remote */
@@ -173,6 +174,9 @@ typedef struct lboard_s {
char brd_name[32];
} lboard_t;
+#define LBOARD 0x01
+#define RBOARD 0x02
+
/* Definitions of board type and class */
#define IP27_BC_MASK 0xf0
#define IP27_BC_NODE 0x10
@@ -188,6 +192,11 @@ typedef struct lboard_s {
#define IP27_BT_BASEIO 0x01
#define IP27_BT_MPLANE8 0x01
+#define IP27_BRD_BASEIO (IP27_BC_IO | IP27_BT_BASEIO)
+#define IP27_BRD_IBRICK (IP27_BC_BRICK | 0x01)
+#define IP27_BRD_PBRICK (IP27_BC_BRICK | 0x02)
+#define IP27_BRD_XBRICK (IP27_BC_BRICK | 0x03)
+
/* Component info. Common info about a component. */
typedef struct klinfo_s { /* Generic info */
@@ -211,15 +220,11 @@ typedef struct klinfo_s { /* Generic info */
unsigned short pad4; /* klbri_t */
} klinfo_t;
-#define KLCONFIG_INFO_ENABLED(_i) ((_i)->flags & KLINFO_ENABLE)
+#define KLINFO_ENABLED 0x01
+#define KLINFO_FAILED 0x02
+
/*
- * Component structures.
- * Following are the currently identified components:
- * CPU, HUB, MEM_BANK,
- * XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE)
- * BRIDGE, IOC3, SuperIO, SCSI, FDDI
- * ROUTER
- * GRAPHICS
+ * Component structure types.
*/
#define KLSTRUCT_UNKNOWN 0
#define KLSTRUCT_CPU 1
@@ -241,11 +246,28 @@ typedef struct klinfo_s { /* Generic info */
#define KLSTRUCT_HUB_UART 17
#define KLSTRUCT_IOC3ENET 18
#define KLSTRUCT_IOC3UART 19
-#define KLSTRUCT_UNUSED 20 /* XXX UNUSED */
+#define KLSTRUCT_UNUSED 20
#define KLSTRUCT_IOC3PCKM 21
#define KLSTRUCT_RAD 22
#define KLSTRUCT_HUB_TTY 23
#define KLSTRUCT_IOC3_TTY 24
+/* new IP35 values */
+#define KLSTRUCT_FIBERCHANNEL 25
+#define KLSTRUCT_MOD_SERIAL_NUM 26
+#define KLSTRUCT_IOC3MS 27
+#define KLSTRUCT_TPU 28
+#define KLSTRUCT_GSN_A 29
+#define KLSTRUCT_GSN_B 30
+#define KLSTRUCT_XTHD 31
+#define KLSTRUCT_QLFIBRE 32
+#define KLSTRUCT_FIREWIRE 33
+#define KLSTRUCT_USB 34
+#define KLSTRUCT_USBKBD 35
+#define KLSTRUCT_USBMS 36
+#define KLSTRUCT_SCSI2 37
+#define KLSTRUCT_PEBRICK 38
+#define KLSTRUCT_GIGENET 39
+#define KLSTRUCT_IDE 40
typedef struct klport_s {
int16_t port_nasid;
@@ -382,8 +404,14 @@ typedef struct klttydev_s {
* Functions.
*/
-void kl_scan_config(int);
vaddr_t kl_get_console_base(void);
+void kl_init(void);
+void kl_scan_config(int);
+void kl_scan_done(void);
+int kl_scan_node(int, uint, int (*)(lboard_t *, void *), void *);
+#define KLBRD_ANY 0
+int kl_scan_board(lboard_t *, uint, int (*)(klinfo_t *, void *), void *);
+#define KLSTRUCT_ANY ((uint)~0)
int kl_n_mode;
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index 831c6046bff..e811e452115 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.7 2009/05/21 16:25:26 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.8 2009/05/27 19:00:19 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -68,27 +68,24 @@ ip27_setup()
xbow_widget_long = ip27_widget_long;
xbow_widget_id = ip27_widget_id;
+ kl_init();
+ if (kl_n_mode != 0)
+ xbow_long_shift = 28;
+
/*
* Scan this node's configuration to find out CPU and memory
* information.
*/
- kl_scan_config(0);
- if (kl_n_mode != 0)
- xbow_long_shift = 28;
+ kl_scan_config(0);
+ kl_scan_done();
/*
* Initialize the early console parameters.
- * This assumes BRIDGE is on widget 8 and IOC3 is mapped in
- * memory space at address 0x600000. Although on IP35 it is
- * actually widget 15...
- *
- * XXX And that 0x600000 should be computed from the first BAR
- * XXX of the IOC3 in pci configuration space. Joy. I'll get there
- * XXX eventually.
+ * This assumes IOC3 is accessible through a widget small window.
*/
- xbow_build_bus_space(&sys_config.console_io, 0, 8, 0);
+ xbow_build_bus_space(&sys_config.console_io, 0, 8 /* whatever */, 0);
/* Constrain to a short window */
sys_config.console_io.bus_base =
kl_get_console_base() & 0xffffffffff000000UL;
@@ -101,6 +98,7 @@ ip27_setup()
* Force widget interrupts to run through us, unless a
* better interrupt master widget is found.
*/
+
xbow_intr_widget_intr_register = ip27_hub_intr_register;
xbow_intr_widget_intr_establish = ip27_hub_intr_establish;
xbow_intr_widget_intr_disestablish = ip27_hub_intr_disestablish;
@@ -111,12 +109,14 @@ ip27_setup()
/*
* Disable all hardware interrupts.
*/
+
IP27_LHUB_S(HUB_CPU0_IMR0, 0);
IP27_LHUB_S(HUB_CPU0_IMR1, 0);
IP27_LHUB_S(HUB_CPU1_IMR0, 0);
IP27_LHUB_S(HUB_CPU1_IMR1, 0);
(void)IP27_LHUB_L(HUB_IR0);
(void)IP27_LHUB_L(HUB_IR1);
+ /* XXX do the other two cpus on IP35 */
}
/*
diff --git a/sys/arch/sgi/sgi/sginode.c b/sys/arch/sgi/sgi/sginode.c
index 02843b59393..3f0b36c5c0b 100644
--- a/sys/arch/sgi/sgi/sginode.c
+++ b/sys/arch/sgi/sgi/sginode.c
@@ -1,5 +1,4 @@
-#define DEBUG
-/* $OpenBSD: sginode.c,v 1.6 2009/05/14 21:08:49 miod Exp $ */
+/* $OpenBSD: sginode.c,v 1.7 2009/05/27 19:00:19 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
*
@@ -56,25 +55,26 @@
int nextcpu = 0;
-void kl_do_boardinfo(lboard_t *);
void kl_add_memory_ip27(int16_t *, unsigned int);
void kl_add_memory_ip35(int16_t *, unsigned int);
+int kl_first_pass_board(lboard_t *, void *);
+int kl_first_pass_comp(klinfo_t *, void *);
+
#ifdef DEBUG
-#define DB_PRF(x) bios_printf x
+#define DB_PRF(x) bios_printf x
#else
#define DB_PRF(x)
#endif
void
-kl_scan_config(int node)
+kl_init()
{
- lboard_t *boardinfo;
kl_config_hdr_t *cfghdr;
u_int64_t val;
- if (node == 0)
- physmem = 0;
+ /* will be recomputed when processing memory information */
+ physmem = 0;
cfghdr = IP27_KLCONFIG_HDR(0);
DB_PRF(("config @%p\n", cfghdr));
@@ -90,133 +90,200 @@ kl_scan_config(int node)
DB_PRF(("Region present %p.\n", val));
val = IP27_LHUB_L(PI_CALIAS_SIZE);
DB_PRF(("Calias size %p.\n", val));
+}
- for (boardinfo = IP27_KLFIRST_BOARD(0); boardinfo != NULL;
- boardinfo = IP27_KLNEXT_BOARD(0, boardinfo)) {
- kl_do_boardinfo(boardinfo);
- if (boardinfo->brd_next == NULL)
- break;
- }
+void
+kl_scan_config(int nasid)
+{
+ kl_scan_node(nasid, KLBRD_ANY, kl_first_pass_board, NULL);
+}
+void
+kl_scan_done()
+{
if (nextcpu > MAX_CPUS) {
bios_printf("%u processors found, increase MAX_CPUS\n",
nextcpu);
}
+ ncpusfound = nextcpu;
}
-void
-kl_do_boardinfo(lboard_t *boardinfo)
+/*
+ * Callback routine for the initial enumration (boards).
+ */
+int
+kl_first_pass_board(lboard_t *boardinfo, void *arg)
{
- klinfo_t *comp;
+ DB_PRF(("%cboard type %x slot %x nasid %x nic %p components %d\n",
+ boardinfo->struct_type & LBOARD ? 'l' : 'r',
+ boardinfo->brd_type, boardinfo->brd_slot, boardinfo->brd_nasid,
+ boardinfo->brd_nic, boardinfo->brd_numcompts));
+
+ kl_scan_board(boardinfo, KLSTRUCT_ANY, kl_first_pass_comp, NULL);
+ return 0;
+}
+
+/*
+ * Callback routine for the initial enumeration (components).
+ * We are interested in cpu and memory information only, but display a few
+ * other things if option DEBUG.
+ */
+int
+kl_first_pass_comp(klinfo_t *comp, void *arg)
+{
+ struct cpuinfo *cpu;
klcpu_t *cpucomp;
- klhub_t *hubcomp;
klmembnk_m_t *memcomp_m;
+#ifdef DEBUG
+ klhub_t *hubcomp;
klmembnk_n_t *memcomp_n;
klxbow_t *xbowcomp;
- struct cpuinfo *cpu;
- int i, j;
-
- DB_PRF(("board type %x slot %x nasid %x nic %p components %d\n",
- boardinfo->brd_type, boardinfo->brd_slot, boardinfo->brd_nasid,
- boardinfo->brd_nic, boardinfo->brd_numcompts));
+ int i;
+#endif
- for (i = 0; i < boardinfo->brd_numcompts; i++) {
- comp = IP27_UNCAC_ADDR(klinfo_t *, 0, boardinfo->brd_compts[i]);
-
- switch(comp->struct_type) {
- case KLSTRUCT_CPU:
- cpucomp = (klcpu_t *)comp;
- DB_PRF(("\tcpu type %x/%x %dMhz cache %dMB speed %dMhz\n",
- cpucomp->cpu_prid, cpucomp->cpu_fpirr,
- cpucomp->cpu_speed,
- cpucomp->cpu_scachesz, cpucomp->cpu_scachespeed));
-
- if (nextcpu < MAX_CPUS) {
- cpu = &sys_config.cpu[nextcpu];
- cpu->clock = cpucomp->cpu_speed * 1000000;
- cpu->type = (cpucomp->cpu_prid >> 8) & 0xff;
- cpu->vers_maj = (cpucomp->cpu_prid >> 4) & 0x0f;
- cpu->vers_min = cpucomp->cpu_prid & 0x0f;
+ switch (comp->struct_type) {
+ case KLSTRUCT_CPU:
+ cpucomp = (klcpu_t *)comp;
+ DB_PRF(("\tcpu type %x/%x %dMhz cache %dMB speed %dMhz\n",
+ cpucomp->cpu_prid, cpucomp->cpu_fpirr, cpucomp->cpu_speed,
+ cpucomp->cpu_scachesz, cpucomp->cpu_scachespeed));
+
+ if (nextcpu < MAX_CPUS) {
+ cpu = &sys_config.cpu[nextcpu];
+ cpu->clock = cpucomp->cpu_speed * 1000000;
+ cpu->type = (cpucomp->cpu_prid >> 8) & 0xff;
+ cpu->vers_maj = (cpucomp->cpu_prid >> 4) & 0x0f;
+ cpu->vers_min = cpucomp->cpu_prid & 0x0f;
#if 0
- cpu->fptype = (cpucomp->cpu_fpirr >> 8) & 0xff;
+ cpu->fptype = (cpucomp->cpu_fpirr >> 8) & 0xff;
#else
- cpu->fptype = cpu->type;
+ cpu->fptype = cpu->type;
#endif
- cpu->fpvers_maj =
- (cpucomp->cpu_fpirr >> 4) & 0x0f;
- cpu->fpvers_min = cpucomp->cpu_fpirr & 0x0f;
- cpu->tlbsize = 64;
- }
- nextcpu++;
- break;
+ cpu->fpvers_maj = (cpucomp->cpu_fpirr >> 4) & 0x0f;
+ cpu->fpvers_min = cpucomp->cpu_fpirr & 0x0f;
+ cpu->tlbsize = 64;
+ }
+ nextcpu++;
+ break;
- case KLSTRUCT_HUB:
- hubcomp = (klhub_t *)comp;
- DB_PRF(("\thub widget %d port %d flag %d speed %dMHz\n",
- hubcomp->hub_info.widid,
- hubcomp->hub_port.port_nasid,
- hubcomp->hub_port.port_flag,
- hubcomp->hub_speed / 1000000));
- break;
-
- case KLSTRUCT_MEMBNK:
- memcomp_m = (klmembnk_m_t *)comp;
- memcomp_n = (klmembnk_n_t *)comp;
- DB_PRF(("\tmemory %dMB, select %x flags %x\n",
- memcomp_m->membnk_memsz,
- memcomp_m->membnk_dimm_select,
- kl_n_mode ?
- memcomp_n->membnk_attr : memcomp_m->membnk_attr));
-
- if (kl_n_mode) {
- for (j = 0; j < MD_MEM_BANKS_N; j++) {
- if (memcomp_n->membnk_bnksz[j] == 0)
- continue;
- DB_PRF(("\t\tbank %d %dMB\n",
- j + 1,
- memcomp_n->membnk_bnksz[j]));
- }
- } else {
- for (j = 0; j < MD_MEM_BANKS_M; j++) {
- if (memcomp_m->membnk_bnksz[j] == 0)
- continue;
- DB_PRF(("\t\tbank %d %dMB\n",
- j + 1,
- memcomp_m->membnk_bnksz[j]));
- }
+ case KLSTRUCT_MEMBNK:
+ memcomp_m = (klmembnk_m_t *)comp;
+#ifdef DEBUG
+ memcomp_n = (klmembnk_n_t *)comp;
+ DB_PRF(("\tmemory %dMB, select %x flags %x\n",
+ memcomp_m->membnk_memsz, memcomp_m->membnk_dimm_select,
+ kl_n_mode ?
+ memcomp_n->membnk_attr : memcomp_m->membnk_attr));
+
+ if (kl_n_mode) {
+ for (i = 0; i < MD_MEM_BANKS_N; i++) {
+ if (memcomp_n->membnk_bnksz[i] == 0)
+ continue;
+ DB_PRF(("\t\tbank %d %dMB\n",
+ i + 1, memcomp_n->membnk_bnksz[i]));
+ }
+ } else {
+ for (i = 0; i < MD_MEM_BANKS_M; i++) {
+ if (memcomp_m->membnk_bnksz[i] == 0)
+ continue;
+ DB_PRF(("\t\tbank %d %dMB\n",
+ i + 1, memcomp_m->membnk_bnksz[i]));
}
+ }
+#endif
- if (sys_config.system_type == SGI_O200)
- kl_add_memory_ip27(memcomp_m->membnk_bnksz,
- kl_n_mode ?
- MD_MEM_BANKS_N : MD_MEM_BANKS_M);
- else
- kl_add_memory_ip35(memcomp_m->membnk_bnksz,
- kl_n_mode ?
- MD_MEM_BANKS_N : MD_MEM_BANKS_M);
+ if (sys_config.system_type == SGI_O200)
+ kl_add_memory_ip27(memcomp_m->membnk_bnksz,
+ kl_n_mode ? MD_MEM_BANKS_N : MD_MEM_BANKS_M);
+ else
+ kl_add_memory_ip35(memcomp_m->membnk_bnksz,
+ kl_n_mode ? MD_MEM_BANKS_N : MD_MEM_BANKS_M);
+ break;
- break;
+#ifdef DEBUG
+ case KLSTRUCT_HUB:
+ hubcomp = (klhub_t *)comp;
+ DB_PRF(("\thub widget %d port %d flag %d speed %dMHz\n",
+ hubcomp->hub_info.widid, hubcomp->hub_port.port_nasid,
+ hubcomp->hub_port.port_flag, hubcomp->hub_speed / 1000000));
+ break;
+
+ case KLSTRUCT_XBOW:
+ xbowcomp = (klxbow_t *)comp;
+ DB_PRF(("\txbow hub master link %d\n",
+ xbowcomp->xbow_hub_master_link));
+ for (i = 0; i < MAX_XBOW_LINKS; i++) {
+ if (xbowcomp->xbow_port_info[i].port_flag &
+ XBOW_PORT_ENABLE)
+ DB_PRF(("\t\twidget %d nasid %d flg %u\n",
+ 8 + i,
+ xbowcomp->xbow_port_info[i].port_nasid,
+ xbowcomp->xbow_port_info[i].port_flag));
+ }
+ break;
- case KLSTRUCT_XBOW:
- xbowcomp = (klxbow_t *)comp;
- DB_PRF(("\txbow hub master link %d\n",
- xbowcomp->xbow_hub_master_link));
- for (j = 0; j < MAX_XBOW_LINKS; j++) {
- if (xbowcomp->xbow_port_info[j].port_flag &
- XBOW_PORT_ENABLE)
- DB_PRF(("\t\twidget %d nasid %d flg %u\n",
- j,
- xbowcomp->xbow_port_info[j].port_nasid,
- xbowcomp->xbow_port_info[j].port_flag));
- }
- break;
+ default:
+ DB_PRF(("\tcomponent widget %d type %d\n",
+ comp->widid, comp->struct_type));
+ break;
+#endif
+ }
+ return 0;
+}
- default:
- DB_PRF(("\tcomponent widget %d type %d\n",
- comp->widid, comp->struct_type));
+/*
+ * Enumerate the boards of a node, and invoke a callback for those matching
+ * the given class.
+ */
+int
+kl_scan_node(int nasid, uint clss, int (*cb)(lboard_t *, void *), void *cbarg)
+{
+ lboard_t *boardinfo;
+
+ for (boardinfo = IP27_KLFIRST_BOARD(nasid); boardinfo != NULL;
+ boardinfo = IP27_KLNEXT_BOARD(nasid, boardinfo)) {
+ if (clss == KLBRD_ANY ||
+ (boardinfo->brd_type & IP27_BC_MASK) == clss) {
+ if ((*cb)(boardinfo, cbarg) != 0)
+ return 1;
}
+ if (boardinfo->brd_next == NULL)
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Enumerate the components of a board, and invoke a callback for those
+ * matching the given type.
+ */
+int
+kl_scan_board(lboard_t *boardinfo, uint type, int (*cb)(klinfo_t *, void *),
+ void *cbarg)
+{
+ klinfo_t *comp;
+ int i;
+
+ if (!ISSET(boardinfo->struct_type, LBOARD))
+ return 0;
+
+ for (i = 0; i < boardinfo->brd_numcompts; i++) {
+ comp = IP27_UNCAC_ADDR(klinfo_t *, boardinfo->brd_nasid,
+ boardinfo->brd_compts[i]);
+
+ if (!ISSET(comp->flags, KLINFO_ENABLED) ||
+ ISSET(comp->flags, KLINFO_FAILED))
+ continue;
+
+ if (type != KLSTRUCT_ANY && comp->struct_type != type)
+ continue;
+
+ if ((*cb)(comp, cbarg) != 0)
+ return 1;
}
+ return 0;
}
/*