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