|
root / base / usr / src / uts / common / sys / smbios_impl.h
smbios_impl.h C 1032 lines 37.9 KB
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2015 OmniTI Computer Consulting, Inc.  All rights reserved.
 * Copyright (c) 2018, Joyent, Inc.
 * Copyright 2025 Oxide Computer Company
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * This header file defines the implementation structures for the SMBIOS access
 * library, libsmbios, and an equivalent kernel module.  Clients should use
 * the <smbios.h> or <sys/smbios.h> header files to access DMTF SMBIOS
 * information, NOT these underlying implementation structures from the spec.
 * In short, do not user this header file or these routines for any purpose.
 */

#ifndef	_SYS_SMBIOS_IMPL_H
#define	_SYS_SMBIOS_IMPL_H

#include <sys/smbios.h>
#include <sys/sysmacros.h>

#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <strings.h>
#include <stddef.h>
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Definitions required to interpret the BIOS type information.
 */
#define	SMB_BIOSXB_EXTROM	6

#define	SMB_BIOS_EXTROM_VALUE_MASK(x)	((x) & 0x3fff)
#define	SMB_BIOS_EXTROM_SHIFT_MASK(x)	(((x) & 0xc000) >> 14)

#pragma pack(1)

typedef struct smb_header {
	uint8_t smbh_type;		/* structure type (SMB_TYPE_* value) */
	uint8_t smbh_len;		/* length in bytes of formatted area */
	uint16_t smbh_hdl;		/* structure handle */
} smb_header_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_BIOS.
 */
typedef struct smb_bios {
	smb_header_t smbbi_hdr;		/* structure header */
	uint8_t smbbi_vendor;		/* bios vendor string */
	uint8_t smbbi_version;		/* bios version string */
	uint16_t smbbi_segment;		/* segment location of bios address */
	uint8_t smbbi_reldate;		/* bios release date */
	uint8_t smbbi_romsize;		/* bios rom size (64k * (n + 1)) */
	uint64_t smbbi_cflags;		/* bios characteristics */
	uint8_t smbbi_xcflags[1];	/* bios characteristics extensions */
} smb_bios_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_SYSTEM.
 */
typedef struct smb_system {
	smb_header_t smbsi_hdr;		/* structure header */
	uint8_t smbsi_manufacturer;	/* manufacturer */
	uint8_t smbsi_product;		/* product name */
	uint8_t smbsi_version;		/* version */
	uint8_t smbsi_serial;		/* serial number */
	uint8_t smbsi_uuid[16];		/* UUID */
	uint8_t smbsi_wakeup;		/* wake-up type */
	uint8_t smbsi_sku;		/* SKU number */
	uint8_t smbsi_family;		/* family */
} smb_system_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_BASEBOARD.
 */
typedef struct smb_bboard {
	smb_header_t smbbb_hdr;		/* structure header */
	uint8_t smbbb_manufacturer;	/* manufacturer */
	uint8_t smbbb_product;		/* product name */
	uint8_t smbbb_version;		/* version */
	uint8_t smbbb_serial;		/* serial number */
	uint8_t smbbb_asset;		/* asset tag */
	uint8_t smbbb_flags;		/* feature flags */
	uint8_t smbbb_location;		/* location in chassis */
	uint16_t smbbb_chassis;		/* chassis handle */
	uint8_t smbbb_type;		/* board type */
	uint8_t smbbb_cn;		/* number of contained handles */
	uint16_t smbbb_cv[1];		/* array of contained handles */
} smb_bboard_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_CHASSIS.
 */
typedef struct smb_chassis {
	smb_header_t smbch_hdr;		/* structure header */
	uint8_t smbch_manufacturer;	/* manufacturer */
	uint8_t smbch_type;		/* type */
	uint8_t smbch_version;		/* version */
	uint8_t smbch_serial;		/* serial number */
	uint8_t smbch_asset;		/* asset tag */
	uint8_t smbch_bustate;		/* boot-up state */
	uint8_t smbch_psstate;		/* power supply state */
	uint8_t smbch_thstate;		/* thermal state */
	uint8_t smbch_security;		/* security state */
	uint32_t smbch_oemdata;		/* OEM-specific data */
	uint8_t smbch_uheight;		/* enclosure height */
	uint8_t smbch_cords;		/* number of power cords */
	uint8_t smbch_cn;		/* number of contained records */
	uint8_t smbch_cm;		/* size of contained records */
	uint8_t smbch_cv[];		/* array of contained records */
} smb_chassis_t;

#define	SMB_CHT_LOCK	0x80		/* lock bit within smbch_type */

typedef struct smb_chassis_entry {
	uint8_t	smbce_type;		/* Containing Element and Type */
	uint8_t	smbce_min;		/* minimum number of elt */
	uint8_t	smbce_max;		/* minimum number of elt */
} smb_chassis_entry_t;

/*
 * Bonus information that follows the variable number of elements.
 */
typedef struct smb_chassis_bonus {
	uint8_t smbcb_sku;		/* chassis SKU, 2.7+ */
	uint8_t smbcb_rtype;		/* rack type, 3.9+ */
	uint8_t smbcb_rheight;		/* rack height, 3.9+ */
} smb_chassis_bonus_t;

#define	SMB_CHE_TYPE_IS_SMB(x)	(((x) & 0x80) ==  0x80)
#define	SMB_CHE_TYPE_TYPE(x)	(((x) & 0x7f))

/*
 * SMBIOS implementation structure for SMB_TYPE_PROCESSOR.
 */
