/* * 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 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_FHC_H #define _SYS_FHC_H #ifdef __cplusplus extern "C" { #endif #include #include /* useful debugging stuff */ #define FHC_ATTACH_DEBUG 0x1 #define FHC_INTERRUPT_DEBUG 0x2 #define FHC_REGISTERS_DEBUG 0x4 #define FHC_CTLOPS_DEBUG 0x8 #define FHC_BOARDS 0 #define FHC_CLOCKS 1 /* * OBP supplies us with 6 register sets for the FHC. The code for the fhc * driver relies on these register sets being presented by the PROM in the * order specified below. If this changes, the following comments must be * revised and the code in fhc_init() must be changed to reflect these * revisions. * * They are: * 0 FHC internal registers * 1 IGR Interrupt Group Number * 2 FanFail IMR, ISMR * 3 System IMR, ISMR * 4 UART IMR, ISMR * 5 TOD IMR, ISMR */ /* * The offsets are defined as offsets from the base of the OBP register * set which the register belongs to. */ /* Register set 0 */ #define FHC_OFF_ID 0x0 /* FHC ID register */ #define FHC_OFF_RCTRL 0x10 /* FHC Reset Control and Status */ #define FHC_OFF_CTRL 0x20 /* FHC Control and Status */ #define FHC_OFF_BSR 0x30 /* FHC Board Status Register */ #define FHC_OFF_JTAG_CTRL 0xF0 /* JTAG Control Register */ #define FHC_OFF_JTAG_CMD 0x100 /* JTAG Comamnd Register */ /* Register sets 2-5, the ISMR offset is the same */ #define FHC_OFF_ISMR 0x10 /* FHC Interrupt State Machine */ /* Bit field defines for FHC Control and Status Register */ #define FHC_CENTERDIS 0x00100000 /* NOTE: this bit is only used by firmware and must always be cleared by OS */ #define FHC_CSR_SYNC 0x00010000 #define FHC_MOD_OFF 0x00008000 #define FHC_ACDC_OFF 0x00004000 #define FHC_FHC_OFF 0x00002000 #define FHC_EPDA_OFF 0x00001000 #define FHC_EPDB_OFF 0x00000800 #define FHC_PS_OFF 0x00000400 #define FHC_NOT_BRD_PRES 0x00000200 #define FHC_LED_LEFT 0x00000040 #define FHC_LED_MID 0x00000020 #define FHC_LED_RIGHT 0x00000010 /* Bit field defines for FHC Reset Control and Status Register */ #define FHC_POR 0x80000000 #define FHC_SOFT_POR 0x40000000 #define FHC_SOFT_XIR 0x20000000 /* Bit field defines for the JTAG control register. */ #define JTAG_MASTER_EN 0x80000000 #define JTAG_MASTER_NPRES 0x40000000 /* Macros for decoding UPA speed pins from the Board Status Register */ #define CPU_0_PINS(bsr) (((bsr) >> 10) & 0x7) #define CPU_1_PINS(bsr) (((bsr) >> 7) & 0x7) #define CID_REV_MASK 0x0fffffff #define ULTRAI_COMPID 0x0002502f #define ULTRAII_COMPID 0x0003602f /* Macro for extracting the "plus" bit from the Board Status Register */ #define ISPLUSBRD(bsr) (((bsr) & 1) == 0) /* Macros for physical access */ #define FHC_OFFSET 0xf8000000ull #define FHC_REGOFF 0x800000ull #define FHC_OFF_IGN 0x2000ull #define FHC_OFF_SIM 0x6000ull #define FHC_OFF_SSM 0x6010ull #define FHC_OFF_UIM 0x8000ull #define FHC_OFF_USM 0x8010ull #define FHC_CTRL(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_CTRL) #define FHC_JTAG_CTRL(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_JTAG_CTRL) #define FHC_IGN(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_IGN) #define FHC_SIM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_SIM) #define FHC_SSM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_SSM) #define FHC_UIM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_UIM) #define FHC_USM(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ FHC_REGOFF + FHC_OFF_USM) /* * the foolowing defines are used for trans phy-addr to board number */ #define BOARD_PHYADDR_SHIFT 24 #define CLOCKBOARD_PHYADDR_BITS 0x1fff8 #define IO_BOARD_NUMBER_SHIFT 10 #define IO_BOARD_NUMBER_MASK 0xf /* * The following defines are used by the fhc driver to determine the * difference between IO and CPU type boards. This will be replaced * later by JTAG scan to determine board type. */ /* XXX */ #define FHC_UPADATA64A 0x40000 #define FHC_UPADATA64B 0x20000 /* XXX */ /* Bit field defines for Board Status Register */ #define FHC_DIAG_MODE 0x40 /* Bit field defines for the FHC Board Status Register when on a disk board */ #define FHC_FANFAIL 0x00000040 #define FHC_SCSI_VDD_OK 0x00000001 /* Size of temperature recording array */ #define MAX_TEMP_HISTORY 16 /* Maximum number of boards in system */ #define MAX_BOARDS 16 /* Maximum number of Board Power Supplies. */ #define MAX_PS_COUNT 8 /* Use predefined strings to name the kstats from this driver. */ #define FHC_KSTAT_NAME "fhc" #define CSR_KSTAT_NAMED "csr" #define BSR_KSTAT_NAMED "bsr" /* * The following defines are for the AC chip, but are needed to be global, * so have been put in the fhc header file. */ /* * Most Sunfire ASICs have the chip rev encoded into bits 31-28 of the * component ID register. */ #define CHIP_REV(c) ((c) >> 28) #ifndef _ASM /* Use predefined strings to name the kstats from this driver. */ /* Bit field defines for Interrupt Mapping registers */ #define IMR_VALID ((uint_t)1 << INR_EN_SHIFT) /* Mondo valid bit */ /* Bit defines for Interrupt State Machine Register */ #define INT_PENDING 3 /* state of the interrupt dispatch */ struct intr_regs { volatile uint_t *mapping_reg; volatile uint_t *clear_reg; uint_t mapping_reg_cache; /* cache current value for CPR */ }; #define BD_IVINTR_SHFT 0x7 /* * Convert the Board Number field in the FHC Board Status Register to * a board number. The field in the register is bits 0,3-1 of the board * number. Therefore a macro is necessary to extract the board number. */ #define FHC_BSR_TO_BD(bsr) ((((bsr) >> 16) & 0x1) | \ (((bsr) >> 12) & 0xE)) #define FHC_INO(ino) ((ino) & 0x7) #define FHC_CPU2BOARD(cpuid) ((cpuid) >> 1) #define FHC_CPU_IS_A(cpuid) (!((cpuid) & 1)) #define FHC_CPU_IS_B(cpuid) ((cpuid) & 1) #define FHC_BOARD2CPU_A(board) ((board) << 1) #define FHC_BOARD2CPU_B(board) (((board) << 1) + 1) #define FHC_PS2BOARD(ps) ((((ps) & 0x6) << 1) | ((ps) & 0x1)) #define FHC_BOARD2PS(board) ((((board) & 0xc) >> 1) | ((board) & 0x1)) #define FHC_OTHER_CPU_ID(cpuid) ((cpuid) ^ 1) /* this base address is assumed to never map to real memory */ #define FHC_BASE_NOMEM (1ull << 40) #define FHC_MAX_ECACHE_SIZE (16 * 1024 * 1024) #define FHC_BOARD_0 0x1c000000000ull #define FHC_BOARD_SPAN 0x200000000ull #define FHC_DTAG_OFFSET 0xfa000000ull #define FHC_BOARD_BASE(cpuid) (FHC_BOARD_0 + (cpuid) * FHC_BOARD_SPAN) #define FHC_DTAG_BASE(cpuid) (FHC_BOARD_BASE(cpuid) + FHC_DTAG_OFFSET) #define FHC_DTAG_LOW 0x300000000ull #define FHC_DTAG_HIGH 0x3ull #define FHC_DTAG_SIZE (16 * 1024 * 1024) #define FHC_DTAG_SKIP 64 /* * Each Sunfire CPU Board has 32Kbytes of SRAM on the FireHose Bus. * * The SRAM is allocated as follows: * * 0x1ff.f020.0000 - 0x1ff.f020.5fff scratch/stacks * 0x1ff.f020.6000 - 0x1ff.f020.67ff reset info (2K bytes) * 0x1ff.f020.6800 - 0x1ff.f020.6fff POST private (2K bytes) * 0x1ff.f020.7000 - 0x1ff.f020.77ff OS private (2K bytes) * 0x1ff.f020.7800 - 0x1ff.f020.7fff OBP private (2K bytes) */ #define FHC_LOCAL_SRAM_BASE 0x1fff0200000ull #define FHC_GLOBAL_SRAM_BASE 0x1c0f8200000ull #define FHC_CPU2GLOBAL_SRAM(mid) \ (FHC_GLOBAL_SRAM_BASE + (mid) * 0x200000000ull) #define FHC_SRAM_OS_BASE 0x7000 #define FHC_LOCAL_OS_PAGEBASE ((FHC_LOCAL_SRAM_BASE + FHC_SRAM_OS_BASE) & \ MMU_PAGEMASK) #define FHC_SRAM_OS_OFFSET ((FHC_LOCAL_SRAM_BASE + FHC_SRAM_OS_BASE) & \ MMU_PAGEOFFSET) #define FHC_SHUTDOWN_WAIT_MSEC 1000 #define FHC_MAX_INO 4 #define FHC_SYS_INO 0x0 #define FHC_UART_INO 0x1 #define FHC_TOD_INO 0x2 #define FHC_FANFAIL_INO 0x3 /* * Defines for the kstats created for passing temperature values and * history out to user level programs. All temperatures passed out * will be in degrees Centigrade, corrected for the board type the * temperature was read from. Since each Board type has a different * response curve for the A/D convertor, the temperatures are all * calibrated inside the kernel. */ #define OVERTEMP_KSTAT_NAME "temperature" /* * This kstat is used for manually overriding temperatures. */ #define TEMP_OVERRIDE_KSTAT_NAME "temperature override" /* * Time averaging based method of recording temperature history. * Higher level temperature arrays are composed of temperature averages * of the array one level below. When the lower array completes a * set of data, the data is averaged and placed into the higher * level array. Then the lower level array is overwritten until * it is once again complete, where the process repeats. * * This method gives a user a fine grained view of the last minute, * and larger grained views of the temperature as one goes back in * time. * * The time units for the longer samples are based on the value * of the OVERTEMP_TIMEOUT_SEC and the number of elements in each * of the arrays between level 1 and the higher level. */ #define OVERTEMP_TIMEOUT_SEC 2 /* definition of the clock board index */ #define CLOCK_BOARD_INDEX 16 #define L1_SZ 30 /* # of OVERTEMP_TIMEOUT_SEC samples */ #define L2_SZ 15 /* size of array for level 2 samples */ #define L3_SZ 12 /* size of array for level 3 samples */ #define L4_SZ 4 /* size of array for level 4 samples */ #define L5_SZ 2 /* size of array for level 5 samples */ /* * Macros for determining when to do the temperature averaging of arrays. */ #define L2_INDEX(i) ((i) / L1_SZ) #define L2_REM(i) ((i) % L1_SZ) #define L3_INDEX(i) ((i) / (L1_SZ * L2_SZ)) #define L3_REM(i) ((i) % (L1_SZ * L2_SZ)) #define L4_INDEX(i) ((i) / (L1_SZ * L2_SZ * L3_SZ)) #define L4_REM(i) ((i) % (L1_SZ * L2_SZ * L3_SZ)) #define L5_INDEX(i) ((i) / (L1_SZ * L2_SZ * L3_SZ * L4_SZ)) #define L5_REM(i) ((i) % (L1_SZ * L2_SZ * L3_SZ * L4_SZ)) /* * define for an illegal temperature. This temperature will never be seen * in a real system, so it is used as an illegal value in the various * functions processing the temperature data structure. */ #define NA_TEMP 0x7FFF /* * State variable for board temperature. Each board has its own * temperature state. State transitions from OK -> bad direction * happen instantaneously, but use a counter in the opposite * direction, so that noise in the A/D counters does not cause * a large number of messages to appear. */ enum temp_state { TEMP_OK = 0, /* normal board temperature */ TEMP_WARN = 1, /* start warning operator */ TEMP_DANGER = 2 }; /* get ready to shutdown */ /* * Number of temperature poll counts to wait before printing that the * system has cooled down. */ #define TEMP_STATE_TIMEOUT_SEC 20 #define TEMP_STATE_COUNT ((TEMP_STATE_TIMEOUT_SEC) / \ (OVERTEMP_TIMEOUT_SEC)) /* * Number of poll counts that a system temperature must be at or above danger * temperature before system is halted and powers down. */ #define SHUTDOWN_TIMEOUT_SEC 20 #define SHUTDOWN_COUNT ((SHUTDOWN_TIMEOUT_SEC) / \ (OVERTEMP_TIMEOUT_SEC)) /* * State variable for temperature trend. Each state represents the * current temperature trend for a given device. */ enum temp_trend { TREND_UNKNOWN = 0, /* Unknown temperature trend */ TREND_RAPID_FALL = 1, /* Rapidly falling temp. */ TREND_FALL = 2, /* Falling temperature */ TREND_STABLE = 3, /* Stable temperature */ TREND_RISE = 4, /* Rising temperature */ TREND_RAPID_RISE = 5, /* Rapidly rising temperature */ TREND_NOISY = 6 }; /* Unknown trend (noisy) */ /* Thresholds for temperature trend */ #define NOISE_THRESH 2 #define RAPID_RISE_THRESH 4 #define RAPID_FALL_THRESH 4 /* * Main structure for passing the calibrated and time averaged temperature * values to user processes. This structure is copied out via the kstat * mechanism. */ #define TEMP_KSTAT_VERSION 3 /* version of temp_stats structure */ struct temp_stats { uint_t index; /* index of current temperature */ short l1[L1_SZ]; /* OVERTEMP_TIMEOUT_SEC samples */ short l2[L2_SZ]; /* level 2 samples */ short l3[L3_SZ]; /* level 3 samples */ short l4[L4_SZ]; /* level 4 samples */ short l5[L5_SZ]; /* level 5 samples */ short max; /* maximum temperature recorded */ short min; /* minimum temperature recorded */ enum temp_state state; /* state of board temperature */ int temp_cnt; /* counter for state changes */ int shutdown_cnt; /* counter for overtemp shutdown */ int version; /* version of this structure */ enum temp_trend trend; /* temperature trend for board */ short override; /* override temperature for testing */ }; /* The variable fhc_cpu_warning_temp_threshold is initialized to this value. */ #define FHC_CPU_WARNING_TEMP_THRESHOLD 45 /* * Fault list management. * * The following defines and enum definitions have been created to support * the fault list (struct ft_list). These defines must match with the * fault string table in fhc.c. If any faults are added, they must be * added at the end of this list, and the table must be modified * accordingly. */ enum ft_type { FT_CORE_PS = 0, /* Core power supply */ FT_OVERTEMP, /* Temperature */ FT_AC_PWR, /* AC power Supply */ FT_PPS, /* Peripheral Power Supply */ FT_CLK_33, /* System 3.3 Volt Power */ FT_CLK_50, /* System 5.0 Volt Power */ FT_V5_P, /* Peripheral 5V Power */ FT_V12_P, /* Peripheral 12V Power */ FT_V5_AUX, /* Auxiliary 5V Power */ FT_V5_P_PCH, /* Peripheral 5V Precharge */ FT_V12_P_PCH, /* Peripheral 12V Precharge */ FT_V3_PCH, /* System 3V Precharge */ FT_V5_PCH, /* System 5V Precharge */ FT_PPS_FAN, /* Peripheral Power Supply Fan */ FT_RACK_EXH, /* Rack Exhaust Fan */ FT_DSK_FAN, /* 4 (or 5) Slot Disk Fan */ FT_AC_FAN, /* AC Box Fan */ FT_KEYSW_FAN, /* Key Switch Fan */ FT_INSUFFICIENT_POWER, /* System has insufficient power */ FT_PROM, /* fault inherited from PROM */ FT_HOT_PLUG, /* hot plug unavailable */ FT_TODFAULT /* tod error detection */ }; enum ft_class { FT_BOARD, FT_SYSTEM }; /* * This extern allows other drivers to use the ft_str_table if they * have fhc specified as a depends_on driver. */ extern char *ft_str_table[]; /* Maximum length of string table entries */ #define MAX_FT_DESC 64 #define FT_LIST_KSTAT_NAME "fault_list" /* * The fault list structure is a structure for holding information on * kernel detected faults. The fault list structures are linked into * a list and the list is protected by the ftlist_mutex. There are * also several routines for manipulating the fault list. */ struct ft_list { int32_t unit; /* unit number of faulting device */ enum ft_type type; /* type of faulting device */ int32_t pad; /* padding to replace old next pointer */ enum ft_class fclass; /* System or board class fault */ time32_t create_time; /* Time stamp at fault detection */ char msg[MAX_FT_DESC]; /* fault string */ }; /* * Allow binary compatibility between ILP32 and LP64 by * eliminating the next pointer and making ft_list a fixed size. * The structure name "ft_list" remains unchanged for * source compatibility of kstat applications. */ struct ft_link_list { struct ft_list f; struct ft_link_list *next; }; /* * Board list management. * * Enumerated types for defining type of system and clock * boards. It is used by both the kernel and user programs. */ enum board_type { EMPTY_BOARD = -1, UNINIT_BOARD = 0, /* Uninitialized board type */ UNKNOWN_BOARD, /* Unknown board type */ CPU_BOARD, /* System board CPU(s) */ MEM_BOARD, /* System board no CPUs */ IO_2SBUS_BOARD, /* 2 SBus & SOC IO Board */ IO_SBUS_FFB_BOARD, /* SBus & FFB SOC IO Board */ IO_PCI_BOARD, /* PCI IO Board */ DISK_BOARD, /* Disk Drive Board */ CLOCK_BOARD, /* System Clock board */ IO_2SBUS_SOCPLUS_BOARD, /* 2 SBus & SOC+ IO board */ IO_SBUS_FFB_SOCPLUS_BOARD /* SBus&FFB&SOC+ board */ }; /* * Defined strings for comparing with OBP board-type property. If OBP ever * changes the board-type properties, these string defines must be changed * as well. */ #define CPU_BD_NAME "cpu" #define MEM_BD_NAME "mem" #define IO_2SBUS_BD_NAME "dual-sbus" #define IO_SBUS_FFB_BD_NAME "upa-sbus" #define IO_PCI_BD_NAME "dual-pci" #define DISK_BD_NAME "disk" #define IO_2SBUS_SOCPLUS_BD_NAME "dual-sbus-soc+" #define IO_SBUS_FFB_SOCPLUS_BD_NAME "upa-sbus-soc+" /* * The following structures and union are needed because the bd_info * structure describes all types of system boards. * XXX - We cannot determine Spitfire rev from JTAG scan, so it is * left blank for now. Future implementations might fill in this info. */ struct cpu_info { int cpu_rev; /* CPU revision */ int cpu_speed; /* rated speed of CPU in MHz */ int cpu_compid; /* CPU component ID */ int sdb0_compid; /* SDB component ID */ int sdb1_compid; /* SDB component ID */ int ec_compid; /* Ecache RAM ID, needed for cache size */ int cache_size; /* Cache size in bytes */ int cpu_sram_mode; /* module's sram mode */ int cpu_detected; /* Something on the CPU JTAG ring. */ }; struct io1_info { int sio0_compid; /* Sysio component ID */ int sio1_compid; /* Sysio component ID */ int hme_compid; /* several revs in existence */ int soc_compid; /* SOC */ }; struct io1plus_info { int sio0_compid; /* Sysio component ID */ int sio1_compid; /* Sysio component ID */ int hme_compid; /* several revs in existence */ int socplus_compid; /* SOC+ */ }; /* Defines for the FFB size field */ #define FFB_FAILED -1 #define FFB_NOT_FOUND 0 #define FFB_SINGLE 1 #define FFB_DOUBLE 2 struct io2_info { int fbc_compid; /* FBC component ID */ int ffb_size; /* not present, single or dbl buffered */ int sio1_compid; /* Sysio component ID */ int hme_compid; /* several revs in existence */ int soc_compid; /* SOC component ID */ }; struct io2plus_info { int fbc_compid; /* FBC component ID */ int ffb_size; /* not present, single or dbl buffered */ int sio1_compid; /* Sysio component ID */ int hme_compid; /* several revs in existence */ int socplus_compid; /* or SOC+ component ID */ }; struct io3_info { int psyo0_compid; /* Psycho+ component ID */ int psyo1_compid; /* Psycho+ component ID */ int cheo_compid; /* Cheerio component ID */ }; struct dsk_info { int disk_pres[2]; int disk_id[2]; }; union bd_un { struct cpu_info cpu[2]; struct io1_info io1; struct io2_info io2; struct io3_info io3; struct dsk_info dsk; struct io1plus_info io1plus; struct io2plus_info io2plus; }; /* * board_state and bd_info are maintained for backward * compatibility with prtdiag and others user programs that may rely * on them. */ enum board_state { UNKNOWN_STATE = 0, /* Unknown board */ ACTIVE_STATE, /* active and working */ HOTPLUG_STATE, /* Hot plugged board */ LOWPOWER_STATE, /* Powered down board */ DISABLED_STATE, /* Board disabled by PROM */ FAILED_STATE /* Board failed by POST */ }; struct bd_info { enum board_type type; /* Type of board */ enum board_state state; /* current state of this board */ int board; /* board number */ int fhc_compid; /* fhc component id */ int ac_compid; /* ac component id */ char prom_rev[64]; /* best guess as to what is needed */ union bd_un bd; }; /* * Config admin interface. * * Receptacle states. */ typedef enum { SYSC_CFGA_RSTATE_EMPTY = 0, /* Empty state */ SYSC_CFGA_RSTATE_DISCONNECTED, /* DISCONNECTED state */ SYSC_CFGA_RSTATE_CONNECTED /* CONNECTED state */ } sysc_cfga_rstate_t; /* * Occupant states. */ typedef enum { SYSC_CFGA_OSTATE_UNCONFIGURED = 0, /* UNCONFIGURED state */ SYSC_CFGA_OSTATE_CONFIGURED /* CONFIGURED state */ } sysc_cfga_ostate_t; /* * Receptacle/Occupant condition. */ typedef enum { SYSC_CFGA_COND_UNKNOWN = 0, /* Unknown condition */ SYSC_CFGA_COND_OK, /* Condition OK */ SYSC_CFGA_COND_FAILING, /* Failing */ SYSC_CFGA_COND_FAILED, /* Failed */ SYSC_CFGA_COND_UNUSABLE /* Unusable */ } sysc_cfga_cond_t; /* * Error definitions for CFGADM platform library */ typedef enum { SYSC_ERR_DEFAULT = 0, /* generic errors */ SYSC_ERR_INTRANS, /* hardware in transition */ SYSC_ERR_UTHREAD, /* can't stop user thread */ SYSC_ERR_KTHREAD, /* can't stop kernel thread */ SYSC_ERR_SUSPEND, /* can't suspend a device */ SYSC_ERR_RESUME, /* can't resume a device */ SYSC_ERR_POWER, /* not enough power for slot */ SYSC_ERR_COOLING, /* not enough cooling for slot */ SYSC_ERR_PRECHARGE, /* not enough precharge for slot */ SYSC_ERR_HOTPLUG, /* Hot Plug Unavailable */ SYSC_ERR_HW_COMPAT, /* incompatible hardware found during dr */ SYSC_ERR_NON_DR_PROM, /* prom not support Dynamic Reconfiguration */ SYSC_ERR_CORE_RESOURCE, /* core resource cannot be removed */ SYSC_ERR_PROM, /* error encountered in OBP/POST */ SYSC_ERR_DR_INIT, /* error encountered in sysc_dr_init op */ SYSC_ERR_NDI_ATTACH, /* error encountered in NDI attach operations */ SYSC_ERR_NDI_DETACH, /* error encountered in NDI detach operations */ SYSC_ERR_RSTATE, /* wrong receptacle state */ SYSC_ERR_OSTATE, /* wrong occupant state */ SYSC_ERR_COND /* invalid condition */ } sysc_err_t; /* * Config admin structure. */ typedef struct sysc_cfga_stat { /* generic representation of the attachment point below */ sysc_cfga_rstate_t rstate; /* current receptacle state */ sysc_cfga_ostate_t ostate; /* current occupant state */ sysc_cfga_cond_t condition; /* current board condition */ time32_t last_change; /* last state/condition change */ uint_t in_transition:1; /* board is in_transition */ /* platform specific below */ enum board_type type; /* Type of board */ int board; /* board number */ int fhc_compid; /* fhc component id */ int ac_compid; /* ac component id */ char prom_rev[64]; /* best guess as to what is needed */ union bd_un bd; uint_t no_detach:1; /* board is non_detachable */ uint_t plus_board:1; /* board is 98 MHz capable */ } sysc_cfga_stat_t; /* * Config admin command structure for SYSC_CFGA ioctls. */ typedef struct sysc_cfga_cmd { uint_t force:1; /* force this state transition */ uint_t test:1; /* Need to test hardware */ int arg; /* generic data for test */ sysc_err_t errtype; /* error code returned */ char *outputstr; /* output returned from ioctl */ } sysc_cfga_cmd_t; typedef struct sysc_cfga_cmd32 { uint_t force:1; /* force this state transition */ uint_t test:1; /* Need to test hardware */ int arg; /* generic data for test */ sysc_err_t errtype; /* error code returned */ caddr32_t outputstr; /* output returned from ioctl */ } sysc_cfga_cmd32_t; typedef struct sysc_cfga_pkt { sysc_cfga_cmd_t cmd_cfga; char *errbuf; /* internal error buffer */ } sysc_cfga_pkt_t; /* * Sysctrl DR sequencer interface. */ typedef struct sysc_dr_handle { dev_info_t **dip_list; /* list of top dips for board */ int dip_list_len; /* length devinfo list */ int flags; /* dr specific flags */ int error; /* dr operation error */ char *errstr; /* dr config/unfig error message */ } sysc_dr_handle_t; #define SYSC_DR_MAX_NODE 32 #define SYSC_DR_FHC 0x1 /* connect phase init (fhc) */ #define SYSC_DR_DEVS 0x2 /* config phase init (devices) */ #define SYSC_DR_FORCE 0x4 /* force detach */ #define SYSC_DR_REMOVE 0x8 /* remove dev_info */ #define SYSC_DR_HANDLE_FHC 0x0 #define SYSC_DR_HANDLE_DEVS 0x1 /* * Sysctrl event interface. */ typedef enum sysc_evt { SYSC_EVT_BD_EMPTY = 0, SYSC_EVT_BD_PRESENT, SYSC_EVT_BD_DISABLED, SYSC_EVT_BD_FAILED, SYSC_EVT_BD_OVERTEMP, SYSC_EVT_BD_TEMP_OK, SYSC_EVT_BD_PS_CHANGE, SYSC_EVT_BD_INS_FAILED, SYSC_EVT_BD_INSERTED, SYSC_EVT_BD_REMOVED, SYSC_EVT_BD_HP_DISABLED, SYSC_EVT_BD_CORE_RESOURCE_DISCONNECT } sysc_evt_t; /* * sysctrl audit message events */ typedef enum sysc_audit_evt { SYSC_AUDIT_RSTATE_EMPTY = 0, SYSC_AUDIT_RSTATE_CONNECT, SYSC_AUDIT_RSTATE_DISCONNECT, SYSC_AUDIT_RSTATE_SUCCEEDED, SYSC_AUDIT_RSTATE_EMPTY_FAILED, SYSC_AUDIT_RSTATE_CONNECT_FAILED, SYSC_AUDIT_RSTATE_DISCONNECT_FAILED, SYSC_AUDIT_OSTATE_CONFIGURE, SYSC_AUDIT_OSTATE_UNCONFIGURE, SYSC_AUDIT_OSTATE_SUCCEEDED, SYSC_AUDIT_OSTATE_CONFIGURE_FAILED, SYSC_AUDIT_OSTATE_UNCONFIGURE_FAILED } sysc_audit_evt_t; typedef struct { void (*update)(void *, sysc_cfga_stat_t *, sysc_evt_t); void *soft; } sysc_evt_handle_t; void fhc_bd_sc_register(void f(void *, sysc_cfga_stat_t *, sysc_evt_t), void *); /* * The board list structure is the central storage for the kernel's * knowledge of normally booted and hotplugged boards. */ typedef struct bd_list { struct fhc_soft_state *softsp; /* handle for DDI soft state */ sysc_cfga_stat_t sc; /* board info */ sysc_dr_handle_t sh[2]; /* sysctrl dr interface */ void *dev_softsp; /* opaque pointer to device state */ void *ac_softsp; /* opaque pointer to our AC */ struct kstat *ksp; /* pointer used in kstat destroy */ int fault; /* failure on this board? */ int flags; /* board state flags */ } fhc_bd_t; /* * Fhc_bd.c holds 2 resizable arrays of boards. First for clock * boards under central and second for normally booted and * hotplugged boards. */ typedef struct resizable_bd_list { fhc_bd_t **boards; int size; int last; int sorted; } fhc_bd_resizable_t; #define BDF_VALID 0x1 /* board entry valid */ #define BDF_DETACH 0x2 /* board detachable */ #define BDF_DISABLED 0x4 /* board disabled */ #define SYSC_OUTPUT_LEN MAXPATHLEN /* output str len */ /* * Board list management interface. */ int fhc_max_boards(void); void fhc_bdlist_init(void); void fhc_bdlist_fini(void); void fhc_bdlist_prime(int, int, int); fhc_bd_t *fhc_bdlist_lock(int); void fhc_bdlist_unlock(void); void fhc_bd_init(struct fhc_soft_state *, int, enum board_type); fhc_bd_t *fhc_bd(int); fhc_bd_t *fhc_bd_clock(void); fhc_bd_t *fhc_bd_first(void); fhc_bd_t *fhc_bd_next(fhc_bd_t *); enum board_type fhc_bd_type(int); char *fhc_bd_typestr(enum board_type); int fhc_bd_valid(int); int fhc_bd_detachable(int); int fhc_bd_insert_scan(void); int fhc_bd_remove_scan(void); int fhc_bd_test(int, sysc_cfga_pkt_t *); int fhc_bd_test_set_cond(int, sysc_cfga_pkt_t *); void fhc_bd_update(int, sysc_evt_t); void fhc_bd_env_set(int, void *); int fhc_bdlist_locked(void); int fhc_bd_busy(int); int fhc_bd_is_jtag_master(int); int fhc_bd_is_plus(int); #if defined(_KERNEL) /* * In order to indicate that we are in an environmental chamber, or * oven, the test people will set the 'mfg-mode' property in the * options node to 'chamber'. Therefore we have the following define. */ #define CHAMBER_VALUE "chamber" /* * zs design for fhc has two zs' interrupting on same interrupt mondo * This requires us to poll for zs and zs alone. The poll list has been * defined as a fixed size for simplicity. */ #define MAX_ZS_CNT 2 /* FHC Interrupt routine wrapper structure */ struct fhc_wrapper_arg { struct fhc_soft_state *softsp; volatile uint_t *clear_reg; volatile uint_t *mapping_reg; dev_info_t *child; uint32_t inum; uint_t (*funcp)(caddr_t, caddr_t); caddr_t arg1; caddr_t arg2; }; /* * The JTAG master command structure. It contains the address of the * the JTAG controller on this system board. The controller can only * be used if this FHC holds the JTAG master signal. This is checked * by reading the JTAG control register on this FHC. */ struct jt_mstr { volatile uint_t *jtag_cmd; int is_master; kmutex_t lock; }; /* Functions exported to manage the fault list */ void reg_fault(int, enum ft_type, enum ft_class); void clear_fault(int, enum ft_type, enum ft_class); int process_fault_list(void); void create_ft_kstats(int); /* memloc's are protected under the bdlist lock */ struct fhc_memloc { struct fhc_memloc *next; int board; /* reference our board element */ uint_t pa; /* base PA of this segment (in MB) */ uint_t size; /* size of this segment (in MB) */ }; /* Functions used to manage memory 'segments' */ #define FHC_MEMLOC_SHIFT 20 #define FHC_MEMLOC_MAX (0x10000000000ull >> FHC_MEMLOC_SHIFT) void fhc_add_memloc(int board, uint64_t pa, uint_t size); void fhc_del_memloc(int board); uint64_t fhc_find_memloc_gap(uint_t size); void fhc_program_memory(int board, uint64_t base); /* Structures used in the driver to manage the hardware */ struct fhc_soft_state { dev_info_t *dip; /* dev info of myself */ struct bd_list *list; /* pointer to board list entry */ int is_central; /* A central space instance of FHC */ volatile uint_t *id; /* FHC ID register */ volatile uint_t *rctrl; /* FHC Reset Control and Status */ volatile uint_t *bsr; /* FHC Board Status register */ volatile uint_t *jtag_ctrl; /* JTAG Control register */ volatile uint_t *igr; /* Interrupt Group Number */ struct intr_regs intr_regs[FHC_MAX_INO]; struct fhc_wrapper_arg poll_list[MAX_ZS_CNT]; struct fhc_wrapper_arg *intr_list[FHC_MAX_INO]; kmutex_t poll_list_lock; uchar_t spurious_zs_cntr; /* Spurious counter for zs devices */ kmutex_t pokefault_mutex; int pokefault; /* this lock protects the following data */ /* ! non interrupt use only ! */ kmutex_t ctrl_lock; /* lock for access to FHC CSR */ volatile uint_t *ctrl; /* FHC Control and Status */ /* The JTAG master structure has internal locking */ struct jt_mstr jt_master; /* the pointer to the kstat is stored for deletion upon detach */ kstat_t *fhc_ksp; }; /* * Function shared with child drivers which require fhc * support. They gain access to this function through the use of the * _depends_on variable. */ enum board_type get_board_type(int board); void update_temp(dev_info_t *pdip, struct temp_stats *envstat, uchar_t value); enum temp_trend temp_trend(struct temp_stats *); void fhc_reboot(void); int overtemp_kstat_update(kstat_t *ksp, int rw); int temp_override_kstat_update(kstat_t *ksp, int rw); void init_temp_arrays(struct temp_stats *envstat); void update_board_leds(fhc_bd_t *, uint_t, uint_t); struct jt_mstr *jtag_master_lock(void); void jtag_master_unlock(struct jt_mstr *); extern int fhc_board_poweroffcpus(int board, char *errbuf, int cpu_flags); /* FHC interrupt specification */ struct fhcintrspec { uint_t mondo; uint_t pil; dev_info_t *child; struct fhc_wrapper_arg *handler_arg; }; /* kstat structure used by fhc to pass data to user programs. */ struct fhc_kstat { struct kstat_named csr; /* FHC Control and Status Register */ struct kstat_named bsr; /* FHC Board Status Register */ }; #endif /* _KERNEL */ #endif /* _ASM */ #ifdef __cplusplus } #endif #endif /* _SYS_FHC_H */