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