typedef struct smb_processor {
	smb_header_t smbpr_hdr;		/* structure header */
	uint8_t smbpr_socket;		/* socket designation */
	uint8_t smbpr_type;		/* processor type (see <smbios.h>) */
	uint8_t smbpr_family;		/* processor family (see <smbios.h>) */
	uint8_t smbpr_manufacturer;	/* manufacturer */
	uint64_t smbpr_cpuid;		/* processor cpuid information */
	uint8_t smbpr_version;		/* version */
	uint8_t smbpr_voltage;		/* voltage */
	uint16_t smbpr_clkspeed;	/* external clock speed in MHz */
	uint16_t smbpr_maxspeed;	/* maximum speed in MHz */
	uint16_t smbpr_curspeed;	/* current speed in MHz */
	uint8_t smbpr_status;		/* status (see <smbios.h>) */
	uint8_t smbpr_upgrade;		/* upgrade */
	uint16_t smbpr_l1cache;		/* L1 cache handle (if any) */
	uint16_t smbpr_l2cache;		/* L2 cache handle (if any) */
	uint16_t smbpr_l3cache;		/* L3 cache handle (if any) */
	uint8_t smbpr_serial;		/* serial number */
	uint8_t smbpr_asset;		/* asset tag */
	uint8_t smbpr_part;		/* part number */
	uint8_t smbpr_corecount;	/* number of cores per socket */
	uint8_t smbpr_coresenabled;	/* number of enabled cores per socket */
	uint8_t smbpr_threadcount;	/* number of threads per socket */
	uint16_t smbpr_cflags;	/* cpu characteristics (see <smbios.h>) */
	uint16_t smbpr_family2;		/* processor family2 (see <smbios.h>) */
	uint16_t smbpr_corecount2;	/* second number of cores per socket */
	uint16_t smbpr_coresenabled2;	/* second number of enabled cores */
	uint16_t smbpr_threadcount2;	/* second number of enabled threads */
	uint16_t smbpr_threaden;	/* enabled thread count */
	uint8_t smbpr_socktype;		/* socket type string */
} smb_processor_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_CACHE.
 */
typedef struct smb_cache {
	smb_header_t smbca_hdr;		/* structure header */
	uint8_t smbca_socket;		/* socket designation */
	uint16_t smbca_config;		/* cache configuration */
	uint16_t smbca_maxsize;		/* maximum installed size */
	uint16_t smbca_size;		/* installed size */
	uint16_t smbca_stype;		/* supported SRAM type */
	uint16_t smbca_ctype;		/* current SRAM type */
	uint8_t smbca_speed;		/* speed in nanoseconds */
	uint8_t smbca_etype;		/* error correction type */
	uint8_t smbca_ltype;		/* logical cache type */
	uint8_t smbca_assoc;		/* associativity */
	uint32_t smbca_maxsize2;	/* maximum installed size 2 */
	uint32_t smbca_size2;		/* installed size 2 */
} smb_cache_t;

/*
 * Convert encoded cache size to bytes: DSP0134 Section 7.8 explains the
 * encoding.  The highest bit is 0 for 1k units, 1 for 64k units, and this
 * macro decodes the value into bytes for exporting to our clients.
 */
#define	SMB_CACHE_SIZE(s)	(((s) & 0x8000) ? \
	((uint32_t)((s) & 0x7FFF) * 64 * 1024) : ((uint32_t)(s) * 1024))

#define	SMB_CACHE_EXT_SIZE(s)	(((s) & 0x80000000U) ?	\
	((uint64_t)((s) & 0x7FFFFFFFULL) * 64ULL * 1024ULL) :	\
	((uint64_t)(s) * 1024ULL))

#define	SMB_CACHE_CFG_MODE(c)		(((c) >> 8) & 3)
#define	SMB_CACHE_CFG_ENABLED(c)	(((c) >> 7) & 1)
#define	SMB_CACHE_CFG_LOCATION(c)	(((c) >> 5) & 3)
#define	SMB_CACHE_CFG_SOCKETED(c)	(((c) >> 3) & 1)
#define	SMB_CACHE_CFG_LEVEL(c)		(((c) & 7) + 1)

/*
 * SMBIOS implementation structure for SMB_TYPE_PORT.
 */
typedef struct smb_port {
	smb_header_t smbpo_hdr;		/* structure header */
	uint8_t smbpo_iref;		/* internal reference designator */
	uint8_t smbpo_itype;		/* internal connector type */
	uint8_t smbpo_eref;		/* external reference designator */
	uint8_t smbpo_etype;		/* external connector type */
	uint8_t smbpo_ptype;		/* port type */
} smb_port_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_SLOT.
 */
typedef struct smb_slot_peer {
	uint16_t smbspb_group_no;	/* segment group number */
	uint8_t smbspb_bus;		/* bus number */
	uint8_t smbspb_df;		/* device/function number */
	uint8_t smbspb_width;		/* electrical width */
} smb_slot_peer_t;

typedef struct smb_slot {
	smb_header_t smbsl_hdr;		/* structure header */
	uint8_t smbsl_name;		/* reference designation */
	uint8_t smbsl_type;		/* slot type */
	uint8_t smbsl_width;		/* slot data bus width */
	uint8_t smbsl_usage;		/* current usage */
	uint8_t smbsl_length;		/* slot length */
	uint16_t smbsl_id;		/* slot ID */
	uint8_t smbsl_ch1;		/* slot characteristics 1 */
	uint8_t smbsl_ch2;		/* slot characteristics 2 */
	uint16_t smbsl_sg;		/* segment group number */
	uint8_t smbsl_bus;		/* bus number */
	uint8_t smbsl_df;		/* device/function number */
	/* Added in SMBIOS 3.2+ */
	uint8_t	smbsl_dbw;		/* Data bus width */
	uint8_t	smbsl_npeers;		/* Peer bdf groups */
	smb_slot_peer_t smbsl_peers[];	/* bifurcation peers */
	/* There are later additions in 3.4+, see smbios_slot_cont_t */
} smb_slot_t;

/*
 * After the variable number of smbsl_peers, the smbios_slot has continued in
 * size and has the following members defined as of version 3.4. These occur
 * starting at byte 14 + 5 * smbsl_npeers.
 */
typedef struct smb_slot_cont {
	uint8_t smbsl_info;		/* slot info */
	uint8_t smbsl_pwidth;		/* slot physical width */
	uint16_t smbsl_pitch;		/* slot pitch */
	/* Added in SMBIOS 3.5 */
	uint8_t smbsl_height;		/* slot height */
} smb_slot_cont_t;

