/* * 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 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_MC_OPL_H #define _SYS_MC_OPL_H #pragma ident "%Z%%M% %I% %E% SMI" #ifdef __cplusplus extern "C" { #endif #include #ifdef DEBUG #define MC_LOG if (oplmc_debug) printf extern int oplmc_debug; #else #define MC_LOG _NOTE(CONSTANTCONDITION) if (0) printf #endif #define MC_PATROL_INTERVAL_SEC 10 #define MC_POLL_EXIT 0x01 /* * load/store MAC register */ extern uint32_t mc_ldphysio(uint64_t); extern void mc_stphysio(uint64_t, uint32_t); #define LD_MAC_REG(paddr) mc_ldphysio(paddr) #define ST_MAC_REG(paddr, data) mc_stphysio((paddr), (data)) #define BANKNUM_PER_SB 8 typedef struct { uint32_t cs_num; uint32_t cs_status; uint32_t cs_avail_hi; uint32_t cs_avail_low; uint32_t dimm_capa_hi; uint32_t dimm_capa_low; uint32_t ndimms; } cs_status_t; typedef struct scf_log { struct scf_log *sl_next; int sl_bank; uint32_t sl_err_add; uint32_t sl_err_log; } scf_log_t; /* * Current max serial number size is 12, but keep enough room * to accomodate any future changes. * * Current max part number size is 18 + 18(Sun's partnumber + FJ's partnumber), * but keep enough room to accomodate any future changes. */ #define MCOPL_MAX_DIMMNAME 3 #define MCOPL_MAX_SERIAL 20 #define MCOPL_MAX_PARTNUM 44 #define MCOPL_MAX_SERIALID (MCOPL_MAX_SERIAL + MCOPL_MAX_PARTNUM) typedef struct mc_dimm_info { struct mc_dimm_info *md_next; char md_dimmname[MCOPL_MAX_DIMMNAME + 1]; char md_serial[MCOPL_MAX_SERIAL + 1]; char md_partnum[MCOPL_MAX_PARTNUM + 1]; } mc_dimm_info_t; typedef struct mc_retry_info { struct mc_retry_info *ri_next; #define RETRY_STATE_PENDING 0 #define RETRY_STATE_ACTIVE 1 #define RETRY_STATE_REWRITE 2 int ri_state; uint32_t ri_addr; } mc_retry_info_t; typedef struct mc_opl_state { struct mc_opl_state *next; dev_info_t *mc_dip; uint32_t mc_status; #define MC_POLL_RUNNING 0x1 #define MC_SOFT_SUSPENDED 0x2 /* suspended by DR */ #define MC_DRIVER_SUSPENDED 0x4 /* DDI_SUSPEND */ #define MC_MEMORYLESS 0x8 uint32_t mc_board_num; /* board# */ uint32_t mc_phys_board_num; /* physical board# */ uint64_t mc_start_address; /* sb-mem-ranges */ uint64_t mc_size; struct mc_bank { uint32_t mcb_status; #define BANK_INSTALLED 0x80000000 #define BANK_MIRROR_MODE 0x40000000 /* 0: normal 1: mirror */ #define BANK_REWRITE_MODE 0x10000000 #define BANK_PTRL_RUNNING 0x00000001 #define MC_RETRY_COUNT 2 mc_retry_info_t mcb_retry_infos[MC_RETRY_COUNT]; mc_retry_info_t *mcb_retry_freelist; mc_retry_info_t *mcb_retry_pending; mc_retry_info_t *mcb_active; int mcb_rewrite_count; uint64_t mcb_reg_base; uint32_t mcb_ptrl_cntl; } mc_bank[BANKNUM_PER_SB]; uchar_t mc_trans_table[2][64]; /* csX-mac-pa-trans-table */ kmutex_t mc_lock; scf_log_t *mc_scf_log[BANKNUM_PER_SB]; scf_log_t *mc_scf_log_tail[BANKNUM_PER_SB]; int mc_scf_total[BANKNUM_PER_SB]; struct memlist *mlist; int mc_scf_retry[BANKNUM_PER_SB]; int mc_last_error; /* number of times memory scanned */ uint64_t mc_period[BANKNUM_PER_SB]; uint32_t mc_speed; int mc_speedup_period[BANKNUM_PER_SB]; int mc_tick_left; mc_dimm_info_t *mc_dimm_list; } mc_opl_t; #define IS_MIRROR(mcp, bn) ((mcp)->mc_bank[bn].mcb_status\ & BANK_MIRROR_MODE) typedef struct mc_addr { int ma_bd; /* board number */ int ma_phys_bd; /* phyiscal board number */ int ma_bank; /* bank number */ uint32_t ma_dimm_addr; /* DIMM address (same format as ERR_ADD) */ } mc_addr_t; typedef struct mc_rsaddr_info { /* patrol restart address/info */ struct mc_addr mi_restartaddr; int mi_valid; int mi_injectrestart; } mc_rsaddr_info_t; typedef struct mc_flt_stat { uint32_t mf_type; /* fault type */ #define FLT_TYPE_INTERMITTENT_CE 0x0001 #define FLT_TYPE_PERMANENT_CE 0x0002 #define FLT_TYPE_UE 0x0003 #define FLT_TYPE_SUE 0x0004 #define FLT_TYPE_MUE 0x0005 #define FLT_TYPE_CMPE 0x0006 uint32_t mf_cntl; /* MAC_BANKm_PTRL_CNTL Register */ uint32_t mf_err_add; /* MAC_BANKm_{PTRL|MI}_ERR_ADD Register */ uint32_t mf_err_log; /* MAC_BANKm_{PTRL|MI}_ERR_LOG Register */ uint32_t mf_synd; uchar_t mf_errlog_valid; uchar_t mf_dimm_slot; uchar_t mf_dram_place; uint64_t mf_flt_paddr; /* faulty physical address */ mc_addr_t mf_flt_maddr; /* faulty DIMM address */ } mc_flt_stat_t; typedef struct mc_aflt { uint64_t mflt_id; /* gethrtime() at time of fault */ mc_opl_t *mflt_mcp; /* mc-opl structure */ char *mflt_erpt_class; /* ereport class name */ int mflt_is_ptrl; /* detected by PTRL or MI */ int mflt_nflts; /* 1 or 2 */ int mflt_pr; /* page retire flags */ mc_flt_stat_t *mflt_stat[2]; /* fault status */ } mc_aflt_t; typedef struct mc_flt_page { uint32_t err_add; /* MAC_BANKm_{PTRL|MI}_ERR_ADD reg */ uint32_t err_log; /* MAC_BANKm_{PTRL|MI}_ERR_LOG reg */ uint64_t fmri_addr; /* FRU name string */ uint32_t fmri_sz; /* length of FRU name +1 */ } mc_flt_page_t; #define MAC_PTRL_STAT(mcp, i) (mcp->mc_bank[i].mcb_reg_base) #define MAC_PTRL_CNTL(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x10) #define MAC_PTRL_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x20) #define MAC_PTRL_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x24) #define MAC_MI_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x28) #define MAC_MI_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x2c) #define MAC_STATIC_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x30) #define MAC_STATIC_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x34) #define MAC_RESTART_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x40) #define MAC_REWRITE_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x44) #define MAC_EG_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x48) #define MAC_EG_CNTL(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x4c) #define MAC_MIRR(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x50) /* use PA[37:6] */ #define MAC_RESTART_PA(pa) ((pa >> 6) & 0xffffffff) /* * This is for changing MI_ERR_ADDR accuracy. * Last two bits of PTRL_ERR_ADDR are always 0. */ #define ROUNDDOWN(a, n) (((a) & ~((n) - 1))) #define MC_BOUND_BYTE 4 /* * MAC_BANKm_PTRL_STAT_Register */ #define MAC_STAT_PTRL_CE 0x00000020 #define MAC_STAT_PTRL_UE 0x00000010 #define MAC_STAT_PTRL_CMPE 0x00000008 #define MAC_STAT_MI_CE 0x00000004 #define MAC_STAT_MI_UE 0x00000002 #define MAC_STAT_MI_CMPE 0x00000001 #define MAC_STAT_PTRL_ERRS (MAC_STAT_PTRL_CE|MAC_STAT_PTRL_UE\ |MAC_STAT_PTRL_CMPE) #define MAC_STAT_MI_ERRS (MAC_STAT_MI_CE|MAC_STAT_MI_UE\ |MAC_STAT_MI_CMPE) /* * MAC_BANKm_PTRL_CTRL_Register */ #define MAC_CNTL_PTRL_START 0x80000000 #define MAC_CNTL_USE_RESTART_ADD 0x40000000 #define MAC_CNTL_PTRL_STOP 0x20000000 #define MAC_CNTL_PTRL_INTERVAL 0x1c000000 #define MAC_CNTL_PTRL_RESET 0x02000000 #define MAC_CNTL_PTRL_STATUS 0x01000000 #define MAC_CNTL_REW_REQ 0x00800000 #define MAC_CNTL_REW_RESET 0x00400000 #define MAC_CNTL_CS0_DEG_MODE 0x00200000 #define MAC_CNTL_PTRL_CE 0x00008000 #define MAC_CNTL_PTRL_UE 0x00004000 #define MAC_CNTL_PTRL_CMPE 0x00002000 #define MAC_CNTL_MI_CE 0x00001000 #define MAC_CNTL_MI_UE 0x00000800 #define MAC_CNTL_MI_CMPE 0x00000400 #define MAC_CNTL_REW_CE 0x00000200 #define MAC_CNTL_REW_UE 0x00000100 #define MAC_CNTL_REW_END 0x00000080 #define MAC_CNTL_PTRL_ADD_MAX 0x00000040 #define MAC_CNTL_REW_CMPE 0x00000020 #define MAC_CNTL_PTRL_ERR_SHIFT 13 #define MAC_CNTL_MI_ERR_SHIFT 10 #define MAC_CNTL_PTRL_PRESERVE_BITS (MAC_CNTL_PTRL_INTERVAL) #define MAC_CNTL_PTRL_ERRS (MAC_CNTL_PTRL_CE|MAC_CNTL_PTRL_UE\ |MAC_CNTL_PTRL_CMPE) #define MAC_CNTL_MI_ERRS (MAC_CNTL_MI_CE|MAC_CNTL_MI_UE\ |MAC_CNTL_MI_CMPE) #define MAC_CNTL_REW_ERRS (MAC_CNTL_REW_CE|MAC_CNTL_REW_CMPE|\ MAC_CNTL_REW_UE|MAC_CNTL_REW_END) #define MAC_CNTL_ALL_ERRS (MAC_CNTL_PTRL_ERRS|\ MAC_CNTL_MI_ERRS|MAC_CNTL_REW_ERRS) #define MAC_ERRLOG_SYND_SHIFT 16 #define MAC_ERRLOG_SYND_MASK 0xffff #define MAC_ERRLOG_DIMMSLOT_SHIFT 13 #define MAC_ERRLOG_DIMMSLOT_MASK 0x7 #define MAC_ERRLOG_DRAM_PLACE_SHIFT 8 #define MAC_ERRLOG_DRAM_PLACE_MASK 0x1f #define MAC_SET_ERRLOG_INFO(flt_stat) \ (flt_stat)->mf_errlog_valid = 1; \ (flt_stat)->mf_synd = ((flt_stat)->mf_err_log >> \ MAC_ERRLOG_SYND_SHIFT) & \ MAC_ERRLOG_SYND_MASK; \ (flt_stat)->mf_dimm_slot = ((flt_stat)->mf_err_log >> \ MAC_ERRLOG_DIMMSLOT_SHIFT) & \ MAC_ERRLOG_DIMMSLOT_MASK; \ (flt_stat)->mf_dram_place = ((flt_stat)->mf_err_log >> \ MAC_ERRLOG_DRAM_PLACE_SHIFT) & \ MAC_ERRLOG_DRAM_PLACE_MASK; extern void mc_write_cntl(mc_opl_t *, int, uint32_t); #define MAC_CMD(mcp, i, cmd) mc_write_cntl(mcp, i, cmd) #define MAC_PTRL_START(mcp, i) { if (!(ldphysio(MAC_PTRL_CNTL(mcp, i)) \ & MAC_CNTL_PTRL_START)) \ MAC_CMD((mcp), (i), MAC_CNTL_PTRL_START); } #define MAC_PTRL_START_ADD(mcp, i) MAC_CMD((mcp), (i),\ MAC_CNTL_PTRL_START|MAC_CNTL_USE_RESTART_ADD) #define MAC_PTRL_STOP(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_PTRL_STOP) #define MAC_PTRL_RESET(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_PTRL_RESET) #define MAC_REW_REQ(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_REW_REQ) #define MAC_REW_RESET(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_REW_RESET) #define MAC_CLEAR_ERRS(mcp, i, errs) MAC_CMD((mcp), (i), errs) #define MAC_CLEAR_ALL_ERRS(mcp, i) MAC_CMD((mcp), (i),\ MAC_CNTL_ALL_ERRS) #define MAC_CLEAR_MAX(mcp, i) \ MAC_CMD((mcp), (i), MAC_CNTL_PTRL_ADD_MAX) /* * MAC_BANKm_PTRL/MI_ERR_ADD/LOG_Register */ #define MAC_ERR_ADD_INVALID 0x80000000 #define MAC_ERR_LOG_INVALID 0x00000080 /* * MAC_BANKm_STATIC_ERR_ADD_Register */ #define MAC_STATIC_ERR_VLD 0x80000000 /* * MAC_BANKm_MIRR_Register */ #define MAC_MIRR_MIRROR_MODE 0x80000000 #define MAC_MIRR_BANK_EXCLUSIVE 0x40000000 #define OPL_BOARD_MAX 16 #define OPL_BANK_MAX 8 #define MC_SET_REWRITE_MODE(mcp, bank) \ ((mcp)->mc_bank[bank].mcb_status |= BANK_REWRITE_MODE) #define MC_CLEAR_REWRITE_MODE(mcp, bank) \ ((mcp)->mc_bank[bank].mcb_status &= ~BANK_REWRITE_MODE) #define MC_REWRITE_MODE(mcp, bank) \ ((mcp)->mc_bank[bank].mcb_status & BANK_REWRITE_MODE) #define MC_REWRITE_ACTIVE(mcp, bank) \ ((mcp)->mc_bank[bank].mcb_active) /* * MAC_BANKm_EG_ADD_Register */ #define MAC_EG_ADD_MASK 0x7ffffffc /* * To set the EG_CNTL register, bit[26-25] and * bit[21-20] must be cleared. Then the other * control bit should be set. Then the bit[26-25] * and bit[21-20] should be set while other bits * should be the same as before. */ #define MAC_EG_CNTL_MASK 0x06300000 #define MAC_EG_ADD_FIX 0x80000000 #define MAC_EG_FORCE_DERR00 0x40000000 #define MAC_EG_FORCE_DERR16 0x20000000 #define MAC_EG_FORCE_DERR64 0x10000000 #define MAC_EG_FORCE_DERR80 0x08000000 #define MAC_EG_DERR_ALWAYS 0x02000000 #define MAC_EG_DERR_ONCE 0x04000000 #define MAC_EG_DERR_NOP 0x06000000 #define MAC_EG_FORCE_READ00 0x00800000 #define MAC_EG_FORCE_READ16 0x00400000 #define MAC_EG_RDERR_ALWAYS 0x00100000 #define MAC_EG_RDERR_ONCE 0x00200000 #define MAC_EG_RDERR_NOP 0x00300000 #define MAC_EG_SETUP_MASK 0xf9cfffff /* For MAC-PA translation */ #define MC_ADDRESS_BITS 40 #define PA_BITS_FOR_MAC 39 #define INDEX_OF_BANK_SUPPLEMENT_BIT 39 #define MP_NONE 128 #define MP_BANK_0 129 #define MP_BANK_1 130 #define MP_BANK_2 131 #define CS_SHIFT 29 #define MC_TT_ENTRIES 64 #define MC_TT_CS 2 /* export interface for error injection */ extern int mc_inject_error(int error_type, uint64_t pa, uint32_t flags); #define MC_INJECT_NOP 0x0 #define MC_INJECT_INTERMITTENT_CE 0x1 #define MC_INJECT_PERMANENT_CE 0x2 #define MC_INJECT_UE 0x3 #define MC_INJECT_INTERMITTENT_MCE 0x11 #define MC_INJECT_PERMANENT_MCE 0x12 #define MC_INJECT_SUE 0x13 #define MC_INJECT_MUE 0x14 #define MC_INJECT_CMPE 0x15 #define MC_INJECT_MIRROR_MODE 0x10 #define MC_INJECT_MIRROR(x) (x & MC_INJECT_MIRROR_MODE) #define MC_INJECT_FLAG_PREFETCH 0x1 #define MC_INJECT_FLAG_NO_TRAP MC_INJECT_FLAG_PREFETCH #define MC_INJECT_FLAG_RESTART 0x2 #define MC_INJECT_FLAG_POLL 0x4 #define MC_INJECT_FLAG_RESET 0x8 #define MC_INJECT_FLAG_OTHER 0x10 #define MC_INJECT_FLAG_LD 0x20 #define MC_INJECT_FLAG_ST 0x40 #define MC_INJECT_FLAG_PATH 0x80 #define MCIOC ('M' << 8) #define MCIOC_FAULT_PAGE (MCIOC|1) #ifdef DEBUG #define MCI_NOP 0x0 #define MCI_CE 0x1 #define MCI_PERM_CE 0x2 #define MCI_UE 0x3 #define MCI_SHOW_ALL 0x4 #define MCI_SHOW_NONE 0x5 #define MCI_CMP 0x6 #define MCI_ALLOC 0x7 #define MCI_M_CE 0x8 #define MCI_M_PCE 0x9 #define MCI_M_UE 0xA #define MCI_SUSPEND 0xB #define MCI_RESUME 0xC #endif #ifdef __cplusplus } #endif #endif /* _SYS_MC_OPL_H */