mirror of
https://git.freebsd.org/src.git
synced 2026-01-16 23:02:24 +00:00
libsa: smbios: Use 64-bit entry point if table below 4GB on non-EFI boot
On amd64, boot blocks and the non-EFI loader are 32-bit compiled as clients of BTX, so cannot access addresses beyond 4GB. However, the 64-bit entry point may refer to a structure table below 4GB, which we want to use if the BIOS does not provide a 32-bit entry point. The situation is similar for powerpc64. Consequently, always compile-in support for the 64-bit entry point, but ensure that it is not selected on 32-bit-compiled boot loaders if the structure table it points to grows beyond 4GB (as it is then not accessible). PR: 284460 Reviewed by: markj MFC after: 2 weeks Relnotes: yes Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D49288
This commit is contained in:
parent
3f744fb8b2
commit
7f005c6699
1 changed files with 14 additions and 23 deletions
|
|
@ -29,11 +29,6 @@
|
|||
|
||||
#define PTOV(x) ptov(x)
|
||||
|
||||
/* Only enable 64-bit entry point if it makes sense */
|
||||
#if __SIZEOF_POINTER__ > 4
|
||||
#define SMBIOS_64BIT_EP 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Detect SMBIOS and export information about the SMBIOS into the
|
||||
* environment.
|
||||
|
|
@ -145,9 +140,7 @@ SMBIOS_GET64(const caddr_t base, int off)
|
|||
|
||||
struct smbios_attr {
|
||||
int probed;
|
||||
#ifdef SMBIOS_64BIT_EP
|
||||
int is_64bit_ep;
|
||||
#endif
|
||||
caddr_t addr;
|
||||
size_t length;
|
||||
size_t count;
|
||||
|
|
@ -184,7 +177,6 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
|
|||
|
||||
/* Search on 16-byte boundaries. */
|
||||
for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) {
|
||||
#ifdef SMBIOS_64BIT_EP
|
||||
/* v3.0, 64-bit Entry point */
|
||||
if (strncmp(cp, SMBIOS3_SIG, sizeof(SMBIOS3_SIG) - 1) == 0 &&
|
||||
/*
|
||||
|
|
@ -195,10 +187,19 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
|
|||
*/
|
||||
SMBIOS_GET8(cp, 0x0a) != 0 &&
|
||||
smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0) {
|
||||
#ifdef __ILP32__
|
||||
uint64_t end_addr;
|
||||
|
||||
end_addr = SMBIOS_GET64(cp, 0x10) + /* Start address. */
|
||||
SMBIOS_GET32(cp, 0x0c); /* Maximum size. */
|
||||
/* Is the table (or part of it) located above 4G? */
|
||||
if (end_addr >= (uint64_t)1 << 32)
|
||||
/* Can't access it with 32-bit addressing. */
|
||||
continue;
|
||||
#endif
|
||||
smbios.is_64bit_ep = 1;
|
||||
return (cp);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* v2.1, 32-bit Entry point */
|
||||
if (strncmp(cp, SMBIOS_SIG, sizeof(SMBIOS_SIG) - 1) == 0 &&
|
||||
|
|
@ -207,13 +208,9 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
|
|||
smbios_checksum(cp + 0x10, 0x0f) == 0) {
|
||||
/*
|
||||
* Note that we saw this entry point, but don't return
|
||||
* it right now on SMBIOS_64BIT_EP as we favor the 64-bit
|
||||
* one if present.
|
||||
* it right now as we favor the 64-bit one if present.
|
||||
*/
|
||||
v2_p = cp;
|
||||
#ifndef SMBIOS_64BIT_EP
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return (v2_p);
|
||||
|
|
@ -586,7 +583,6 @@ smbios_probe(const caddr_t addr)
|
|||
if (saddr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef SMBIOS_64BIT_EP
|
||||
if (smbios.is_64bit_ep) {
|
||||
/* Structure Table Length */
|
||||
smbios.length = SMBIOS_GET32(saddr, 0x0c);
|
||||
|
|
@ -601,9 +597,7 @@ smbios_probe(const caddr_t addr)
|
|||
smbios.ver = 0;
|
||||
maj_off = 0x07;
|
||||
min_off = 0x08;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
/* Structure Table Length */
|
||||
smbios.length = SMBIOS_GET16(saddr, 0x16);
|
||||
/* Structure Table Address */
|
||||
|
|
@ -661,11 +655,8 @@ smbios_detect(const caddr_t addr)
|
|||
dmi < smbios.addr + smbios.length && i < smbios.count; i++)
|
||||
dmi = smbios_parse_table(dmi);
|
||||
|
||||
setenv("smbios.entry_point_type",
|
||||
#ifdef SMBIOS_64BIT_EP
|
||||
smbios.is_64bit_ep ? "v3 (64-bit)" :
|
||||
#endif
|
||||
"v2.1 (32-bit)", 1);
|
||||
setenv("smbios.entry_point_type", smbios.is_64bit_ep ?
|
||||
"v3 (64-bit)" : "v2.1 (32-bit)", 1);
|
||||
sprintf(buf, "%d.%d", smbios.major, smbios.minor);
|
||||
setenv("smbios.version", buf, 1);
|
||||
if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue