Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/smbios/smbios.c
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf | * http://www.dmtf.org/standards/published_documents/DSP0134.pdf | ||||
*/ | */ | ||||
struct smbios_softc { | struct smbios_softc { | ||||
device_t dev; | device_t dev; | ||||
struct resource * res; | struct resource * res; | ||||
int rid; | int rid; | ||||
union { | |||||
struct smbios_eps * eps; | struct smbios_eps * eps; | ||||
struct smbios3_eps * eps3; | |||||
}; | }; | ||||
bool eps_64bit; | |||||
}; | |||||
#define RES2EPS(res) ((struct smbios_eps *)rman_get_virtual(res)) | #define RES2EPS(res) ((struct smbios_eps *)rman_get_virtual(res)) | ||||
#define RES2EPS3(res) ((struct smbios3_eps *)rman_get_virtual(res)) | |||||
static devclass_t smbios_devclass; | static devclass_t smbios_devclass; | ||||
static void smbios_identify (driver_t *, device_t); | static void smbios_identify (driver_t *, device_t); | ||||
static int smbios_probe (device_t); | static int smbios_probe (device_t); | ||||
static int smbios_attach (device_t); | static int smbios_attach (device_t); | ||||
static int smbios_detach (device_t); | static int smbios_detach (device_t); | ||||
static int smbios_modevent (module_t, int, void *); | static int smbios_modevent (module_t, int, void *); | ||||
static int smbios_cksum (struct smbios_eps *); | static bool smbios_eps_64bit(void *); | ||||
static int smbios_cksum (void *); | |||||
static void | static void | ||||
smbios_identify (driver_t *driver, device_t parent) | smbios_identify (driver_t *driver, device_t parent) | ||||
{ | { | ||||
struct smbios3_eps *eps3; | |||||
struct smbios_eps *eps; | struct smbios_eps *eps; | ||||
device_t child; | device_t child; | ||||
vm_paddr_t addr; | vm_paddr_t addr; | ||||
int length; | int length; | ||||
int rid; | int rid; | ||||
bool eps_64bit; | |||||
if (!device_is_alive(parent)) | if (!device_is_alive(parent)) | ||||
return; | return; | ||||
#if defined(__amd64__) || defined(__i386__) | #if defined(__amd64__) || defined(__i386__) | ||||
addr = bios_sigsearch(SMBIOS_START, SMBIOS3_SIG, SMBIOS3_LEN, | |||||
SMBIOS_STEP, SMBIOS_OFF); | |||||
if (addr != 0) { | |||||
eps_64bit = true; | |||||
} else { | |||||
eps_64bit = false; | |||||
addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN, | addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN, | ||||
SMBIOS_STEP, SMBIOS_OFF); | SMBIOS_STEP, SMBIOS_OFF); | ||||
} | |||||
#else | #else | ||||
addr = 0; | addr = 0; | ||||
#endif | #endif | ||||
if (addr != 0) { | if (addr != 0) { | ||||
if (eps_64bit) { | |||||
eps3 = pmap_mapbios(addr, 0x18); | |||||
length = eps3->length; | |||||
} else { | |||||
eps = pmap_mapbios(addr, 0x1f); | eps = pmap_mapbios(addr, 0x1f); | ||||
manu: Should take the opportunity of updating this files to add defines for the table length instead… | |||||
rid = 0; | |||||
length = eps->length; | length = eps->length; | ||||
} | |||||
rid = 0; | |||||
if (length != 0x1f) { | if (!eps_64bit && length != 0x1f) { | ||||
manuUnsubmitted Not Done Inline ActionsSame here manu: Same here | |||||
u_int8_t major, minor; | u_int8_t major, minor; | ||||
major = eps->major_version; | major = eps->major_version; | ||||
minor = eps->minor_version; | minor = eps->minor_version; | ||||
/* SMBIOS v2.1 implementation might use 0x1e. */ | /* SMBIOS v2.1 implementation might use 0x1e. */ | ||||
if (length == 0x1e && major == 2 && minor == 1) | if (length == 0x1e && major == 2 && minor == 1) | ||||
length = 0x1f; | length = 0x1f; | ||||
else | else | ||||
return; | return; | ||||
} | } | ||||
child = BUS_ADD_CHILD(parent, 5, "smbios", -1); | child = BUS_ADD_CHILD(parent, 5, "smbios", -1); | ||||
device_set_driver(child, driver); | device_set_driver(child, driver); | ||||
bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); | bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); | ||||
device_set_desc(child, "System Management BIOS"); | device_set_desc(child, "System Management BIOS"); | ||||
if (eps_64bit) | |||||
pmap_unmapbios((vm_offset_t)eps3, 0x18); | |||||
else | |||||
pmap_unmapbios((vm_offset_t)eps, 0x1f); | pmap_unmapbios((vm_offset_t)eps, 0x1f); | ||||
manuUnsubmitted Not Done Inline ActionsAnd same here. manu: And same here. | |||||
} | } | ||||
return; | return; | ||||
} | } | ||||
static int | static int | ||||
smbios_probe (device_t dev) | smbios_probe (device_t dev) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
int rid; | int rid; | ||||
int error; | int error; | ||||
error = 0; | error = 0; | ||||
rid = 0; | rid = 0; | ||||
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); | res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); | ||||
if (res == NULL) { | if (res == NULL) { | ||||
device_printf(dev, "Unable to allocate memory resource.\n"); | device_printf(dev, "Unable to allocate memory resource.\n"); | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
if (smbios_cksum(RES2EPS(res))) { | if (smbios_cksum(rman_get_virtual(res))) { | ||||
device_printf(dev, "SMBIOS checksum failed.\n"); | device_printf(dev, "SMBIOS checksum failed.\n"); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
bad: | bad: | ||||
if (res) | if (res) | ||||
bus_release_resource(dev, SYS_RES_MEMORY, rid, res); | bus_release_resource(dev, SYS_RES_MEMORY, rid, res); | ||||
Show All 13 Lines | smbios_attach (device_t dev) | ||||
sc->rid = 0; | sc->rid = 0; | ||||
sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, | sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, | ||||
RF_ACTIVE); | RF_ACTIVE); | ||||
if (sc->res == NULL) { | if (sc->res == NULL) { | ||||
device_printf(dev, "Unable to allocate memory resource.\n"); | device_printf(dev, "Unable to allocate memory resource.\n"); | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto bad; | goto bad; | ||||
} | } | ||||
sc->eps = RES2EPS(sc->res); | sc->eps_64bit = smbios_eps_64bit(rman_get_virtual(sc->res)); | ||||
if (sc->eps_64bit) { | |||||
sc->eps3 = RES2EPS3(sc->res); | |||||
device_printf(dev, "Version: %u.%u", | device_printf(dev, "Version: %u.%u", | ||||
sc->eps3->major_version, sc->eps3->minor_version); | |||||
} else { | |||||
sc->eps = RES2EPS(sc->res); | |||||
device_printf(dev, "Version: %u.%u", | |||||
sc->eps->major_version, sc->eps->minor_version); | sc->eps->major_version, sc->eps->minor_version); | ||||
if (bcd2bin(sc->eps->BCD_revision)) | if (bcd2bin(sc->eps->BCD_revision)) | ||||
printf(", BCD Revision: %u.%u", | printf(", BCD Revision: %u.%u", | ||||
bcd2bin(sc->eps->BCD_revision >> 4), | bcd2bin(sc->eps->BCD_revision >> 4), | ||||
bcd2bin(sc->eps->BCD_revision & 0x0f)); | bcd2bin(sc->eps->BCD_revision & 0x0f)); | ||||
} | |||||
printf("\n"); | printf("\n"); | ||||
return (0); | return (0); | ||||
bad: | bad: | ||||
if (sc->res) | if (sc->res) | ||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); | bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | static driver_t smbios_driver = { | ||||
"smbios", | "smbios", | ||||
smbios_methods, | smbios_methods, | ||||
sizeof(struct smbios_softc), | sizeof(struct smbios_softc), | ||||
}; | }; | ||||
DRIVER_MODULE(smbios, nexus, smbios_driver, smbios_devclass, smbios_modevent, 0); | DRIVER_MODULE(smbios, nexus, smbios_driver, smbios_devclass, smbios_modevent, 0); | ||||
MODULE_VERSION(smbios, 1); | MODULE_VERSION(smbios, 1); | ||||
static bool | |||||
smbios_eps_64bit (void *v) | |||||
{ | |||||
struct smbios3_eps *e; | |||||
e = (struct smbios3_eps *)v; | |||||
return (memcmp(e->anchor_string, SMBIOS3_SIG, SMBIOS3_LEN) == 0); | |||||
} | |||||
static int | static int | ||||
smbios_cksum (struct smbios_eps *e) | smbios_cksum (void *v) | ||||
{ | { | ||||
struct smbios3_eps *eps3; | |||||
struct smbios_eps *eps; | |||||
u_int8_t *ptr; | u_int8_t *ptr; | ||||
u_int8_t cksum; | u_int8_t cksum; | ||||
u_int8_t length; | |||||
int i; | int i; | ||||
ptr = (u_int8_t *)e; | if (smbios_eps_64bit(v)) { | ||||
eps3 = (struct smbios3_eps *)v; | |||||
length = eps3->length; | |||||
} else { | |||||
eps = (struct smbios_eps *)v; | |||||
length = eps->length; | |||||
} | |||||
ptr = (u_int8_t *)v; | |||||
cksum = 0; | cksum = 0; | ||||
for (i = 0; i < e->length; i++) { | for (i = 0; i < length; i++) { | ||||
cksum += ptr[i]; | cksum += ptr[i]; | ||||
} | } | ||||
return (cksum); | return (cksum); | ||||
} | } |
Should take the opportunity of updating this files to add defines for the table length instead of using magic numbers here ?