ac.h revision 1341:6d7c4f090a72
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 33extern "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 */ 147enum ac_bank_id { Bank0 = 0, Bank1 = 1 }; 148enum ac_bank_status { StUnknown = 0, StNoMem, StBad, StActive, StSpare }; 149enum 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 176typedef 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 */ 229typedef 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 238typedef 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 247typedef uint_t ac_mem_version_t; /* platform interface rev */ 248#define AC_MEM_ADMIN_VERSION 1 249 250typedef uint_t mem_test_handle_t; 251 252typedef 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 */ 267typedef 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 277typedef 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 */ 286typedef 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 */ 296typedef 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 303typedef 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 313typedef 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 320typedef 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 */ 329typedef 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 352typedef 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). */ 377struct 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 391typedef 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 */ 452struct 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 */ 464struct 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 484extern void ac_blkcopy(caddr_t, caddr_t, uint_t, uint_t); 485extern void ac_mapin(uint64_t, caddr_t); 486extern void ac_unmap(caddr_t); 487 488/* kstat structure used by ac to pass data to user programs. */ 489struct 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