/*
 * The first byte that the smb_slot_cont_t is defined to start at. Note, this
 * was originally indicated to be 0x14 in the SMBIOS 3.4 specification. This has
 * been noted as an errata. Right now we assume that most things have the
 * updated behavior in SMBIOS 3.5. However, if we encounter things in the wild
 * that have the other offset then we will need to condition this on 3.4.
 */
#define	SMB_SLOT_CONT_START	0x13

/*
 * SMBIOS implementation structure for SMB_TYPE_OBDEVS.
 */
typedef struct smb_obdev {
	uint8_t smbob_type;		/* encoded type and enable bit */
	uint8_t smbob_name;		/* description string */
} smb_obdev_t;

#define	SMB_OBT_ENABLED		0x80	/* enable bit within smbob_type */

/*
 * SMBIOS implementation structure for SMB_TYPE_OEMSTR, SMB_TYPE_SYSCONFSTR,
 * and SMB_TYPE_LANG.
 */
typedef struct smb_strtab {
	smb_header_t smbtb_hdr;		/* structure header */
	uint8_t smbtb_count;		/* number of strings */
} smb_strtab_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_LANG.
 */
typedef struct smb_lang {
	smb_header_t smblang_hdr;	/* structure header */
	uint8_t smblang_num;		/* number of installed languages */
	uint8_t smblang_flags;		/* flags */
	uint8_t smblang_resv[15];	/* reserved for future use */
	uint8_t smblang_cur;		/* current language string */
} smb_lang_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_EVENTLOG.
 */
typedef struct smb_sel {
	smb_header_t smbsel_hdr;	/* structure header */
	uint16_t smbsel_len;		/* log area length */
	uint16_t smbsel_hdroff;		/* header offset */
	uint16_t smbsel_dataoff;	/* data offset */
	uint8_t smbsel_method;		/* access method */
	uint8_t smbsel_status;		/* status flags */
	uint32_t smbsel_token;		/* change token */
	uint32_t smbsel_addr;		/* access method address */
	uint8_t smbsel_format;		/* header format */
	uint8_t smbsel_typec;		/* number of type descriptors */
	uint8_t smbsel_typesz;		/* size of each type descriptor */
	uint8_t smbsel_typev[1];	/* array of type descriptors */
} smb_sel_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_MEMARRAY.
 */
typedef struct smb_memarray {
	smb_header_t smbmarr_hdr;	/* structure header */
	uint8_t smbmarr_loc;		/* location */
	uint8_t smbmarr_use;		/* use */
	uint8_t smbmarr_ecc;		/* error detect/correct mechanism */
	uint32_t smbmarr_cap;		/* maximum capacity */
	uint16_t smbmarr_err;		/* error handle */
	uint16_t smbmarr_ndevs;		/* number of slots or sockets */
	uint64_t smbmarr_extcap;	/* extended maximum capacity */
} smb_memarray_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_MEMARRAYMAP.
 */
typedef struct smb_memarrmap {
	smb_header_t smbamap_hdr;	/* structure header */
	uint32_t smbamap_start;		/* starting address in kilobytes */
	uint32_t smbamap_end;		/* ending address in kilobytes */
	uint16_t smbamap_array;		/* physical memory array handle */
	uint8_t smbamap_width;		/* partition width */
	uint64_t smbamap_extstart;	/* extended starting address in bytes */
	uint64_t smbamap_extend;	/* extended ending address in bytes */
} smb_memarrmap_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_MEMDEVICE.
 */
typedef struct smb_memdevice {
	smb_header_t smbmdev_hdr;	/* structure header */
	uint16_t smbmdev_array;		/* array handle */
	uint16_t smbmdev_error;		/* error handle */
	uint16_t smbmdev_twidth;	/* total width */
	uint16_t smbmdev_dwidth;	/* data width */
	uint16_t smbmdev_size;		/* size in either K or MB */
	uint8_t smbmdev_form;		/* form factor */
	uint8_t smbmdev_set;		/* device set */
	uint8_t smbmdev_dloc;		/* device locator */
	uint8_t smbmdev_bloc;		/* bank locator */
	uint8_t smbmdev_type;		/* memory type */
	uint16_t smbmdev_flags;		/* detail flags */
	uint16_t smbmdev_speed;		/* speed in MT/s */
	uint8_t smbmdev_manufacturer;	/* manufacturer */
	uint8_t smbmdev_serial;		/* serial number */
	uint8_t smbmdev_asset;		/* asset tag */
	uint8_t smbmdev_part;		/* part number */
	uint8_t smbmdev_attrs;		/* attributes */
	uint32_t smbmdev_extsize;	/* extended size */
	uint16_t smbmdev_clkspeed;	/* configured clock speed */
	uint16_t smbmdev_minvolt;	/* minimum voltage */
	uint16_t smbmdev_maxvolt;	/* maximum voltage */
	uint16_t smbmdev_confvolt;	/* configured voltage */
	/* Added in SMBIOS 3.2 */
	uint8_t smbmdev_memtech;	/* memory technology */
	uint16_t smbmdev_opmode;	/* memory operating mode capability */
	uint8_t smbmdev_fwver;		/* firmware version */
	uint16_t smbmdev_modulemfgid;	/* module manufacturer ID */
	uint16_t smbmdev_moduleprodid;	/* module product ID */
	uint16_t smbmdev_memsysmfgid;	/* memory controller manufacturer id */
	uint16_t smbmdev_memsysprodid;	/* memory controller product id */
	uint64_t smbmdev_nvsize;	/* non-volatile memory size */
	uint64_t smbmdev_volsize;	/* volatile memory size */
	uint64_t smbmdev_cachesize;	/* cache size */
	uint64_t smbmdev_logicalsize;	/* logical size */
	/* Added in SMBIOS 3.3 */
	uint32_t smbmdev_extspeed;	/* Extended device speed */
	uint32_t smbmdev_extclkspeed;	/* Extended clock speed */
	/* Added in SMBIOS 3.7 */
	uint16_t smbmdev_pmic0mfgid;	/* PMIC0 Manufacturer ID */
	uint16_t smbmdev_pmic0rev;	/* PMIC0 Revision */
	uint16_t smbmdev_rcdmfgid;	/* RCD Manufacturer ID */
	uint16_t smbmdev_rcdrev;	/* RCD Revision */
} smb_memdevice_t;

