diff options
| -rw-r--r-- | sys/amd64/include/metadata.h | 1 | ||||
| -rw-r--r-- | sys/amd64/include/pc/bios.h | 4 | ||||
| -rw-r--r-- | sys/boot/i386/libi386/biossmap.c | 131 | ||||
| -rw-r--r-- | sys/i386/include/metadata.h | 1 | ||||
| -rw-r--r-- | sys/i386/include/pc/bios.h | 4 |
5 files changed, 97 insertions, 44 deletions
diff --git a/sys/amd64/include/metadata.h b/sys/amd64/include/metadata.h index 84e6f87399704..4c7ec9e154a2a 100644 --- a/sys/amd64/include/metadata.h +++ b/sys/amd64/include/metadata.h @@ -30,5 +30,6 @@ #define _MACHINE_METADATA_H_ #define MODINFOMD_SMAP 0x1001 +#define MODINFOMD_SMAP_XATTR 0x1002 #endif /* !_MACHINE_METADATA_H_ */ diff --git a/sys/amd64/include/pc/bios.h b/sys/amd64/include/pc/bios.h index 782d4bfc66342..364f86cb32e9a 100644 --- a/sys/amd64/include/pc/bios.h +++ b/sys/amd64/include/pc/bios.h @@ -48,6 +48,10 @@ extern u_int32_t bios_sigsearch(u_int32_t start, u_char *sig, int siglen, #define SMAP_TYPE_ACPI_NVS 4 #define SMAP_TYPE_ACPI_ERROR 5 +#define SMAP_XATTR_ENABLED 0x00000001 +#define SMAP_XATTR_NON_VOLATILE 0x00000002 +#define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE) + struct bios_smap { u_int64_t base; u_int64_t length; diff --git a/sys/boot/i386/libi386/biossmap.c b/sys/boot/i386/libi386/biossmap.c index 51f015a2514d4..5a788c1724955 100644 --- a/sys/boot/i386/libi386/biossmap.c +++ b/sys/boot/i386/libi386/biossmap.c @@ -33,74 +33,107 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <sys/param.h> #include <sys/linker.h> +#include <sys/queue.h> +#include <sys/stddef.h> #include <machine/metadata.h> +#include <machine/psl.h> #include <machine/pc/bios.h> #include "bootstrap.h" #include "libi386.h" #include "btxv86.h" -static struct { - struct bios_smap _smap_entry; - char pad[8]; /* Bad BIOS writer, no cookie! */ -} smap; +#define V86_CY(x) ((x) & PSL_C) -static struct bios_smap *smapbase; -static int smaplen; +struct smap_buf { + struct bios_smap smap; + uint32_t xattr; /* Extended attribute from ACPI 3.0 */ + STAILQ_ENTRY(smap_buf) bufs; +}; + +#define SMAP_BUFSIZE offsetof(struct smap_buf, bufs) + +static struct bios_smap *smapbase; +static uint32_t *smapattr; +static u_int smaplen; void bios_getsmap(void) { - int n; + struct smap_buf buf; + STAILQ_HEAD(smap_head, smap_buf) head = + STAILQ_HEAD_INITIALIZER(head); + struct smap_buf *cur, *next; + u_int n, x; + STAILQ_INIT(&head); n = 0; - smaplen = 0; - /* Count up segments in system memory map */ + x = 0; v86.ebx = 0; do { v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap); + v86.addr = 0x15; + v86.eax = 0xe820; /* int 0x15 function 0xe820 */ + v86.ecx = SMAP_BUFSIZE; v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); + v86.es = VTOPSEG(&buf); + v86.edi = VTOPOFF(&buf); v86int(); - if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) + if (V86_CY(v86.efl) || v86.eax != SMAP_SIG || + v86.ecx < sizeof(buf.smap) || v86.ecx > SMAP_BUFSIZE) + break; + + next = malloc(sizeof(*next)); + if (next == NULL) break; + next->smap = buf.smap; + if (v86.ecx == SMAP_BUFSIZE) { + next->xattr = buf.xattr; + x++; + } + STAILQ_INSERT_TAIL(&head, next, bufs); n++; } while (v86.ebx != 0); - if (n == 0) - return; - n += 10; /* spare room */ - smapbase = malloc(n * sizeof(*smapbase)); + smaplen = n; - /* Save system memory map */ - v86.ebx = 0; - do { - v86.ctl = V86_FLAGS; - v86.addr = 0x15; /* int 0x15 function 0xe820*/ - v86.eax = 0xe820; - v86.ecx = sizeof(struct bios_smap); - v86.edx = SMAP_SIG; - v86.es = VTOPSEG(&smap); - v86.edi = VTOPOFF(&smap); - v86int(); - bcopy(&smap, &smapbase[smaplen], sizeof(struct bios_smap)); - smaplen++; - if ((v86.efl & 1) || (v86.eax != SMAP_SIG)) - break; - } while (v86.ebx != 0 && smaplen < n); + if (smaplen > 0) { + smapbase = malloc(smaplen * sizeof(*smapbase)); + if (smapbase != NULL) { + n = 0; + STAILQ_FOREACH(cur, &head, bufs) + smapbase[n++] = cur->smap; + } + if (smaplen == x) { + smapattr = malloc(smaplen * sizeof(*smapattr)); + if (smapattr != NULL) { + n = 0; + STAILQ_FOREACH(cur, &head, bufs) + smapattr[n++] = cur->xattr & + SMAP_XATTR_MASK; + } + } else + smapattr = NULL; + cur = STAILQ_FIRST(&head); + while (cur != NULL) { + next = STAILQ_NEXT(cur, bufs); + free(cur); + cur = next; + } + } } void bios_addsmapdata(struct preloaded_file *kfp) { - int len; + size_t size; - if (smapbase == 0 || smaplen == 0) + if (smapbase == NULL || smaplen == 0) return; - len = smaplen * sizeof(*smapbase); - file_addmetadata(kfp, MODINFOMD_SMAP, len, smapbase); + size = smaplen * sizeof(*smapbase); + file_addmetadata(kfp, MODINFOMD_SMAP, size, smapbase); + if (smapattr != NULL) { + size = smaplen * sizeof(*smapattr); + file_addmetadata(kfp, MODINFOMD_SMAP_XATTR, size, smapattr); + } } COMMAND_SET(smap, "smap", "show BIOS SMAP", command_smap); @@ -108,12 +141,22 @@ COMMAND_SET(smap, "smap", "show BIOS SMAP", command_smap); static int command_smap(int argc, char *argv[]) { - int i; + u_int i; - if (smapbase == 0 || smaplen == 0) + if (smapbase == NULL || smaplen == 0) return (CMD_ERROR); - for (i = 0; i < smaplen; i++) - printf("SMAP type=%02x base=%016llx len=%016llx\n", - smapbase[i].type, smapbase[i].base, smapbase[i].length); + if (smapattr != NULL) + for (i = 0; i < smaplen; i++) + printf("SMAP type=%02x base=%016llx len=%016llx attr=%02x\n", + (unsigned int)smapbase[i].type, + (unsigned long long)smapbase[i].base, + (unsigned long long)smapbase[i].length, + (unsigned int)smapattr[i]); + else + for (i = 0; i < smaplen; i++) + printf("SMAP type=%02x base=%016llx len=%016llx\n", + (unsigned int)smapbase[i].type, + (unsigned long long)smapbase[i].base, + (unsigned long long)smapbase[i].length); return (CMD_OK); } diff --git a/sys/i386/include/metadata.h b/sys/i386/include/metadata.h index 84e6f87399704..4c7ec9e154a2a 100644 --- a/sys/i386/include/metadata.h +++ b/sys/i386/include/metadata.h @@ -30,5 +30,6 @@ #define _MACHINE_METADATA_H_ #define MODINFOMD_SMAP 0x1001 +#define MODINFOMD_SMAP_XATTR 0x1002 #endif /* !_MACHINE_METADATA_H_ */ diff --git a/sys/i386/include/pc/bios.h b/sys/i386/include/pc/bios.h index ca060249d2904..e705d130baa95 100644 --- a/sys/i386/include/pc/bios.h +++ b/sys/i386/include/pc/bios.h @@ -281,6 +281,10 @@ struct PIR_table #define SMAP_TYPE_ACPI_NVS 4 #define SMAP_TYPE_ACPI_ERROR 5 +#define SMAP_XATTR_ENABLED 0x00000001 +#define SMAP_XATTR_NON_VOLATILE 0x00000002 +#define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE) + struct bios_smap { u_int64_t base; u_int64_t length; |
