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 #define EFSYS_OPT_NAMES 1 163 164 #define EFSYS_OPT_SIENA 1 165 #define EFSYS_OPT_HUNTINGTON 1 166 #define EFSYS_OPT_MEDFORD 1 167 #define EFSYS_OPT_MEDFORD2 1 168 #ifdef DEBUG 169 #define EFSYS_OPT_CHECK_REG 1 170 #else 171 #define EFSYS_OPT_CHECK_REG 0 172 #endif 173 174 #define EFSYS_OPT_MCDI 1 175 #define EFSYS_OPT_MCDI_LOGGING 0 176 #define EFSYS_OPT_MCDI_PROXY_AUTH 0 177 178 #define EFSYS_OPT_MAC_STATS 1 179 180 #define EFSYS_OPT_LOOPBACK 0 181 182 #define EFSYS_OPT_MON_MCDI 0 183 #define EFSYS_OPT_MON_STATS 0 184 185 #define EFSYS_OPT_PHY_STATS 1 186 #define EFSYS_OPT_BIST 1 187 #define EFSYS_OPT_PHY_LED_CONTROL 1 188 #define EFSYS_OPT_PHY_FLAGS 0 189 190 #define EFSYS_OPT_VPD 1 191 #define EFSYS_OPT_NVRAM 1 192 #define EFSYS_OPT_BOOTCFG 0 193 #define EFSYS_OPT_IMAGE_LAYOUT 0 194 195 #define EFSYS_OPT_DIAG 0 196 #define EFSYS_OPT_RX_SCALE 1 197 #define EFSYS_OPT_QSTATS 1 198 #define EFSYS_OPT_FILTER 1 199 #define EFSYS_OPT_RX_SCATTER 0 200 201 #define EFSYS_OPT_EV_PREFETCH 0 202 203 #define EFSYS_OPT_DECODE_INTR_FATAL 1 204 205 #define EFSYS_OPT_LICENSING 0 206 207 #define EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0 208 209 #define EFSYS_OPT_RX_PACKED_STREAM 0 210 211 #define EFSYS_OPT_RX_ES_SUPER_BUFFER 0 212 213 #define EFSYS_OPT_TUNNEL 0 214 215 #define EFSYS_OPT_FW_SUBVARIANT_AWARE 0 216 217 /* ID */ 218 219 typedef struct __efsys_identifier_s efsys_identifier_t; 220 221 /* PROBE */ 222 223 #ifndef DTRACE_PROBE 224 225 #define EFSYS_PROBE(_name) 226 227 #define EFSYS_PROBE1(_name, _type1, _arg1) 228 229 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) 230 231 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 232 _type3, _arg3) 233 234 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 235 _type3, _arg3, _type4, _arg4) 236 237 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 238 _type3, _arg3, _type4, _arg4, _type5, _arg5) 239 240 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 241 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 242 _type6, _arg6) 243 244 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 245 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 246 _type6, _arg6, _type7, _arg7) 247 248 #else /* DTRACE_PROBE */ 249 250 #define EFSYS_PROBE(_name) \ 251 DTRACE_PROBE(_name) 252 253 #define EFSYS_PROBE1(_name, _type1, _arg1) \ 254 DTRACE_PROBE1(_name, _type1, _arg1) 255 256 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \ 257 DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2) 258 259 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 260 _type3, _arg3) \ 261 DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2, \ 262 _type3, _arg3) 263 264 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 265 _type3, _arg3, _type4, _arg4) \ 266 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 267 _type3, _arg3, _type4, _arg4) 268 269 #ifdef DTRACE_PROBE5 270 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 271 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 272 DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 273 _type3, _arg3, _type4, _arg4, _type5, _arg5) 274 #else 275 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 276 _type3, _arg3, _type4, _arg4, _type5, _arg5) \ 277 DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2, \ 278 _type3, _arg3, _type4, _arg4) 279 #endif 280 281 #ifdef DTRACE_PROBE6 282 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 283 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 284 _type6, _arg6) \ 285 DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 286 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 287 _type6, _arg6) 288 #else 289 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 290 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 291 _type6, _arg6) \ 292 EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \ 293 _type3, _arg3, _type4, _arg4, _type5, _arg5) 294 #endif 295 296 #ifdef DTRACE_PROBE7 297 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 298 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 299 _type6, _arg6, _type7, _arg7) \ 300 DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 301 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 302 _type6, _arg6, _type7, _arg7) 303 #else 304 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \ 305 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 306 _type6, _arg6, _type7, _arg7) \ 307 EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \ 308 _type3, _arg3, _type4, _arg4, _type5, _arg5, \ 309 _type6, _arg6) 310 #endif 311 312 #endif /* DTRACE_PROBE */ 313 314 /* DMA */ 315 316 typedef uint64_t efsys_dma_addr_t; 317 318 typedef struct efsys_mem_s { 319 bus_dma_tag_t esm_tag; 320 bus_dmamap_t esm_map; 321 caddr_t esm_base; 322 efsys_dma_addr_t esm_addr; 323 size_t esm_size; 324 } efsys_mem_t; 325 326 #define EFSYS_MEM_SIZE(_esmp) \ 327 ((_esmp)->esm_size) 328 329 #define EFSYS_MEM_ADDR(_esmp) \ 330 ((_esmp)->esm_addr) 331 332 #define EFSYS_MEM_IS_NULL(_esmp) \ 333 ((_esmp)->esm_base == NULL) 334 335 #define EFSYS_MEM_ZERO(_esmp, _size) \ 336 do { \ 337 (void) memset((_esmp)->esm_base, 0, (_size)); \ 338 \ 339 _NOTE(CONSTANTCONDITION) \ 340 } while (B_FALSE) 341 342 #define EFSYS_MEM_READD(_esmp, _offset, _edp) \ 343 do { \ 344 uint32_t *addr; \ 345 \ 346 _NOTE(CONSTANTCONDITION) \ 347 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 348 sizeof (efx_dword_t)), \ 349 ("not power of 2 aligned")); \ 350 \ 351 addr = (void *)((_esmp)->esm_base + (_offset)); \ 352 \ 353 (_edp)->ed_u32[0] = *addr; \ 354 \ 355 EFSYS_PROBE2(mem_readd, unsigned int, (_offset), \ 356 uint32_t, (_edp)->ed_u32[0]); \ 357 \ 358 _NOTE(CONSTANTCONDITION) \ 359 } while (B_FALSE) 360 361 #if defined(__x86_64__) 362 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ 363 do { \ 364 uint64_t *addr; \ 365 \ 366 _NOTE(CONSTANTCONDITION) \ 367 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 368 sizeof (efx_qword_t)), \ 369 ("not power of 2 aligned")); \ 370 \ 371 addr = (void *)((_esmp)->esm_base + (_offset)); \ 372 \ 373 (_eqp)->eq_u64[0] = *addr; \ 374 \ 375 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ 376 uint32_t, (_eqp)->eq_u32[1], \ 377 uint32_t, (_eqp)->eq_u32[0]); \ 378 \ 379 _NOTE(CONSTANTCONDITION) \ 380 } while (B_FALSE) 381 #else 382 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \ 383 do { \ 384 uint32_t *addr; \ 385 \ 386 _NOTE(CONSTANTCONDITION) \ 387 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 388 sizeof (efx_qword_t)), \ 389 ("not power of 2 aligned")); \ 390 \ 391 addr = (void *)((_esmp)->esm_base + (_offset)); \ 392 \ 393 (_eqp)->eq_u32[0] = *addr++; \ 394 (_eqp)->eq_u32[1] = *addr; \ 395 \ 396 EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \ 397 uint32_t, (_eqp)->eq_u32[1], \ 398 uint32_t, (_eqp)->eq_u32[0]); \ 399 \ 400 _NOTE(CONSTANTCONDITION) \ 401 } while (B_FALSE) 402 #endif 403 404 #if defined(__x86_64__) 405 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \ 406 do { \ 407 uint64_t *addr; \ 408 \ 409 _NOTE(CONSTANTCONDITION) \ 410 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 411 sizeof (efx_oword_t)), \ 412 ("not power of 2 aligned")); \ 413 \ 414 addr = (void *)((_esmp)->esm_base + (_offset)); \ 415 \ 416 (_eop)->eo_u64[0] = *addr++; \ 417 (_eop)->eo_u64[1] = *addr; \ 418 \ 419 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ 420 uint32_t, (_eop)->eo_u32[3], \ 421 uint32_t, (_eop)->eo_u32[2], \ 422 uint32_t, (_eop)->eo_u32[1], \ 423 uint32_t, (_eop)->eo_u32[0]); \ 424 \ 425 _NOTE(CONSTANTCONDITION) \ 426 } while (B_FALSE) 427 #else 428 #define EFSYS_MEM_READO(_esmp, _offset, _eop) \ 429 do { \ 430 uint32_t *addr; \ 431 \ 432 _NOTE(CONSTANTCONDITION) \ 433 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 434 sizeof (efx_oword_t)), \ 435 ("not power of 2 aligned")); \ 436 \ 437 addr = (void *)((_esmp)->esm_base + (_offset)); \ 438 \ 439 (_eop)->eo_u32[0] = *addr++; \ 440 (_eop)->eo_u32[1] = *addr++; \ 441 (_eop)->eo_u32[2] = *addr++; \ 442 (_eop)->eo_u32[3] = *addr; \ 443 \ 444 EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \ 445 uint32_t, (_eop)->eo_u32[3], \ 446 uint32_t, (_eop)->eo_u32[2], \ 447 uint32_t, (_eop)->eo_u32[1], \ 448 uint32_t, (_eop)->eo_u32[0]); \ 449 \ 450 _NOTE(CONSTANTCONDITION) \ 451 } while (B_FALSE) 452 #endif 453 454 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \ 455 do { \ 456 uint32_t *addr; \ 457 \ 458 _NOTE(CONSTANTCONDITION) \ 459 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 460 sizeof (efx_dword_t)), \ 461 ("not power of 2 aligned")); \ 462 \ 463 EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \ 464 uint32_t, (_edp)->ed_u32[0]); \ 465 \ 466 addr = (void *)((_esmp)->esm_base + (_offset)); \ 467 \ 468 *addr = (_edp)->ed_u32[0]; \ 469 \ 470 _NOTE(CONSTANTCONDITION) \ 471 } while (B_FALSE) 472 473 #if defined(__x86_64__) 474 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ 475 do { \ 476 uint64_t *addr; \ 477 \ 478 _NOTE(CONSTANTCONDITION) \ 479 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 480 sizeof (efx_qword_t)), \ 481 ("not power of 2 aligned")); \ 482 \ 483 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ 484 uint32_t, (_eqp)->eq_u32[1], \ 485 uint32_t, (_eqp)->eq_u32[0]); \ 486 \ 487 addr = (void *)((_esmp)->esm_base + (_offset)); \ 488 \ 489 *addr = (_eqp)->eq_u64[0]; \ 490 \ 491 _NOTE(CONSTANTCONDITION) \ 492 } while (B_FALSE) 493 494 #else 495 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \ 496 do { \ 497 uint32_t *addr; \ 498 \ 499 _NOTE(CONSTANTCONDITION) \ 500 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 501 sizeof (efx_qword_t)), \ 502 ("not power of 2 aligned")); \ 503 \ 504 EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \ 505 uint32_t, (_eqp)->eq_u32[1], \ 506 uint32_t, (_eqp)->eq_u32[0]); \ 507 \ 508 addr = (void *)((_esmp)->esm_base + (_offset)); \ 509 \ 510 *addr++ = (_eqp)->eq_u32[0]; \ 511 *addr = (_eqp)->eq_u32[1]; \ 512 \ 513 _NOTE(CONSTANTCONDITION) \ 514 } while (B_FALSE) 515 #endif 516 517 #if defined(__x86_64__) 518 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ 519 do { \ 520 uint64_t *addr; \ 521 \ 522 _NOTE(CONSTANTCONDITION) \ 523 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 524 sizeof (efx_oword_t)), \ 525 ("not power of 2 aligned")); \ 526 \ 527 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ 528 uint32_t, (_eop)->eo_u32[3], \ 529 uint32_t, (_eop)->eo_u32[2], \ 530 uint32_t, (_eop)->eo_u32[1], \ 531 uint32_t, (_eop)->eo_u32[0]); \ 532 \ 533 addr = (void *)((_esmp)->esm_base + (_offset)); \ 534 \ 535 *addr++ = (_eop)->eo_u64[0]; \ 536 *addr = (_eop)->eo_u64[1]; \ 537 \ 538 _NOTE(CONSTANTCONDITION) \ 539 } while (B_FALSE) 540 #else 541 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \ 542 do { \ 543 uint32_t *addr; \ 544 \ 545 _NOTE(CONSTANTCONDITION) \ 546 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 547 sizeof (efx_oword_t)), \ 548 ("not power of 2 aligned")); \ 549 \ 550 EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \ 551 uint32_t, (_eop)->eo_u32[3], \ 552 uint32_t, (_eop)->eo_u32[2], \ 553 uint32_t, (_eop)->eo_u32[1], \ 554 uint32_t, (_eop)->eo_u32[0]); \ 555 \ 556 addr = (void *)((_esmp)->esm_base + (_offset)); \ 557 \ 558 *addr++ = (_eop)->eo_u32[0]; \ 559 *addr++ = (_eop)->eo_u32[1]; \ 560 *addr++ = (_eop)->eo_u32[2]; \ 561 *addr = (_eop)->eo_u32[3]; \ 562 \ 563 _NOTE(CONSTANTCONDITION) \ 564 } while (B_FALSE) 565 #endif 566 567 /* BAR */ 568 569 #define SFXGE_LOCK_NAME_MAX 16 570 571 typedef struct efsys_bar_s { 572 struct mtx esb_lock; 573 char esb_lock_name[SFXGE_LOCK_NAME_MAX]; 574 bus_space_tag_t esb_tag; 575 bus_space_handle_t esb_handle; 576 int esb_rid; 577 struct resource *esb_res; 578 } efsys_bar_t; 579 580 #define SFXGE_BAR_LOCK_INIT(_esbp, _ifname) \ 581 do { \ 582 snprintf((_esbp)->esb_lock_name, \ 583 sizeof((_esbp)->esb_lock_name), \ 584 "%s:bar", (_ifname)); \ 585 mtx_init(&(_esbp)->esb_lock, (_esbp)->esb_lock_name, \ 586 NULL, MTX_DEF); \ 587 _NOTE(CONSTANTCONDITION) \ 588 } while (B_FALSE) 589 #define SFXGE_BAR_LOCK_DESTROY(_esbp) \ 590 mtx_destroy(&(_esbp)->esb_lock) 591 #define SFXGE_BAR_LOCK(_esbp) \ 592 mtx_lock(&(_esbp)->esb_lock) 593 #define SFXGE_BAR_UNLOCK(_esbp) \ 594 mtx_unlock(&(_esbp)->esb_lock) 595 596 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \ 597 do { \ 598 _NOTE(CONSTANTCONDITION) \ 599 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 600 sizeof (efx_dword_t)), \ 601 ("not power of 2 aligned")); \ 602 \ 603 _NOTE(CONSTANTCONDITION) \ 604 if (_lock) \ 605 SFXGE_BAR_LOCK(_esbp); \ 606 \ 607 (_edp)->ed_u32[0] = bus_space_read_stream_4( \ 608 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 609 (_offset)); \ 610 \ 611 EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \ 612 uint32_t, (_edp)->ed_u32[0]); \ 613 \ 614 _NOTE(CONSTANTCONDITION) \ 615 if (_lock) \ 616 SFXGE_BAR_UNLOCK(_esbp); \ 617 _NOTE(CONSTANTCONDITION) \ 618 } while (B_FALSE) 619 620 #if defined(SFXGE_USE_BUS_SPACE_8) 621 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ 622 do { \ 623 _NOTE(CONSTANTCONDITION) \ 624 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 625 sizeof (efx_qword_t)), \ 626 ("not power of 2 aligned")); \ 627 \ 628 SFXGE_BAR_LOCK(_esbp); \ 629 \ 630 (_eqp)->eq_u64[0] = bus_space_read_stream_8( \ 631 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 632 (_offset)); \ 633 \ 634 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ 635 uint32_t, (_eqp)->eq_u32[1], \ 636 uint32_t, (_eqp)->eq_u32[0]); \ 637 \ 638 SFXGE_BAR_UNLOCK(_esbp); \ 639 _NOTE(CONSTANTCONDITION) \ 640 } while (B_FALSE) 641 642 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ 643 do { \ 644 _NOTE(CONSTANTCONDITION) \ 645 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 646 sizeof (efx_oword_t)), \ 647 ("not power of 2 aligned")); \ 648 \ 649 _NOTE(CONSTANTCONDITION) \ 650 if (_lock) \ 651 SFXGE_BAR_LOCK(_esbp); \ 652 \ 653 (_eop)->eo_u64[0] = bus_space_read_stream_8( \ 654 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 655 (_offset)); \ 656 (_eop)->eo_u64[1] = bus_space_read_stream_8( \ 657 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 658 (_offset) + 8); \ 659 \ 660 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ 661 uint32_t, (_eop)->eo_u32[3], \ 662 uint32_t, (_eop)->eo_u32[2], \ 663 uint32_t, (_eop)->eo_u32[1], \ 664 uint32_t, (_eop)->eo_u32[0]); \ 665 \ 666 _NOTE(CONSTANTCONDITION) \ 667 if (_lock) \ 668 SFXGE_BAR_UNLOCK(_esbp); \ 669 _NOTE(CONSTANTCONDITION) \ 670 } while (B_FALSE) 671 672 #else 673 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \ 674 do { \ 675 _NOTE(CONSTANTCONDITION) \ 676 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 677 sizeof (efx_qword_t)), \ 678 ("not power of 2 aligned")); \ 679 \ 680 SFXGE_BAR_LOCK(_esbp); \ 681 \ 682 (_eqp)->eq_u32[0] = bus_space_read_stream_4( \ 683 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 684 (_offset)); \ 685 (_eqp)->eq_u32[1] = bus_space_read_stream_4( \ 686 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 687 (_offset) + 4); \ 688 \ 689 EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \ 690 uint32_t, (_eqp)->eq_u32[1], \ 691 uint32_t, (_eqp)->eq_u32[0]); \ 692 \ 693 SFXGE_BAR_UNLOCK(_esbp); \ 694 _NOTE(CONSTANTCONDITION) \ 695 } while (B_FALSE) 696 697 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \ 698 do { \ 699 _NOTE(CONSTANTCONDITION) \ 700 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 701 sizeof (efx_oword_t)), \ 702 ("not power of 2 aligned")); \ 703 \ 704 _NOTE(CONSTANTCONDITION) \ 705 if (_lock) \ 706 SFXGE_BAR_LOCK(_esbp); \ 707 \ 708 (_eop)->eo_u32[0] = bus_space_read_stream_4( \ 709 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 710 (_offset)); \ 711 (_eop)->eo_u32[1] = bus_space_read_stream_4( \ 712 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 713 (_offset) + 4); \ 714 (_eop)->eo_u32[2] = bus_space_read_stream_4( \ 715 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 716 (_offset) + 8); \ 717 (_eop)->eo_u32[3] = bus_space_read_stream_4( \ 718 (_esbp)->esb_tag, (_esbp)->esb_handle, \ 719 (_offset) + 12); \ 720 \ 721 EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \ 722 uint32_t, (_eop)->eo_u32[3], \ 723 uint32_t, (_eop)->eo_u32[2], \ 724 uint32_t, (_eop)->eo_u32[1], \ 725 uint32_t, (_eop)->eo_u32[0]); \ 726 \ 727 _NOTE(CONSTANTCONDITION) \ 728 if (_lock) \ 729 SFXGE_BAR_UNLOCK(_esbp); \ 730 _NOTE(CONSTANTCONDITION) \ 731 } while (B_FALSE) 732 #endif 733 734 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \ 735 do { \ 736 _NOTE(CONSTANTCONDITION) \ 737 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 738 sizeof (efx_dword_t)), \ 739 ("not power of 2 aligned")); \ 740 \ 741 _NOTE(CONSTANTCONDITION) \ 742 if (_lock) \ 743 SFXGE_BAR_LOCK(_esbp); \ 744 \ 745 EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \ 746 uint32_t, (_edp)->ed_u32[0]); \ 747 \ 748 /* \ 749 * Make sure that previous writes to the dword have \ 750 * been done. It should be cheaper than barrier just \ 751 * after the write below. \ 752 */ \ 753 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 754 (_offset), sizeof (efx_dword_t), \ 755 BUS_SPACE_BARRIER_WRITE); \ 756 bus_space_write_stream_4((_esbp)->esb_tag, \ 757 (_esbp)->esb_handle, \ 758 (_offset), (_edp)->ed_u32[0]); \ 759 \ 760 _NOTE(CONSTANTCONDITION) \ 761 if (_lock) \ 762 SFXGE_BAR_UNLOCK(_esbp); \ 763 _NOTE(CONSTANTCONDITION) \ 764 } while (B_FALSE) 765 766 #if defined(SFXGE_USE_BUS_SPACE_8) 767 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ 768 do { \ 769 _NOTE(CONSTANTCONDITION) \ 770 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 771 sizeof (efx_qword_t)), \ 772 ("not power of 2 aligned")); \ 773 \ 774 SFXGE_BAR_LOCK(_esbp); \ 775 \ 776 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ 777 uint32_t, (_eqp)->eq_u32[1], \ 778 uint32_t, (_eqp)->eq_u32[0]); \ 779 \ 780 /* \ 781 * Make sure that previous writes to the qword have \ 782 * been done. It should be cheaper than barrier just \ 783 * after the write below. \ 784 */ \ 785 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 786 (_offset), sizeof (efx_qword_t), \ 787 BUS_SPACE_BARRIER_WRITE); \ 788 bus_space_write_stream_8((_esbp)->esb_tag, \ 789 (_esbp)->esb_handle, \ 790 (_offset), (_eqp)->eq_u64[0]); \ 791 \ 792 SFXGE_BAR_UNLOCK(_esbp); \ 793 _NOTE(CONSTANTCONDITION) \ 794 } while (B_FALSE) 795 #else 796 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \ 797 do { \ 798 _NOTE(CONSTANTCONDITION) \ 799 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 800 sizeof (efx_qword_t)), \ 801 ("not power of 2 aligned")); \ 802 \ 803 SFXGE_BAR_LOCK(_esbp); \ 804 \ 805 EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \ 806 uint32_t, (_eqp)->eq_u32[1], \ 807 uint32_t, (_eqp)->eq_u32[0]); \ 808 \ 809 /* \ 810 * Make sure that previous writes to the qword have \ 811 * been done. It should be cheaper than barrier just \ 812 * after the last write below. \ 813 */ \ 814 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 815 (_offset), sizeof (efx_qword_t), \ 816 BUS_SPACE_BARRIER_WRITE); \ 817 bus_space_write_stream_4((_esbp)->esb_tag, \ 818 (_esbp)->esb_handle, \ 819 (_offset), (_eqp)->eq_u32[0]); \ 820 /* \ 821 * It should be guaranteed that the last dword comes \ 822 * the last, so barrier entire qword to be sure that \ 823 * neither above nor below writes are reordered. \ 824 */ \ 825 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 826 (_offset), sizeof (efx_qword_t), \ 827 BUS_SPACE_BARRIER_WRITE); \ 828 bus_space_write_stream_4((_esbp)->esb_tag, \ 829 (_esbp)->esb_handle, \ 830 (_offset) + 4, (_eqp)->eq_u32[1]); \ 831 \ 832 SFXGE_BAR_UNLOCK(_esbp); \ 833 _NOTE(CONSTANTCONDITION) \ 834 } while (B_FALSE) 835 #endif 836 837 /* 838 * Guarantees 64bit aligned 64bit writes to write combined BAR mapping 839 * (required by PIO hardware) 840 */ 841 #define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp) \ 842 do { \ 843 _NOTE(CONSTANTCONDITION) \ 844 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 845 sizeof (efx_qword_t)), \ 846 ("not power of 2 aligned")); \ 847 \ 848 (void) (_esbp); \ 849 (void) (_eqp); \ 850 \ 851 /* FIXME: Perform a 64-bit write */ \ 852 KASSERT(0, ("not implemented")); \ 853 \ 854 _NOTE(CONSTANTCONDITION) \ 855 } while (B_FALSE) 856 857 #if defined(SFXGE_USE_BUS_SPACE_8) 858 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ 859 do { \ 860 _NOTE(CONSTANTCONDITION) \ 861 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 862 sizeof (efx_oword_t)), \ 863 ("not power of 2 aligned")); \ 864 \ 865 _NOTE(CONSTANTCONDITION) \ 866 if (_lock) \ 867 SFXGE_BAR_LOCK(_esbp); \ 868 \ 869 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ 870 uint32_t, (_eop)->eo_u32[3], \ 871 uint32_t, (_eop)->eo_u32[2], \ 872 uint32_t, (_eop)->eo_u32[1], \ 873 uint32_t, (_eop)->eo_u32[0]); \ 874 \ 875 /* \ 876 * Make sure that previous writes to the oword have \ 877 * been done. It should be cheaper than barrier just \ 878 * after the last write below. \ 879 */ \ 880 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 881 (_offset), sizeof (efx_oword_t), \ 882 BUS_SPACE_BARRIER_WRITE); \ 883 bus_space_write_stream_8((_esbp)->esb_tag, \ 884 (_esbp)->esb_handle, \ 885 (_offset), (_eop)->eo_u64[0]); \ 886 /* \ 887 * It should be guaranteed that the last qword comes \ 888 * the last, so barrier entire oword to be sure that \ 889 * neither above nor below writes are reordered. \ 890 */ \ 891 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 892 (_offset), sizeof (efx_oword_t), \ 893 BUS_SPACE_BARRIER_WRITE); \ 894 bus_space_write_stream_8((_esbp)->esb_tag, \ 895 (_esbp)->esb_handle, \ 896 (_offset) + 8, (_eop)->eo_u64[1]); \ 897 \ 898 _NOTE(CONSTANTCONDITION) \ 899 if (_lock) \ 900 SFXGE_BAR_UNLOCK(_esbp); \ 901 _NOTE(CONSTANTCONDITION) \ 902 } while (B_FALSE) 903 904 #else 905 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \ 906 do { \ 907 _NOTE(CONSTANTCONDITION) \ 908 KASSERT(EFX_IS_P2ALIGNED(size_t, _offset, \ 909 sizeof (efx_oword_t)), \ 910 ("not power of 2 aligned")); \ 911 \ 912 _NOTE(CONSTANTCONDITION) \ 913 if (_lock) \ 914 SFXGE_BAR_LOCK(_esbp); \ 915 \ 916 EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \ 917 uint32_t, (_eop)->eo_u32[3], \ 918 uint32_t, (_eop)->eo_u32[2], \ 919 uint32_t, (_eop)->eo_u32[1], \ 920 uint32_t, (_eop)->eo_u32[0]); \ 921 \ 922 /* \ 923 * Make sure that previous writes to the oword have \ 924 * been done. It should be cheaper than barrier just \ 925 * after the last write below. \ 926 */ \ 927 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 928 (_offset), sizeof (efx_oword_t), \ 929 BUS_SPACE_BARRIER_WRITE); \ 930 bus_space_write_stream_4((_esbp)->esb_tag, \ 931 (_esbp)->esb_handle, \ 932 (_offset), (_eop)->eo_u32[0]); \ 933 bus_space_write_stream_4((_esbp)->esb_tag, \ 934 (_esbp)->esb_handle, \ 935 (_offset) + 4, (_eop)->eo_u32[1]); \ 936 bus_space_write_stream_4((_esbp)->esb_tag, \ 937 (_esbp)->esb_handle, \ 938 (_offset) + 8, (_eop)->eo_u32[2]); \ 939 /* \ 940 * It should be guaranteed that the last dword comes \ 941 * the last, so barrier entire oword to be sure that \ 942 * neither above nor below writes are reordered. \ 943 */ \ 944 bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ 945 (_offset), sizeof (efx_oword_t), \ 946 BUS_SPACE_BARRIER_WRITE); \ 947 bus_space_write_stream_4((_esbp)->esb_tag, \ 948 (_esbp)->esb_handle, \ 949 (_offset) + 12, (_eop)->eo_u32[3]); \ 950 \ 951 _NOTE(CONSTANTCONDITION) \ 952 if (_lock) \ 953 SFXGE_BAR_UNLOCK(_esbp); \ 954 _NOTE(CONSTANTCONDITION) \ 955 } while (B_FALSE) 956 #endif 957 958 /* Use the standard octo-word write for doorbell writes */ 959 #define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop) \ 960 do { \ 961 EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE); \ 962 _NOTE(CONSTANTCONDITION) \ 963 } while (B_FALSE) 964 965 /* SPIN */ 966 967 #define EFSYS_SPIN(_us) \ 968 do { \ 969 DELAY(_us); \ 970 _NOTE(CONSTANTCONDITION) \ 971 } while (B_FALSE) 972 973 #define EFSYS_SLEEP EFSYS_SPIN 974 975 /* BARRIERS */ 976 977 #define EFSYS_MEM_READ_BARRIER() rmb() 978 #define EFSYS_PIO_WRITE_BARRIER() 979 980 /* DMA SYNC */ 981 #define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size) \ 982 do { \ 983 bus_dmamap_sync((_esmp)->esm_tag, \ 984 (_esmp)->esm_map, \ 985 BUS_DMASYNC_POSTREAD); \ 986 _NOTE(CONSTANTCONDITION) \ 987 } while (B_FALSE) 988 989 #define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size) \ 990 do { \ 991 bus_dmamap_sync((_esmp)->esm_tag, \ 992 (_esmp)->esm_map, \ 993 BUS_DMASYNC_PREWRITE); \ 994 _NOTE(CONSTANTCONDITION) \ 995 } while (B_FALSE) 996 997 /* TIMESTAMP */ 998 999 typedef clock_t efsys_timestamp_t; 1000 1001 #define EFSYS_TIMESTAMP(_usp) \ 1002 do { \ 1003 clock_t now; \ 1004 \ 1005 now = ticks; \ 1006 *(_usp) = now * hz / 1000000; \ 1007 _NOTE(CONSTANTCONDITION) \ 1008 } while (B_FALSE) 1009 1010 /* KMEM */ 1011 1012 #define EFSYS_KMEM_ALLOC(_esip, _size, _p) \ 1013 do { \ 1014 (_esip) = (_esip); \ 1015 /* \ 1016 * The macro is used in non-sleepable contexts, for \ 1017 * example, holding a mutex. \ 1018 */ \ 1019 (_p) = malloc((_size), M_SFXGE, M_NOWAIT|M_ZERO); \ 1020 _NOTE(CONSTANTCONDITION) \ 1021 } while (B_FALSE) 1022 1023 #define EFSYS_KMEM_FREE(_esip, _size, _p) \ 1024 do { \ 1025 (void) (_esip); \ 1026 (void) (_size); \ 1027 free((_p), M_SFXGE); \ 1028 _NOTE(CONSTANTCONDITION) \ 1029 } while (B_FALSE) 1030 1031 /* LOCK */ 1032 1033 typedef struct efsys_lock_s { 1034 struct mtx lock; 1035 char lock_name[SFXGE_LOCK_NAME_MAX]; 1036 } efsys_lock_t; 1037 1038 #define SFXGE_EFSYS_LOCK_INIT(_eslp, _ifname, _label) \ 1039 do { \ 1040 efsys_lock_t *__eslp = (_eslp); \ 1041 \ 1042 snprintf((__eslp)->lock_name, \ 1043 sizeof((__eslp)->lock_name), \ 1044 "%s:%s", (_ifname), (_label)); \ 1045 mtx_init(&(__eslp)->lock, (__eslp)->lock_name, \ 1046 NULL, MTX_DEF); \ 1047 } while (B_FALSE) 1048 #define SFXGE_EFSYS_LOCK_DESTROY(_eslp) \ 1049 mtx_destroy(&(_eslp)->lock) 1050 #define SFXGE_EFSYS_LOCK(_eslp) \ 1051 mtx_lock(&(_eslp)->lock) 1052 #define SFXGE_EFSYS_UNLOCK(_eslp) \ 1053 mtx_unlock(&(_eslp)->lock) 1054 #define SFXGE_EFSYS_LOCK_ASSERT_OWNED(_eslp) \ 1055 mtx_assert(&(_eslp)->lock, MA_OWNED) 1056 1057 typedef int efsys_lock_state_t; 1058 1059 #define EFSYS_LOCK_MAGIC 0x000010c4 1060 1061 #define EFSYS_LOCK(_lockp, _state) \ 1062 do { \ 1063 SFXGE_EFSYS_LOCK(_lockp); \ 1064 (_state) = EFSYS_LOCK_MAGIC; \ 1065 _NOTE(CONSTANTCONDITION) \ 1066 } while (B_FALSE) 1067 1068 #define EFSYS_UNLOCK(_lockp, _state) \ 1069 do { \ 1070 if ((_state) != EFSYS_LOCK_MAGIC) \ 1071 KASSERT(B_FALSE, ("not locked")); \ 1072 SFXGE_EFSYS_UNLOCK(_lockp); \ 1073 _NOTE(CONSTANTCONDITION) \ 1074 } while (B_FALSE) 1075 1076 /* STAT */ 1077 1078 typedef uint64_t efsys_stat_t; 1079 1080 #define EFSYS_STAT_INCR(_knp, _delta) \ 1081 do { \ 1082 *(_knp) += (_delta); \ 1083 _NOTE(CONSTANTCONDITION) \ 1084 } while (B_FALSE) 1085 1086 #define EFSYS_STAT_DECR(_knp, _delta) \ 1087 do { \ 1088 *(_knp) -= (_delta); \ 1089 _NOTE(CONSTANTCONDITION) \ 1090 } while (B_FALSE) 1091 1092 #define EFSYS_STAT_SET(_knp, _val) \ 1093 do { \ 1094 *(_knp) = (_val); \ 1095 _NOTE(CONSTANTCONDITION) \ 1096 } while (B_FALSE) 1097 1098 #define EFSYS_STAT_SET_QWORD(_knp, _valp) \ 1099 do { \ 1100 *(_knp) = le64toh((_valp)->eq_u64[0]); \ 1101 _NOTE(CONSTANTCONDITION) \ 1102 } while (B_FALSE) 1103 1104 #define EFSYS_STAT_SET_DWORD(_knp, _valp) \ 1105 do { \ 1106 *(_knp) = le32toh((_valp)->ed_u32[0]); \ 1107 _NOTE(CONSTANTCONDITION) \ 1108 } while (B_FALSE) 1109 1110 #define EFSYS_STAT_INCR_QWORD(_knp, _valp) \ 1111 do { \ 1112 *(_knp) += le64toh((_valp)->eq_u64[0]); \ 1113 _NOTE(CONSTANTCONDITION) \ 1114 } while (B_FALSE) 1115 1116 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \ 1117 do { \ 1118 *(_knp) -= le64toh((_valp)->eq_u64[0]); \ 1119 _NOTE(CONSTANTCONDITION) \ 1120 } while (B_FALSE) 1121 1122 /* ERR */ 1123 1124 extern void sfxge_err(efsys_identifier_t *, unsigned int, 1125 uint32_t, uint32_t); 1126 1127 #if EFSYS_OPT_DECODE_INTR_FATAL 1128 #define EFSYS_ERR(_esip, _code, _dword0, _dword1) \ 1129 do { \ 1130 sfxge_err((_esip), (_code), (_dword0), (_dword1)); \ 1131 _NOTE(CONSTANTCONDITION) \ 1132 } while (B_FALSE) 1133 #endif 1134 1135 /* ASSERT */ 1136 1137 #define EFSYS_ASSERT(_exp) do { \ 1138 if (!(_exp)) \ 1139 panic("%s", #_exp); \ 1140 } while (0) 1141 1142 #define EFSYS_ASSERT3(_x, _op, _y, _t) do { \ 1143 const _t __x = (_t)(_x); \ 1144 const _t __y = (_t)(_y); \ 1145 if (!(__x _op __y)) \ 1146 panic("assertion failed at %s:%u", __FILE__, __LINE__); \ 1147 } while(0) 1148 1149 #define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t) 1150 #define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t) 1151 #define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t) 1152 1153 /* ROTATE */ 1154 1155 #define EFSYS_HAS_ROTL_DWORD 0 1156 1157 #ifdef __cplusplus 1158 } 1159 #endif 1160 1161 #endif /* _SYS_EFSYS_H */ 1162