#define	SMB_MDS_KBYTES		0x8000	/* size in specified in kilobytes */

/*
 * SMBIOS implementation structure for SMB_TYPE_MEMDEVICEMAP.
 */
typedef struct smb_memdevmap {
	smb_header_t smbdmap_hdr;	/* structure header */
	uint32_t smbdmap_start;		/* starting address in kilobytes */
	uint32_t smbdmap_end;		/* ending address in kilobytes */
	uint16_t smbdmap_device;	/* memory device handle */
	uint16_t smbdmap_array;		/* memory array mapped address handle */
	uint8_t smbdmap_rpos;		/* row position */
	uint8_t smbdmap_ipos;		/* interleave position */
	uint8_t smbdmap_idepth;		/* interleave depth */
	uint64_t smbdmap_extstart;	/* extended starting address */
	uint64_t smbdmap_extend;	/* extended ending address */
} smb_memdevmap_t;

typedef struct smb_pointdev {
	smb_header_t smbpdev_hdr;	/* structure header */
	uint8_t smbpdev_type;		/* device type */
	uint8_t smbpdev_iface;		/* device interface */
	uint8_t smbpdev_nbuttons;	/* number of buttons */
} smb_pointdev_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_BATTERY.
 */
typedef struct smb_battery {
	smb_header_t smbbat_hdr;	/* structure header */
	uint8_t smbbat_loc;		/* location */
	uint8_t smbbat_manufacturer;	/* manufacturer */
	uint8_t smbbat_date;		/* manufacture date */
	uint8_t smbbat_serial;		/* serial number */
	uint8_t smbbat_devname;		/* device name */
	uint8_t smbbat_chem;		/* device chemistry */
	uint16_t smbbat_cap;		/* design capacity in mW hours */
	uint16_t smbbat_volt;		/* design voltage in mV */
	uint8_t smbbat_version;		/* SBDS version string */
	uint8_t smbbat_err;		/* error percentage */
	uint16_t smbbat_ssn;		/* SBDS serial number */
	uint16_t smbbat_sdate;		/* SBDS manufacture date */
	uint8_t smbbat_schem;		/* SBDS chemistry string */
	uint8_t smbbat_mult;		/* design capacity multiplier */
	uint32_t smbbat_oemdata;	/* OEM-specific data */
} smb_battery_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_SECURITY.
 */
typedef struct smb_hwsec {
	smb_header_t smbhs_hdr;		/* structure header */
	uint8_t smbhs_settings;		/* settings byte */
} smb_hwsec_t;

#define	SMB_HWS_PWR_PS(x)	(((x) & 0xC0) >> 6)
#define	SMB_HWS_KBD_PS(x)	(((x) & 0x30) >> 4)
#define	SMB_HWS_ADM_PS(x)	(((x) & 0x0C) >> 2)
#define	SMB_HWS_PAN_PS(x)	(((x) & 0x03) >> 0)

/*
 * SMBIOS implementation structure for SMB_TYPE_VPROBE.
 */
typedef struct smb_vprobe {
	smb_header_t smbvpr_hdr;	/* structure header */
	uint8_t smbvpr_descr;		/* description string */
	uint8_t smbvpr_locstat;		/* location and status */
	uint16_t smbvpr_maxval;		/* maximum voltage */
	uint16_t smbvpr_minval;		/* minimum voltage */
	uint16_t smbvpr_resolution;	/* probe resolution */
	uint16_t smbvpr_tolerance;	/* probe tolerance */
	uint16_t smbvpr_accuracy;	/* probe accuracy */
	uint32_t smbvpr_oem;		/* vendor-specific data */
	uint16_t smbvpr_nominal;	/* nominal value */
} smb_vprobe_t;

#define	SMB_VPROBE_MINLEN		0x14
#define	SMB_VPROBE_NOMINAL_MINLEN	0x16

#define	SMB_VPROBE_LOCATION(x)	((x) & 0x1f)
#define	SMB_VPROBE_STATUS(x)	(((x) >> 5) & 0x7)

/*
 * SMBIOS implementation structure for SMB_TYPE_COOLDEV.
 */
typedef struct smb_cooldev {
	smb_header_t smbcdev_hdr;	/* structure header */
	uint16_t smbcdev_tprobe;	/* temperature probe */
	uint8_t smbcdev_typstat;	/* type and status */
	uint8_t smbcdev_group;		/* group identifier */
	uint32_t smbcdev_oem;		/* vendor-specific data */
	uint16_t smbcdev_nominal;	/* nominal value */
	uint8_t smbcdev_descr;		/* description string */
} smb_cooldev_t;

#define	SMB_COOLDEV_MINLEN		0x0c
#define	SMB_COOLDEV_NOMINAL_MINLEN	0x0e
#define	SMB_COOLDEV_DESCR_MINLEN	0x0f

#define	SMB_COOLDEV_TYPE(x)	((x) & 0x1f)
#define	SMB_COOLDEV_STATUS(x)	(((x) >> 5) & 0x7)

/*
 * SMBIOS implementation structure for SMB_TYPE_TPROBE.
 */
typedef struct smb_tprobe {
	smb_header_t smbtpr_hdr;	/* structure header */
	uint8_t smbtpr_descr;		/* description string */
	uint8_t smbtpr_locstat;		/* location and status */
	uint16_t smbtpr_maxval;		/* maximum temperature */
	uint16_t smbtpr_minval;		/* minimum temperature */
	uint16_t smbtpr_resolution;	/* probe resolution */
	uint16_t smbtpr_tolerance;	/* probe tolerance */
	uint16_t smbtpr_accuracy;	/* probe accuracy */
	uint32_t smbtpr_oem;		/* vendor-specific data */
	uint16_t smbtpr_nominal;	/* nominal value */
} smb_tprobe_t;

#define	SMB_TPROBE_MINLEN		0x14
#define	SMB_TPROBE_NOMINAL_MINLEN	0x16

