summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2009-04-15 17:31:22 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2009-04-15 17:31:22 +0000
commitcebe9dc98adf16eecd80299eae1424fa2c89c934 (patch)
tree42347e17b226dd42a13dd0a4b0ea3697313e1f46
parentb0089534dac28739f0175f1ae58ef59b4ecacbc4 (diff)
Notes
-rw-r--r--sys/amd64/include/metadata.h1
-rw-r--r--sys/amd64/include/pc/bios.h4
-rw-r--r--sys/boot/i386/libi386/biossmap.c131
-rw-r--r--sys/i386/include/metadata.h1
-rw-r--r--sys/i386/include/pc/bios.h4
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;