diff options
| author | jl139090 <none@none> | 2006-04-08 10:25:15 -0700 |
|---|---|---|
| committer | jl139090 <none@none> | 2006-04-08 10:25:15 -0700 |
| commit | 25cf1a301a396c38e8adf52c15f537b80d2483f7 (patch) | |
| tree | a76776c2cfbbe43c1ae252223c7ccfa5df15c21c /usr/src/lib/libprtdiag_psr | |
| parent | 918fadfadf0c235e6c65ca652caab042b6f05976 (diff) | |
| download | illumos-joyent-25cf1a301a396c38e8adf52c15f537b80d2483f7.tar.gz | |
PSARC 2004/750 Solaris for OPL
6379529 Solaris for OPL Project
--HG--
rename : usr/src/cmd/sckmd/sparc/sun4u/sckm.sh => deleted_files/usr/src/cmd/sckmd/sparc/sun4u/sckm.sh
Diffstat (limited to 'usr/src/lib/libprtdiag_psr')
| -rw-r--r-- | usr/src/lib/libprtdiag_psr/sparc/Makefile | 9 | ||||
| -rw-r--r-- | usr/src/lib/libprtdiag_psr/sparc/opl/Makefile | 74 | ||||
| -rw-r--r-- | usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c | 850 |
3 files changed, 928 insertions, 5 deletions
diff --git a/usr/src/lib/libprtdiag_psr/sparc/Makefile b/usr/src/lib/libprtdiag_psr/sparc/Makefile index e9d36c0d44..1a5121e2bc 100644 --- a/usr/src/lib/libprtdiag_psr/sparc/Makefile +++ b/usr/src/lib/libprtdiag_psr/sparc/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -29,7 +28,7 @@ PRTDIAG_PLATFORMS= desktop tazmo javelin sunfire starfire serengeti \ montecarlo littleneck starcat daktari cherrystone \ - lw8 snowbird ontario schumacher + lw8 snowbird ontario schumacher opl all := TARGET= all lint := TARGET= lint diff --git a/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile b/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile new file mode 100644 index 0000000000..16eb8eb1e5 --- /dev/null +++ b/usr/src/lib/libprtdiag_psr/sparc/opl/Makefile @@ -0,0 +1,74 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libprtdiag_psr/sparc/opl/Makefile + +UTSBASE = ../../../../../src/uts + +PLATFORM_OBJECTS= opl.o + +include ../Makefile.com + +IFLAGS += -I$(USR_PLAT_DIR)/sun4u/include -I ../../../libprtdiag/inc +LINTFLAGS += $(IFLAGS) + +LDLIBS += -ldevinfo -lkstat + +#IMPLEMENTED_PLATFORM = SUNW,OPL-Enterprise +#PLATFORM=$(IMPLEMENTED_PLATFORM) +PLATFORM = SUNW,SPARC-Enterprise + +.KEEP_STATE: + +PLATLIBS= $(USR_PLAT_DIR)/$(PLATFORM)/lib/ + +install: all $(USR_PSM_LIBS) + +$(USR_PSM_LIB_DIR): + cd $(UTSBASE)/sun4u/opl; $(MAKE) $(USR_PSM_LIB_DIR) + +# +# install rule +# +$(USR_PSM_LIB_DIR)/%: % $(USR_PSM_LIB_DIR) + $(INS.file) + +POFILE= libprtdiag_psr_opl.po +POFILES= opl.po + +_msg: $(MSGDOMAIN) $(POFILE) + $(RM) $(MSGDOMAIN)/$(POFILE) + $(CP) $(POFILE) $(MSGDOMAIN) + +$(POFILE): $(POFILES) + $(RM) $@ + $(CAT) $(POFILES) > $@ + +$(POFILES): + $(RM) messages.po + $(XGETTEXT) $(XGETFLAGS) `$(GREP) -l gettext common/opl.c` + $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@ + $(RM) messages.po diff --git a/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c new file mode 100644 index 0000000000..9bce08b95a --- /dev/null +++ b/usr/src/lib/libprtdiag_psr/sparc/opl/common/opl.c @@ -0,0 +1,850 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Opl Platform specific functions. + * + * called when : + * machine_type == MTYPE_OPL + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <string.h> +#include <varargs.h> +#include <fcntl.h> +#include <assert.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <sys/systeminfo.h> +#include <sys/openpromio.h> +#include <libintl.h> +#include <syslog.h> +#include <sys/dkio.h> +#include <pdevinfo.h> +#include <libprtdiag.h> +#include <libdevinfo.h> +#include <kstat.h> + +/* + * Globals and externs + */ +#define KBYTE 1024 +#define MBYTE (KBYTE * KBYTE) +#define HZ_TO_MHZ(x) ((((uint64_t)(x)) + 500000) / 1000000) +#define SCF_SECURE_MODE_KSTAT_NAMED "secure_mode" +#define SCF_STAT_MODE_UNLOCK 0 +#define SCF_STAT_MODE_LOCK 1 +#define SCF_SYSTEM_KSTAT_NAME "scf" +#ifndef TEXT_DOMAIN +#define TEXT_DOMAIN "SYS_TEST" +#endif /* TEXT_DOMAIN */ +#define IS_PCI_BRIDGE(name, type) \ + (((name) != NULL) && ((type) != NULL) && \ + (strncmp((name), "pci", 3) == 0) && \ + (strncmp((type), "pci", 3) == 0)) + +/* + * Global functions and variables + * these functions will overlay the symbol table of libprtdiag + * at runtime (Opl systems only) + */ +struct cs_status { + int cs_number; + int status; + int avail_hi; + int avail_lo; + int dimm_hi; + int dimm_lo; + int dimms; +}; + +int do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag); +void *get_prop_val(Prop *prop); +void display_pci(Board_node *); +void display_ffb(Board_node *, int); +void display_sbus(Board_node *board); +void display_cpu_devices(Sys_tree *tree); +void display_cpus(Board_node *board); +void display_memoryconf(Sys_tree *tree, struct grp_info *grps); +void display_io_cards(struct io_card *list); +void display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, + struct system_kstat_data *kstats); +Prop *find_prop(Prom_node *pnode, char *name); + +/* Local functions */ +static void opl_disp_environ(void); +static void opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root); +static uint64_t print_opl_memory_line(int lsb, struct cs_status *cs_stat, + int ngrps); +static uint64_t get_opl_mem_regs(Board_node *bnode); +void add_node(Sys_tree *root, Prom_node *pnode); +static int get_prop_size(Prop *prop); + +/* + * Display all the leaf PCI nodes on this board that have "reg" property. + * If the "reg" property is NULL for a leaf node, skip parsing its sibling + * nodes and display the parent node properties. + */ +void +display_pci(Board_node *board) +{ + struct io_card *card_list = NULL; + struct io_card card; + Prom_node *pci, *card_node; + char *name, *type; + int *int_val; + + if (board == NULL) + return; + + /* Initialize common information */ + card.board = board->board_num; + + pci = board->nodes; + while (pci != NULL) { + name = get_node_name(pci); + + /* Skip non-PCI board nodes */ + if ((name == NULL) || (strcmp(name, "pci") != 0)) { + pci = pci->sibling; + continue; + } + + type = (char *)get_prop_val(find_prop(pci, "device_type")); + + /* + * Skip PCI/ebus devices + * They have name == "pci" and type == "pci" + */ + if (strcmp(type, "pci") == 0) { + pci = pci->sibling; + continue; + } + + card_node = pci; + while (card_node != NULL) { + int pci_parent_bridge = 0; + + /* If it does have a child, skip to leaf child */ + if (card_node->child != NULL) { + card_node = card_node->child; + continue; + } + + /* Get name of the card */ + name = (char *)get_prop_val(find_prop + (card_node, "name")); + + /* Get type of card */ + type = (char *)get_prop_val(find_prop + (card_node, "device_type")); + + /* Leaf pci-bridges are to be ignored */ + if (!IS_PCI_BRIDGE(name, type)) { + + /* Get reg property of the node */ + int_val = (int *)get_prop_val(find_prop + (card_node, "reg")); + + /* + * If no "reg" property check to see + * whether parent node has reg property. + * and check if parent is a bridge + */ + if (int_val == NULL) { + Prom_node *cparent = card_node->parent; + if (cparent == NULL) + break; + + name = (char *)get_prop_val(find_prop + (cparent, "name")); + + type = (char *)get_prop_val(find_prop + (cparent, "device_type")); + + /* check if parent is a bridge */ + if (IS_PCI_BRIDGE(name, type)) + pci_parent_bridge = 1; + + int_val = (int *)get_prop_val( + find_prop(cparent, "reg")); + + if (int_val != NULL) + /* Switch to parent */ + card_node = cparent; + else + /* parent node has no reg */ + break; + } + + if (!pci_parent_bridge) { + + name = (char *)get_prop_val(find_prop + (card_node, "name")); + + if (name == NULL) + card.name[0] = '\0'; + else { + (void) snprintf(card.name, + MAXSTRLEN, "%s", name); + } + + /* Get the model of this card */ + name = (char *)get_prop_val(find_prop + (card_node, "model")); + + if (name == NULL) { + (void) snprintf(card.model, + MAXSTRLEN, "%s", "N/A"); + } else { + (void) snprintf(card.model, + MAXSTRLEN, "%s", name); + } + + /* insert card to the list */ + card_list = insert_io_card + (card_list, &card); + + } + + } + + /* + * Parse sibling nodes. + * Then move up the parent's sibling upto the top + * intermediate node + * Stop if pci board node is reached. + */ + if (card_node->sibling != NULL) + card_node = card_node->sibling; + else { + Prom_node *cparent; + cparent = card_node->parent; + card_node = NULL; + while (cparent != NULL) { + if (cparent == pci) + break; + if (cparent->sibling != NULL) { + card_node = cparent->sibling; + break; + } + cparent = cparent->parent; + } + } + + } + + /* On to the next board node */ + pci = pci->sibling; + + } + + display_io_cards(card_list); + free_io_cards(card_list); +} + +/* + * There are no FFB's on OPL. + */ +/*ARGSUSED*/ +void +display_ffb(Board_node *board, int table) +{ +} + +/* + * There are no Sbus's on OPL. + */ +/*ARGSUSED*/ +void +display_sbus(Board_node *board) +{ +} + +/* + * Details of I/O information. Print out all the io cards. + */ +void +display_io_cards(struct io_card *list) +{ + char *hdrfmt = "%-6.6s %-14.14s %-12.12s\n"; + + struct io_card *p; + + if (list == NULL) + return; + + (void) textdomain(TEXT_DOMAIN); + + log_printf(hdrfmt, gettext("LSB"), gettext("Name"), gettext("Model"), + 0); + + log_printf(hdrfmt, "---", "-----------------", "------------", 0); + + for (p = list; p != NULL; p = p->next) { + + /* Board number */ + log_printf(" %02d ", p->board, 0); + + /* Card name */ + log_printf("%-15.15s", p->name, 0); + + /* Card model */ + log_printf("%-12.12s", p->model, 0); + + log_printf("\n", 0); + } + log_printf("\n", 0); +} + +/* + * Details of CPU information. + */ +void +display_cpu_devices(Sys_tree *tree) +{ + Board_node *bnode; + char *hdrfmt = + "%-5.5s %-8.8s %-20.20s %-8.8s %-8.8s %-8.8s %-8.8s\n"; + + (void) textdomain(TEXT_DOMAIN); + + /* + * Display the table header for CPUs . Then display the CPU + * frequency, cache size, and processor revision of all cpus. + */ + log_printf("\n", 0); + log_printf("====================================", 0); + log_printf(gettext(" CPUs "), 0); + log_printf("====================================", 0); + log_printf("\n\n", 0); + + log_printf(hdrfmt, + "", + gettext("CPU"), + gettext(" CPU "), + gettext("Run"), + gettext("L2$"), + gettext("CPU"), + gettext("CPU"), 0); + + log_printf(hdrfmt, + gettext("LSB"), + gettext("Chip"), + gettext(" ID "), + gettext("MHz"), + gettext(" MB"), + gettext("Impl."), + gettext("Mask"), 0); + + log_printf(hdrfmt, + "---", "----", "--------------------", "----", + "---", "-----", "----", 0); + + /* Now display all of the cpus on each board */ + for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { + display_cpus(bnode); + } + + log_printf("\n", 0); +} + +/* + * Display the CPUs present on this board. + */ +void +display_cpus(Board_node *board) +{ + int *impl, *mask, *cpuid, *portid, *l2cache_size; + uint_t freq; /* CPU clock frequency */ + Prom_node *pnode, *cpu; + char *name; + + (void) textdomain(TEXT_DOMAIN); + + /* + * Get the Cpus' properties for display + */ + for (pnode = board->nodes; pnode != NULL; pnode = pnode->sibling) { + char cpu_str[MAXSTRLEN], fcpu_str[MAXSTRLEN] = {0}; + + name = get_node_name(pnode); + if ((name == NULL) || (strncmp(name, "cmp", 3) != 0)) { + continue; + } + + portid = (int *)get_prop_val(find_prop(pnode, "portid")); + freq = (HZ_TO_MHZ(get_cpu_freq(pnode->child))); + l2cache_size = + (int *)get_prop_val + (find_prop(pnode->child, "l2-cache-size")); + impl = + (int *)get_prop_val + (find_prop(pnode->child, "implementation#")); + mask = (int *)get_prop_val(find_prop(pnode->child, "mask#")); + + /* Lsb id */ + log_printf(" %02d ", board->board_num, 0); + + if (portid != NULL) + log_printf("%3d ", (((*portid)>>3)&0x3), 0); + + /* + * Specific parsing of the CMP/CORE/CPU chain. + * The internal cpu tree built by walk_di_tree() + * in common code can be illustrated by the diagram + * below: + * + * cmp->cpu->cpu->cpu->cpu->(next board nodes) + * / \ + * core core + * where "/" or "\" are children + * and "->" are siblings + */ + for (cpu = pnode->sibling; cpu != NULL; ) { + Prom_node *cpu_next = NULL; + + name = get_node_name(cpu); + if ((name == NULL) || (strncmp(name, "cpu", 3) != 0)) { + break; + } + + /* Id assigned to Virtual processor core */ + cpuid = (int *)get_prop_val(find_prop(cpu, "cpuid")); + cpu_next = cpu->sibling; + + if (cpu_next != NULL) { + name = get_node_name(cpu_next); + + if ((name == NULL) || + (strncmp(name, "cpu", 3) != 0)) { + cpu_next = NULL; + } + } + + if (cpuid != NULL) { + /* Used for printing in comma format */ + (void) sprintf(cpu_str, "%4d", *cpuid); + (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN); + + if (cpu_next != NULL) + (void) strlcat(fcpu_str, ",", MAXSTRLEN); + } else { + (void) sprintf(cpu_str, "%4s", "N/A"); + (void) strlcat(fcpu_str, cpu_str, MAXSTRLEN); + + if (cpu_next != NULL) + (void) strlcat(fcpu_str, ",", MAXSTRLEN); + } + cpu = cpu_next; + } + + log_printf("%-20.20s", fcpu_str, 0); + + /* Running frequency */ + if (freq != 0) + log_printf(" %4ld ", freq, 0); + else + log_printf(" %4s ", "N/A", 0); + + /* L2 cache size */ + if (l2cache_size == NULL) + log_printf(" %3s ", "N/A", 0); + else { + log_printf("%4.1f ", + (float)(*l2cache_size) / (float)(1<<20), 0); + } + + + /* Implementation number of processor */ + if (impl != NULL) + log_printf("%4d ", *impl, 0); + else + log_printf("%4s ", "N/A", 0); + + /* Mask Set version */ + /* Bits 31:24 of VER register is mask. */ + /* Mask value : Non MTP mode - 00-7f, MTP mode - 80-ff */ + if (mask == NULL) + log_printf("%4s", "N/A", 0); + else + log_printf("%4d", (*mask)&0xff, 0); + + log_printf("\n", 0); + + } +} + +/* + * Gather memory information: Details of memory information. + */ +static uint64_t +get_opl_mem_regs(Board_node *bnode) +{ + Prom_node *pnode; + struct cs_status *cs_stat; + uint64_t total_mem = 0; + int cs_size, ngrps; + + pnode = dev_find_node(bnode->nodes, "pseudo-mc"); + while (pnode != NULL) { + + cs_size = get_prop_size(find_prop(pnode, "cs-status")); + + if (cs_size > 0) { + + /* OBP returns lists of 7 ints */ + cs_stat = (struct cs_status *)get_prop_val + (find_prop(pnode, "cs-status")); + + /* cs_size must be at least 28 */ + ngrps = cs_size/sizeof (struct cs_status); + + if (cs_stat != NULL) { + total_mem += + print_opl_memory_line(bnode->board_num, + cs_stat, ngrps); + } + } + + pnode = dev_next_node(pnode, "pseudo-mc"); + } + return (total_mem); +} + +/* + * Display memory information. + */ +/*ARGSUSED*/ +void +display_memoryconf(Sys_tree *tree, struct grp_info *grps) +{ + Board_node *bnode = tree->bd_list; + uint64_t total_mem = 0, total_sys_mem = 0; + char *hdrfmt = "\n%-5.5s %-6.6s %-12.12s %-10.10s" + " %-8.8s %-10.10s"; + + (void) textdomain(TEXT_DOMAIN); + + log_printf("======================", 0); + log_printf(gettext(" Memory Configuration "), 0); + log_printf("======================", 0); + log_printf("\n", 0); + + log_printf(hdrfmt, + "", + gettext("Memory"), + gettext("Available"), + gettext("Memory"), + gettext("DIMM"), + gettext("Number of"), + 0); + + log_printf(hdrfmt, + gettext("LSB"), + gettext("Group"), + gettext("Size"), + gettext("Status"), + gettext("Size"), + gettext("DIMMs"), 0); + + log_printf(hdrfmt, + "---", "-------", "------------", "-------", "-----", + "---------", 0); + + log_printf("\n", 0); + + for (bnode = tree->bd_list; bnode != NULL; bnode = bnode->next) { + total_mem += get_opl_mem_regs(bnode); + } + + /* + * Sanity check to ensure that the total amount of system + * memory matches the total number of memory that + * we find here. Display error message if there is a mis-match. + */ + total_sys_mem = (((uint64_t)sysconf(_SC_PAGESIZE) * (uint64_t)sysconf + (_SC_PHYS_PAGES)) / MBYTE); + + if (total_mem != total_sys_mem) { + log_printf(dgettext(TEXT_DOMAIN, + "\nError:total available size [%lldMB] does not match" + " total system memory [%lldMB]\n"), + total_mem, total_sys_mem, 0); + } + +} + +/* + * This function provides Opl's formatting of the memory config + * information that get_opl_mem_regs() has gathered. + */ +static uint64_t +print_opl_memory_line(int lsb, struct cs_status *cs_stat, int ngrps) +{ + int i; + uint64_t total_board_mem = 0; + + (void) textdomain(TEXT_DOMAIN); + + + for (i = 0; i < ngrps; i++) { + int64_t mem_size = 0; + + mem_size = ((((int64_t)cs_stat[i].avail_hi)<<32) + + cs_stat[i].avail_lo); + + if (mem_size == 0) continue; + + /* Lsb Id */ + log_printf(" %02d ", lsb, 0); + + /* Memory Group Number */ + if ((cs_stat[i].cs_number) == 0) + log_printf("%-6.6s", "A", 0); + else + log_printf("%-6.6s", "B", 0); + + /* Memory Group Size */ + log_printf(" %4lldMB ", mem_size/MBYTE, 0); + + total_board_mem += (mem_size/MBYTE); + + /* Memory Group Status */ + log_printf("%-11.11s", + cs_stat[i].status ? "partial": "okay", 0); + + /* DIMM Size */ + log_printf("%4lldMB ", + ((((int64_t)cs_stat[i].dimm_hi)<<32) + + cs_stat[i].dimm_lo)/MBYTE, 0); + + /* Number of DIMMs */ + log_printf("%9d\n", cs_stat[i].dimms); + } + return (total_board_mem); +} + +/* + * Details of hardware revision and environmental status. + */ +/*ARGSUSED*/ +void +display_diaginfo(int flag, Prom_node *root, Sys_tree *tree, + struct system_kstat_data *kstats) +{ + /* Print the PROM revisions */ + if (flag) + opl_disp_hw_revisions(tree, root); +} + +/* + * Gather and display hardware revision and environmental status + */ +/*ARGSUSED*/ +static void +opl_disp_hw_revisions(Sys_tree *tree, Prom_node *root) +{ + char *version; + Prom_node *pnode; + + (void) textdomain(TEXT_DOMAIN); + + /* Print the header */ + log_printf("\n", 0); + log_printf("====================", 0); + log_printf(gettext(" Hardware Revisions "), 0); + log_printf("====================", 0); + log_printf("\n\n", 0); + + /* Display Prom revision header */ + log_printf(gettext("System PROM revisions:"), 0); + log_printf("\n----------------------\n", 0); + log_printf("\n", 0); + + /* Display OBP version info */ + pnode = dev_find_node(root, "openprom"); + if (pnode != NULL) { + version = (char *)get_prop_val(find_prop(pnode, "version")); + if (version != NULL) + log_printf("%s\n\n", version, 0); + else + log_printf("%s\n\n", "N/A", 0); + } + + /* Print the header */ + log_printf("\n", 0); + log_printf("===================", 0); + log_printf(gettext(" Environmental Status "), 0); + log_printf("===================", 0); + log_printf("\n\n", 0); + + opl_disp_environ(); +} + +/* + * Gather environmental information + */ +static void +opl_disp_environ(void) +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *k; + + if ((kc = kstat_open()) == NULL) + return; + + if ((ksp = kstat_lookup + (kc, "scfd", 0, SCF_SYSTEM_KSTAT_NAME)) == NULL) { + (void) kstat_close(kc); + return; + } + + if (kstat_read(kc, ksp, NULL) == -1) { + (void) kstat_close(kc); + return; + } + + if ((k = (kstat_named_t *)kstat_data_lookup + (ksp, SCF_SECURE_MODE_KSTAT_NAMED)) == NULL) { + (void) kstat_close(kc); + return; + } + + if (k->value.c[0] == SCF_STAT_MODE_LOCK) + log_printf("Mode switch is in LOCK mode ", 0); + else if (k->value.c[0] == SCF_STAT_MODE_UNLOCK) + log_printf("Mode switch is in UNLOCK mode", 0); + else + log_printf("Mode switch is in UNKNOWN mode", 0); + + log_printf("\n", 0); + + (void) kstat_close(kc); +} + + +/* + * Calls do_devinfo() in order to use the libdevinfo device tree + * instead of OBP's device tree. + */ +int +do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag) +{ + return (do_devinfo(syserrlog, pgname, log_flag, prt_flag)); +} + +/* + * Return the property value for the Prop + * passed in. (When using libdevinfo) + */ +void * +get_prop_val(Prop *prop) +{ + if (prop == NULL) + return (NULL); + + return ((void *)(prop->value.val_ptr)); +} + +/* + * Return the property size for the Prop + * passed in. (When using libdevinfo) + */ +static int +get_prop_size(Prop *prop) +{ + + if ((prop != NULL) && (prop->size > 0)) + return (prop->size); + else + return (0); +} + + +/* + * Search a Prom node and retrieve the property with the correct + * name. (When using libdevinfo) + */ +Prop * +find_prop(Prom_node *pnode, char *name) +{ + Prop *prop; + + if (pnode == NULL) + return (NULL); + + for (prop = pnode->props; prop != NULL; prop = prop->next) { + if (prop->name.val_ptr != NULL && + strcmp((char *)(prop->name.val_ptr), name) == 0) + break; + } + + return (prop); +} + +/* + * This function adds a board node to the board structure where that + * that node's physical component lives. + */ +void +add_node(Sys_tree *root, Prom_node *pnode) +{ + int board; + Board_node *bnode; + Prom_node *p; + char *type; + + if ((board = get_board_num(pnode)) == -1) { + type = get_node_type(pnode); + if ((type != NULL) && (strcmp(type, "cpu") == 0)) + board = get_board_num((pnode->parent)->parent); + } + + /* find the node with the same board number */ + if ((bnode = find_board(root, board)) == NULL) { + bnode = insert_board(root, board); + bnode->board_type = UNKNOWN_BOARD; + } + + /* now attach this prom node to the board list */ + /* Insert this node at the end of the list */ + pnode->sibling = NULL; + if (bnode->nodes == NULL) + bnode->nodes = pnode; + else { + p = bnode->nodes; + while (p->sibling != NULL) + p = p->sibling; + p->sibling = pnode; + } + +} |