#define	SMB_TPROBE_LOCATION(x)	((x) & 0x1f)
#define	SMB_TPROBE_STATUS(x)	(((x) >> 5) & 0x7)

/*
 * SMBIOS implementation structure for SMB_TYPE_IPROBE.
 */
typedef struct smb_iprobe {
	smb_header_t smbipr_hdr;	/* structure header */
	uint8_t smbipr_descr;		/* description string */
	uint8_t smbipr_locstat;		/* location and status */
	uint16_t smbipr_maxval;		/* maximum current */
	uint16_t smbipr_minval;		/* minimum current */
	uint16_t smbipr_resolution;	/* probe resolution */
	uint16_t smbipr_tolerance;	/* probe tolerance */
	uint16_t smbipr_accuracy;	/* probe accuracy */
	uint32_t smbipr_oem;		/* vendor-specific data */
	uint16_t smbipr_nominal;	/* nominal value */
} smb_iprobe_t;

#define	SMB_IPROBE_MINLEN		0x14
#define	SMB_IPROBE_NOMINAL_MINLEN	0x16

#define	SMB_IPROBE_LOCATION(x)	((x) & 0x1f)
#define	SMB_IPROBE_STATUS(x)	(((x) >> 5) & 0x7)

/*
 * SMBIOS implementation structure for SMB_TYPE_BOOT.
 */
typedef struct smb_boot {
	smb_header_t smbbo_hdr;		/* structure header */
	uint8_t smbbo_pad[6];		/* reserved for future use */
	uint8_t smbbo_status[1];	/* variable-length status buffer */
} smb_boot_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_MGMTDEV.
 */
typedef struct smb_mgmtdev {
	smb_header_t smbmgd_hdr;	/* structure header */
	uint8_t smbmgd_desc;		/* description */
	uint8_t smbmgd_dtype;		/* device type */
	uint32_t smbmgd_addr;		/* device address */
	uint8_t smbmgd_atype;		/* address type */
} smb_mgmtdev_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_MGMTDEVCP.
 */
typedef struct smb_mgmtcomp {
	smb_header_t smbmgc_hdr;	/* structure header */
	uint8_t smbmgc_desc;		/* description */
	uint16_t smbmgc_mgmtdev;	/* management device handle */
	uint16_t smbmgc_comp;		/* component handle */
	uint16_t smbmgc_thresh;		/* threshold handle */
} smb_mgmtcomp_t;


/*
 * SMBIOS implementation structure for SMB_TYPE_IPMIDEV.
 */
typedef struct smb_ipmi {
	smb_header_t smbipm_hdr;	/* structure header */
	uint8_t smbipm_type;		/* interface type */
	uint8_t smbipm_spec;		/* specification revision */
	uint8_t smbipm_i2c;		/* i2C slave address */
	uint8_t smbipm_bus;		/* NV storage device bus ID */
	uint64_t smbipm_addr;		/* base address */
	uint8_t smbipm_info;		/* base address modifier/intr info */
	uint8_t smbipm_intr;		/* interrupt number */
} smb_ipmi_t;

#define	SMB_IPM_SPEC_MAJOR(x)	(((x) & 0xF0) >> 4)
#define	SMB_IPM_SPEC_MINOR(x)	((x) & 0x0F)

#define	SMB_IPM_ADDR_IO		1ULL

#define	SMB_IPM_INFO_REGS(x)	(((x) & 0xC0) >> 6)
#define	SMB_IPM_INFO_LSB(x)	(((x) & 0x10) >> 4)
#define	SMB_IPM_INFO_ISPEC(x)	(((x) & 0x08) >> 3)
#define	SMB_IPM_INFO_IPOL(x)	(((x) & 0x02) >> 1)
#define	SMB_IPM_INFO_IMODE(x)	(((x) & 0x01) >> 0)

#define	SMB_IPM_REGS_1B		0
#define	SMB_IPM_REGS_4B		1
#define	SMB_IPM_REGS_16B	2

#define	SMB_IPM_IPOL_LO		0
#define	SMB_IPM_IPOL_HI		1

#define	SMB_IPM_IMODE_EDGE	0
#define	SMB_IPM_IMODE_LEVEL	1

/*
 * SMBIOS implementation structure for SMB_TYPE_POWERSUP.
 */
typedef struct smb_powersup {
	smb_header_t smbpsup_hdr;	/* structure header */
	uint8_t smbpsup_group;		/* group id */
	uint8_t smbpsup_loc;		/* location tag */
	uint8_t smbpsup_devname;	/* device name */
	uint8_t smbpsup_manufacturer;	/* manufacturer */
	uint8_t smbpsup_serial;		/* serial number */
	uint8_t smbpsup_asset;		/* asset tag */
	uint8_t smbpsup_part;		/* part number */
	uint8_t smbpsup_rev;		/* revision string */
	uint16_t smbpsup_max;		/* max output in milliwatts */
	uint16_t smbpsup_char;		/* characteristics */
	uint16_t smbpsup_vprobe;	/* voltage probe handle */
	uint16_t smbpsup_cooldev;	/* cooling device handle */
	uint16_t smbpsup_iprobe;	/* current probe handle */
} smb_powersup_t;

#define	SMB_PSU_CHARS_ISHOT(x)		((x) & 0x01)
#define	SMB_PSU_CHARS_ISPRES(x)		((x) & 0x02)
#define	SMB_PSU_CHARS_ISUNPLUG(x)	((x) & 0x04)
#define	SMB_PSU_CHARS_IVRS(x)		(((x) >> 3) & 0xf)
#define	SMB_PSU_CHARS_STATUS(x)		(((x) >> 7) & 0x7)
#define	SMB_PSU_CHARS_TYPE(x)		(((x) >> 10) & 0xf)

/*
 * SMBIOS implementation structure for SMB_TYPE_ADDINFO.
 */
typedef struct smb_addinfo {
	smb_header_t smbai_hdr;
	uint8_t smbai_nents;
	uint8_t smbai_data[];
} smb_addinfo_t;

