1
0
Files
2022-09-29 17:59:04 +03:00

597 lines
13 KiB
C

/**************************************************************************
* *
* Copyright (C) 1996 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/*
* slots.c
* Support for slot nbumbering on SN0 machines
*/
#ident "$Revision: 1.33 $"
#include <sys/types.h>
#include <sys/SN/slotnum.h>
#include <sys/SN/arch.h>
#include <sys/xtalk/xtalk.h>
#include <sys/xtalk/xbow.h>
#include <sys/SN/agent.h>
#include <sys/SN/SN0/ip27config.h>
#include <sys/SN/SN0/ip27log.h>
#ifndef _STANDALONE
#include <sys/systm.h>
#include <sys/pda.h>
#else
#include <libsc.h>
#include <libkl.h>
#endif
/*
* Origin 2000:
*
* Xbow 0 Old New
* ------
* port 8: W0 IO1 (BaseIO slot)
* 9: N0 N1
* A: N2 N3
* B: W3 IO4
* C: W1 IO2 (PCI Module slot)
* D: W5 IO6
* E: W4 IO5
* F: W2 IO3
*
* Xbow 1
* ------
* port 8: W10 IO11
* 9: N3 N4
* A: N1 N2
* B: W7 IO8
* C: W9 IO10
* D: W11 IO12
* E: W6 IO7
* F: W8 IO9
*
* Onyx 2 Deskside:
*
* Xbow 0 Slot
* ------
* port 8: IO4 (Gfx slot)
* 9: N2
* A: N1
* B: IO2 (PCI Module slot)
* C: IO6
* D: IO5
* E: IO3
* F: IO1 (BaseIO slot)
*
* Speedo xbox:
*
* Xbow
* ----
* Port Slot
* 8 io7
* 9 io1
* A Motherboard
* B io2
* C io3
* D io4
* E io5
* F io6
*/
static volatile int kxbowslot_table[MAX_XBOW_PORTS] = {
SLOTNUM_XTALK_CLASS | 4, /* Gfx slot */
SLOTNUM_KNODE_CLASS | 2,
SLOTNUM_KNODE_CLASS | 1,
SLOTNUM_XTALK_CLASS | 2, /* PCI wart */
SLOTNUM_XTALK_CLASS | 6,
SLOTNUM_XTALK_CLASS | 5,
SLOTNUM_XTALK_CLASS | 3,
SLOTNUM_XTALK_CLASS | 1 /* Base IO */
};
static volatile int xbow0slot_table[MAX_XBOW_PORTS] = {
SLOTNUM_XTALK_CLASS | 1, /* Base IO */
SLOTNUM_NODE_CLASS | 1,
SLOTNUM_NODE_CLASS | 3,
SLOTNUM_XTALK_CLASS | 4,
SLOTNUM_XTALK_CLASS | 2, /* PCI wart */
SLOTNUM_XTALK_CLASS | 6,
SLOTNUM_XTALK_CLASS | 5,
SLOTNUM_XTALK_CLASS | 3
};
static volatile int xbow1slot_table[MAX_XBOW_PORTS] = {
SLOTNUM_XTALK_CLASS | 11,
SLOTNUM_NODE_CLASS | 4,
SLOTNUM_NODE_CLASS | 2,
SLOTNUM_XTALK_CLASS | 8,
SLOTNUM_XTALK_CLASS | 10,
SLOTNUM_XTALK_CLASS | 12,
SLOTNUM_XTALK_CLASS | 7,
SLOTNUM_XTALK_CLASS | 9
};
static volatile int xboxslot_table[MAX_XBOW_PORTS] = {
SLOTNUM_XTALK_CLASS | 7,
SLOTNUM_XTALK_CLASS | 1,
SLOTNUM_NODE_CLASS | 1,
SLOTNUM_XTALK_CLASS | 2,
SLOTNUM_XTALK_CLASS | 3,
SLOTNUM_XTALK_CLASS | 4,
SLOTNUM_XTALK_CLASS | 5,
SLOTNUM_XTALK_CLASS | 6
};
#define NODE_SLOTBIT_SIZE 8
#define ROUTER_SLOTBIT_SIZE 16
static volatile int nodeslot_table[NODE_SLOTBIT_SIZE] = {
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_KNODE_CLASS | 2,
SLOTNUM_KNODE_CLASS | 1,
SLOTNUM_NODE_CLASS | 4,
SLOTNUM_NODE_CLASS | 3,
SLOTNUM_NODE_CLASS | 2,
SLOTNUM_NODE_CLASS | 1
};
/* Define a new slot table for the 12p 4io config */
static volatile int CONFIG_12P4I_nodeslot_table[NODE_SLOTBIT_SIZE] = {
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_NODE_CLASS | 6,
SLOTNUM_NODE_CLASS | 5,
SLOTNUM_NODE_CLASS | 4,
SLOTNUM_NODE_CLASS | 3,
SLOTNUM_NODE_CLASS | 2,
SLOTNUM_NODE_CLASS | 1
};
static volatile int slotwidget_table[4] = {
0x9,
0xa,
0xa,
0x9
};
/* In the case of speedo with an xbox .
* The master hub always goes to port 10 of the xbow.
* Slave if present will go to port 9.
* NOTE: Dual hosting of xbox is not fully supported yet.
*/
static volatile int xboxslotwidget_table[2] = {
0xa,
0xa
};
static volatile int kslotwidget_table[4] = {
0xa,
0x9,
0xff,
0xff
};
static volatile int routerslot_table[ROUTER_SLOTBIT_SIZE] = {
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_ROUTER_CLASS | 2,
SLOTNUM_ROUTER_CLASS | 1
};
static volatile int meta_routerslot_table[ROUTER_SLOTBIT_SIZE] = {
SLOTNUM_ROUTER_CLASS | 8,
SLOTNUM_ROUTER_CLASS | 7,
SLOTNUM_ROUTER_CLASS | 6,
SLOTNUM_ROUTER_CLASS | 5,
SLOTNUM_ROUTER_CLASS | 4,
SLOTNUM_ROUTER_CLASS | 3,
SLOTNUM_ROUTER_CLASS | 2,
SLOTNUM_ROUTER_CLASS | 1,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS,
SLOTNUM_INVALID_CLASS
};
/* Inverse mapping from the displayed slot number to widget number */
/* Needed for command line parsing of flash prom commands. */
static volatile int slot_to_widget_table[] = {
8, 0xC, 0xF, 0xB, 0xE, 0xD, 0x1E, 0x1B, 0x1F, 0x1C, 0x18, 0x1D
} ;
static volatile int xboxslot_to_widget_table[] = {
0x9,0xb,0xc,0xd,0xe,0xf,8,-1
};
static volatile int kslot_to_widget_table[] = {
0xf, 0xb, 0xe, 0x8, 0xd, 0xc, -1, -1, -1, -1, -1, -1
};
slotid_t
xbwidget_to_xtslot(int crossbow, int widget)
{
if ((widget < BASE_XBOW_PORT) || (widget >= MAX_PORT_NUM))
return SLOTNUM_INVALID_CLASS;
if (SLOTNUM_GETCLASS(get_my_slotid()) == SLOTNUM_KNODE_CLASS) {
/* KEGO */
if (crossbow != 0) {
printf("xbwidget_to_xtslot: Error - crossbow nonzero on Kego (%d).\n", crossbow);
return SLOTNUM_INVALID_CLASS;
}
return kxbowslot_table[widget - BASE_XBOW_PORT];
} else {
/* Speedo with xbox */
if (SN00)
return(xboxslot_table[widget - BASE_XBOW_PORT]);
/* 8P12IO */
if (crossbow == 0)
return xbow0slot_table[widget - BASE_XBOW_PORT];
else if (crossbow == 1)
return xbow1slot_table[widget - BASE_XBOW_PORT];
else
return SLOTNUM_INVALID_CLASS;
}
}
slotid_t
hub_slotbits_to_slot(slotid_t slotbits)
{
slotid_t new_slotbits;
#ifndef _STANDALONE
if (private.p_sn00) {
#else
if (SN00) {
#endif
new_slotbits = (slotbits & MSU_SN00_SLOTID_MASK) >> MSU_SN00_SLOTID_SHFT;
return(2 - new_slotbits);
} else
new_slotbits = slotbits & MSU_SN0_SLOTID_MASK;
if (new_slotbits >= NODE_SLOTBIT_SIZE) {
return SLOTNUM_INVALID_CLASS;
} else {
if (CONFIG_12P4I)
return(CONFIG_12P4I_nodeslot_table[new_slotbits]);
else {
return nodeslot_table[new_slotbits];
}
}
}
xwidgetnum_t
hub_slot_to_widget(slotid_t slot)
{
if (SLOTNUM_GETSLOT(slot) >= NODE_SLOTBIT_SIZE) {
return -1;
} else {
if (SLOTNUM_GETCLASS(slot) == SLOTNUM_KNODE_CLASS) {
return kslotwidget_table[SLOTNUM_GETSLOT(slot) - 1];
} else {
/* Right now this is needed for an SN00 with an xbox.
* In the case of single host it is assumed that the
* hub comes in on port 10 of the xbow.
* In the case of dual hosts master comes is thru
* port 10 & slave thru port 9.
*/
if (SN00)
return(xboxslotwidget_table[SLOTNUM_GETSLOT(slot) - 1]);
return slotwidget_table[SLOTNUM_GETSLOT(slot) - 1];
}
}
}
slotid_t
hub_slot_to_crossbow(slotid_t hub_slot)
{
/* Crossbow 0 is connected to nodes 1 and 3. */
/* Crossbow 1 is connected to nodes 2 and 4. */
if (SLOTNUM_GETCLASS(hub_slot) == SLOTNUM_KNODE_CLASS)
return 0;
else
return ((hub_slot - 1) & 1);
}
slotid_t
router_slotbits_to_slot(slotid_t slotbits)
{
if (slotbits >= ROUTER_SLOTBIT_SIZE)
return SLOTNUM_INVALID_CLASS;
else
return routerslot_table[slotbits];
}
slotid_t
meta_router_slotbits_to_slot(slotid_t slotbits)
{
if (slotbits >= ROUTER_SLOTBIT_SIZE)
return SLOTNUM_INVALID_CLASS;
else
return meta_routerslot_table[slotbits];
}
/*
* This is static because calling outside of this
* file is the wrong thing to do. Outside callers should call
* get_slotname() as systems like the Origin 200 can and do
* have special slot naming needs
*/
static char *
get_slotclass(slotid_t slotnum)
{
switch (SLOTNUM_GETCLASS(slotnum)) {
case SLOTNUM_NODE_CLASS:
case SLOTNUM_KNODE_CLASS:
return "n";
case SLOTNUM_ROUTER_CLASS:
return "r";
case SLOTNUM_XTALK_CLASS:
return "io";
case SLOTNUM_INVALID_CLASS:
return "Invalid";
default:
return "Unknown";
}
}
void
get_slotname(slotid_t slotnum, char *name)
{
/*
* On Origin 200 slots 1 and 11 are really the IO
* on the motherboard
*/
#ifndef _STANDALONE
if (private.p_sn00) {
#else
if (SN00){
#endif
if (((SLOTNUM_GETCLASS(slotnum) == SLOTNUM_NODE_CLASS) &&
(SLOTNUM_GETSLOT(slotnum) == 1)) ||
((SLOTNUM_GETCLASS(slotnum) == SLOTNUM_NODE_CLASS) &&
(SLOTNUM_GETSLOT(slotnum) == 2))) {
strcpy(name, SN00_MOTHERBOARD);
return;
}
}
sprintf(name, "%s%d", get_slotclass(slotnum), SLOTNUM_GETSLOT(slotnum));
}
slotid_t
get_node_slotid(nasid_t nasid)
{
slotid_t slotbits = REMOTE_HUB_L(nasid, MD_SLOTID_USTAT) & MSU_SLOTID_MASK;
return (hub_slotbits_to_slot(slotbits));
}
slotid_t
get_my_slotid()
{
slotid_t slotbits = LOCAL_HUB_L(MD_SLOTID_USTAT) & MSU_SLOTID_MASK;
return (hub_slotbits_to_slot(slotbits));
}
slotid_t
get_node_crossbow(nasid_t nasid)
{
return hub_slot_to_crossbow(get_node_slotid(nasid));
}
void
get_my_slotname(char *name)
{
get_slotname(get_my_slotid(), name);
}
slotid_t
get_widget_slotnum(int xbow, int widget)
{
return xbwidget_to_xtslot(xbow, widget);
}
void
get_widget_slotname(int xbow, int widget, char *name)
{
get_slotname(get_widget_slotnum(xbow, widget), name);
}
void
router_slotbits_to_slotname(int slotbits, char *name)
{
slotid_t slotnum;
slotnum = router_slotbits_to_slot(slotbits);
get_slotname(slotnum, name);
}
int
slot_to_widget(int slotnum)
{
if (SLOTNUM_GETCLASS(get_my_slotid()) == SLOTNUM_KNODE_CLASS) {
/* KEGO */
return kslot_to_widget_table[slotnum];
} else {
/* Speedo with xbox */
if (SN00) {
if (slotnum >= MAX_XBOW_PORTS)
return(-1);
else
return(xboxslot_to_widget_table[slotnum]);
}
else
return slot_to_widget_table[slotnum];
}
}
/*
* int hub_slot_get(void)
*
* Returns current node card slot number from 1 (rightmost) to 4 (leftmost).
*
* On KEGO, there are only two node cards with slot numbers 5 and 6; this
* routine converts those to 1 and 2.
*
*/
slotid_t
hub_slot_get()
{
return (SLOTNUM_GETSLOT(get_my_slotid()));
}
#ifdef _STANDALONE
/*
* Function: get_module_slot
* Args: bridge_base -> bridge widget base
* module, slot -> ptrs to be filled up
* Retunrs: nothing
* Note: moduleid must be set properly in the log
*/
void get_module_slot(__psunsigned_t bridge_base, moduleid_t *module, int *slot)
{
int nasid, wid_num;
char buf[8];
nasid = NASID_GET(bridge_base);
ip27log_getenv(nasid, IP27LOG_MODULE_KEY, buf, "0", 0);
*module = atoi(buf);
wid_num = WIDGETID_GET(bridge_base);
*slot = SLOTNUM_GETSLOT(xbwidget_to_xtslot(get_node_crossbow(nasid),
wid_num));
}
#endif
/* Check if a node in a particular slot can talk to the
* elsc. In 12p 4io config nodes in slots 5 & 6 are
* disabled from talking to the elsc.
*/
int
node_can_talk_to_elsc(void)
{
if (CONFIG_12P4I) {
if (hub_slot_get() <=
HIGHEST_I2C_VISIBLE_NODESLOT)
return 1;
else
return 0;
}
return 1;
}
/*
* is_xbox_config
* Checks if the configuration is a speedo connected to an xbox.
*/
int
is_xbox_config(nasid_t nasid)
{
if (!SN00)
return(0);
#if defined(_STANDALONE)
/* Check if the hub is talking to a xbow */
return(hubii_widget_is_xbow(nasid));
#else
/* Xbow present is a convenienc macro to check if a particular
* hub is talking to an xbow over its xtalk link.
*/
#define XBOW_PRESENT(_n) \
(((((*(volatile __int32_t *)(NODE_SWIN_BASE(_n, 0) + WIDGET_ID))) & \
WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT) == XBOW_WIDGET_PART_NUM)
return(XBOW_PRESENT(nasid));
#endif
}
/*
* ip27log_xbox_nasid_clear
* Clear the promlog variable to indicate the nasid attached to the xbox.
*/
void
ip27log_xbox_nasid_clear(nasid_t nasid)
{
(void)ip27log_unsetenv(nasid,IP27LOG_XBOX_NASID,0);
}
/*
* ip27log_xbox_nasid_set
* Set the promlog variable to indicate the nasid attached to the xbox.
*/
void
ip27log_xbox_nasid_set(nasid_t nasid,nasid_t xbox_nasid)
{
char buf[8];
sprintf(buf,"%d",xbox_nasid);
(void)ip27log_setenv(nasid,IP27LOG_XBOX_NASID,buf,0);
}
/*
* ip27log_xbox_nasid_get
* Read the promlog xbox_nasid variable to find out nasid of the node
* attached to the xbox.
*/
nasid_t
ip27log_xbox_nasid_get(nasid_t nasid)
{
char buf[8];
char invalid_nasid[8];
/* The default value for this promlog variable is INVALID_NASID */
sprintf(invalid_nasid,"%d",INVALID_NASID);
(void)ip27log_getenv(nasid,IP27LOG_XBOX_NASID,buf,invalid_nasid,0);
return(atoi(buf));
}
/*
* xbox_nasid_get
* Return the nasid of the node connected to the xbox.
*/
nasid_t
xbox_nasid_get(void)
{
/* If we are not a speedo then this function shouldn't be used
*/
if (!SN00)
return(INVALID_NASID);
/* Get the xbox_nasid from the promlog */
return(ip27log_xbox_nasid_get(get_nasid()));
}