1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_MC_OPL_H 27 #define _SYS_MC_OPL_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/note.h> 36 37 #ifdef DEBUG 38 #define MC_LOG if (oplmc_debug) printf 39 extern int oplmc_debug; 40 #else 41 #define MC_LOG _NOTE(CONSTANTCONDITION) if (0) printf 42 #endif 43 44 #define MC_PATROL_INTERVAL_SEC 10 45 46 #define MC_POLL_EXIT 0x01 47 48 /* 49 * load/store MAC register 50 */ 51 extern uint32_t mc_ldphysio(uint64_t); 52 extern void mc_stphysio(uint64_t, uint32_t); 53 #define LD_MAC_REG(paddr) mc_ldphysio(paddr) 54 #define ST_MAC_REG(paddr, data) mc_stphysio((paddr), (data)) 55 56 #define BANKNUM_PER_SB 8 57 58 typedef struct { 59 uint32_t cs_num; 60 uint32_t cs_status; 61 uint32_t cs_avail_hi; 62 uint32_t cs_avail_low; 63 uint32_t dimm_capa_hi; 64 uint32_t dimm_capa_low; 65 uint32_t ndimms; 66 } cs_status_t; 67 68 typedef struct scf_log { 69 struct scf_log *sl_next; 70 int sl_bank; 71 uint32_t sl_err_add; 72 uint32_t sl_err_log; 73 } scf_log_t; 74 75 /* 76 * Current max serial number size is 12, but keep enough room 77 * to accomodate any future changes. 78 * 79 * Current max part number size is 18 + 18(Sun's partnumber + FJ's partnumber), 80 * but keep enough room to accomodate any future changes. 81 */ 82 #define MCOPL_MAX_DIMMNAME 3 83 #define MCOPL_MAX_SERIAL 20 84 #define MCOPL_MAX_PARTNUM 44 85 #define MCOPL_MAX_SERIALID (MCOPL_MAX_SERIAL + MCOPL_MAX_PARTNUM) 86 87 typedef struct mc_dimm_info { 88 struct mc_dimm_info *md_next; 89 char md_dimmname[MCOPL_MAX_DIMMNAME + 1]; 90 char md_serial[MCOPL_MAX_SERIAL + 1]; 91 char md_partnum[MCOPL_MAX_PARTNUM + 1]; 92 } mc_dimm_info_t; 93 94 typedef struct mc_retry_info { 95 struct mc_retry_info *ri_next; 96 #define RETRY_STATE_PENDING 0 97 #define RETRY_STATE_ACTIVE 1 98 #define RETRY_STATE_REWRITE 2 99 int ri_state; 100 uint32_t ri_addr; 101 } mc_retry_info_t; 102 103 typedef struct mc_opl_state { 104 struct mc_opl_state *next; 105 dev_info_t *mc_dip; 106 uint32_t mc_status; 107 #define MC_POLL_RUNNING 0x1 108 #define MC_SOFT_SUSPENDED 0x2 /* suspended by DR */ 109 #define MC_DRIVER_SUSPENDED 0x4 /* DDI_SUSPEND */ 110 #define MC_MEMORYLESS 0x8 111 uint32_t mc_board_num; /* board# */ 112 uint32_t mc_phys_board_num; /* physical board# */ 113 uint64_t mc_start_address; /* sb-mem-ranges */ 114 uint64_t mc_size; 115 struct mc_bank { 116 uint32_t mcb_status; 117 #define BANK_INSTALLED 0x80000000 118 #define BANK_MIRROR_MODE 0x40000000 /* 0: normal 1: mirror */ 119 #define BANK_REWRITE_MODE 0x10000000 120 121 #define BANK_PTRL_RUNNING 0x00000001 122 123 #define MC_RETRY_COUNT 2 124 mc_retry_info_t mcb_retry_infos[MC_RETRY_COUNT]; 125 mc_retry_info_t *mcb_retry_freelist; 126 mc_retry_info_t *mcb_retry_pending; 127 mc_retry_info_t *mcb_active; 128 int mcb_rewrite_count; 129 130 uint64_t mcb_reg_base; 131 uint32_t mcb_ptrl_cntl; 132 } mc_bank[BANKNUM_PER_SB]; 133 uchar_t mc_trans_table[2][64]; /* csX-mac-pa-trans-table */ 134 kmutex_t mc_lock; 135 scf_log_t *mc_scf_log[BANKNUM_PER_SB]; 136 scf_log_t *mc_scf_log_tail[BANKNUM_PER_SB]; 137 int mc_scf_total[BANKNUM_PER_SB]; 138 struct memlist *mlist; 139 int mc_scf_retry[BANKNUM_PER_SB]; 140 int mc_last_error; 141 /* number of times memory scanned */ 142 uint64_t mc_period[BANKNUM_PER_SB]; 143 uint32_t mc_speed; 144 int mc_speedup_period[BANKNUM_PER_SB]; 145 int mc_tick_left; 146 mc_dimm_info_t *mc_dimm_list; 147 } mc_opl_t; 148 149 #define IS_MIRROR(mcp, bn) ((mcp)->mc_bank[bn].mcb_status\ 150 & BANK_MIRROR_MODE) 151 typedef struct mc_addr { 152 int ma_bd; /* board number */ 153 int ma_phys_bd; /* phyiscal board number */ 154 int ma_bank; /* bank number */ 155 uint32_t ma_dimm_addr; /* DIMM address (same format as ERR_ADD) */ 156 } mc_addr_t; 157 158 typedef struct mc_rsaddr_info { /* patrol restart address/info */ 159 struct mc_addr mi_restartaddr; 160 int mi_valid; 161 int mi_injectrestart; 162 } mc_rsaddr_info_t; 163 164 typedef struct mc_flt_stat { 165 uint32_t mf_type; /* fault type */ 166 #define FLT_TYPE_INTERMITTENT_CE 0x0001 167 #define FLT_TYPE_PERMANENT_CE 0x0002 168 #define FLT_TYPE_UE 0x0003 169 #define FLT_TYPE_SUE 0x0004 170 #define FLT_TYPE_MUE 0x0005 171 #define FLT_TYPE_CMPE 0x0006 172 uint32_t mf_cntl; /* MAC_BANKm_PTRL_CNTL Register */ 173 uint32_t mf_err_add; /* MAC_BANKm_{PTRL|MI}_ERR_ADD Register */ 174 uint32_t mf_err_log; /* MAC_BANKm_{PTRL|MI}_ERR_LOG Register */ 175 uint32_t mf_synd; 176 uchar_t mf_errlog_valid; 177 uchar_t mf_dimm_slot; 178 uchar_t mf_dram_place; 179 uint64_t mf_flt_paddr; /* faulty physical address */ 180 mc_addr_t mf_flt_maddr; /* faulty DIMM address */ 181 } mc_flt_stat_t; 182 183 typedef struct mc_aflt { 184 uint64_t mflt_id; /* gethrtime() at time of fault */ 185 mc_opl_t *mflt_mcp; /* mc-opl structure */ 186 char *mflt_erpt_class; /* ereport class name */ 187 int mflt_is_ptrl; /* detected by PTRL or MI */ 188 int mflt_nflts; /* 1 or 2 */ 189 int mflt_pr; /* page retire flags */ 190 mc_flt_stat_t *mflt_stat[2]; /* fault status */ 191 } mc_aflt_t; 192 193 typedef struct mc_flt_page { 194 uint32_t err_add; /* MAC_BANKm_{PTRL|MI}_ERR_ADD reg */ 195 uint32_t err_log; /* MAC_BANKm_{PTRL|MI}_ERR_LOG reg */ 196 uint64_t fmri_addr; /* FRU name string */ 197 uint32_t fmri_sz; /* length of FRU name +1 */ 198 } mc_flt_page_t; 199 200 #define MAC_PTRL_STAT(mcp, i) (mcp->mc_bank[i].mcb_reg_base) 201 #define MAC_PTRL_CNTL(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x10) 202 #define MAC_PTRL_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x20) 203 #define MAC_PTRL_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x24) 204 #define MAC_MI_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x28) 205 #define MAC_MI_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x2c) 206 #define MAC_STATIC_ERR_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x30) 207 #define MAC_STATIC_ERR_LOG(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x34) 208 #define MAC_RESTART_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x40) 209 #define MAC_REWRITE_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x44) 210 #define MAC_EG_ADD(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x48) 211 #define MAC_EG_CNTL(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x4c) 212 #define MAC_MIRR(mcp, i) (mcp->mc_bank[i].mcb_reg_base + 0x50) 213 214 /* use PA[37:6] */ 215 #define MAC_RESTART_PA(pa) ((pa >> 6) & 0xffffffff) 216 217 /* 218 * This is for changing MI_ERR_ADDR accuracy. 219 * Last two bits of PTRL_ERR_ADDR are always 0. 220 */ 221 #define ROUNDDOWN(a, n) (((a) & ~((n) - 1))) 222 #define MC_BOUND_BYTE 4 223 224 /* 225 * MAC_BANKm_PTRL_STAT_Register 226 */ 227 #define MAC_STAT_PTRL_CE 0x00000020 228 #define MAC_STAT_PTRL_UE 0x00000010 229 #define MAC_STAT_PTRL_CMPE 0x00000008 230 #define MAC_STAT_MI_CE 0x00000004 231 #define MAC_STAT_MI_UE 0x00000002 232 #define MAC_STAT_MI_CMPE 0x00000001 233 234 #define MAC_STAT_PTRL_ERRS (MAC_STAT_PTRL_CE|MAC_STAT_PTRL_UE\ 235 |MAC_STAT_PTRL_CMPE) 236 #define MAC_STAT_MI_ERRS (MAC_STAT_MI_CE|MAC_STAT_MI_UE\ 237 |MAC_STAT_MI_CMPE) 238 239 /* 240 * MAC_BANKm_PTRL_CTRL_Register 241 */ 242 #define MAC_CNTL_PTRL_START 0x80000000 243 #define MAC_CNTL_USE_RESTART_ADD 0x40000000 244 #define MAC_CNTL_PTRL_STOP 0x20000000 245 #define MAC_CNTL_PTRL_INTERVAL 0x1c000000 246 #define MAC_CNTL_PTRL_RESET 0x02000000 247 #define MAC_CNTL_PTRL_STATUS 0x01000000 248 #define MAC_CNTL_REW_REQ 0x00800000 249 #define MAC_CNTL_REW_RESET 0x00400000 250 #define MAC_CNTL_CS0_DEG_MODE 0x00200000 251 #define MAC_CNTL_PTRL_CE 0x00008000 252 #define MAC_CNTL_PTRL_UE 0x00004000 253 #define MAC_CNTL_PTRL_CMPE 0x00002000 254 #define MAC_CNTL_MI_CE 0x00001000 255 #define MAC_CNTL_MI_UE 0x00000800 256 #define MAC_CNTL_MI_CMPE 0x00000400 257 #define MAC_CNTL_REW_CE 0x00000200 258 #define MAC_CNTL_REW_UE 0x00000100 259 #define MAC_CNTL_REW_END 0x00000080 260 #define MAC_CNTL_PTRL_ADD_MAX 0x00000040 261 #define MAC_CNTL_REW_CMPE 0x00000020 262 263 #define MAC_CNTL_PTRL_ERR_SHIFT 13 264 #define MAC_CNTL_MI_ERR_SHIFT 10 265 266 #define MAC_CNTL_PTRL_PRESERVE_BITS (MAC_CNTL_PTRL_INTERVAL) 267 268 #define MAC_CNTL_PTRL_ERRS (MAC_CNTL_PTRL_CE|MAC_CNTL_PTRL_UE\ 269 |MAC_CNTL_PTRL_CMPE) 270 #define MAC_CNTL_MI_ERRS (MAC_CNTL_MI_CE|MAC_CNTL_MI_UE\ 271 |MAC_CNTL_MI_CMPE) 272 #define MAC_CNTL_REW_ERRS (MAC_CNTL_REW_CE|MAC_CNTL_REW_CMPE|\ 273 MAC_CNTL_REW_UE|MAC_CNTL_REW_END) 274 #define MAC_CNTL_ALL_ERRS (MAC_CNTL_PTRL_ERRS|\ 275 MAC_CNTL_MI_ERRS|MAC_CNTL_REW_ERRS) 276 277 #define MAC_ERRLOG_SYND_SHIFT 16 278 #define MAC_ERRLOG_SYND_MASK 0xffff 279 #define MAC_ERRLOG_DIMMSLOT_SHIFT 13 280 #define MAC_ERRLOG_DIMMSLOT_MASK 0x7 281 #define MAC_ERRLOG_DRAM_PLACE_SHIFT 8 282 #define MAC_ERRLOG_DRAM_PLACE_MASK 0x1f 283 284 #define MAC_SET_ERRLOG_INFO(flt_stat) \ 285 (flt_stat)->mf_errlog_valid = 1; \ 286 (flt_stat)->mf_synd = ((flt_stat)->mf_err_log >> \ 287 MAC_ERRLOG_SYND_SHIFT) & \ 288 MAC_ERRLOG_SYND_MASK; \ 289 (flt_stat)->mf_dimm_slot = ((flt_stat)->mf_err_log >> \ 290 MAC_ERRLOG_DIMMSLOT_SHIFT) & \ 291 MAC_ERRLOG_DIMMSLOT_MASK; \ 292 (flt_stat)->mf_dram_place = ((flt_stat)->mf_err_log >> \ 293 MAC_ERRLOG_DRAM_PLACE_SHIFT) & \ 294 MAC_ERRLOG_DRAM_PLACE_MASK; 295 296 extern void mc_write_cntl(mc_opl_t *, int, uint32_t); 297 #define MAC_CMD(mcp, i, cmd) mc_write_cntl(mcp, i, cmd) 298 299 #define MAC_PTRL_START(mcp, i) { if (!(ldphysio(MAC_PTRL_CNTL(mcp, i)) \ 300 & MAC_CNTL_PTRL_START)) \ 301 MAC_CMD((mcp), (i), MAC_CNTL_PTRL_START); } 302 303 #define MAC_PTRL_START_ADD(mcp, i) MAC_CMD((mcp), (i),\ 304 MAC_CNTL_PTRL_START|MAC_CNTL_USE_RESTART_ADD) 305 #define MAC_PTRL_STOP(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_PTRL_STOP) 306 #define MAC_PTRL_RESET(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_PTRL_RESET) 307 #define MAC_REW_REQ(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_REW_REQ) 308 #define MAC_REW_RESET(mcp, i) MAC_CMD((mcp), (i), MAC_CNTL_REW_RESET) 309 #define MAC_CLEAR_ERRS(mcp, i, errs) MAC_CMD((mcp), (i), errs) 310 #define MAC_CLEAR_ALL_ERRS(mcp, i) MAC_CMD((mcp), (i),\ 311 MAC_CNTL_ALL_ERRS) 312 #define MAC_CLEAR_MAX(mcp, i) \ 313 MAC_CMD((mcp), (i), MAC_CNTL_PTRL_ADD_MAX) 314 315 316 /* 317 * MAC_BANKm_PTRL/MI_ERR_ADD/LOG_Register 318 */ 319 #define MAC_ERR_ADD_INVALID 0x80000000 320 #define MAC_ERR_LOG_INVALID 0x00000080 321 322 /* 323 * MAC_BANKm_STATIC_ERR_ADD_Register 324 */ 325 #define MAC_STATIC_ERR_VLD 0x80000000 326 327 /* 328 * MAC_BANKm_MIRR_Register 329 */ 330 #define MAC_MIRR_MIRROR_MODE 0x80000000 331 #define MAC_MIRR_BANK_EXCLUSIVE 0x40000000 332 333 #define OPL_BOARD_MAX 16 334 #define OPL_BANK_MAX 8 335 336 #define MC_SET_REWRITE_MODE(mcp, bank) \ 337 ((mcp)->mc_bank[bank].mcb_status |= BANK_REWRITE_MODE) 338 339 #define MC_CLEAR_REWRITE_MODE(mcp, bank) \ 340 ((mcp)->mc_bank[bank].mcb_status &= ~BANK_REWRITE_MODE) 341 342 #define MC_REWRITE_MODE(mcp, bank) \ 343 ((mcp)->mc_bank[bank].mcb_status & BANK_REWRITE_MODE) 344 345 #define MC_REWRITE_ACTIVE(mcp, bank) \ 346 ((mcp)->mc_bank[bank].mcb_active) 347 348 /* 349 * MAC_BANKm_EG_ADD_Register 350 */ 351 #define MAC_EG_ADD_MASK 0x7ffffffc 352 /* 353 * To set the EG_CNTL register, bit[26-25] and 354 * bit[21-20] must be cleared. Then the other 355 * control bit should be set. Then the bit[26-25] 356 * and bit[21-20] should be set while other bits 357 * should be the same as before. 358 */ 359 #define MAC_EG_CNTL_MASK 0x06300000 360 361 #define MAC_EG_ADD_FIX 0x80000000 362 #define MAC_EG_FORCE_DERR00 0x40000000 363 #define MAC_EG_FORCE_DERR16 0x20000000 364 #define MAC_EG_FORCE_DERR64 0x10000000 365 #define MAC_EG_FORCE_DERR80 0x08000000 366 #define MAC_EG_DERR_ALWAYS 0x02000000 367 #define MAC_EG_DERR_ONCE 0x04000000 368 #define MAC_EG_DERR_NOP 0x06000000 369 #define MAC_EG_FORCE_READ00 0x00800000 370 #define MAC_EG_FORCE_READ16 0x00400000 371 #define MAC_EG_RDERR_ALWAYS 0x00100000 372 #define MAC_EG_RDERR_ONCE 0x00200000 373 #define MAC_EG_RDERR_NOP 0x00300000 374 375 #define MAC_EG_SETUP_MASK 0xf9cfffff 376 377 /* For MAC-PA translation */ 378 #define MC_ADDRESS_BITS 40 379 #define PA_BITS_FOR_MAC 39 380 #define INDEX_OF_BANK_SUPPLEMENT_BIT 39 381 #define MP_NONE 128 382 #define MP_BANK_0 129 383 #define MP_BANK_1 130 384 #define MP_BANK_2 131 385 386 #define CS_SHIFT 29 387 #define MC_TT_ENTRIES 64 388 #define MC_TT_CS 2 389 390 391 /* export interface for error injection */ 392 extern int mc_inject_error(int error_type, uint64_t pa, uint32_t flags); 393 394 #define MC_INJECT_NOP 0x0 395 #define MC_INJECT_INTERMITTENT_CE 0x1 396 #define MC_INJECT_PERMANENT_CE 0x2 397 #define MC_INJECT_UE 0x3 398 #define MC_INJECT_INTERMITTENT_MCE 0x11 399 #define MC_INJECT_PERMANENT_MCE 0x12 400 #define MC_INJECT_SUE 0x13 401 #define MC_INJECT_MUE 0x14 402 #define MC_INJECT_CMPE 0x15 403 404 #define MC_INJECT_MIRROR_MODE 0x10 405 #define MC_INJECT_MIRROR(x) (x & MC_INJECT_MIRROR_MODE) 406 407 #define MC_INJECT_FLAG_PREFETCH 0x1 408 #define MC_INJECT_FLAG_NO_TRAP MC_INJECT_FLAG_PREFETCH 409 #define MC_INJECT_FLAG_RESTART 0x2 410 #define MC_INJECT_FLAG_POLL 0x4 411 #define MC_INJECT_FLAG_RESET 0x8 412 #define MC_INJECT_FLAG_OTHER 0x10 413 #define MC_INJECT_FLAG_LD 0x20 414 #define MC_INJECT_FLAG_ST 0x40 415 #define MC_INJECT_FLAG_PATH 0x80 416 417 #define MCIOC ('M' << 8) 418 #define MCIOC_FAULT_PAGE (MCIOC|1) 419 420 #ifdef DEBUG 421 422 #define MCI_NOP 0x0 423 #define MCI_CE 0x1 424 #define MCI_PERM_CE 0x2 425 #define MCI_UE 0x3 426 #define MCI_SHOW_ALL 0x4 427 #define MCI_SHOW_NONE 0x5 428 #define MCI_CMP 0x6 429 #define MCI_ALLOC 0x7 430 #define MCI_M_CE 0x8 431 #define MCI_M_PCE 0x9 432 #define MCI_M_UE 0xA 433 #define MCI_SUSPEND 0xB 434 #define MCI_RESUME 0xC 435 436 #endif 437 438 #ifdef __cplusplus 439 } 440 #endif 441 442 #endif /* _SYS_MC_OPL_H */ 443