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 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_AC_H 28 #define _SYS_AC_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* useful debugging stuff */ 37 #define AC_ATTACH_DEBUG 0x1 38 #define AC_REGISTERS_DEBUG 0x2 39 40 /* 41 * OBP supplies us with two register sets for the AC nodes. They are: 42 * 43 * 0 miscellaneous regs 44 * 1 Cache tags 45 * 46 * We do not use the cache tags for anything in the kernel, so we 47 * do not map them in. 48 */ 49 50 /* Macros for physical acccess, fhc.h has to be present */ 51 #define AC_OFFSET 0x00001000000ull 52 #define AC_CENTRAL 0x80000000 53 #define AC_ARB_FAST 0x00002000 54 #define AC_BCSR(board) (FHC_BOARD_BASE(2*(board)) + FHC_OFFSET + \ 55 AC_OFFSET + AC_OFF_BCSR) 56 57 /* Register set 0 Offsets */ 58 #define AC_OFF_BRCS 0x10 59 #define AC_OFF_BCSR 0x20 60 #define AC_OFF_ESR 0x30 61 #define AC_OFF_EMR 0x40 62 #define AC_OFF_MEMCTL 0x60 63 #define AC_OFF_MEMDEC0 0x70 64 #define AC_OFF_MEMDEC1 0x80 65 #define AC_OFF_UPA0 0x2000 66 #define AC_OFF_UPA1 0x4000 67 #define AC_OFF_CNTR 0x6000 68 #define AC_OFF_MCCR 0x6020 69 70 /* Use predefined strings to name the kstats from this driver. */ 71 #define AC_KSTAT_NAME "address_controller" 72 #define MEMCTL_KSTAT_NAMED "acmemctl" 73 #define MEMDECODE0_KSTAT_NAMED "acmemdecode0" 74 #define MEMDECODE1_KSTAT_NAMED "acmemdecode1" 75 #define CNTR_KSTAT_NAMED "accounter" 76 #define MCCR_KSTAT_NAMED "acmccr" 77 #define BANK_0_KSTAT_NAMED "acbank0" 78 #define BANK_1_KSTAT_NAMED "acbank1" 79 80 /* used for the picN kstats */ 81 #define AC_NUM_PICS 2 82 #define AC_COUNTER_TO_PIC0(CNTR) ((CNTR) & 0xFFFFFFFFULL) 83 #define AC_COUNTER_TO_PIC1(CNTR) ((CNTR) >> 32) 84 85 /* used to clear/set the pcr */ 86 #define AC_CLEAR_PCR(PCR) ((PCR) & ~(0x3F3F)) 87 #define AC_SET_HOT_PLUG(PCR) ((PCR) | (0x3F3F)) 88 89 /* used for programming the pic */ 90 #define AC_SET_PIC_BUS_PAUSE(BRD) (0x80000000LL - 0x9ac4 - ((BRD) << 3)) 91 92 /* defines for AC Board Configuration and Status Register */ 93 #define NO_CACHE 0 94 #define CACHE_512K 2 95 #define CACHE_1M 3 96 #define CACHE_2M 4 97 #define CACHE_4M 5 98 #define CACHE_8M 6 99 #define CACHE_16M 7 100 101 #define ARB_MASTER 0x8000 102 #define ARB_INIT 0x4000 103 #define ARB_FAST 0x2000 104 #define FTC_CPAR 0x0200 105 106 #define AC_CSR_REFEN (1ULL << 27) 107 108 /* defines for Memory decode registers */ 109 #define AC_MEM_VALID 0x8000000000000000ULL 110 111 /* size of a memory SIMM group */ 112 #define RASIZE0(memctl) (8 << ((((memctl) >> 8) & 0x7) << 1)) 113 #define RASIZE1(memctl) (8 << ((((memctl) >> 11) & 0x7) << 1)) 114 #define RATBL0(memctl) (((memctl) >> 8) & 0x7) 115 #define RATBL1(memctl) (((memctl) >> 11) & 0x7) 116 117 /* 118 * Interleave factor of a memory SIMM group. 119 * Possible values are 1, 2, 4, 8, and 16. 1 means not interleaved. 120 * Larger groups can be interleaved with smaller groups. Groups 121 * on the same board can be interleaved as well. 122 */ 123 #define INTLV0(memctl) (1 << ((memctl) & 0x7)) 124 #define INTLV1(memctl) (1 << (((memctl) >> 3) & 0x7)) 125 #define INTVAL0(memctl) ((memctl) & 0x7) 126 #define INTVAL1(memctl) (((memctl) >> 3) & 0x7) 127 128 /* 129 * Physical base mask of a memory SIMM group. Note that this is 130 * not the real physical base, and is just used to match up the 131 * interleaving of groups. The mask bits (UK) are used to mask 132 * out the match (UM) field so that the bases can be compared. 133 */ 134 #define GRP_UK(memdec) (((memdec) >> 39) & 0xFFF) 135 #define GRP_UM(memdec) (((memdec) >> 12) & 0x7FFF) 136 #define GRP_BASE(memdec) (GRP_UM(memdec) & ~(GRP_UK(memdec))) 137 #define GRP_LK(memdec) (((memdec) >> 6) & 0xf) 138 #define GRP_LM(memdec) ((memdec) & 0xf) 139 #define GRP_LBASE(memdec) (GRP_LM(memdec) & ~(GRP_LK(memdec))) 140 #define GRP_REALBASE(m) ((GRP_BASE(m) << 26) | (GRP_LBASE(m) << 6)) 141 #define GRP_UK2SPAN(memdec) ((GRP_UK(memdec) + 1) << 26) 142 #define GRP_SPANMB(memdec) (GRP_UK2SPAN(memdec) >> 20) 143 144 /* 145 * memory states and conditions for sunfire memory system 146 */ 147 enum ac_bank_id { Bank0 = 0, Bank1 = 1 }; 148 enum ac_bank_status { StUnknown = 0, StNoMem, StBad, StActive, StSpare }; 149 enum ac_bank_condition { ConUnknown = 0, ConOK, ConFailing, ConFailed, 150 ConTest, ConBad }; 151 152 /* 153 * AC memory bank ioctl interface. 154 */ 155 156 /* 'G' (for gigabytes!) does not appear to be used elsewhere in the kernel */ 157 #define AC_IOC ('G'<<8) 158 159 /* 160 * For all AC_MEM_ ioctls the arg pointer points to a sysc_cfga_cmd_t 161 * except for AC_MEM_ADMIN_VER. The private pointer then points to a 162 * structure of the appropriate type, if required. 163 */ 164 #define AC_MEM_ADMIN_VER (AC_IOC|0) /* arg is &ac_mem_version_t */ 165 #define AC_MEM_CONFIGURE (AC_IOC|1) /* private == NULL */ 166 #define AC_MEM_UNCONFIGURE (AC_IOC|2) /* private == NULL */ 167 #define AC_MEM_STAT (AC_IOC|3) /* ac_stat_t */ 168 #define AC_MEM_TEST_START (AC_IOC|4) /* ac_mem_test_start_t */ 169 #define AC_MEM_TEST_STOP (AC_IOC|5) /* ac_mem_test_stop_t */ 170 #define AC_MEM_TEST_READ (AC_IOC|6) /* ac_mem_test_read_t */ 171 #define AC_MEM_TEST_WRITE (AC_IOC|7) /* ac_mem_test_write_t */ 172 #define AC_MEM_EXERCISE (AC_IOC|128) /* various */ 173 174 #define AC_OUTPUT_LEN MAXPATHLEN /* output str len */ 175 176 typedef enum { 177 AC_ERR_DEFAULT = 0, /* generic errors */ 178 AC_ERR_INTRANS, /* hardware in transition */ 179 AC_ERR_UTHREAD, /* can't stop user thread */ 180 AC_ERR_KTHREAD, /* can't stop kernel thread */ 181 AC_ERR_SUSPEND, /* can't suspend a device */ 182 AC_ERR_RESUME, /* can't resume a device */ 183 AC_ERR_POWER, /* not enough power for slot */ 184 AC_ERR_COOLING, /* not enough cooling for slot */ 185 AC_ERR_PRECHARGE, /* not enough precharge for slot */ 186 AC_ERR_HOTPLUG, /* Hot Plug Unavailable */ 187 AC_ERR_HW_COMPAT, /* incompatible hardware found during dr */ 188 AC_ERR_NON_DR_PROM, /* prom not support Dynamic Reconfiguration */ 189 AC_ERR_CORE_RESOURCE, /* core resource cannot be removed */ 190 AC_ERR_PROM, /* error encountered in OBP/POST */ 191 AC_ERR_DR_INIT, /* error encountered in sysc_dr_init op */ 192 AC_ERR_NDI_ATTACH, /* error encountered in NDI attach operations */ 193 AC_ERR_NDI_DETACH, /* error encountered in NDI detach operations */ 194 AC_ERR_RSTATE, /* wrong receptacle state */ 195 AC_ERR_OSTATE, /* wrong occupant state */ 196 AC_ERR_COND, /* invalid condition */ 197 AC_ERR_BD, /* invalid board id */ 198 AC_ERR_BD_TYPE, /* invalid board type */ 199 AC_ERR_BD_STATE, /* invalid board state */ 200 AC_ERR_MEM_PERM, /* no write permission */ 201 AC_ERR_MEM_BK, /* invalid memory bank */ 202 AC_ERR_MEM_TEST, /* invalid memory test id */ 203 AC_ERR_MEM_TEST_PAR, /* invalid memory test parameter(s) */ 204 AC_ERR_KPM_CANCELLED, /* kphysm_del_cancel (for complete) */ 205 AC_ERR_KPM_REFUSED, /* kphysm_pre_del failed (for complete) */ 206 AC_ERR_KPM_SPAN, /* memory already in use (add) */ 207 AC_ERR_KPM_DUP, /* memory span duplicate (delete) */ 208 AC_ERR_KPM_FAULT, /* memory access test failed (add) */ 209 AC_ERR_KPM_RESOURCE, /* some resource was not available */ 210 AC_ERR_KPM_NOTSUP, /* operation not supported */ 211 AC_ERR_KPM_NOHANDLES, /* cannot allocate any more handles */ 212 AC_ERR_KPM_NONRELOC, /* non-relocatable pages in span */ 213 AC_ERR_KPM_HANDLE, /* bad handle supplied */ 214 AC_ERR_KPM_BUSY, /* memory in span is being deleted */ 215 AC_ERR_KPM_NOTVIABLE, /* vM viability test failed */ 216 AC_ERR_KPM_SEQUENCE, /* function called out of sequence */ 217 AC_ERR_KPM_NOWORK, /* no pages to delete */ 218 AC_ERR_KPM_NOTFINISHED, /* thread not finished */ 219 AC_ERR_KPM_NOTRUNNING, /* thread not running */ 220 AC_ERR_VMEM, /* insufficient virtual memory */ 221 AC_ERR_INTR, /* delete interrupt by user */ 222 AC_ERR_TIMEOUT, /* delete timed out */ 223 AC_ERR_MEM_DEINTLV /* could not de-interleave memory */ 224 } ac_err_t; 225 226 /* 227 * Config admin command structure for AC_MEM ioctls. 228 */ 229 typedef struct ac_cfga_cmd { 230 uint_t force:1; /* force this state transition */ 231 uint_t test:1; /* Need to test hardware */ 232 int arg; /* generic data for test */ 233 ac_err_t errtype; /* error code returned */ 234 char *outputstr; /* output returned from ioctl */ 235 void *private; /* command private data */ 236 } ac_cfga_cmd_t; 237 238 typedef struct ac_cfga_cmd32 { 239 uint_t force:1; /* force this state transition */ 240 uint_t test:1; /* Need to test hardware */ 241 int arg; /* generic data for test */ 242 ac_err_t errtype; /* error code returned */ 243 caddr32_t outputstr; /* output returned from ioctl */ 244 caddr32_t private; /* command private data */ 245 } ac_cfga_cmd32_t; 246 247 typedef uint_t ac_mem_version_t; /* platform interface rev */ 248 #define AC_MEM_ADMIN_VERSION 1 249 250 typedef uint_t mem_test_handle_t; 251 252 typedef struct { 253 uint64_t module_id; 254 uint64_t afsr; 255 uint64_t afar; 256 uint64_t udbh_error_reg; 257 uint64_t udbl_error_reg; 258 } sunfire_processor_error_regs_t; 259 260 /* 261 * page_size gives the requires size for the read or write buffer. 262 * A read can be restricted to one or more line_size units starting 263 * at a multiple of line_size units from the start of the page. 264 * afar_base is the physical base of the bank being tested so 265 * that the afar value can be translated to an offset into the bank. 266 */ 267 typedef struct { 268 mem_test_handle_t handle; 269 pid_t tester_pid; /* PID of test starter */ 270 sysc_cfga_cond_t prev_condition; 271 u_longlong_t bank_size; /* bytes */ 272 uint_t page_size; /* bytes */ 273 uint_t line_size; /* bytes */ 274 u_longlong_t afar_base; 275 } ac_mem_test_start_t; 276 277 typedef struct { 278 mem_test_handle_t handle; 279 sysc_cfga_cond_t condition; 280 } ac_mem_test_stop_t; 281 282 /* 283 * line_offset is in the range 0 - (page_size/line_size)-1 284 * line_count is in the range 1 - (page_size/line_size) 285 */ 286 typedef struct { 287 u_longlong_t page_num; 288 uint_t line_offset; 289 uint_t line_count; 290 } ac_test_addr_t; 291 292 /* 293 * Data will be transferred in/out of the buffer at: 294 * (page_buf + (line_offset*line_size)) 295 */ 296 typedef struct { 297 mem_test_handle_t handle; 298 void *page_buf; 299 ac_test_addr_t address; 300 sunfire_processor_error_regs_t *error_buf; 301 } ac_mem_test_read_t; 302 303 typedef struct { 304 mem_test_handle_t handle; 305 void *page_buf; 306 ac_test_addr_t address; 307 } ac_mem_test_write_t; 308 309 #ifdef _SYSCALL32 310 311 /* Kernel's view of ILP32 structure version. */ 312 313 typedef struct { 314 mem_test_handle_t handle; 315 caddr32_t page_buf; /* void * */ 316 ac_test_addr_t address; 317 caddr32_t error_buf; /* sunfire_processor_error_regs_t */ 318 } ac_mem_test_read32_t; 319 320 typedef struct { 321 mem_test_handle_t handle; 322 caddr32_t page_buf; /* void * */ 323 ac_test_addr_t address; 324 } ac_mem_test_write32_t; 325 326 #endif /* _SYSCALL32 */ 327 328 /* structure returned from AC_MEM_STAT ioctl */ 329 typedef struct { 330 sysc_cfga_rstate_t rstate; 331 sysc_cfga_ostate_t ostate; 332 sysc_cfga_cond_t condition; 333 time_t status_time; 334 uint_t board; 335 uint_t real_size; 336 uint_t use_size; 337 uint_t busy; /* add/delete in progress */ 338 uint_t page_size; /* bytes */ 339 uint64_t phys_pages; 340 uint64_t managed; 341 uint64_t nonrelocatable; 342 /* to supply address, group, info */ 343 uint64_t ac_memctl; 344 uint64_t ac_decode0; 345 uint64_t ac_decode1; 346 } ac_stat_t; 347 348 #ifdef _SYSCALL32 349 350 /* Kernel's view of ILP32 structure version. */ 351 352 typedef struct { 353 sysc_cfga_rstate_t rstate; 354 sysc_cfga_ostate_t ostate; 355 sysc_cfga_cond_t condition; 356 time32_t status_time; 357 uint_t board; 358 uint_t real_size; 359 uint_t use_size; 360 uint_t busy; /* add/delete in progress */ 361 uint_t page_size; /* bytes */ 362 uint64_t phys_pages; 363 uint64_t managed; 364 uint64_t nonrelocatable; 365 /* to supply address, group, info */ 366 uint64_t ac_memctl; 367 uint64_t ac_decode0; 368 uint64_t ac_decode1; 369 } ac_stat32_t; 370 371 #endif /* _SYSCALL32 */ 372 373 /* Command values in cmd_cfga.arg for the AC_MEM_EXERCISE ioctl. */ 374 #define AC_MEMX_RELOCATE_ALL 0 375 376 /* Stats structure for AC_MEMX_RELOCATE_ALL (cmd_cfga.private != NULL). */ 377 struct ac_memx_relocate_stats { 378 uint_t base; 379 uint_t npgs; 380 uint_t nopaget; 381 uint_t nolock; 382 uint_t isfree; 383 uint_t reloc; 384 uint_t noreloc; 385 }; 386 387 /* End of ioctl interface. */ 388 389 #if defined(_KERNEL) 390 391 typedef struct { 392 ac_cfga_cmd_t cmd_cfga; 393 char *errbuf; /* internal error buffer */ 394 struct ac_soft_state *softsp; 395 uint_t bank; /* Decoded bank number. */ 396 } ac_cfga_pkt_t; 397 398 #define AC_ERR_SET(pkt, err) (pkt)->cmd_cfga.errtype = (err) 399 400 #define MEM_BOARD_VISIBLE(BD) \ 401 ((BD)->sc.rstate == SYSC_CFGA_RSTATE_CONNECTED && \ 402 (BD)->sc.ostate == SYSC_CFGA_OSTATE_CONFIGURED) 403 404 #ifndef TRUE 405 #define TRUE (1) 406 #endif 407 #ifndef FALSE 408 #define FALSE (0) 409 #endif 410 411 #define AC_BANK0_STATUS "bank-0-status" 412 #define AC_BANK1_STATUS "bank-1-status" 413 #define AC_BANK_NOMEM "nomem" 414 #define AC_BANK_OK "ok" 415 #define AC_BANK_SPARE "spare" 416 #define AC_BANK_FAILED "failed" 417 418 /* 419 * Test for a valid size setting. The size must be set as 420 * a contiguous number of bits starting at the least significant bit. 421 * Adding one to such a number causes a carry to be propagated to 422 * the first zero bit, eg 00111 -> 01000. Thus for a correctly 423 * formed value, the AND of the two numbers is 0. 424 */ 425 #define GRP_SIZE_IS_SET(memdec) ((GRP_UK(memdec) & (GRP_UK(memdec) + 1)) == 0) 426 427 /* set the decode register bits according to the desired bank layout */ 428 #define SETUP_DECODE(addr, mb, intlv, group) \ 429 ((((addr) >> 26) & 0x7fffULL) << 12) | /* UM */ \ 430 ((((mb) >> 6) - 1ULL) << 39) | /* UK */ \ 431 ((group) & 0xfULL) | /* LM */ \ 432 ((0xfULL << (intlv) & 0xfULL) << 6) /* LK */ 433 434 /* 435 * Driver minor number macros. 436 */ 437 #define AC_GETINSTANCE(M) ((M) >> 1) 438 #define AC_GETBANK(M) ((M) & 1) 439 #define AC_PUTINSTANCE(I) ((I) << 1) 440 441 /* 442 * Attachment point names. 443 */ 444 #define NAME_BANK0 "bank0" 445 #define NAME_BANK1 "bank1" 446 447 /* 448 * Memory Database 449 * This information is generally accessed through the bd_list so we will 450 * just protect it by that for now. 451 */ 452 struct ac_mem_info { 453 int busy; /* A bank is in transition */ 454 time_t status_change; /* Time of last change */ 455 456 sysc_cfga_rstate_t rstate; 457 sysc_cfga_ostate_t ostate; 458 sysc_cfga_cond_t condition; 459 uint_t real_size; /* Real size in MB of bank */ 460 uint_t use_size; /* In use size in MB */ 461 }; 462 463 /* Structures used in the driver to manage the hardware */ 464 struct ac_soft_state { 465 dev_info_t *dip; /* dev info of myself */ 466 dev_info_t *pdip; /* dev info of my parent */ 467 int board; /* Board number for this AC */ 468 469 /* fields protected by bd_list lock */ 470 struct ac_mem_info bank[2]; /* memory bank information */ 471 472 /* Mapped addresses of registers */ 473 void *ac_base; /* Base address of Address Controller */ 474 volatile uint32_t *ac_id; /* ID register */ 475 volatile uint64_t *ac_memctl; /* Memory Control */ 476 volatile uint64_t *ac_memdecode0; /* Memory Decode 0 */ 477 volatile uint64_t *ac_memdecode1; /* Memory Decode 1 */ 478 volatile uint64_t *ac_counter; /* AC counter register */ 479 volatile uint32_t *ac_mccr; /* AC Counter control */ 480 kstat_t *ac_ksp; 481 kstat_t *ac_counters_ksp; /* performance counter kstat */ 482 }; 483 484 extern void ac_blkcopy(caddr_t, caddr_t, uint_t, uint_t); 485 extern void ac_mapin(uint64_t, caddr_t); 486 extern void ac_unmap(caddr_t); 487 488 /* kstat structure used by ac to pass data to user programs. */ 489 struct ac_kstat { 490 struct kstat_named ac_memctl; /* AC Memory control */ 491 struct kstat_named ac_memdecode0; /* AC Memory Decode Bank 0 */ 492 struct kstat_named ac_memdecode1; /* AC Memory Decode Bank 1 */ 493 struct kstat_named ac_mccr; /* AC Mem Counter Control */ 494 struct kstat_named ac_counter; /* AC Counter */ 495 struct kstat_named ac_bank0_status; 496 struct kstat_named ac_bank1_status; 497 }; 498 499 #endif /* _KERNEL */ 500 501 #ifdef __cplusplus 502 } 503 #endif 504 505 #endif /* _SYS_AC_H */ 506