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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_SYSIOSBUS_H 28 #define _SYS_SYSIOSBUS_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifndef _ASM 33 #include <sys/avintr.h> 34 #include <sys/vmem.h> 35 #include <sys/ontrap.h> 36 #include <sys/machsystm.h> 37 #endif 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* Things for debugging */ 44 #ifdef SYSIO_MEM_DEBUG 45 #define IO_MEMUSAGE 46 #endif /* SYSIO_MEM_DEBUG */ 47 48 /* 49 * sysio sbus constant definitions. 50 */ 51 #define NATURAL_REG_SIZE 0x8 /* 8 Bytes is Fusion reg size */ 52 #define MIN_REG_SIZE 0x4 /* Smallest Fusion reg size */ 53 #define OFF_SYSIO_CTRL_REG 0x10 54 #define SYSIO_CTRL_REG_SIZE (NATURAL_REG_SIZE) 55 #define OFF_SBUS_CTRL_REG 0x2000 56 #define SBUS_CTRL_REG_SIZE (NATURAL_REG_SIZE) 57 #define OFF_SBUS_SLOT_CONFIG 0x2020 58 #define SBUS_SLOT_CONFIG_SIZE (NATURAL_REG_SIZE * 7) 59 #define OFF_INTR_MAPPING_REG 0x2c00 60 /* #define INTR_MAPPING_REG_SIZE (NATURAL_REG_SIZE * 16 * 8) */ 61 #define INTR_MAPPING_REG_SIZE 0x490 62 #define OFF_CLR_INTR_REG 0x3408 63 /* #define CLR_INTR_REG_SIZE (NATURAL_REG_SIZE * 16 * 8) */ 64 #define CLR_INTR_REG_SIZE 0x488 65 #define OFF_INTR_RETRY_REG 0x2c20 66 #define INTR_RETRY_REG_SIZE (MIN_REG_SIZE) 67 #define OFF_SBUS_INTR_STATE_REG 0x4800 68 #define SBUS_INTR_STATE_REG_SIZE (NATURAL_REG_SIZE * 2) 69 #define SYSIO_IGN 46 70 #define SBUS_ARBIT_ALL 0x3full 71 #define SYSIO_VER_SHIFT 56 72 73 /* Error registers */ 74 #define OFF_SYSIO_ECC_REGS 0x20 75 #define SYSIO_ECC_REGS_SIZE NATURAL_REG_SIZE 76 #define OFF_SYSIO_UE_REGS 0x30 77 #define SYSIO_UE_REGS_SIZE (NATURAL_REG_SIZE * 2) 78 #define OFF_SYSIO_CE_REGS 0x40 79 #define SYSIO_CE_REGS_SIZE (NATURAL_REG_SIZE * 2) 80 #define OFF_SBUS_ERR_REGS 0x2010 81 #define SBUS_ERR_REGS_SIZE (NATURAL_REG_SIZE * 2) 82 83 /* Interrupts */ 84 #define INTERRUPT_CPU_FIELD 26 /* Bit shift for mondo TID field */ 85 #define INTERRUPT_GROUP_NUMBER 6 /* Bit shift for mondo IGN field */ 86 #define INTERRUPT_VALID 0x80000000ull /* Mondo valid bit */ 87 #define SBUS_INTR_IDLE 0ull 88 #define INT_PENDING 3 /* state of the interrupt dispatch */ 89 /* 90 * Fix these (RAZ) 91 * Interrupt Mapping Register defines 92 */ 93 #define IMR_VALID 0x80000000ull /* Valid bit */ 94 #define IMR_TID 0x7C000000ull /* TID bits */ 95 #define IMR_IGN 0x000007C0ull /* IGN bits */ 96 #define IMR_INO 0x0000003Full /* INO bits */ 97 #define IMR_TID_SHIFT 26 /* Bit shift for TID field */ 98 #define IMR_IGN_SHIFT 6 /* Bit shift for IGN field */ 99 100 #define MAX_SBUS (30) 101 #define MAX_SBUS_LEVEL (7) 102 #define MAX_SBUS_SLOTS (7) /* 4 external slots + 3 internal */ 103 #define EXT_SBUS_SLOTS 4 /* Number of external sbus slots */ 104 #define MAX_SBUS_SLOT_ADDR 0x10 /* Max slot address on SYSIO */ 105 #define SYSIO_BURST_RANGE (0x7f) /* 32 bit: 64 Byte to 1 Byte burst */ 106 #define SYSIO64_BURST_RANGE (0x78) /* 64 bit: 64 Byte to 8 Byte burst */ 107 #define SYSIO_BURST_MASK 0xffff 108 #define SYSIO64_BURST_MASK 0xffff0000 109 #define SYSIO64_BURST_SHIFT 16 110 #define MAX_PIL 16 111 112 /* Slot config register defines */ 113 #define SBUS_ETM 0x4000ull 114 #define SYSIO_SLAVEBURST_MASK 0x1e /* Mask for hardware register */ 115 #define SYSIO_SLAVEBURST_RANGE (0x78) /* 32 bit: 64 Byte to 8 Byte burst */ 116 #define SYSIO64_SLAVEBURST_RANGE (0x78) /* 64 bit: 64 Byte to 8 Byte burst */ 117 #define SYSIO_SLAVEBURST_REGSHIFT 2 /* Convert bit positions 2**8 to 2**1 */ 118 119 /* 120 * Offsets of sysio, sbus, registers 121 */ 122 /* Slot configuration register mapping offsets */ 123 #define SBUS_SLOT0_CONFIG 0x0 124 #define SBUS_SLOT1_CONFIG 0x1 125 #define SBUS_SLOT2_CONFIG 0x2 126 #define SBUS_SLOT3_CONFIG 0x3 127 #define SBUS_SLOT4_CONFIG 0x4 128 #define SBUS_SLOT5_CONFIG 0x5 129 #define SBUS_SLOT6_CONFIG 0x6 130 131 /* Interrupt mapping register mapping offsets */ 132 #define SBUS_SLOT0_MAPREG 0x0 133 #define SBUS_SLOT1_MAPREG 0x1 134 #define SBUS_SLOT2_MAPREG 0x2 135 #define SBUS_SLOT3_MAPREG 0x3 136 #define ESP_MAPREG 0x80 137 #define ETHER_MAPREG 0x81 138 #define PP_MAPREG 0x82 139 #define AUDIO_MAPREG 0x83 140 #define KBDMOUSE_MAPREG 0x85 141 #define FLOPPY_MAPREG 0x86 142 #define THERMAL_MAPREG 0x87 143 #define TIMER0_MAPREG 0x8C 144 #define TIMER1_MAPREG 0x8D 145 #define UE_ECC_MAPREG 0x8E 146 #define CE_ECC_MAPREG 0x8F 147 #define SBUS_ERR_MAPREG 0x90 148 #define PM_WAKEUP_MAPREG 0x91 149 #define FFB_MAPPING_REG 0x92 150 #define EXP_MAPPING_REG 0x93 151 152 /* Interrupt clear register mapping offsets */ 153 #define SBUS_SLOT0_L1_CLEAR 0x0 154 #define SBUS_SLOT0_L2_CLEAR 0x1 155 #define SBUS_SLOT0_L3_CLEAR 0x2 156 #define SBUS_SLOT0_L4_CLEAR 0x3 157 #define SBUS_SLOT0_L5_CLEAR 0x4 158 #define SBUS_SLOT0_L6_CLEAR 0x5 159 #define SBUS_SLOT0_L7_CLEAR 0x6 160 #define SBUS_SLOT1_L1_CLEAR 0x8 161 #define SBUS_SLOT1_L2_CLEAR 0x9 162 #define SBUS_SLOT1_L3_CLEAR 0xa 163 #define SBUS_SLOT1_L4_CLEAR 0xb 164 #define SBUS_SLOT1_L5_CLEAR 0xc 165 #define SBUS_SLOT1_L6_CLEAR 0xd 166 #define SBUS_SLOT1_L7_CLEAR 0xe 167 #define SBUS_SLOT2_L1_CLEAR 0x10 168 #define SBUS_SLOT2_L2_CLEAR 0x11 169 #define SBUS_SLOT2_L3_CLEAR 0x12 170 #define SBUS_SLOT2_L4_CLEAR 0x13 171 #define SBUS_SLOT2_L5_CLEAR 0x14 172 #define SBUS_SLOT2_L6_CLEAR 0x15 173 #define SBUS_SLOT2_L7_CLEAR 0x16 174 #define SBUS_SLOT3_L1_CLEAR 0x18 175 #define SBUS_SLOT3_L2_CLEAR 0x19 176 #define SBUS_SLOT3_L3_CLEAR 0x1a 177 #define SBUS_SLOT3_L4_CLEAR 0x1b 178 #define SBUS_SLOT3_L5_CLEAR 0x1c 179 #define SBUS_SLOT3_L6_CLEAR 0x1d 180 #define SBUS_SLOT3_L7_CLEAR 0x1e 181 #define ESP_CLEAR 0x7f 182 #define ETHER_CLEAR 0x80 183 #define PP_CLEAR 0x81 184 #define AUDIO_CLEAR 0x82 185 #define KBDMOUSE_CLEAR 0x84 186 #define FLOPPY_CLEAR 0x85 187 #define THERMAL_CLEAR 0x86 188 #define TIMER0_CLEAR 0x8B 189 #define TIMER1_CLEAR 0x8C 190 #define UE_ECC_CLEAR 0x8D 191 #define CE_ECC_CLEAR 0x8E 192 #define SBUS_ERR_CLEAR 0x8F 193 #define PM_WAKEUP_CLEAR 0x90 194 195 /* 196 * Bit shift for accessing the keyboard mouse interrupt state reg. 197 * note - The external devices are the only other devices where 198 * we need to check the interrupt state before adding or removing 199 * interrupts. There is an algorithm to calculate their bit shift. 200 */ 201 #define ESP_INTR_STATE_SHIFT 0 202 #define ETHER_INTR_STATE_SHIFT 2 203 #define PP_INTR_STATE_SHIFT 4 204 #define AUDIO_INTR_STATE_SHIFT 6 205 #define KBDMOUSE_INTR_STATE_SHIFT 10 206 #define FLOPPY_INTR_STATE_SHIFT 12 207 #define THERMAL_INTR_STATE_SHIFT 14 208 #define TIMER0_INTR_STATE_SHIFT 22 209 #define TIMER1_INTR_STATE_SHIFT 24 210 #define UE_INTR_STATE_SHIFT 26 211 #define CE_INTR_STATE_SHIFT 28 212 #define SERR_INTR_STATE_SHIFT 30 213 #define PM_INTR_STATE_SHIFT 32 214 215 #define MAX_INO_TABLE_SIZE 58 /* Max num of sbus devices on sysio */ 216 #define MAX_MONDO_EXTERNAL 0x1f 217 #define SBUS_MAX_INO 0x3f 218 #define THERMAL_MONDO 0x2a 219 #define UE_ECC_MONDO 0x34 220 #define CE_ECC_MONDO 0x35 221 #define SBUS_ERR_MONDO 0x36 222 223 /* used for the picN kstats */ 224 #define SBUS_NUM_PICS 2 225 #define SBUS_NUM_EVENTS 14 226 #define SBUS_PIC0_MASK 0x00000000FFFFFFFFULL /* pic0 bits of %pic */ 227 228 /* Offsets for Performance registers */ 229 #define OFF_SBUS_PCR 0x100 230 #define OFF_SBUS_PIC 0x108 231 232 /* 233 * used to build array of event-names and pcr-mask values 234 */ 235 typedef struct sbus_event_mask { 236 char *event_name; 237 uint64_t pcr_mask; 238 } sbus_event_mask_t; 239 240 /* 241 * This type is used to describe addresses that we expect a device 242 * to place on a bus i.e. addresses from the iommu address space. 243 */ 244 typedef uint32_t ioaddr_t; 245 246 247 /* 248 * sysio sbus soft state data structure. 249 * We use the sbus_ctrl_reg to flush hardware store buffers because 250 * there is very little hardware contention on this register. 251 */ 252 struct sbus_soft_state { 253 dev_info_t *dip; /* dev info of myself */ 254 int upa_id; /* UPA ID of this SYSIO */ 255 256 /* 257 * device node address property: 258 */ 259 caddr_t address; 260 261 /* 262 * access handles in case we need to map the registers ourself: 263 */ 264 ddi_acc_handle_t ac; 265 266 volatile uint64_t *iommu_flush_reg; /* IOMMU regs */ 267 volatile uint64_t *iommu_ctrl_reg; 268 volatile uint64_t *tsb_base_addr; /* Hardware reg for phys TSB base */ 269 volatile uint64_t *soft_tsb_base_addr; /* virtual address of TSB base */ 270 volatile uint64_t *iommu_tlb_tag; 271 volatile uint64_t *iommu_tlb_data; 272 273 size_t iommu_dvma_size; 274 ioaddr_t iommu_dvma_base; 275 uint16_t iommu_tsb_cookie; 276 277 278 volatile uint64_t *sysio_ctrl_reg; /* sysio regs */ 279 volatile uint64_t *sbus_ctrl_reg; /* also used to flush store bufs */ 280 volatile uint64_t *sbus_slot_config_reg; 281 uint_t sbus_slave_burstsizes[MAX_SBUS_SLOTS]; 282 283 volatile uint64_t *intr_mapping_reg; /* Interrupt regs */ 284 volatile uint64_t *clr_intr_reg; 285 volatile uint64_t *intr_retry_reg; 286 volatile uint64_t *sbus_intr_state; 287 volatile uint64_t *obio_intr_state; 288 int8_t intr_hndlr_cnt[MAX_SBUS_SLOT_ADDR]; /* intmapreg cntr by slot */ 289 uchar_t spurious_cntrs[MAX_PIL + 1]; /* Spurious intr counter */ 290 291 volatile uint64_t *sysio_ecc_reg; /* sysio ecc control reg */ 292 volatile uint64_t *sysio_ue_reg; /* sysio ue ecc error regs */ 293 volatile uint64_t *sysio_ce_reg; /* sysio ce ecc error regs */ 294 volatile uint64_t *sbus_err_reg; /* sbus async error regs */ 295 296 volatile uint64_t *str_buf_ctrl_reg; /* streaming buffer regs */ 297 volatile uint64_t *str_buf_flush_reg; 298 volatile uint64_t *str_buf_sync_reg; 299 volatile uint64_t *str_buf_pg_tag_diag; 300 kmutex_t sync_reg_lock; /* lock around sync flush reg */ 301 int stream_buf_off; 302 303 uint_t sbus_burst_sizes; 304 uint_t sbus64_burst_sizes; 305 306 vmem_t *dvma_arena; /* DVMA arena for this IOMMU */ 307 uintptr_t dvma_call_list_id; /* DVMA callback list */ 308 kmutex_t dma_pool_lock; 309 caddr_t dmaimplbase; /* dma_pool_lock protects this */ 310 int dma_reserve; /* Size reserved for fast DVMA */ 311 312 struct sbus_wrapper_arg *intr_list[MAX_INO_TABLE_SIZE]; 313 kmutex_t intr_poll_list_lock; /* to add/rem to intr poll list */ 314 kmutex_t pokefault_mutex; /* mutex for pokefaults */ 315 on_trap_data_t *ontrap_data; /* Data used to handle poke faults */ 316 hrtime_t bto_timestamp; /* time of first timeout */ 317 int bto_ctr; /* counter for timeouts thereafter */ 318 pfn_t sbus_io_lo_pfn; 319 pfn_t sbus_io_hi_pfn; 320 struct iophyslist *sbus_io_ranges; 321 int intr_mapping_ign; /* placeholder for the IGN */ 322 #ifdef _STARFIRE 323 caddr_t ittrans_cookie; /* starfire intr target translation */ 324 #endif /* _STARFIRE */ 325 #ifdef DEBUG 326 kmutex_t iomemlock; /* Memory usage lock (debug only) */ 327 struct io_mem_list *iomem; /* Memory usage list (debug only) */ 328 #endif /* DEBUG */ 329 /* 330 * Performance registers and kstat. 331 */ 332 volatile uint64_t *sbus_pcr; /* perf counter control */ 333 volatile uint64_t *sbus_pic; /* perf counter register */ 334 kstat_t *sbus_counters_ksp; /* perf counter kstat */ 335 }; 336 337 338 /* 339 * Ugly interrupt cruft due to sysio inconsistencies. 340 */ 341 struct sbus_slot_entry { 342 uint64_t slot_config; 343 uint64_t mapping_reg; 344 uint64_t clear_reg; 345 int diagreg_shift; 346 }; 347 348 struct sbus_intr_handler { 349 dev_info_t *dip; 350 uint32_t inum; 351 uint_t (*funcp)(); 352 caddr_t arg1; 353 caddr_t arg2; 354 uint_t intr_state; 355 struct sbus_intr_handler *next; 356 }; 357 358 /* sbus Interrupt routine wrapper structure */ 359 struct sbus_wrapper_arg { 360 struct sbus_soft_state *softsp; 361 volatile uint64_t *clear_reg; 362 uint32_t pil; 363 struct sbus_intr_handler *handler_list; 364 }; 365 366 367 /* 368 * SYSIO parent private data structure contains register, interrupt, property 369 * and range information. 370 * Note: the only thing different from the "generic" sbus parent private 371 * data is the interrupt specification. 372 */ 373 struct sysio_parent_private_data { 374 int par_nreg; /* number of regs */ 375 struct regspec *par_reg; /* array of regs */ 376 int par_nintr; /* number of interrupts */ 377 struct sysiointrspec *par_intr; /* array of possible interrupts */ 378 int par_nrng; /* number of ranges */ 379 struct rangespec *par_rng; /* array of ranges */ 380 uint_t slot; /* Slot number, on this sbus */ 381 uint_t offset; /* Offset of first real "reg" */ 382 }; 383 #define SYSIO_PD(d) \ 384 ((struct sysio_parent_private_data *)DEVI((d))->devi_parent_data) 385 386 #define sysio_pd_getnreg(dev) (SYSIO_PD(dev)->par_nreg) 387 #define sysio_pd_getnintr(dev) (SYSIO_PD(dev)->par_nintr) 388 #define sysio_pd_getnrng(dev) (SYSIO_PD(dev)->par_nrng) 389 #define sysio_pd_getslot(dev) (SYSIO_PD(dev)->slot) 390 #define sysio_pd_getoffset(dev) (SYSIO_PD(dev)->offset) 391 392 #define sysio_pd_getreg(dev, n) (&SYSIO_PD(dev)->par_reg[(n)]) 393 #define sysio_pd_getintr(dev, n) (&SYSIO_PD(dev)->par_intr[(n)]) 394 #define sysio_pd_getrng(dev, n) (&SYSIO_PD(dev)->par_rng[(n)]) 395 396 #define IS_INTRA_SBUS(softsp, pfn) (pfn >= softsp->sbus_io_lo_pfn && \ 397 pfn <= softsp->sbus_io_hi_pfn) 398 399 /* Used for legacy interrupts */ 400 #define SBUS_INTR_STATE_DISABLE 0 /* disabled */ 401 #define SBUS_INTR_STATE_ENABLE 1 /* enabled */ 402 403 struct io_mem_list { 404 dev_info_t *rdip; 405 ulong_t ioaddr; 406 ulong_t addr; 407 pgcnt_t npages; 408 pfn_t *pfn; 409 struct io_mem_list *next; 410 }; 411 412 /* 413 * Function prototypes. 414 */ 415 416 417 #ifdef __cplusplus 418 } 419 #endif 420 421 #endif /* _SYS_SYSIOSBUS_H */ 422