#include "smbios_test.h"
static uint16_t smbios_pinfo_phandle = 0x1;
static uint64_t smbios_pinfo_isa = 0x4010d;
static uint8_t smbios_pinfo_hartid[16];
static uint8_t smbios_pinfo_vendid[16];
static uint8_t smbios_pinfo_archid[16];
static uint8_t smbios_pinfo_machid[16];
static uint8_t smbios_pinfo_metdi[16];
static uint8_t smbios_pinfo_mitdi[16];
boolean_t
smbios_test_pinfo_mktable_amd64(smbios_test_table_t *table)
{
smb_processor_info_t pi;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t);
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = 0;
pi.smbpai_type = SMB_PROCINFO_T_AMD64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
boolean_t
smbios_test_pinfo_verify_amd64(smbios_hdl_t *hdl)
{
smbios_struct_t sp;
smbios_processor_info_t pinfo;
smbios_processor_info_riscv_t rv;
boolean_t ret = B_TRUE;
if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) {
warnx("failed to lookup SMBIOS processor additional "
"information: %s", smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != 0) {
warnx("failed to get SMBIOS processor additional "
"information: %s", smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (pinfo.smbpi_processor != smbios_pinfo_phandle) {
warnx("processor handle incorrect, found 0x%" _PRIxID,
pinfo.smbpi_processor);
ret = B_FALSE;
}
if (pinfo.smbpi_ptype != SMB_PROCINFO_T_AMD64) {
warnx("processor type incorrect, found 0x%x",
pinfo.smbpi_ptype);
ret = B_FALSE;
}
if (strcmp(smbios_processor_info_type_desc(pinfo.smbpi_ptype),
"X64 (x86-64, Intel64, AMD64, EMT64)") != 0) {
warnx("processor type incorrect, found %s",
smbios_processor_info_type_desc(pinfo.smbpi_ptype));
ret = B_FALSE;
}
if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) {
warnx("accidentally got riscv info on non-riscv handle");
ret = B_FALSE;
}
if (smbios_errno(hdl) != ESMB_TYPE) {
warnx("encountered wrong errno for RISC-V info, found: 0x%x",
smbios_errno(hdl));
ret = B_FALSE;
}
return (ret);
}
boolean_t
smbios_test_pinfo_mktable_riscv(smbios_test_table_t *table)
{
smb_processor_info_t pi;
smb_processor_info_riscv_t rv;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t) +
sizeof (smb_processor_info_riscv_t);
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = sizeof (smb_processor_info_riscv_t);
pi.smbpai_type = SMB_PROCINFO_T_RV64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
rv.smbpairv_vers = 1;
rv.smbpairv_len = sizeof (smb_processor_info_riscv_t);
arc4random_buf(smbios_pinfo_hartid, sizeof (smbios_pinfo_hartid));
bcopy(smbios_pinfo_hartid, rv.smbpairv_hartid,
sizeof (smbios_pinfo_hartid));
rv.smbpairv_boot = 1;
arc4random_buf(smbios_pinfo_vendid, sizeof (smbios_pinfo_vendid));
bcopy(smbios_pinfo_vendid, rv.smbpairv_vendid,
sizeof (smbios_pinfo_vendid));
arc4random_buf(smbios_pinfo_archid, sizeof (smbios_pinfo_archid));
bcopy(smbios_pinfo_archid, rv.smbpairv_archid,
sizeof (smbios_pinfo_archid));
arc4random_buf(smbios_pinfo_machid, sizeof (smbios_pinfo_machid));
bcopy(smbios_pinfo_machid, rv.smbpairv_machid,
sizeof (smbios_pinfo_machid));
rv.smbpairv_boot = 1;
rv.smbpairv_isa = htole64(smbios_pinfo_isa);
rv.smbpairv_privlvl = SMB_RV_PRIV_M | SMB_RV_PRIV_S;
arc4random_buf(smbios_pinfo_metdi, sizeof (smbios_pinfo_metdi));
bcopy(smbios_pinfo_metdi, rv.smbpairv_metdi,
sizeof (smbios_pinfo_metdi));
arc4random_buf(smbios_pinfo_mitdi, sizeof (smbios_pinfo_mitdi));
bcopy(smbios_pinfo_mitdi, rv.smbpairv_mitdi,
sizeof (smbios_pinfo_mitdi));
rv.smbpairv_xlen = SMB_RV_WIDTH_64B;
rv.smbpairv_mxlen = SMB_RV_WIDTH_64B;
rv.smbpairv_sxlen = SMB_RV_WIDTH_128B;
rv.smbpairv_uxlen = SMB_RV_WIDTH_32B;
smbios_test_table_append_raw(table, &rv, sizeof (rv));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
static void
smbios_test_pinfo_id_mismatch(uint8_t *act, uint8_t *exp)
{
uint_t i;
(void) fprintf(stderr, "found: ");
for (i = 0; i < 16; i++) {
(void) fprintf(stderr, " %02x", act[i]);
}
(void) fprintf(stderr, "\nexpected: ");
for (i = 0; i < 16; i++) {
(void) fprintf(stderr, " %02x", exp[i]);
}
(void) fprintf(stderr, "\n");
}
boolean_t
smbios_test_pinfo_verify_riscv(smbios_hdl_t *hdl)
{
smbios_struct_t sp;
smbios_processor_info_t pinfo;
smbios_processor_info_riscv_t rv;
boolean_t ret = B_TRUE;
if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) {
warnx("failed to lookup SMBIOS processor additional "
"information: %s", smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != 0) {
warnx("failed to get SMBIOS processor additional "
"information: %s", smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (pinfo.smbpi_processor != smbios_pinfo_phandle) {
warnx("processor handle incorrect, found 0x%" _PRIxID,
pinfo.smbpi_processor);
ret = B_FALSE;
}
if (pinfo.smbpi_ptype != SMB_PROCINFO_T_RV64) {
warnx("processor type incorrect, found 0x%x",
pinfo.smbpi_ptype);
ret = B_FALSE;
}
if (strcmp(smbios_processor_info_type_desc(pinfo.smbpi_ptype),
"64-bit RISC-V (RV64)") != 0) {
warnx("processor type incorrect, found %s",
smbios_processor_info_type_desc(pinfo.smbpi_ptype));
ret = B_FALSE;
}
if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != 0) {
warnx("failed to get SMBIOS processor additional "
"information for RISC-V: %s",
smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (bcmp(rv.smbpirv_hartid, smbios_pinfo_hartid,
sizeof (smbios_pinfo_hartid)) != 0) {
warnx("RISC-V hart id's don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_hartid,
smbios_pinfo_hartid);
ret = B_FALSE;
}
if (bcmp(rv.smbpirv_vendid, smbios_pinfo_vendid,
sizeof (smbios_pinfo_vendid)) != 0) {
warnx("RISC-V vend id's don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_vendid,
smbios_pinfo_vendid);
ret = B_FALSE;
}
if (bcmp(rv.smbpirv_archid, smbios_pinfo_archid,
sizeof (smbios_pinfo_archid)) != 0) {
warnx("RISC-V arch id's don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_archid,
smbios_pinfo_archid);
ret = B_FALSE;
}
if (bcmp(rv.smbpirv_machid, smbios_pinfo_machid,
sizeof (smbios_pinfo_machid)) != 0) {
warnx("RISC-V mach id's don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_machid,
smbios_pinfo_machid);
ret = B_FALSE;
}
if (bcmp(rv.smbpirv_metdi, smbios_pinfo_metdi,
sizeof (smbios_pinfo_metdi)) != 0) {
warnx("RISC-V METDI don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_metdi,
smbios_pinfo_metdi);
ret = B_FALSE;
}
if (bcmp(rv.smbpirv_mitdi, smbios_pinfo_mitdi,
sizeof (smbios_pinfo_mitdi)) != 0) {
warnx("RISC-V METDI don't match");
smbios_test_pinfo_id_mismatch(rv.smbpirv_mitdi,
smbios_pinfo_mitdi);
ret = B_FALSE;
}
if (rv.smbpirv_isa != smbios_pinfo_isa) {
warnx("RISC-V ISA mismatch");
ret = B_FALSE;
}
if (rv.smbpirv_privlvl != (SMB_RV_PRIV_M | SMB_RV_PRIV_S)) {
warnx("RISC-V privilege level mismatch, found: 0x%x",
rv.smbpirv_privlvl);
ret = B_FALSE;
}
if (rv.smbpirv_xlen != SMB_RV_WIDTH_64B) {
warnx("RISC-V xlen mismatch, found: 0x%x", rv.smbpirv_xlen);
ret = B_FALSE;
}
if (rv.smbpirv_mxlen != SMB_RV_WIDTH_64B) {
warnx("RISC-V mxlen mismatch, found: 0x%x", rv.smbpirv_mxlen);
ret = B_FALSE;
}
if (rv.smbpirv_sxlen != SMB_RV_WIDTH_128B) {
warnx("RISC-V sxlen mismatch, found: 0x%x", rv.smbpirv_sxlen);
ret = B_FALSE;
}
if (rv.smbpirv_uxlen != SMB_RV_WIDTH_32B) {
warnx("RISC-V uxlen mismatch, found: 0x%x", rv.smbpirv_uxlen);
ret = B_FALSE;
}
if (strcmp(smbios_riscv_priv_desc(SMB_RV_PRIV_M), "Machine Mode") !=
0) {
warnx("SMB_RV_PRIV_M string desc mismatch, found %s",
smbios_riscv_priv_desc(SMB_RV_PRIV_M));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_priv_name(SMB_RV_PRIV_U), "SMB_RV_PRIV_U") !=
0) {
warnx("SMB_RV_PRIV_U string name mismatch, found %s",
smbios_riscv_priv_name(SMB_RV_PRIV_U));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_width_desc(SMB_RV_WIDTH_64B), "64-bit") !=
0) {
warnx("SMB_RV_WIDTH_64B string desc mismatch, found %s",
smbios_riscv_width_desc(SMB_RV_WIDTH_64B));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_width_desc(SMB_RV_WIDTH_128B), "128-bit") !=
0) {
warnx("SMB_RV_WIDTH_128B string desc mismatch, found %s",
smbios_riscv_width_desc(SMB_RV_WIDTH_128B));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_A), "Atomic") != 0) {
warnx("SMB_RV_ISA_A string desc mismatch, found %s",
smbios_riscv_isa_desc(SMB_RV_ISA_A));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_C), "Compressed") != 0) {
warnx("SMB_RV_ISA_C string desc mismatch, found %s",
smbios_riscv_isa_desc(SMB_RV_ISA_C));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_desc(SMB_RV_ISA_Q),
"Quad-precision floating-point") != 0) {
warnx("SMB_RV_ISA_Q string desc mismatch, found %s",
smbios_riscv_isa_desc(SMB_RV_ISA_Q));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_A), "SMB_RV_ISA_A") != 0) {
warnx("SMB_RV_ISA_A string name mismatch, found %s",
smbios_riscv_isa_name(SMB_RV_ISA_A));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_C), "SMB_RV_ISA_C") != 0) {
warnx("SMB_RV_ISA_Q string name mismatch, found %s",
smbios_riscv_isa_name(SMB_RV_ISA_C));
ret = B_FALSE;
}
if (strcmp(smbios_riscv_isa_name(SMB_RV_ISA_Q), "SMB_RV_ISA_Q") != 0) {
warnx("SMB_RV_ISA_Q string name mismatch, found %s",
smbios_riscv_isa_name(SMB_RV_ISA_Q));
ret = B_FALSE;
}
return (ret);
}
boolean_t
smbios_test_pinfo_mktable_invlen1(smbios_test_table_t *table)
{
smb_processor_info_t pi;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = 2;
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = 0;
pi.smbpai_type = SMB_PROCINFO_T_AMD64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
boolean_t
smbios_test_pinfo_mktable_invlen2(smbios_test_table_t *table)
{
smb_processor_info_t pi;
smb_processor_info_riscv_t rv;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t);
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = sizeof (smb_processor_info_riscv_t);
pi.smbpai_type = SMB_PROCINFO_T_RV64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
arc4random_buf(&rv, sizeof (rv));
rv.smbpairv_vers = 1;
rv.smbpairv_len = sizeof (smb_processor_info_riscv_t);
smbios_test_table_append_raw(table, &rv, sizeof (rv));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
boolean_t
smbios_test_pinfo_mktable_invlen3(smbios_test_table_t *table)
{
smb_processor_info_t pi;
smb_processor_info_riscv_t rv;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t);
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = 0;
pi.smbpai_type = SMB_PROCINFO_T_RV64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
arc4random_buf(&rv, sizeof (rv));
rv.smbpairv_vers = 1;
rv.smbpairv_len = sizeof (smb_processor_info_riscv_t);
smbios_test_table_append_raw(table, &rv, sizeof (rv));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
boolean_t
smbios_test_pinfo_mktable_invlen4(smbios_test_table_t *table)
{
smb_processor_info_t pi;
smb_processor_info_riscv_t rv;
pi.smbpai_hdr.smbh_type = SMB_TYPE_PROCESSOR_INFO;
pi.smbpai_hdr.smbh_len = sizeof (smb_processor_info_t) +
sizeof (smb_processor_info_riscv_t);
pi.smbpai_proc = htole16(smbios_pinfo_phandle);
pi.smbpai_len = sizeof (smb_processor_info_riscv_t);
pi.smbpai_type = SMB_PROCINFO_T_RV64;
(void) smbios_test_table_append(table, &pi, sizeof (pi));
arc4random_buf(&rv, sizeof (rv));
rv.smbpairv_vers = 1;
rv.smbpairv_len = sizeof (smb_processor_info_riscv_t) * 2;
smbios_test_table_append_raw(table, &rv, sizeof (rv));
smbios_test_table_append_eot(table);
return (B_TRUE);
}
static boolean_t
smbios_test_pinfo_verify_badtable(smbios_hdl_t *hdl, int smberr,
boolean_t valid_pinfo)
{
smbios_struct_t sp;
smbios_processor_info_t pinfo;
smbios_processor_info_riscv_t rv;
boolean_t ret = B_TRUE;
if (smbios_lookup_type(hdl, SMB_TYPE_PROCESSOR_INFO, &sp) == -1) {
warnx("failed to lookup SMBIOS processor additional "
"information: %s", smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (!valid_pinfo) {
if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) !=
-1) {
warnx("accidentally parsed invalid processor "
"additional information as valid");
ret = B_FALSE;
}
if (smbios_errno(hdl) != smberr) {
warnx("encountered wrong error for processor info, "
"found: 0x%x", smbios_errno(hdl));
ret = B_FALSE;
}
} else {
if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) !=
0) {
warnx("failed to get SMBIOS processor additional "
"information: %s",
smbios_errmsg(smbios_errno(hdl)));
ret = B_FALSE;
}
}
if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) {
warnx("accidentally got riscv info on invalid handle");
ret = B_FALSE;
}
if (smbios_errno(hdl) != smberr) {
warnx("encountered wrong error for amd64 info, found: 0x%x",
smbios_errno(hdl));
ret = B_FALSE;
}
return (ret);
}
boolean_t
smbios_test_pinfo_verify_invlen1(smbios_hdl_t *hdl)
{
return (smbios_test_pinfo_verify_badtable(hdl, ESMB_SHORT, B_FALSE));
}
boolean_t
smbios_test_pinfo_verify_invlen2(smbios_hdl_t *hdl)
{
return (smbios_test_pinfo_verify_badtable(hdl, ESMB_CORRUPT, B_FALSE));
}
boolean_t
smbios_test_pinfo_verify_invlen3(smbios_hdl_t *hdl)
{
return (smbios_test_pinfo_verify_badtable(hdl, ESMB_SHORT, B_TRUE));
}
boolean_t
smbios_test_pinfo_verify_invlen4(smbios_hdl_t *hdl)
{
return (smbios_test_pinfo_verify_badtable(hdl, ESMB_CORRUPT, B_TRUE));
}
boolean_t
smbios_test_pinfo_verify_badtype(smbios_hdl_t *hdl)
{
smbios_struct_t sp;
smbios_processor_info_t pinfo;
smbios_processor_info_riscv_t rv;
boolean_t ret = B_TRUE;
if (smbios_lookup_type(hdl, SMB_TYPE_MEMDEVICE, &sp) == -1) {
warnx("failed to lookup SMBIOS memory device information: %s",
smbios_errmsg(smbios_errno(hdl)));
return (B_FALSE);
}
if (smbios_info_processor_info(hdl, sp.smbstr_id, &pinfo) != -1) {
warnx("accidentally parsed invalid processor additional "
"information as valid");
ret = B_FALSE;
}
if (smbios_errno(hdl) != ESMB_TYPE) {
warnx("encountered wrong error for processor info, found: 0x%x",
smbios_errno(hdl));
ret = B_FALSE;
}
if (smbios_info_processor_riscv(hdl, sp.smbstr_id, &rv) != -1) {
warnx("accidentally got riscv info on invalid handle");
ret = B_FALSE;
}
if (smbios_errno(hdl) != ESMB_TYPE) {
warnx("encountered wrong error for processor info, found: 0x%x",
smbios_errno(hdl));
ret = B_FALSE;
}
return (ret);
}