/*
 * This contains the additional information entry. There are in theory n of
 * these in the smbai_data[] member of the additional information structure
 * above. The offset here is to the referenced handle.
 */
typedef struct smb_addinfo_ent {
	uint8_t smbaie_len;
	uint16_t smbaie_rhdl;
	uint8_t smbaie_off;
	uint8_t smbaie_str;
	uint8_t smbaie_val[];
} smb_addinfo_ent_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_OBDEVEXT.
 */
typedef struct smb_obdev_ext {
	smb_header_t smbobe_hdr;	/* structure header */
	uint8_t smbobe_name;		/* reference designation */
	uint8_t smbobe_dtype;		/* device type */
	uint8_t smbobe_dti;		/* device type instance */
	uint16_t smbobe_sg;		/* segment group number */
	uint8_t smbobe_bus;		/* bus number */
	uint8_t smbobe_df;		/* device/function number */
} smb_obdev_ext_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_TPM
 */
typedef struct smb_tpm {
	smb_header_t smbtpm_hdr;	/* structure header */
	uint8_t smbtpm_vid[4];		/* vendor ID */
	uint8_t smbtpm_major;		/* major version */
	uint8_t smbtpm_minor;		/* minor version */
	uint32_t smbtpm_fwv1;		/* firmware version 1 */
	uint32_t smbtpm_fwv2;		/* firmware version 2 */
	uint8_t smbtpm_desc;		/* description */
	uint64_t smbtpm_chars;		/* characteristics */
	uint32_t smbtpm_oem;		/* OEM data */
} smb_tpm_t;

/*
 * SMBIOS implementation structure for SMB_TYPE_PROCESSOR_INFO
 */
typedef struct smb_processor_info {
	smb_header_t smbpai_hdr;	/* structure handle */
	uint16_t smbpai_proc;		/* processor handle */
	uint8_t smbpai_len;		/* length of processor specific data */
	uint8_t smbpai_type;		/* processor type */
	uint8_t smbpai_data[];		/* processor-specific block */
} smb_processor_info_t;

typedef struct smb_processor_info_riscv {
	uint16_t smbpairv_vers;		/* structure revision */
	uint8_t smbpairv_len;		/* length of structure */
	uint8_t smbpairv_hartid[16];	/* id of the hart */
	uint8_t smbpairv_boot;		/* boot hart */
	uint8_t smbpairv_vendid[16];	/* machine vendor id */
	uint8_t smbpairv_archid[16];	/* arch vendor id */
	uint8_t smbpairv_machid[16];	/* machine impl id */
	uint32_t smbpairv_isa;		/* supported ISA */
	uint8_t smbpairv_privlvl;		/* supported privilege levels */
	uint8_t smbpairv_metdi[16];	/* Machine exception trap delegation */
	uint8_t smbpairv_mitdi[16];	/* Machine interrupt trap delegation */
	uint8_t smbpairv_xlen;		/* Register width */
	uint8_t smbpairv_mxlen;		/* Machine register width */
	uint8_t smbpairv_rsvd;		/* Reserved */
	uint8_t smbpairv_sxlen;		/* Supervisor register width */
	uint8_t smbpairv_uxlen;		/* User register width */
} smb_processor_info_riscv_t;

/*
 * SMBIOS implementation structure for SMBIOS_TYPE_FWINFO.
 */
typedef struct smb_fwinfo {
	smb_header_t smbfwii_hdr;	/* structure handle */
	uint8_t smbfwii_name;		/* Firmware component name */
	uint8_t smbfwii_vers;		/* Firmware version */
	uint8_t smbfwii_vers_fmt;	/* Version format */
	uint8_t smbfwii_id;		/* Firmware ID */
	uint8_t smbfwii_id_fmt;		/* Firmware ID format */
	uint8_t smbfwii_reldate;	/* Release Date */
	uint8_t smbfwii_mfg;		/* Manufacturer */
	uint8_t smbfwii_lsv;		/* Lowest supported version */
	uint64_t smbfwii_imgsz;		/* Image size */
	uint16_t smbfwii_chars;		/* Characteristics */
	uint8_t smbfwii_state;		/* State */
	uint8_t smbfwii_ncomps;		/* Number of associated components */
	uint16_t smbfwii_comps[];	/* Variable handles */
} smb_fwinfo_t;

/*
 * SMBIOS implementation structure for SMBIOS_TYPE_STRPROP.
 */
typedef struct smb_strprop {
	smb_header_t smbstrp_hdr;	/* structure handle */
	uint16_t smbstrp_prop_id;	/* string property ID */
	uint8_t smbstrp_prop_val;	/* string property value */
	uint16_t smbstrp_phdl;		/* parent handle */
} smb_strprop_t;

/*
 * SMBIOS implementation structure for SUN_OEM_EXT_PROCESSOR.
 */
typedef struct smb_processor_ext {
	smb_header_t smbpre_hdr;	/* structure header */
	uint16_t smbpre_processor;	/* processor handle */
	uint8_t smbpre_fru;		/* FRU indicator */
	uint8_t smbpre_n;		/* number of APIC IDs */
	uint16_t smbpre_apicid[1];	/* strand initial apic id */
} smb_processor_ext_t;

/*
 * SMBIOS implementation structure for SUN_OEM_EXT_PORT.
 */
typedef struct smb_port_ext {
	smb_header_t smbpoe_hdr;	/* structure header */
	uint16_t smbpoe_chassis;	/* chassis handle */
	uint16_t smbpoe_port;		/* port connector handle */
	uint8_t smbpoe_dtype;		/* device type */
	uint16_t smbpoe_devhdl;		/* device handle */
	uint8_t smbpoe_phy;		/* PHY number */
} smb_port_ext_t;

/*
 * SMBIOS implementation structure for SUN_OEM_PCIEXRC.
 */
typedef struct smb_pciexrc {
	smb_header_t smbpciexrc_hdr;	/* structure header */
	uint16_t smbpciexrc_bboard;	/* base board handle */
	uint16_t smbpciexrc_bdf;	/* PCI Bus/Dev/Func */
} smb_pciexrc_t;

