From 142f545264089ad6a493f097b3c2eefacd6e357c Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Wed, 27 May 2009 19:00:20 +0000 Subject: Rework KL board and component enumeration, to allow it to be used from drivers with callback routines. While there, skip disabled or failed components. --- sys/arch/sgi/include/mnode.h | 50 +++++-- sys/arch/sgi/sgi/ip27_machdep.c | 24 ++-- sys/arch/sgi/sgi/sginode.c | 285 +++++++++++++++++++++++++--------------- 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; } /* -- cgit v1.2.3