xref: /titanic_53/usr/src/boot/sys/boot/i386/libi386/biossmap.c (revision 4a5d661a82b942b6538acd26209d959ce98b593a)
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