/*
* 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.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* 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 1999-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Desktop Platform specific functions.
*
* Called when:
* machine_type == MTYPE_DARWIN &&
* machine_type == MTYPE_DEFAULT
*
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <kvm.h>
#include <varargs.h>
#include <errno.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/systeminfo.h>
#include <sys/openpromio.h>
#include <kstat.h>
#include <libintl.h>
#include <syslog.h>
#include "pdevinfo.h"
#include "display.h"
#include "pdevinfo_sun4u.h"
#include "display_sun4u.h"
#include "libprtdiag.h"
#if !defined(TEXT_DOMAIN)
#endif
/*
* State variable to signify the type of machine we're currently
* running on. Since prtdiag has come to be the dumping ground
* for lots of platform-specific routines, and machine architecture
* alone is not enough to determine our course of action, we need
* to enumerate the different machine types that we should worry
* about.
*/
enum machine_type {
};
extern int print_flag;
/*
* these functions will overlay the symbol table of libprtdiag
* at runtime (desktop systems only)
*/
struct system_kstat_data *kstats);
struct system_kstat_data *sys_kstat,
void display_sbus(Board_node *);
/* local functions */
static void dt_disp_asic_revs(Sys_tree *);
static void display_sabre_pci(Board_node *);
static void get_machine_type(void);
int
{
#ifdef lint
#endif
/*
* silently check for any types of machine errors
*/
print_flag = 0;
if (disp_fail_parts(tree)) {
/* set exit_code to show failures */
exit_code = 1;
}
print_flag = 1;
return (exit_code);
}
void
{
#ifdef lint
#endif
}
/*
* disp_fail_parts
*
* Display the failed parts in the system. This function looks for
* the status property in all PROM nodes. On systems where
* the PROM does not supports passing diagnostic information
* thruogh the device tree, this routine will be silent.
*/
int
{
int exit_code;
int system_failed = 0;
exit_code = 0;
/* go through all of the boards looking for failed units. */
/* find failed chips */
system_failed = 1;
exit_code = 1;
if (print_flag == 0) {
return (exit_code);
}
log_printf("\n", 0);
"Replaceable Units (FRU) in System:\n"), 0);
log_printf("=========================="
"====================\n", 0);
}
void *value;
/* sanity check of data retreived from PROM */
continue;
}
/* Find the board type of this board */
board_type = "CPU";
} else {
board_type = "IO";
}
"\tPROM fault string: %s\n"), value, 0);
"\tFailed Field Replaceable Unit is "), 0);
/*
* Determine whether FRU is CPU module, system
* board, or SBus card.
*/
"SBus Card %d\n"),
get_sbus_slot(pnode), 0);
"PCI Card %d"),
get_pci_device(pnode), 0);
"module Board %d Module %d\n"), 0,
} else {
"%s board %d\n"), board_type,
}
}
}
if (!system_failed) {
log_printf("\n", 0);
"No failures found in System\n"), 0);
log_printf("===========================\n", 0);
}
if (system_failed)
return (1);
else
return (0);
}
void
{
#ifdef lint
#endif
/* Display failed units */
(void) disp_fail_parts(tree);
}
void
struct system_kstat_data *kstats)
{
#ifdef lint
#endif
/*
* Now display the last powerfail time and the fatal hardware
* reset information. We do this under a couple of conditions.
* First if the user asks for it. The second is iof the user
* told us to do logging, and we found a system failure.
*/
if (flag) {
/*
* display time of latest powerfail. Not all systems
* have this capability. For those that do not, this
* is just a no-op.
*/
}
return;
}
void
{
/*
* We have different routines for walking/displaying PCI
* devices depending on whether the PCI device is a
* Psycho or a Sabre.
*/
return;
}
return;
}
}
void
{
#ifdef lint
#endif
}
/*
* local functions
*/
void
{
char *name;
int *version;
/* Print the header */
log_printf("\n", 0);
log_printf("=========================", 0);
log_printf(" HW Revisions ", 0);
log_printf("=========================", 0);
log_printf("\n", 0);
log_printf("\n", 0);
log_printf("ASIC Revisions:\n", 0);
log_printf("---------------\n", 0);
/* Find sysio and print rev */
log_printf("SBus: %s Rev %d\n",
}
}
/* Find Psycho and print rev */
log_printf("PCI: %s Rev %d\n",
}
/* Find Cheerio and print rev */
}
/* Find the FEPS and print rev */
if (*version == 0xa0) {
log_printf("2.0\n", 0);
} else if (*version == 0x20) {
log_printf("2.1\n", 0);
} else {
}
}
}
log_printf("\n", 0);
display_ffb(bnode, 0);
}
/*
* print the header and call display_dev_node() to walk the device
* tree (darwin platform only).
*/
static void
{
return;
log_printf(" Bus# Freq\n", 0);
log_printf("Brd Type MHz Slot "
"Name Model", 0);
log_printf("\n", 0);
log_printf("--- ---- ---- ---- "
"-------------------------------- ----------------------", 0);
log_printf("\n", 0);
log_printf("\n", 0);
}
/*
* Recursively traverse the device tree and use tree depth as filter.
* called by: display_sabre_pci()
*/
static void
{
unsigned int reghi;
if (!np)
return;
if (depth > 2)
return;
if (!regval)
return;
else
if (!model)
model = "";
if (!name)
name = "";
if (depth == 2) {
if (compat)
else
log_printf("\n", 0);
#ifdef DEBUG
if (!compat)
compat = "";
printf("bus=%d slot=%d name=%s model=%s compat=%s\n",
#endif
}
}
/*
* display_sbus
* Display all the SBus IO cards on this board.
*/
void
{
int freq;
int card_num;
void *value;
return;
/* Skip failed nodes for now */
if (node_failed(sbus))
continue;
/* Calculate SBus frequency in MHz */
else
freq = -1;
char *model;
char *name;
char *child_name;
if (card_num == -1)
continue;
/* Fill in card information */
/* Try and get card status */
/* XXX - For now, don't display failed cards */
continue;
/*
* sets the machine_type var if not already set
*/
/*
* For desktops, the only high slot number that
* needs to be displayed is the # 14 slot.
*/
if (machine_type == MTYPE_DEFAULT &&
continue;
}
/* Now gather all of the node names for that card */
"model"));
continue;
/* Figure out how we want to display the name */
(child_name != NULL)) {
"device_type"));
(char *)value);
else
} else {
}
}
}
/* We're all done gathering card info, now print it out */
}
static void
get_machine_type(void)
{
/* Figure out what kind of machine we're on */
}
}