- Re-shuffle the <machine/pc/bios.h> headers to move all kernel-specific
bits under #ifdef _KERNEL but leave definitions for various structures defined by standards ($PIR table, SMAP entries, etc.) available to userland. - Consolidate duplicate SMBIOS table structure definitions in ipmi(4) and smbios(4) in <machine/pc/bios.h> and make them available to userland. MFC after: 2 weeks
This commit is contained in:
parent
6e95460966
commit
960b5a7080
@ -30,16 +30,9 @@
|
||||
#ifndef _MACHINE_PC_BIOS_H_
|
||||
#define _MACHINE_PC_BIOS_H_
|
||||
|
||||
extern u_int32_t bios_sigsearch(u_int32_t start, u_char *sig, int siglen,
|
||||
int paralen, int sigofs);
|
||||
|
||||
#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
|
||||
#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
|
||||
|
||||
/*
|
||||
* Int 15:E820 'SMAP' structure
|
||||
*/
|
||||
|
||||
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
|
||||
|
||||
#define SMAP_TYPE_MEMORY 1
|
||||
@ -58,22 +51,61 @@ struct bios_smap {
|
||||
u_int32_t type;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* System Management BIOS
|
||||
*/
|
||||
#define SMBIOS_START 0xf0000
|
||||
#define SMBIOS_STEP 0x10
|
||||
#define SMBIOS_OFF 0
|
||||
#define SMBIOS_LEN 4
|
||||
#define SMBIOS_SIG "_SM_"
|
||||
|
||||
struct smbios_eps {
|
||||
uint8_t anchor_string[4]; /* '_SM_' */
|
||||
uint8_t checksum;
|
||||
uint8_t length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint16_t maximum_structure_size;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t formatted_area[5];
|
||||
uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
|
||||
uint8_t intermediate_checksum;
|
||||
uint16_t structure_table_length;
|
||||
uint32_t structure_table_address;
|
||||
uint16_t number_structures;
|
||||
uint8_t BCD_revision;
|
||||
};
|
||||
|
||||
struct smbios_structure_header {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
|
||||
#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
|
||||
|
||||
struct bios_oem_signature {
|
||||
char * anchor; /* search anchor string in BIOS memory */
|
||||
size_t offset; /* offset from anchor (may be negative) */
|
||||
size_t totlen; /* total length of BIOS string to copy */
|
||||
} __packed;
|
||||
|
||||
struct bios_oem_range {
|
||||
u_int from; /* shouldn't be below 0xe0000 */
|
||||
u_int to; /* shouldn't be above 0xfffff */
|
||||
} __packed;
|
||||
|
||||
struct bios_oem {
|
||||
struct bios_oem_range range;
|
||||
struct bios_oem_signature signature[];
|
||||
} __packed;
|
||||
|
||||
extern int
|
||||
bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
|
||||
|
||||
int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
|
||||
uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
|
||||
int sigofs);
|
||||
#endif
|
||||
|
||||
#endif /* _MACHINE_PC_BIOS_H_ */
|
||||
|
@ -52,29 +52,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define pmap_unmapbios pmap_unmapdev
|
||||
#endif
|
||||
|
||||
struct smbios_table {
|
||||
uint8_t anchor_string[4];
|
||||
uint8_t checksum;
|
||||
uint8_t length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint16_t maximum_structure_size;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t formatted_area[5];
|
||||
uint8_t DMI_anchor_string[5];
|
||||
uint8_t intermediate_checksum;
|
||||
uint16_t structure_table_length;
|
||||
uint32_t structure_table_address;
|
||||
uint16_t number_structures;
|
||||
uint8_t BCD_revision;
|
||||
};
|
||||
|
||||
struct structure_header {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
};
|
||||
|
||||
struct ipmi_entry {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
@ -102,13 +79,7 @@ struct ipmi_entry {
|
||||
#define SPACING_32 0x1
|
||||
#define SPACING_16 0x2
|
||||
|
||||
#define SMBIOS_START 0xf0000
|
||||
#define SMBIOS_STEP 0x10
|
||||
#define SMBIOS_OFF 0
|
||||
#define SMBIOS_LEN 4
|
||||
#define SMBIOS_SIG "_SM_"
|
||||
|
||||
typedef void (*smbios_callback_t)(struct structure_header *, void *);
|
||||
typedef void (*smbios_callback_t)(struct smbios_structure_header *, void *);
|
||||
|
||||
static struct ipmi_get_info ipmi_info;
|
||||
static int ipmi_probed;
|
||||
@ -116,13 +87,13 @@ static struct mtx ipmi_info_mtx;
|
||||
MTX_SYSINIT(ipmi_info, &ipmi_info_mtx, "ipmi info", MTX_DEF);
|
||||
|
||||
static void ipmi_smbios_probe(struct ipmi_get_info *);
|
||||
static int smbios_cksum(struct smbios_table *);
|
||||
static int smbios_cksum(struct smbios_eps *);
|
||||
static void smbios_walk_table(uint8_t *, int, smbios_callback_t,
|
||||
void *);
|
||||
static void smbios_ipmi_info(struct structure_header *, void *);
|
||||
static void smbios_ipmi_info(struct smbios_structure_header *, void *);
|
||||
|
||||
static void
|
||||
smbios_ipmi_info(struct structure_header *h, void *arg)
|
||||
smbios_ipmi_info(struct smbios_structure_header *h, void *arg)
|
||||
{
|
||||
struct ipmi_get_info *info;
|
||||
struct ipmi_entry *s;
|
||||
@ -178,10 +149,10 @@ smbios_ipmi_info(struct structure_header *h, void *arg)
|
||||
static void
|
||||
smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
|
||||
{
|
||||
struct structure_header *s;
|
||||
struct smbios_structure_header *s;
|
||||
|
||||
while (entries--) {
|
||||
s = (struct structure_header *)p;
|
||||
s = (struct smbios_structure_header *)p;
|
||||
cb(s, arg);
|
||||
|
||||
/*
|
||||
@ -208,7 +179,7 @@ smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
|
||||
static void
|
||||
ipmi_smbios_probe(struct ipmi_get_info *info)
|
||||
{
|
||||
struct smbios_table *header;
|
||||
struct smbios_eps *header;
|
||||
void *table;
|
||||
u_int32_t addr;
|
||||
|
||||
@ -225,9 +196,9 @@ ipmi_smbios_probe(struct ipmi_get_info *info)
|
||||
* length and then map it a second time with the actual length so
|
||||
* we can verify the checksum.
|
||||
*/
|
||||
header = pmap_mapbios(addr, sizeof(struct smbios_table));
|
||||
header = pmap_mapbios(addr, sizeof(struct smbios_eps));
|
||||
table = pmap_mapbios(addr, header->length);
|
||||
pmap_unmapbios((vm_offset_t)header, sizeof(struct smbios_table));
|
||||
pmap_unmapbios((vm_offset_t)header, sizeof(struct smbios_eps));
|
||||
header = table;
|
||||
if (smbios_cksum(header) != 0) {
|
||||
pmap_unmapbios((vm_offset_t)header, header->length);
|
||||
@ -282,7 +253,7 @@ ipmi_smbios_identify(struct ipmi_get_info *info)
|
||||
}
|
||||
|
||||
static int
|
||||
smbios_cksum(struct smbios_table *e)
|
||||
smbios_cksum(struct smbios_eps *e)
|
||||
{
|
||||
u_int8_t *ptr;
|
||||
u_int8_t cksum;
|
||||
|
@ -43,31 +43,6 @@ struct bios32_SDheader
|
||||
u_int8_t pad[5];
|
||||
};
|
||||
|
||||
/*
|
||||
* BIOS32 Service Directory entry. Caller supplies name, bios32_SDlookup
|
||||
* fills in the rest of the details.
|
||||
*/
|
||||
struct bios32_SDentry
|
||||
{
|
||||
union
|
||||
{
|
||||
u_int8_t name[4]; /* service identifier */
|
||||
u_int32_t id; /* as a 32-bit value */
|
||||
} ident;
|
||||
u_int32_t base; /* base of service */
|
||||
u_int32_t len; /* service length */
|
||||
u_int32_t entry; /* entrypoint offset from base */
|
||||
vm_offset_t ventry; /* entrypoint in kernel virtual segment */
|
||||
};
|
||||
|
||||
extern int bios32_SDlookup(struct bios32_SDentry *ent);
|
||||
extern u_int32_t bios_sigsearch(u_int32_t start, u_char *sig, int siglen,
|
||||
int paralen, int sigofs);
|
||||
|
||||
#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
|
||||
#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
|
||||
|
||||
|
||||
/*
|
||||
* PnP BIOS presence structure
|
||||
*/
|
||||
@ -88,52 +63,13 @@ struct PnPBIOS_table
|
||||
u_int32_t pmdataseg; /* protected-mode data segment */
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* Exported lookup results
|
||||
*/
|
||||
extern struct bios32_SDentry PCIbios;
|
||||
|
||||
struct segment_info {
|
||||
u_int base;
|
||||
u_int limit;
|
||||
};
|
||||
|
||||
#define BIOSCODE_FLAG 0x01
|
||||
#define BIOSDATA_FLAG 0x02
|
||||
#define BIOSUTIL_FLAG 0x04
|
||||
#define BIOSARGS_FLAG 0x08
|
||||
|
||||
struct bios_segments {
|
||||
struct segment_info code32; /* 32-bit code (mandatory) */
|
||||
struct segment_info code16; /* 16-bit code */
|
||||
struct segment_info data; /* 16-bit data */
|
||||
struct segment_info util; /* 16-bit utility */
|
||||
struct segment_info args; /* 16-bit args */
|
||||
};
|
||||
|
||||
struct bios_regs {
|
||||
u_int eax;
|
||||
u_int ebx;
|
||||
u_int ecx;
|
||||
u_int edx;
|
||||
u_int esi;
|
||||
u_int edi;
|
||||
};
|
||||
|
||||
struct bios_args {
|
||||
u_int entry; /* entry point of routine */
|
||||
struct bios_regs r;
|
||||
struct bios_segments seg;
|
||||
};
|
||||
|
||||
/*
|
||||
* PnP BIOS return codes
|
||||
*/
|
||||
#define PNP_SUCCESS 0x00
|
||||
#define PNP_NOT_SET_STATICALLY 0x7f
|
||||
#define PNP_UNKNOWN_FUNCTION 0x81
|
||||
#define PNP_FUNTION_NOT_SUPPORTED 0x82
|
||||
#define PNP_FUNCTION_NOT_SUPPORTED 0x82
|
||||
#define PNP_INVALID_HANDLE 0x83
|
||||
#define PNP_BAD_PARAMETER 0x84
|
||||
#define PNP_SET_FAILED 0x85
|
||||
@ -219,11 +155,6 @@ struct bios_args {
|
||||
#define PCIBIOS_GET_IRQ_ROUTING 0xb10e
|
||||
#define PCIBIOS_ROUTE_INTERRUPT 0xb10f
|
||||
|
||||
extern int bios16(struct bios_args *, char *, ...);
|
||||
extern int bios16_call(struct bios_regs *, char *);
|
||||
extern int bios32(struct bios_regs *, u_int, u_short);
|
||||
extern void set_bios_selectors(struct bios_segments *, int);
|
||||
|
||||
/*
|
||||
* PCI interrupt routing table.
|
||||
*
|
||||
@ -272,7 +203,6 @@ struct PIR_table
|
||||
/*
|
||||
* Int 15:E820 'SMAP' structure
|
||||
*/
|
||||
|
||||
#define SMAP_SIG 0x534D4150 /* 'SMAP' */
|
||||
|
||||
#define SMAP_TYPE_MEMORY 1
|
||||
@ -291,22 +221,122 @@ struct bios_smap {
|
||||
u_int32_t type;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* System Management BIOS
|
||||
*/
|
||||
#define SMBIOS_START 0xf0000
|
||||
#define SMBIOS_STEP 0x10
|
||||
#define SMBIOS_OFF 0
|
||||
#define SMBIOS_LEN 4
|
||||
#define SMBIOS_SIG "_SM_"
|
||||
|
||||
struct smbios_eps {
|
||||
uint8_t anchor_string[4]; /* '_SM_' */
|
||||
uint8_t checksum;
|
||||
uint8_t length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint16_t maximum_structure_size;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t formatted_area[5];
|
||||
uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
|
||||
uint8_t intermediate_checksum;
|
||||
uint16_t structure_table_length;
|
||||
uint32_t structure_table_address;
|
||||
uint16_t number_structures;
|
||||
uint8_t BCD_revision;
|
||||
};
|
||||
|
||||
struct smbios_structure_header {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
|
||||
#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
|
||||
|
||||
struct bios_oem_signature {
|
||||
char * anchor; /* search anchor string in BIOS memory */
|
||||
size_t offset; /* offset from anchor (may be negative) */
|
||||
size_t totlen; /* total length of BIOS string to copy */
|
||||
} __packed;
|
||||
|
||||
struct bios_oem_range {
|
||||
u_int from; /* shouldn't be below 0xe0000 */
|
||||
u_int to; /* shouldn't be above 0xfffff */
|
||||
} __packed;
|
||||
|
||||
struct bios_oem {
|
||||
struct bios_oem_range range;
|
||||
struct bios_oem_signature signature[];
|
||||
} __packed;
|
||||
|
||||
extern int
|
||||
bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
|
||||
struct segment_info {
|
||||
u_int base;
|
||||
u_int limit;
|
||||
};
|
||||
|
||||
#define BIOSCODE_FLAG 0x01
|
||||
#define BIOSDATA_FLAG 0x02
|
||||
#define BIOSUTIL_FLAG 0x04
|
||||
#define BIOSARGS_FLAG 0x08
|
||||
|
||||
struct bios_segments {
|
||||
struct segment_info code32; /* 32-bit code (mandatory) */
|
||||
struct segment_info code16; /* 16-bit code */
|
||||
struct segment_info data; /* 16-bit data */
|
||||
struct segment_info util; /* 16-bit utility */
|
||||
struct segment_info args; /* 16-bit args */
|
||||
};
|
||||
|
||||
struct bios_regs {
|
||||
u_int eax;
|
||||
u_int ebx;
|
||||
u_int ecx;
|
||||
u_int edx;
|
||||
u_int esi;
|
||||
u_int edi;
|
||||
};
|
||||
|
||||
struct bios_args {
|
||||
u_int entry; /* entry point of routine */
|
||||
struct bios_regs r;
|
||||
struct bios_segments seg;
|
||||
};
|
||||
|
||||
/*
|
||||
* BIOS32 Service Directory entry. Caller supplies name, bios32_SDlookup
|
||||
* fills in the rest of the details.
|
||||
*/
|
||||
struct bios32_SDentry
|
||||
{
|
||||
union
|
||||
{
|
||||
u_int8_t name[4]; /* service identifier */
|
||||
u_int32_t id; /* as a 32-bit value */
|
||||
} ident;
|
||||
u_int32_t base; /* base of service */
|
||||
u_int32_t len; /* service length */
|
||||
u_int32_t entry; /* entrypoint offset from base */
|
||||
vm_offset_t ventry; /* entrypoint in kernel virtual segment */
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported lookup results
|
||||
*/
|
||||
extern struct bios32_SDentry PCIbios;
|
||||
|
||||
int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
|
||||
uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
|
||||
int sigofs);
|
||||
int bios16(struct bios_args *, char *, ...);
|
||||
int bios16_call(struct bios_regs *, char *);
|
||||
int bios32(struct bios_regs *, u_int, u_short);
|
||||
int bios32_SDlookup(struct bios32_SDentry *ent);
|
||||
void set_bios_selectors(struct bios_segments *, int);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _MACHINE_PC_BIOS_H_ */
|
||||
|
@ -50,30 +50,6 @@ __FBSDID("$FreeBSD$");
|
||||
* http://www.dmtf.org/standards/published_documents/DSP0134.pdf
|
||||
*/
|
||||
|
||||
/*
|
||||
* SMBIOS Entry Point Structure
|
||||
*/
|
||||
struct smbios_eps {
|
||||
u_int8_t Anchor[4]; /* '_SM_' */
|
||||
u_int8_t Checksum;
|
||||
u_int8_t Length;
|
||||
|
||||
u_int8_t SMBIOS_Major;
|
||||
u_int8_t SMBIOS_Minor;
|
||||
u_int16_t Max_Size;
|
||||
u_int8_t Revision;
|
||||
u_int8_t Formatted_Area[5];
|
||||
|
||||
u_int8_t Intermediate_Anchor[5]; /* '_DMI_' */
|
||||
u_int8_t Intermediate_Checksum;
|
||||
|
||||
u_int16_t Structure_Table_Length;
|
||||
u_int32_t Structure_Table_Address;
|
||||
u_int16_t Structure_Count;
|
||||
|
||||
u_int8_t SMBIOS_BCD_Revision;
|
||||
} __packed;
|
||||
|
||||
struct smbios_softc {
|
||||
device_t dev;
|
||||
struct resource * res;
|
||||
@ -82,12 +58,6 @@ struct smbios_softc {
|
||||
struct smbios_eps * eps;
|
||||
};
|
||||
|
||||
#define SMBIOS_START 0xf0000
|
||||
#define SMBIOS_STEP 0x10
|
||||
#define SMBIOS_OFF 0
|
||||
#define SMBIOS_LEN 4
|
||||
#define SMBIOS_SIG "_SM_"
|
||||
|
||||
#define RES2EPS(res) ((struct smbios_eps *)rman_get_virtual(res))
|
||||
#define ADDR2EPS(addr) ((struct smbios_eps *)BIOS_PADDRTOVADDR(addr))
|
||||
|
||||
@ -116,13 +86,13 @@ smbios_identify (driver_t *driver, device_t parent)
|
||||
SMBIOS_STEP, SMBIOS_OFF);
|
||||
if (addr != 0) {
|
||||
rid = 0;
|
||||
length = ADDR2EPS(addr)->Length;
|
||||
length = ADDR2EPS(addr)->length;
|
||||
|
||||
if (length != 0x1f) {
|
||||
u_int8_t major, minor;
|
||||
|
||||
major = ADDR2EPS(addr)->SMBIOS_Major;
|
||||
minor = ADDR2EPS(addr)->SMBIOS_Minor;
|
||||
major = ADDR2EPS(addr)->major_version;
|
||||
minor = ADDR2EPS(addr)->minor_version;
|
||||
|
||||
/* SMBIOS v2.1 implementation might use 0x1e. */
|
||||
if (length == 0x1e && major == 2 && minor == 1)
|
||||
@ -189,11 +159,11 @@ smbios_attach (device_t dev)
|
||||
sc->eps = RES2EPS(sc->res);
|
||||
|
||||
device_printf(dev, "Version: %u.%u",
|
||||
sc->eps->SMBIOS_Major, sc->eps->SMBIOS_Minor);
|
||||
if (bcd2bin(sc->eps->SMBIOS_BCD_Revision))
|
||||
sc->eps->major_version, sc->eps->minor_version);
|
||||
if (bcd2bin(sc->eps->BCD_revision))
|
||||
printf(", BCD Revision: %u.%u",
|
||||
bcd2bin(sc->eps->SMBIOS_BCD_Revision >> 4),
|
||||
bcd2bin(sc->eps->SMBIOS_BCD_Revision & 0x0f));
|
||||
bcd2bin(sc->eps->BCD_revision >> 4),
|
||||
bcd2bin(sc->eps->BCD_revision & 0x0f));
|
||||
printf("\n");
|
||||
|
||||
return (0);
|
||||
@ -269,7 +239,7 @@ smbios_cksum (struct smbios_eps *e)
|
||||
|
||||
ptr = (u_int8_t *)e;
|
||||
cksum = 0;
|
||||
for (i = 0; i < e->Length; i++) {
|
||||
for (i = 0; i < e->length; i++) {
|
||||
cksum += ptr[i];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user