/*
 * SMBIOS implementation structure for SUN_OEM_EXT_MEMARRAY.
 */
typedef struct smb_memarray_ext {
	smb_header_t smbmarre_hdr;	/* structure header */
	uint16_t smbmarre_ma;		/* memory array handle */
	uint16_t smbmarre_component;	/* component parent handle */
	uint16_t smbmarre_bdf;		/* PCI bus/dev/funct */
} smb_memarray_ext_t;

/*
 * SMBIOS implementation structure for SUN_OEM_EXT_MEMDEVICE.
 */
typedef struct smb_memdevice_ext {
	smb_header_t smbmdeve_hdr;	/* structure header */
	uint16_t smbmdeve_mdev;		/* memory device handle */
	uint8_t smbmdeve_dchan;		/* DRAM channel */
	uint8_t smbmdeve_ncs;		/* number of chip select */
	uint8_t smbmdeve_cs[];		/* chip selects */
} smb_memdevice_ext_t;

#pragma pack()

typedef struct smb_struct {
	const smb_header_t *smbst_hdr;	/* address of raw structure data */
	const uchar_t *smbst_str;	/* address of string data (if any) */
	const uchar_t *smbst_end;	/* address of 0x0000 ending tag */
	struct smb_struct *smbst_next;	/* next structure in hash chain */
	uint16_t *smbst_strtab;		/* string index -> offset table */
	uint_t smbst_strtablen;		/* length of smbst_strtab */
} smb_struct_t;

struct smbios_hdl {
	smbios_entry_point_t sh_ent_type; /* structure table entry point type */
	smbios_entry_t sh_ent;		/* structure table entry point */
	uint_t sh_ent_stnum;		/* number of structure table entries */
	const void *sh_buf;		/* structure table buffer */
	size_t sh_buflen;		/* size of structure table buffer */
	smb_struct_t *sh_structs;	/* array of structure descriptors */
	uint_t sh_nstructs;		/* number of active structures */
	smb_struct_t **sh_hash;		/* hash bucket array for descriptors */
	uint_t sh_hashlen;		/* hash bucket array length */
	int sh_err;			/* error code for smbios_errno() */
	int sh_libvers;			/* library client abi version */
	int sh_smbvers;			/* derived underlying format version */
	uint_t sh_flags;		/* miscellaneous flags (see below) */
};

#define	SMB_FL_DEBUG	0x1		/* print debug messages for this hdl */
#define	SMB_FL_BUFALLOC	0x2		/* sh_buf was allocated by library */
#define	SMB_FL_TRUNC	0x4		/* smbios table is truncated */

#define	SMB_BIOS_DEVICE		"/dev/xsvc"	/* device w/ BIOS physmem */
#define	SMB_SMBIOS_DEVICE	"/dev/smbios"	/* device w/ SMBIOS image */

#define	SMB_RANGE_START	0xF0000		/* start of physical address range */
#define	SMB_RANGE_LIMIT	0xFFFFF		/* limit of physical address range */
#define	SMB_SCAN_STEP	16		/* stepping by paragraph */

#define	SMB_MAJMIN(M, m)	((((M) & 0xFF) << 8) | ((m) & 0xFF))
#define	SMB_MAJOR(v)		(((v) & 0xFF00) >> 8)
#define	SMB_MINOR(v)		(((v) & 0x00FF))

#define	ESMB_BASE	1000		/* base value for libsmbios errnos */

enum {
	ESMB_NOTFOUND = ESMB_BASE,	/* SMBIOS table not found on system */
	ESMB_MAPDEV,			/* failed to map SMBIOS table */
	ESMB_NOENT,			/* failed to locate structure */
	ESMB_NOMEM,			/* failed to allocate memory */
	ESMB_NOHDR,			/* failed to read SMBIOS header */
	ESMB_NOSTAB,			/* failed to read SMBIOS struct table */
	ESMB_NOINFO,			/* no common info for structure */
	ESMB_SHORT,			/* buffer length doesn't match header */
	ESMB_CORRUPT,			/* buffer struct or len is corrupt */
	ESMB_VERSION,			/* version not supported by library */
	ESMB_NOTSUP,			/* feature not supported by provider */
	ESMB_HEADER,			/* SMBIOS header corrupt or invalid */
	ESMB_OLD,			/* SMBIOS version is too old for us */
	ESMB_NEW,			/* SMBIOS version is too new for us */
	ESMB_CKSUM,			/* SMBIOS header checksum mismatch */
	ESMB_INVAL,			/* invalid function call argument */
	ESMB_TYPE,			/* structure type mismatch */
	ESMB_UNKNOWN,			/* unknown error */
	ESMB_REQVAL			/* invalid requested value */
};

extern const smb_struct_t *smb_lookup_type(smbios_hdl_t *, uint_t);
extern const smb_struct_t *smb_lookup_id(smbios_hdl_t *, uint_t);
extern const char *smb_strptr(const smb_struct_t *, uint_t);
extern boolean_t smb_gteq(smbios_hdl_t *, int);
extern boolean_t smb_libgteq(smbios_hdl_t *, int);

extern int smb_set_errno(smbios_hdl_t *, int);
extern smbios_hdl_t *smb_open_error(smbios_hdl_t *, int *, int);
extern const char *smb_strerror(int);

extern void *smb_alloc(size_t);
extern void *smb_zalloc(size_t);
extern void smb_free(void *, size_t);

extern void smb_dprintf(smbios_hdl_t *, const char *, ...);

extern int _smb_debug;

/*
 * The following series of structures represent the base versions of public
 * structures that are used inside by the smbios routines. This allows the
 * common code to properly know how much it should or should not bzero and how
 * to handle additions to the spec. Types should only be added here if we need
 * to extend the public structures in sys/smbios.h due to a change in the spec.
 *
 * Types here have the name smb_base_%s which corresponds to smbios_%s.
 */
