1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010-2016 Solarflare Communications Inc. 5 * All rights reserved. 6 * 7 * This software was developed in part by Philip Paeps under contract for 8 * Solarflare Communications, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * The views and conclusions contained in the software and documentation are 32 * those of the authors and should not be interpreted as representing official 33 * policies, either expressed or implied, of the FreeBSD Project. 34 * 35 * $FreeBSD$ 36 */ 37 38 #ifndef _SYS_EFSYS_H 39 #define _SYS_EFSYS_H 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 #include <sys/param.h> 46 #include <sys/bus.h> 47 #include <sys/endian.h> 48 #include <sys/lock.h> 49 #include <sys/malloc.h> 50 #include <sys/mbuf.h> 51 #include <sys/mutex.h> 52 #include <sys/rwlock.h> 53 #include <sys/sdt.h> 54 #include <sys/systm.h> 55 56 #include <machine/bus.h> 57 #include <machine/endian.h> 58 59 #define EFSYS_HAS_UINT64 1 60 #if defined(__x86_64__) 61 #define EFSYS_USE_UINT64 1 62 #else 63 #define EFSYS_USE_UINT64 0 64 #endif 65 #define EFSYS_HAS_SSE2_M128 0 66 #if _BYTE_ORDER == _BIG_ENDIAN 67 #define EFSYS_IS_BIG_ENDIAN 1 68 #define EFSYS_IS_LITTLE_ENDIAN 0 69 #elif _BYTE_ORDER == _LITTLE_ENDIAN 70 #define EFSYS_IS_BIG_ENDIAN 0 71 #define EFSYS_IS_LITTLE_ENDIAN 1 72 #endif 73 #include "efx_types.h" 74 75 #ifndef B_FALSE 76 #define B_FALSE FALSE 77 #endif 78 #ifndef B_TRUE 79 #define B_TRUE TRUE 80 #endif 81 82 #ifndef IS2P 83 #define ISP2(x) (((x) & ((x) - 1)) == 0) 84 #endif 85 86 #if defined(__x86_64__) 87 88 #define SFXGE_USE_BUS_SPACE_8 1 89 90 #if !defined(bus_space_read_stream_8) 91 92 #define bus_space_read_stream_8(t, h, o) \ 93 bus_space_read_8((t), (h), (o)) 94 95 #define bus_space_write_stream_8(t, h, o, v) \ 96 bus_space_write_8((t), (h), (o), (v)) 97 98 #endif 99 100 #endif 101 102 #define ENOTACTIVE EINVAL 103 104 /* Memory type to use on FreeBSD */ 105 MALLOC_DECLARE(M_SFXGE); 106 107 /* Machine dependend prefetch wrappers */ 108 #if defined(__i386__) || defined(__amd64__) 109 static __inline void 110 prefetch_read_many(void *addr) 111 { 112 113 __asm__( 114 "prefetcht0 (%0)" 115 : 116 : "r" (addr)); 117 } 118 119 static __inline void 120 prefetch_read_once(void *addr) 121 { 122 123 __asm__( 124 "prefetchnta (%0)" 125 : 126 : "r" (addr)); 127 } 128 #else 129 static __inline void 130 prefetch_read_many(void *addr) 131 { 132 133 } 134 135 static __inline void 136 prefetch_read_once(void *addr) 137 { 138 139 } 140 #endif 141 142 #if defined(__i386__) || defined(__amd64__) 143 #include <vm/vm.h> 144 #include <vm/pmap.h> 145 #endif 146 static __inline void 147 sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map, 148 struct mbuf *m, bus_dma_segment_t *seg) 149 { 150 #if defined(__i386__) || defined(__amd64__) 151 seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t)); 152 seg->ds_len = m->m_len; 153 #else 154 int nsegstmp; 155 156 bus_dmamap_load_mbuf_sg(tag, map, m, seg, &nsegstmp, 0); 157 #endif 158 } 159 160 /* Code inclusion options */ 161 162 163 #define EFSYS_OPT_NAMES 1 164 165 #define EFSYS_OPT_SIENA 1 166 #define EFSYS_OPT_HUNTINGTON 1 167 #define EFSYS_OPT_MEDFORD 1 168 #define EFSYS_OPT_MEDFORD2 1 169 #ifdef DEBUG 170 #define EFSYS_OPT_CHECK_REG 1 171 #else 172 #define EFSYS_OPT_CHECK_REG 0 173 #endif 174 175 #define EFSYS_OPT_MCDI 1 176 #define EFSYS_OPT_MCDI_LOGGING 0 177 #define EFSYS_OPT_MCDI_PROXY_AUTH 0 178 179 #define EFSYS_OPT_MAC_STATS 1 180 181 #define EFSYS_OPT_LOOPBACK 0 182 183 #define EFSYS_OPT_MON_MCDI 0 184 #define EFSYS_OPT_MON_STATS 0 185 186 #define EFSYS_OPT_PHY_STATS 1 187 #define EFSYS_OPT_BIST 1 188 #define EFSYS_OPT_PHY_LED_CONTROL 1 189 #define EFSYS_OPT_PHY_FLAGS 0 190 191 #define EFSYS_OPT_VPD 1 192 #define EFSYS_OPT_NVRAM 1 193 #define EFSYS_OPT_BOOTCFG 0 194 #define EFSYS_OPT_IMAGE_LAYOUT 0 195 196 #define EFSYS_OPT_DIAG 0 197 #define EFSYS_OPT_RX_SCALE 1 198 #define EFSYS_OPT_QSTATS 1 199 #define EFSYS_OPT_FILTER 1 200 #define EFSYS_OPT_RX_SCATTER 0 201 202 #define EFSYS_OPT_EV_PREFETCH 0 203 204 #define EFSYS_OPT_DECODE_INTR_FATAL 1 205 206 #define EFSYS_OPT_LICENSING 0 207 208 #define EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0 209 210 #define EFSYS_OPT_RX_PACKED_STREAM 0 211 212 #define EFSYS_OPT_RX_ES_SUPER_BUFFER 0 213 214 #define EFSYS_OPT_TUNNEL 0 215 216 #define EFSYS_OPT_FW_SUBVARIANT_AWARE 0 217 218 /* ID */ 219 220 typedef struct __efsys_identifier_s efsys_identifier_t; 221 222 /* PROBE */ 223 224 #ifndef DTRACE_PROBE 225 226 #define EFSYS_PROBE(_name) 227 228 #define EFSYS_PROBE1(_name, _type1, _arg1) 229 230 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) 231 232 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 233 _type3, _arg3) 234 235 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 236 _type3, _arg3, _type4, _arg4) 237 238 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 239 _type3, _arg3, _type4, _arg4, _type5, _arg5) 240 241 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 242 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 243 _type6, _arg6) 244 245 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 246 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 247 _type6, _arg6, _type7, _arg7) 248 249 #else /* DTRACE_PROBE */ 250 251 #define EFSYS_PROBE(_name) \ 252 DTRACE_PROBE(_name) 253 254 #define EFSYS_PROBE1(_name, _type1, _arg1) \ 255 DTRACE_PROBE1(_name, _type1, _arg1) 256 257 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \ 258 DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2) 259 260 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 261 _type3, _arg3) \ 262 DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 263 _type3, _arg3) 264 265 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 266 _type3, _arg3, _type4, _arg4) \ 267 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 268 _type3, _arg3, _type4, _arg4) 269 270 #ifdef DTRACE_PROBE5 271 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 272 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 273 DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 274 _type3, _arg3, _type4, _arg4, _type5, _arg5) 275 #else 276 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 277 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 278 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 279 _type3, _arg3, _type4, _arg4) 280 #endif 281 282 #ifdef DTRACE_PROBE6 283 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 284 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 285 _type6, _arg6) \ 286 DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 287 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 288 _type6, _arg6) 289 #else 290 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 291 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 292 _type6, _arg6) \ 293 EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 294 _type3, _arg3, _type4, _arg4, _type5, _arg5) 295 #endif 296 297 #ifdef DTRACE_PROBE7 298 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 299 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 300 _type6, _arg6, _type7, _arg7) \ 301 DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 302 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 303 _type6, _arg6, _type7, _arg7) 304 #else 305 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 306 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 307 _type6, _arg6, _type7, _arg7) \ 308 EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 309 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 310 _type6, _arg6) 311 #endif 312 313 #endif /* DTRACE_PROBE */ 314 315 /* DMA */ 316 317 typedef uint64_t efsys_dma_addr_t; 318 319 typedef struct efsys_mem_s { 320 bus_dma_tag_t esm_tag; 321 bus_dmamap_t esm_map; 322 caddr_t esm_base; 323 efsys_dma_addr_t esm_addr; 324 size_t esm_size; 325 } efsys_mem_t; 326 327 #define EFSYS_MEM_SIZE(_esmp) \ 328 ((_esmp)->esm_size) 329 330 #define EFSYS_MEM_ADDR(_esmp) \ 331 ((_esmp)->esm_addr) 332 333 #define EFSYS_MEM_IS_NULL(_esmp) \ 334 ((_esmp)->esm_base == NULL) 335 336 337 #define EFSYS_MEM_ZERO(_esmp, _size) \ 338 do { \ 339 (void) memset((_esmp)->esm_base, 0, (_size)); \ 340 \ 341 _NOTE(CONSTANTCONDITION) \ 342 } while (B_FALSE) 343 344 #define EFSYS_MEM_READD(_esmp, _offset, _edp) \ 345 do { \ 346 uint32_t *addr; \ 347 \ 348 _NOTE(CONSTANTCONDITION) \ 349 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 350 sizeof (efx_dword_t)), \ 351 ("not power of 2 aligned")); \ 352 \ 353 addr = (void *)((_esmp)->esm_base + (_offset)); \ 354 \ 355 (_edp)->ed_u32[0] = *addr; \ 356 \ 357 EFSYS_PROBE2(mem_readd, unsigned int, (_offset), \ 358 uint32_t, (_edp)->ed_u32[0]); \ 359 \ 360 _NOTE(CONSTANTCONDITION) \ 361 } while (B_FALSE) 362 363 #if defined(__x86_64__) 364 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ 365 do { \ 366 uint64_t *addr; \ 367 \ 368 _NOTE(CONSTANTCONDITION) \ 369 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 370 sizeof (efx_qword_t)), \ 371 ("not power of 2 aligned")); \ 372 \ 373 addr = (void *)((_esmp)->esm_base + (_offset)); \ 374 \ 375 (_eqp)->eq_u64[0] = *addr; \ 376 \ 377 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ 378 uint32_t, (_eqp)->eq_u32[1], \ 379 uint32_t, (_eqp)->eq_u32[0]); \ 380 \ 381 _NOTE(CONSTANTCONDITION) \ 382 } while (B_FALSE) 383 #else 384 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ 385 do { \ 386 uint32_t *addr; \ 387 \ 388 _NOTE(CONSTANTCONDITION) \ 389 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 390 sizeof (efx_qword_t)), \ 391 ("not power of 2 aligned")); \ 392 \ 393 addr = (void *)((_esmp)->esm_base + (_offset)); \ 394 \ 395 (_eqp)->eq_u32[0] = *addr++; \ 396 (_eqp)->eq_u32[1] = *addr; \ 397 \ 398 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ 399 uint32_t, (_eqp)->eq_u32[1], \ 400 uint32_t, (_eqp)->eq_u32[0]); \ 401 \ 402 _NOTE(CONSTANTCONDITION) \ 403 } while (B_FALSE) 404 #endif 405 406 #if defined(__x86_64__) 407 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \ 408 do { \ 409 uint64_t *addr; \ 410 \ 411 _NOTE(CONSTANTCONDITION) \ 412 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 413 sizeof (efx_oword_t)), \ 414 ("not power of 2 aligned")); \ 415 \ 416 addr = (void *)((_esmp)->esm_base + (_offset)); \ 417 \ 418 (_eop)->eo_u64[0] = *addr++; \ 419 (_eop)->eo_u64[1] = *addr; \ 420 \ 421 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ 422 uint32_t, (_eop)->eo_u32[3], \ 423 uint32_t, (_eop)->eo_u32[2], \ 424 uint32_t, (_eop)->eo_u32[1], \ 425 uint32_t, (_eop)->eo_u32[0]); \ 426 \ 427 _NOTE(CONSTANTCONDITION) \ 428 } while (B_FALSE) 429 #else 430 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \ 431 do { \ 432 uint32_t *addr; \ 433 \ 434 _NOTE(CONSTANTCONDITION) \ 435 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 436 sizeof (efx_oword_t)), \ 437 ("not power of 2 aligned")); \ 438 \ 439 addr = (void *)((_esmp)->esm_base + (_offset)); \ 440 \ 441 (_eop)->eo_u32[0] = *addr++; \ 442 (_eop)->eo_u32[1] = *addr++; \ 443 (_eop)->eo_u32[2] = *addr++; \ 444 (_eop)->eo_u32[3] = *addr; \ 445 \ 446 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ 447 uint32_t, (_eop)->eo_u32[3], \ 448 uint32_t, (_eop)->eo_u32[2], \ 449 uint32_t, (_eop)->eo_u32[1], \ 450 uint32_t, (_eop)->eo_u32[0]); \ 451 \ 452 _NOTE(CONSTANTCONDITION) \ 453 } while (B_FALSE) 454 #endif 455 456 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \ 457 do { \ 458 uint32_t *addr; \ 459 \ 460 _NOTE(CONSTANTCONDITION) \ 461 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 462 sizeof (efx_dword_t)), \ 463 ("not power of 2 aligned")); \ 464 \ 465 EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \ 466 uint32_t, (_edp)->ed_u32[0]); \ 467 \ 468 addr = (void *)((_esmp)->esm_base + (_offset)); \ 469 \ 470 *addr = (_edp)->ed_u32[0]; \ 471 \ 472 _NOTE(CONSTANTCONDITION) \ 473 } while (B_FALSE) 474 475 #if defined(__x86_64__) 476 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ 477 do { \ 478 uint64_t *addr; \ 479 \ 480 _NOTE(CONSTANTCONDITION) \ 481 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 482 sizeof (efx_qword_t)), \ 483 ("not power of 2 aligned")); \ 484 \ 485 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ 486 uint32_t, (_eqp)->eq_u32[1], \ 487 uint32_t, (_eqp)->eq_u32[0]); \ 488 \ 489 addr = (void *)((_esmp)->esm_base + (_offset)); \ 490 \ 491 *addr = (_eqp)->eq_u64[0]; \ 492 \ 493 _NOTE(CONSTANTCONDITION) \ 494 } while (B_FALSE) 495 496 #else 497 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ 498 do { \ 499 uint32_t *addr; \ 500 \ 501 _NOTE(CONSTANTCONDITION) \ 502 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 503 sizeof (efx_qword_t)), \ 504 ("not power of 2 aligned")); \ 505 \ 506 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ 507 uint32_t, (_eqp)->eq_u32[1], \ 508 uint32_t, (_eqp)->eq_u32[0]); \ 509 \ 510 addr = (void *)((_esmp)->esm_base + (_offset)); \ 511 \ 512 *addr++ = (_eqp)->eq_u32[0]; \ 513 *addr = (_eqp)->eq_u32[1]; \ 514 \ 515 _NOTE(CONSTANTCONDITION) \ 516 } while (B_FALSE) 517 #endif 518 519 #if defined(__x86_64__) 520 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ 521 do { \ 522 uint64_t *addr; \ 523 \ 524 _NOTE(CONSTANTCONDITION) \ 525 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 526 sizeof (efx_oword_t)), \ 527 ("not power of 2 aligned")); \ 528 \ 529 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ 530 uint32_t, (_eop)->eo_u32[3], \ 531 uint32_t, (_eop)->eo_u32[2], \ 532 uint32_t, (_eop)->eo_u32[1], \ 533 uint32_t, (_eop)->eo_u32[0]); \ 534 \ 535 addr = (void *)((_esmp)->esm_base + (_offset)); \ 536 \ 537 *addr++ = (_eop)->eo_u64[0]; \ 538 *addr = (_eop)->eo_u64[1]; \ 539 \ 540 _NOTE(CONSTANTCONDITION) \ 541 } while (B_FALSE) 542 #else 543 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ 544 do { \ 545 uint32_t *addr; \ 546 \ 547 _NOTE(CONSTANTCONDITION) \ 548 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 549 sizeof (efx_oword_t)), \ 550 ("not power of 2 aligned")); \ 551 \ 552 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ 553 uint32_t, (_eop)->eo_u32[3], \ 554 uint32_t, (_eop)->eo_u32[2], \ 555 uint32_t, (_eop)->eo_u32[1], \ 556 uint32_t, (_eop)->eo_u32[0]); \ 557 \ 558 addr = (void *)((_esmp)->esm_base + (_offset)); \ 559 \ 560 *addr++ = (_eop)->eo_u32[0]; \ 561 *addr++ = (_eop)->eo_u32[1]; \ 562 *addr++ = (_eop)->eo_u32[2]; \ 563 *addr = (_eop)->eo_u32[3]; \ 564 \ 565 _NOTE(CONSTANTCONDITION) \ 566 } while (B_FALSE) 567 #endif 568 569 /* BAR */ 570 571 #define SFXGE_LOCK_NAME_MAX 16 572 573 typedef struct efsys_bar_s { 574 struct mtx esb_lock; 575 char esb_lock_name[SFXGE_LOCK_NAME_MAX]; 576 bus_space_tag_t esb_tag; 577 bus_space_handle_t esb_handle; 578 int esb_rid; 579 struct resource *esb_res; 580 } efsys_bar_t; 581 582 #define SFXGE_BAR_LOCK_INIT(_esbp, _ifname) \ 583 do { \ 584 snprintf((_esbp)->esb_lock_name, \ 585 sizeof((_esbp)->esb_lock_name), \ 586 "%s:bar", (_ifname)); \ 587 mtx_init(&(_esbp)->esb_lock, (_esbp)->esb_lock_name, \ 588 NULL, MTX_DEF); \ 589 _NOTE(CONSTANTCONDITION) \ 590 } while (B_FALSE) 591 #define SFXGE_BAR_LOCK_DESTROY(_esbp) \ 592 mtx_destroy(&(_esbp)->esb_lock) 593 #define SFXGE_BAR_LOCK(_esbp) \ 594 mtx_lock(&(_esbp)->esb_lock) 595 #define SFXGE_BAR_UNLOCK(_esbp) \ 596 mtx_unlock(&(_esbp)->esb_lock) 597 598 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \ 599 do { \ 600 _NOTE(CONSTANTCONDITION) \ 601 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 602 sizeof (efx_dword_t)), \ 603 ("not power of 2 aligned")); \ 604 \ 605 _NOTE(CONSTANTCONDITION) \ 606 if (_lock) \ 607 SFXGE_BAR_LOCK(_esbp); \ 608 \ 609 (_edp)->ed_u32[0] = bus_space_read_stream_4( \ 610 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 611 (_offset)); \ 612 \ 613 EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \ 614 uint32_t, (_edp)->ed_u32[0]); \ 615 \ 616 _NOTE(CONSTANTCONDITION) \ 617 if (_lock) \ 618 SFXGE_BAR_UNLOCK(_esbp); \ 619 _NOTE(CONSTANTCONDITION) \ 620 } while (B_FALSE) 621 622 #if defined(SFXGE_USE_BUS_SPACE_8) 623 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ 624 do { \ 625 _NOTE(CONSTANTCONDITION) \ 626 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 627 sizeof (efx_qword_t)), \ 628 ("not power of 2 aligned")); \ 629 \ 630 SFXGE_BAR_LOCK(_esbp); \ 631 \ 632 (_eqp)->eq_u64[0] = bus_space_read_stream_8( \ 633 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 634 (_offset)); \ 635 \ 636 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ 637 uint32_t, (_eqp)->eq_u32[1], \ 638 uint32_t, (_eqp)->eq_u32[0]); \ 639 \ 640 SFXGE_BAR_UNLOCK(_esbp); \ 641 _NOTE(CONSTANTCONDITION) \ 642 } while (B_FALSE) 643 644 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ 645 do { \ 646 _NOTE(CONSTANTCONDITION) \ 647 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 648 sizeof (efx_oword_t)), \ 649 ("not power of 2 aligned")); \ 650 \ 651 _NOTE(CONSTANTCONDITION) \ 652 if (_lock) \ 653 SFXGE_BAR_LOCK(_esbp); \ 654 \ 655 (_eop)->eo_u64[0] = bus_space_read_stream_8( \ 656 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 657 (_offset)); \ 658 (_eop)->eo_u64[1] = bus_space_read_stream_8( \ 659 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 660 (_offset) + 8); \ 661 \ 662 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ 663 uint32_t, (_eop)->eo_u32[3], \ 664 uint32_t, (_eop)->eo_u32[2], \ 665 uint32_t, (_eop)->eo_u32[1], \ 666 uint32_t, (_eop)->eo_u32[0]); \ 667 \ 668 _NOTE(CONSTANTCONDITION) \ 669 if (_lock) \ 670 SFXGE_BAR_UNLOCK(_esbp); \ 671 _NOTE(CONSTANTCONDITION) \ 672 } while (B_FALSE) 673 674 #else 675 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ 676 do { \ 677 _NOTE(CONSTANTCONDITION) \ 678 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 679 sizeof (efx_qword_t)), \ 680 ("not power of 2 aligned")); \ 681 \ 682 SFXGE_BAR_LOCK(_esbp); \ 683 \ 684 (_eqp)->eq_u32[0] = bus_space_read_stream_4( \ 685 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 686 (_offset)); \ 687 (_eqp)->eq_u32[1] = bus_space_read_stream_4( \ 688 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 689 (_offset) + 4); \ 690 \ 691 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ 692 uint32_t, (_eqp)->eq_u32[1], \ 693 uint32_t, (_eqp)->eq_u32[0]); \ 694 \ 695 SFXGE_BAR_UNLOCK(_esbp); \ 696 _NOTE(CONSTANTCONDITION) \ 697 } while (B_FALSE) 698 699 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ 700 do { \ 701 _NOTE(CONSTANTCONDITION) \ 702 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 703 sizeof (efx_oword_t)), \ 704 ("not power of 2 aligned")); \ 705 \ 706 _NOTE(CONSTANTCONDITION) \ 707 if (_lock) \ 708 SFXGE_BAR_LOCK(_esbp); \ 709 \ 710 (_eop)->eo_u32[0] = bus_space_read_stream_4( \ 711 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 712 (_offset)); \ 713 (_eop)->eo_u32[1] = bus_space_read_stream_4( \ 714 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 715 (_offset) + 4); \ 716 (_eop)->eo_u32[2] = bus_space_read_stream_4( \ 717 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 718 (_offset) + 8); \ 719 (_eop)->eo_u32[3] = bus_space_read_stream_4( \ 720 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 721 (_offset) + 12); \ 722 \ 723 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ 724 uint32_t, (_eop)->eo_u32[3], \ 725 uint32_t, (_eop)->eo_u32[2], \ 726 uint32_t, (_eop)->eo_u32[1], \ 727 uint32_t, (_eop)->eo_u32[0]); \ 728 \ 729 _NOTE(CONSTANTCONDITION) \ 730 if (_lock) \ 731 SFXGE_BAR_UNLOCK(_esbp); \ 732 _NOTE(CONSTANTCONDITION) \ 733 } while (B_FALSE) 734 #endif 735 736 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \ 737 do { \ 738 _NOTE(CONSTANTCONDITION) \ 739 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 740 sizeof (efx_dword_t)), \ 741 ("not power of 2 aligned")); \ 742 \ 743 _NOTE(CONSTANTCONDITION) \ 744 if (_lock) \ 745 SFXGE_BAR_LOCK(_esbp); \ 746 \ 747 EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \ 748 uint32_t, (_edp)->ed_u32[0]); \ 749 \ 750 /* \ 751 * Make sure that previous writes to the dword have \ 752 * been done. It should be cheaper than barrier just \ 753 * after the write below. \ 754 */ \ 755 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 756 (_offset), sizeof (efx_dword_t), \ 757 BUS_SPACE_BARRIER_WRITE); \ 758 bus_space_write_stream_4((_esbp)->esb_tag, \ 759 (_esbp)->esb_handle, \ 760 (_offset), (_edp)->ed_u32[0]); \ 761 \ 762 _NOTE(CONSTANTCONDITION) \ 763 if (_lock) \ 764 SFXGE_BAR_UNLOCK(_esbp); \ 765 _NOTE(CONSTANTCONDITION) \ 766 } while (B_FALSE) 767 768 #if defined(SFXGE_USE_BUS_SPACE_8) 769 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ 770 do { \ 771 _NOTE(CONSTANTCONDITION) \ 772 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 773 sizeof (efx_qword_t)), \ 774 ("not power of 2 aligned")); \ 775 \ 776 SFXGE_BAR_LOCK(_esbp); \ 777 \ 778 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ 779 uint32_t, (_eqp)->eq_u32[1], \ 780 uint32_t, (_eqp)->eq_u32[0]); \ 781 \ 782 /* \ 783 * Make sure that previous writes to the qword have \ 784 * been done. It should be cheaper than barrier just \ 785 * after the write below. \ 786 */ \ 787 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 788 (_offset), sizeof (efx_qword_t), \ 789 BUS_SPACE_BARRIER_WRITE); \ 790 bus_space_write_stream_8((_esbp)->esb_tag, \ 791 (_esbp)->esb_handle, \ 792 (_offset), (_eqp)->eq_u64[0]); \ 793 \ 794 SFXGE_BAR_UNLOCK(_esbp); \ 795 _NOTE(CONSTANTCONDITION) \ 796 } while (B_FALSE) 797 #else 798 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ 799 do { \ 800 _NOTE(CONSTANTCONDITION) \ 801 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 802 sizeof (efx_qword_t)), \ 803 ("not power of 2 aligned")); \ 804 \ 805 SFXGE_BAR_LOCK(_esbp); \ 806 \ 807 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ 808 uint32_t, (_eqp)->eq_u32[1], \ 809 uint32_t, (_eqp)->eq_u32[0]); \ 810 \ 811 /* \ 812 * Make sure that previous writes to the qword have \ 813 * been done. It should be cheaper than barrier just \ 814 * after the last write below. \ 815 */ \ 816 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 817 (_offset), sizeof (efx_qword_t), \ 818 BUS_SPACE_BARRIER_WRITE); \ 819 bus_space_write_stream_4((_esbp)->esb_tag, \ 820 (_esbp)->esb_handle, \ 821 (_offset), (_eqp)->eq_u32[0]); \ 822 /* \ 823 * It should be guaranteed that the last dword comes \ 824 * the last, so barrier entire qword to be sure that \ 825 * neither above nor below writes are reordered. \ 826 */ \ 827 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 828 (_offset), sizeof (efx_qword_t), \ 829 BUS_SPACE_BARRIER_WRITE); \ 830 bus_space_write_stream_4((_esbp)->esb_tag, \ 831 (_esbp)->esb_handle, \ 832 (_offset) + 4, (_eqp)->eq_u32[1]); \ 833 \ 834 SFXGE_BAR_UNLOCK(_esbp); \ 835 _NOTE(CONSTANTCONDITION) \ 836 } while (B_FALSE) 837 #endif 838 839 /* 840 * Guarantees 64bit aligned 64bit writes to write combined BAR mapping 841 * (required by PIO hardware) 842 */ 843 #define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp) \ 844 do { \ 845 _NOTE(CONSTANTCONDITION) \ 846 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 847 sizeof (efx_qword_t)), \ 848 ("not power of 2 aligned")); \ 849 \ 850 (void) (_esbp); \ 851 \ 852 /* FIXME: Perform a 64-bit write */ \ 853 KASSERT(0, ("not implemented")); \ 854 \ 855 _NOTE(CONSTANTCONDITION) \ 856 } while (B_FALSE) 857 858 #if defined(SFXGE_USE_BUS_SPACE_8) 859 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ 860 do { \ 861 _NOTE(CONSTANTCONDITION) \ 862 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 863 sizeof (efx_oword_t)), \ 864 ("not power of 2 aligned")); \ 865 \ 866 _NOTE(CONSTANTCONDITION) \ 867 if (_lock) \ 868 SFXGE_BAR_LOCK(_esbp); \ 869 \ 870 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ 871 uint32_t, (_eop)->eo_u32[3], \ 872 uint32_t, (_eop)->eo_u32[2], \ 873 uint32_t, (_eop)->eo_u32[1], \ 874 uint32_t, (_eop)->eo_u32[0]); \ 875 \ 876 /* \ 877 * Make sure that previous writes to the oword have \ 878 * been done. It should be cheaper than barrier just \ 879 * after the last write below. \ 880 */ \ 881 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 882 (_offset), sizeof (efx_oword_t), \ 883 BUS_SPACE_BARRIER_WRITE); \ 884 bus_space_write_stream_8((_esbp)->esb_tag, \ 885 (_esbp)->esb_handle, \ 886 (_offset), (_eop)->eo_u64[0]); \ 887 /* \ 888 * It should be guaranteed that the last qword comes \ 889 * the last, so barrier entire oword to be sure that \ 890 * neither above nor below writes are reordered. \ 891 */ \ 892 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 893 (_offset), sizeof (efx_oword_t), \ 894 BUS_SPACE_BARRIER_WRITE); \ 895 bus_space_write_stream_8((_esbp)->esb_tag, \ 896 (_esbp)->esb_handle, \ 897 (_offset) + 8, (_eop)->eo_u64[1]); \ 898 \ 899 _NOTE(CONSTANTCONDITION) \ 900 if (_lock) \ 901 SFXGE_BAR_UNLOCK(_esbp); \ 902 _NOTE(CONSTANTCONDITION) \ 903 } while (B_FALSE) 904 905 #else 906 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ 907 do { \ 908 _NOTE(CONSTANTCONDITION) \ 909 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 910 sizeof (efx_oword_t)), \ 911 ("not power of 2 aligned")); \ 912 \ 913 _NOTE(CONSTANTCONDITION) \ 914 if (_lock) \ 915 SFXGE_BAR_LOCK(_esbp); \ 916 \ 917 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ 918 uint32_t, (_eop)->eo_u32[3], \ 919 uint32_t, (_eop)->eo_u32[2], \ 920 uint32_t, (_eop)->eo_u32[1], \ 921 uint32_t, (_eop)->eo_u32[0]); \ 922 \ 923 /* \ 924 * Make sure that previous writes to the oword have \ 925 * been done. It should be cheaper than barrier just \ 926 * after the last write below. \ 927 */ \ 928 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 929 (_offset), sizeof (efx_oword_t), \ 930 BUS_SPACE_BARRIER_WRITE); \ 931 bus_space_write_stream_4((_esbp)->esb_tag, \ 932 (_esbp)->esb_handle, \ 933 (_offset), (_eop)->eo_u32[0]); \ 934 bus_space_write_stream_4((_esbp)->esb_tag, \ 935 (_esbp)->esb_handle, \ 936 (_offset) + 4, (_eop)->eo_u32[1]); \ 937 bus_space_write_stream_4((_esbp)->esb_tag, \ 938 (_esbp)->esb_handle, \ 939 (_offset) + 8, (_eop)->eo_u32[2]); \ 940 /* \ 941 * It should be guaranteed that the last dword comes \ 942 * the last, so barrier entire oword to be sure that \ 943 * neither above nor below writes are reordered. \ 944 */ \ 945 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 946 (_offset), sizeof (efx_oword_t), \ 947 BUS_SPACE_BARRIER_WRITE); \ 948 bus_space_write_stream_4((_esbp)->esb_tag, \ 949 (_esbp)->esb_handle, \ 950 (_offset) + 12, (_eop)->eo_u32[3]); \ 951 \ 952 _NOTE(CONSTANTCONDITION) \ 953 if (_lock) \ 954 SFXGE_BAR_UNLOCK(_esbp); \ 955 _NOTE(CONSTANTCONDITION) \ 956 } while (B_FALSE) 957 #endif 958 959 /* Use the standard octo-word write for doorbell writes */ 960 #define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop) \ 961 do { \ 962 EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE); \ 963 _NOTE(CONSTANTCONDITION) \ 964 } while (B_FALSE) 965 966 /* SPIN */ 967 968 #define EFSYS_SPIN(_us) \ 969 do { \ 970 DELAY(_us); \ 971 _NOTE(CONSTANTCONDITION) \ 972 } while (B_FALSE) 973 974 #define EFSYS_SLEEP EFSYS_SPIN 975 976 /* BARRIERS */ 977 978 #define EFSYS_MEM_READ_BARRIER() rmb() 979 #define EFSYS_PIO_WRITE_BARRIER() 980 981 /* DMA SYNC */ 982 #define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size) \ 983 do { \ 984 bus_dmamap_sync((_esmp)->esm_tag, \ 985 (_esmp)->esm_map, \ 986 BUS_DMASYNC_POSTREAD); \ 987 _NOTE(CONSTANTCONDITION) \ 988 } while (B_FALSE) 989 990 #define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size) \ 991 do { \ 992 bus_dmamap_sync((_esmp)->esm_tag, \ 993 (_esmp)->esm_map, \ 994 BUS_DMASYNC_PREWRITE); \ 995 _NOTE(CONSTANTCONDITION) \ 996 } while (B_FALSE) 997 998 /* TIMESTAMP */ 999 1000 typedef clock_t efsys_timestamp_t; 1001 1002 #define EFSYS_TIMESTAMP(_usp) \ 1003 do { \ 1004 clock_t now; \ 1005 \ 1006 now = ticks; \ 1007 *(_usp) = now * hz / 1000000; \ 1008 _NOTE(CONSTANTCONDITION) \ 1009 } while (B_FALSE) 1010 1011 /* KMEM */ 1012 1013 #define EFSYS_KMEM_ALLOC(_esip, _size, _p) \ 1014 do { \ 1015 (_esip) = (_esip); \ 1016 /* \ 1017 * The macro is used in non-sleepable contexts, for \ 1018 * example, holding a mutex. \ 1019 */ \ 1020 (_p) = malloc((_size), M_SFXGE, M_NOWAIT|M_ZERO); \ 1021 _NOTE(CONSTANTCONDITION) \ 1022 } while (B_FALSE) 1023 1024 #define EFSYS_KMEM_FREE(_esip, _size, _p) \ 1025 do { \ 1026 (void) (_esip); \ 1027 (void) (_size); \ 1028 free((_p), M_SFXGE); \ 1029 _NOTE(CONSTANTCONDITION) \ 1030 } while (B_FALSE) 1031 1032 /* LOCK */ 1033 1034 typedef struct efsys_lock_s { 1035 struct mtx lock; 1036 char lock_name[SFXGE_LOCK_NAME_MAX]; 1037 } efsys_lock_t; 1038 1039 #define SFXGE_EFSYS_LOCK_INIT(_eslp, _ifname, _label) \ 1040 do { \ 1041 efsys_lock_t *__eslp = (_eslp); \ 1042 \ 1043 snprintf((__eslp)->lock_name, \ 1044 sizeof((__eslp)->lock_name), \ 1045 "%s:%s", (_ifname), (_label)); \ 1046 mtx_init(&(__eslp)->lock, (__eslp)->lock_name, \ 1047 NULL, MTX_DEF); \ 1048 } while (B_FALSE) 1049 #define SFXGE_EFSYS_LOCK_DESTROY(_eslp) \ 1050 mtx_destroy(&(_eslp)->lock) 1051 #define SFXGE_EFSYS_LOCK(_eslp) \ 1052 mtx_lock(&(_eslp)->lock) 1053 #define SFXGE_EFSYS_UNLOCK(_eslp) \ 1054 mtx_unlock(&(_eslp)->lock) 1055 #define SFXGE_EFSYS_LOCK_ASSERT_OWNED(_eslp) \ 1056 mtx_assert(&(_eslp)->lock, MA_OWNED) 1057 1058 typedef int efsys_lock_state_t; 1059 1060 #define EFSYS_LOCK_MAGIC 0x000010c4 1061 1062 #define EFSYS_LOCK(_lockp, _state) \ 1063 do { \ 1064 SFXGE_EFSYS_LOCK(_lockp); \ 1065 (_state) = EFSYS_LOCK_MAGIC; \ 1066 _NOTE(CONSTANTCONDITION) \ 1067 } while (B_FALSE) 1068 1069 #define EFSYS_UNLOCK(_lockp, _state) \ 1070 do { \ 1071 if ((_state) != EFSYS_LOCK_MAGIC) \ 1072 KASSERT(B_FALSE, ("not locked")); \ 1073 SFXGE_EFSYS_UNLOCK(_lockp); \ 1074 _NOTE(CONSTANTCONDITION) \ 1075 } while (B_FALSE) 1076 1077 /* STAT */ 1078 1079 typedef uint64_t efsys_stat_t; 1080 1081 #define EFSYS_STAT_INCR(_knp, _delta) \ 1082 do { \ 1083 *(_knp) += (_delta); \ 1084 _NOTE(CONSTANTCONDITION) \ 1085 } while (B_FALSE) 1086 1087 #define EFSYS_STAT_DECR(_knp, _delta) \ 1088 do { \ 1089 *(_knp) -= (_delta); \ 1090 _NOTE(CONSTANTCONDITION) \ 1091 } while (B_FALSE) 1092 1093 #define EFSYS_STAT_SET(_knp, _val) \ 1094 do { \ 1095 *(_knp) = (_val); \ 1096 _NOTE(CONSTANTCONDITION) \ 1097 } while (B_FALSE) 1098 1099 #define EFSYS_STAT_SET_QWORD(_knp, _valp) \ 1100 do { \ 1101 *(_knp) = le64toh((_valp)->eq_u64[0]); \ 1102 _NOTE(CONSTANTCONDITION) \ 1103 } while (B_FALSE) 1104 1105 #define EFSYS_STAT_SET_DWORD(_knp, _valp) \ 1106 do { \ 1107 *(_knp) = le32toh((_valp)->ed_u32[0]); \ 1108 _NOTE(CONSTANTCONDITION) \ 1109 } while (B_FALSE) 1110 1111 #define EFSYS_STAT_INCR_QWORD(_knp, _valp) \ 1112 do { \ 1113 *(_knp) += le64toh((_valp)->eq_u64[0]); \ 1114 _NOTE(CONSTANTCONDITION) \ 1115 } while (B_FALSE) 1116 1117 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \ 1118 do { \ 1119 *(_knp) -= le64toh((_valp)->eq_u64[0]); \ 1120 _NOTE(CONSTANTCONDITION) \ 1121 } while (B_FALSE) 1122 1123 /* ERR */ 1124 1125 extern void sfxge_err(efsys_identifier_t *, unsigned int, 1126 uint32_t, uint32_t); 1127 1128 #if EFSYS_OPT_DECODE_INTR_FATAL 1129 #define EFSYS_ERR(_esip, _code, _dword0, _dword1) \ 1130 do { \ 1131 sfxge_err((_esip), (_code), (_dword0), (_dword1)); \ 1132 _NOTE(CONSTANTCONDITION) \ 1133 } while (B_FALSE) 1134 #endif 1135 1136 /* ASSERT */ 1137 1138 #define EFSYS_ASSERT(_exp) do { \ 1139 if (!(_exp)) \ 1140 panic("%s", #_exp); \ 1141 } while (0) 1142 1143 #define EFSYS_ASSERT3(_x, _op, _y, _t) do { \ 1144 const _t __x = (_t)(_x); \ 1145 const _t __y = (_t)(_y); \ 1146 if (!(__x _op __y)) \ 1147 panic("assertion failed at %s:%u", __FILE__, __LINE__); \ 1148 } while(0) 1149 1150 #define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t) 1151 #define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t) 1152 #define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t) 1153 1154 /* ROTATE */ 1155 1156 #define EFSYS_HAS_ROTL_DWORD 0 1157 1158 #ifdef __cplusplus 1159 } 1160 #endif 1161 1162 #endif /* _SYS_EFSYS_H */ 1163