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