typedef struct smb_base_chassis {
	uint32_t smbbc_oemdata;		/* OEM-specific data */
	uint8_t smbbc_lock;		/* lock present? */
	uint8_t smbbc_type;		/* type */
	uint8_t smbbc_bustate;		/* boot-up state */
	uint8_t smbbc_psstate;		/* power supply state */
	uint8_t smbbc_thstate;		/* thermal state */
	uint8_t smbbc_security;		/* security status */
	uint8_t smbbc_uheight;		/* enclosure height in U's */
	uint8_t smbbc_cords;		/* number of power cords */
	uint8_t smbbc_elems;		/* number of element records (n) */
	uint8_t smbbc_elemlen;		/* length of contained element (m) */
} smb_base_chassis_t;

typedef struct smb_base_processor {
	uint64_t smbbp_cpuid;		/* processor cpuid information */
	uint32_t smbbp_family;		/* processor family */
	uint8_t smbbp_type;		/* processor type (SMB_PRT_*) */
	uint8_t smbbp_voltage;		/* voltage (SMB_PRV_*) */
	uint8_t smbbp_status;		/* status (SMB_PRS_*) */
	uint8_t smbbp_upgrade;		/* upgrade (SMB_PRU_*) */
	uint32_t smbbp_clkspeed;	/* external clock speed in MHz */
	uint32_t smbbp_maxspeed;	/* maximum speed in MHz */
	uint32_t smbbp_curspeed;	/* current speed in MHz */
	id_t smbbp_l1cache;		/* L1 cache handle */
	id_t smbbp_l2cache;		/* L2 cache handle */
	id_t smbbp_l3cache;		/* L3 cache handle */
} smb_base_processor_t;

typedef struct smb_base_memdevice {
	id_t smbbmd_array;		/* handle of physical memory array */
	id_t smbbmd_error;		/* handle of memory error data */
	uint32_t smbbmd_twidth;		/* total width in bits including ecc */
	uint32_t smbbmd_dwidth;		/* data width in bits */
	uint64_t smbbmd_size;		/* size in bytes (see note above) */
	uint8_t smbbmd_form;		/* form factor */
	uint8_t smbbmd_set;		/* set (0x00=none, 0xFF=unknown) */
	uint8_t smbbmd_type;		/* memory type */
	uint8_t smbbmd_pad;		/* padding */
	uint32_t smbbmd_flags;		/* flags (see below) */
	uint32_t smbbmd_speed;		/* speed in MHz */
	const char *smbbmd_dloc;	/* physical device locator string */
	const char *smbbmd_bloc;	/* physical bank locator string */
	uint8_t smbbmd_rank;		/* rank */
} smb_base_memdevice_t;

typedef struct smb_base_bios {
	const char *smbbb_vendor;	/* bios vendor string */
	const char *smbbb_version;	/* bios version string */
	const char *smbbb_reldate;	/* bios release date */
	uint32_t smbbb_segment;		/* bios address segment location */
	uint32_t smbbb_romsize;		/* bios rom size in bytes */
	uint32_t smbbb_runsize;		/* bios image size in bytes */
	uint64_t smbbb_cflags;		/* bios characteristics */
	const uint8_t *smbbb_xcflags;	/* bios characteristics extensions */
	size_t smbbb_nxcflags;		/* number of smbb_xcflags[] bytes */
	smbios_version_t smbbb_biosv;	/* bios version */
	smbios_version_t smbbb_ecfwv;	/* bios embedded ctrl f/w version */
} smb_base_bios_t;

typedef struct smb_base_cache {
	uint32_t smbba_maxsize;		/* maximum installed size in bytes */
	uint32_t smbba_size;		/* installed size in bytes */
	uint16_t smbba_stype;		/* supported SRAM types (SMB_CAT_*) */
	uint16_t smbba_ctype;		/* current SRAM type (SMB_CAT_*) */
	uint8_t smbba_speed;		/* speed in nanoseconds */
	uint8_t smbba_etype;		/* error correction type (SMB_CAE_*) */
	uint8_t smbba_ltype;		/* logical cache type (SMB_CAG_*) */
	uint8_t smbba_assoc;		/* associativity (SMB_CAA_*) */
	uint8_t smbba_level;		/* cache level */
	uint8_t smbba_mode;		/* cache mode (SMB_CAM_*) */
	uint8_t smbba_location;		/* cache location (SMB_CAL_*) */
	uint8_t smbba_flags;		/* cache flags (SMB_CAF_*) */
} smb_base_cache_t;

typedef struct smb_base_slot {
	const char *smbbl_name;		/* reference designation */
	uint8_t smbbl_type;		/* slot type */
	uint8_t smbbl_width;		/* slot data bus width */
	uint8_t smbbl_usage;		/* current usage */
	uint8_t smbbl_length;		/* slot length */
	uint16_t smbbl_id;		/* slot ID */
	uint8_t smbbl_ch1;		/* slot characteristics 1 */
	uint8_t smbbl_ch2;		/* slot characteristics 2 */
	uint16_t smbbl_sg;		/* segment group number */
	uint8_t smbbl_bus;		/* bus number */
	uint8_t smbbl_df;		/* device/function number */
} smb_base_slot_t;

/*
 * Prior to reivison 3.5 of the library and interface we had embedded a 256 byte
 * string for the SKU into here rather than pointing to constant data. This,
 * combined withe bugs in the implementation, generally led to strings with
 * garbage. As part of fixing this with the 3.5 support, we moved the struct to
 * ve more inline with everything else.
 */
typedef struct smb_chassis_pre35 {
	uint32_t smbc_oemdata;		/* OEM-specific data */
	uint8_t smbc_lock;		/* lock present? */
	uint8_t smbc_type;		/* type */
	uint8_t smbc_bustate;		/* boot-up state */
	uint8_t smbc_psstate;		/* power supply state */
	uint8_t smbc_thstate;		/* thermal state */
	uint8_t smbc_security;		/* security status */
	uint8_t smbc_uheight;		/* enclosure height in U's */
	uint8_t smbc_cords;		/* number of power cords */
	uint8_t smbc_elems;		/* number of element records (n) */
	uint8_t smbc_elemlen;		/* length of contained element (m) */
	char smbc_sku[256];
} smb_chassis_pre35_t;

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_SMBIOS_IMPL_H */