1*4a5d661aSToomas Soome /*-
2*4a5d661aSToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3*4a5d661aSToomas Soome * All rights reserved.
4*4a5d661aSToomas Soome *
5*4a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
6*4a5d661aSToomas Soome * modification, are permitted provided that the following conditions
7*4a5d661aSToomas Soome * are met:
8*4a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
9*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
10*4a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
11*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
12*4a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
13*4a5d661aSToomas Soome *
14*4a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*4a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*4a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*4a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*4a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*4a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*4a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*4a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*4a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*4a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*4a5d661aSToomas Soome * SUCH DAMAGE.
25*4a5d661aSToomas Soome */
26*4a5d661aSToomas Soome
27*4a5d661aSToomas Soome #include <sys/cdefs.h>
28*4a5d661aSToomas Soome __FBSDID("$FreeBSD$");
29*4a5d661aSToomas Soome
30*4a5d661aSToomas Soome /*
31*4a5d661aSToomas Soome * Obtain memory configuration information from the BIOS
32*4a5d661aSToomas Soome */
33*4a5d661aSToomas Soome #include <stand.h>
34*4a5d661aSToomas Soome #include <sys/param.h>
35*4a5d661aSToomas Soome #include <sys/linker.h>
36*4a5d661aSToomas Soome #include <sys/queue.h>
37*4a5d661aSToomas Soome #include <sys/stddef.h>
38*4a5d661aSToomas Soome #include <machine/metadata.h>
39*4a5d661aSToomas Soome #include <machine/pc/bios.h>
40*4a5d661aSToomas Soome #include "bootstrap.h"
41*4a5d661aSToomas Soome #include "libi386.h"
42*4a5d661aSToomas Soome #include "btxv86.h"
43*4a5d661aSToomas Soome
44*4a5d661aSToomas Soome struct smap_buf {
45*4a5d661aSToomas Soome struct bios_smap smap;
46*4a5d661aSToomas Soome uint32_t xattr; /* Extended attribute from ACPI 3.0 */
47*4a5d661aSToomas Soome STAILQ_ENTRY(smap_buf) bufs;
48*4a5d661aSToomas Soome };
49*4a5d661aSToomas Soome
50*4a5d661aSToomas Soome #define SMAP_BUFSIZE offsetof(struct smap_buf, bufs)
51*4a5d661aSToomas Soome
52*4a5d661aSToomas Soome static struct bios_smap *smapbase;
53*4a5d661aSToomas Soome static uint32_t *smapattr;
54*4a5d661aSToomas Soome static u_int smaplen;
55*4a5d661aSToomas Soome
56*4a5d661aSToomas Soome void
bios_getsmap(void)57*4a5d661aSToomas Soome bios_getsmap(void)
58*4a5d661aSToomas Soome {
59*4a5d661aSToomas Soome struct smap_buf buf;
60*4a5d661aSToomas Soome STAILQ_HEAD(smap_head, smap_buf) head =
61*4a5d661aSToomas Soome STAILQ_HEAD_INITIALIZER(head);
62*4a5d661aSToomas Soome struct smap_buf *cur, *next;
63*4a5d661aSToomas Soome u_int n, x;
64*4a5d661aSToomas Soome
65*4a5d661aSToomas Soome STAILQ_INIT(&head);
66*4a5d661aSToomas Soome n = 0;
67*4a5d661aSToomas Soome x = 0;
68*4a5d661aSToomas Soome v86.ebx = 0;
69*4a5d661aSToomas Soome do {
70*4a5d661aSToomas Soome v86.ctl = V86_FLAGS;
71*4a5d661aSToomas Soome v86.addr = 0x15;
72*4a5d661aSToomas Soome v86.eax = 0xe820; /* int 0x15 function 0xe820 */
73*4a5d661aSToomas Soome v86.ecx = SMAP_BUFSIZE;
74*4a5d661aSToomas Soome v86.edx = SMAP_SIG;
75*4a5d661aSToomas Soome v86.es = VTOPSEG(&buf);
76*4a5d661aSToomas Soome v86.edi = VTOPOFF(&buf);
77*4a5d661aSToomas Soome v86int();
78*4a5d661aSToomas Soome if (V86_CY(v86.efl) || v86.eax != SMAP_SIG ||
79*4a5d661aSToomas Soome v86.ecx < sizeof(buf.smap) || v86.ecx > SMAP_BUFSIZE)
80*4a5d661aSToomas Soome break;
81*4a5d661aSToomas Soome
82*4a5d661aSToomas Soome next = malloc(sizeof(*next));
83*4a5d661aSToomas Soome if (next == NULL)
84*4a5d661aSToomas Soome break;
85*4a5d661aSToomas Soome next->smap = buf.smap;
86*4a5d661aSToomas Soome if (v86.ecx == SMAP_BUFSIZE) {
87*4a5d661aSToomas Soome next->xattr = buf.xattr;
88*4a5d661aSToomas Soome x++;
89*4a5d661aSToomas Soome }
90*4a5d661aSToomas Soome STAILQ_INSERT_TAIL(&head, next, bufs);
91*4a5d661aSToomas Soome n++;
92*4a5d661aSToomas Soome } while (v86.ebx != 0);
93*4a5d661aSToomas Soome smaplen = n;
94*4a5d661aSToomas Soome
95*4a5d661aSToomas Soome if (smaplen > 0) {
96*4a5d661aSToomas Soome smapbase = malloc(smaplen * sizeof(*smapbase));
97*4a5d661aSToomas Soome if (smapbase != NULL) {
98*4a5d661aSToomas Soome n = 0;
99*4a5d661aSToomas Soome STAILQ_FOREACH(cur, &head, bufs)
100*4a5d661aSToomas Soome smapbase[n++] = cur->smap;
101*4a5d661aSToomas Soome }
102*4a5d661aSToomas Soome if (smaplen == x) {
103*4a5d661aSToomas Soome smapattr = malloc(smaplen * sizeof(*smapattr));
104*4a5d661aSToomas Soome if (smapattr != NULL) {
105*4a5d661aSToomas Soome n = 0;
106*4a5d661aSToomas Soome STAILQ_FOREACH(cur, &head, bufs)
107*4a5d661aSToomas Soome smapattr[n++] = cur->xattr &
108*4a5d661aSToomas Soome SMAP_XATTR_MASK;
109*4a5d661aSToomas Soome }
110*4a5d661aSToomas Soome } else
111*4a5d661aSToomas Soome smapattr = NULL;
112*4a5d661aSToomas Soome cur = STAILQ_FIRST(&head);
113*4a5d661aSToomas Soome while (cur != NULL) {
114*4a5d661aSToomas Soome next = STAILQ_NEXT(cur, bufs);
115*4a5d661aSToomas Soome free(cur);
116*4a5d661aSToomas Soome cur = next;
117*4a5d661aSToomas Soome }
118*4a5d661aSToomas Soome }
119*4a5d661aSToomas Soome }
120*4a5d661aSToomas Soome
121*4a5d661aSToomas Soome void
bios_addsmapdata(struct preloaded_file * kfp)122*4a5d661aSToomas Soome bios_addsmapdata(struct preloaded_file *kfp)
123*4a5d661aSToomas Soome {
124*4a5d661aSToomas Soome size_t size;
125*4a5d661aSToomas Soome
126*4a5d661aSToomas Soome if (smapbase == NULL || smaplen == 0)
127*4a5d661aSToomas Soome return;
128*4a5d661aSToomas Soome size = smaplen * sizeof(*smapbase);
129*4a5d661aSToomas Soome file_addmetadata(kfp, MODINFOMD_SMAP, size, smapbase);
130*4a5d661aSToomas Soome if (smapattr != NULL) {
131*4a5d661aSToomas Soome size = smaplen * sizeof(*smapattr);
132*4a5d661aSToomas Soome file_addmetadata(kfp, MODINFOMD_SMAP_XATTR, size, smapattr);
133*4a5d661aSToomas Soome }
134*4a5d661aSToomas Soome }
135*4a5d661aSToomas Soome
136*4a5d661aSToomas Soome COMMAND_SET(smap, "smap", "show BIOS SMAP", command_smap);
137*4a5d661aSToomas Soome
138*4a5d661aSToomas Soome static int
command_smap(int argc,char * argv[])139*4a5d661aSToomas Soome command_smap(int argc, char *argv[])
140*4a5d661aSToomas Soome {
141*4a5d661aSToomas Soome u_int i;
142*4a5d661aSToomas Soome
143*4a5d661aSToomas Soome if (smapbase == NULL || smaplen == 0)
144*4a5d661aSToomas Soome return (CMD_ERROR);
145*4a5d661aSToomas Soome if (smapattr != NULL)
146*4a5d661aSToomas Soome for (i = 0; i < smaplen; i++)
147*4a5d661aSToomas Soome printf("SMAP type=%02x base=%016llx len=%016llx attr=%02x\n",
148*4a5d661aSToomas Soome (unsigned int)smapbase[i].type,
149*4a5d661aSToomas Soome (unsigned long long)smapbase[i].base,
150*4a5d661aSToomas Soome (unsigned long long)smapbase[i].length,
151*4a5d661aSToomas Soome (unsigned int)smapattr[i]);
152*4a5d661aSToomas Soome else
153*4a5d661aSToomas Soome for (i = 0; i < smaplen; i++)
154*4a5d661aSToomas Soome printf("SMAP type=%02x base=%016llx len=%016llx\n",
155*4a5d661aSToomas Soome (unsigned int)smapbase[i].type,
156*4a5d661aSToomas Soome (unsigned long long)smapbase[i].base,
157*4a5d661aSToomas Soome (unsigned long long)smapbase[i].length);
158*4a5d661aSToomas Soome return (CMD_OK);
159*4a5d661aSToomas Soome }
160