xref: /freebsd/sys/i386/include/pc/bios.h (revision 66df505066f51e6d8411b966765d828817f88971)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1997 Michael Smith
5  * Copyright (c) 1998 Jonathan Lemon
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 #ifndef _MACHINE_PC_BIOS_H_
33 #define _MACHINE_PC_BIOS_H_
34 
35 /*
36  * Signature structure for the BIOS32 Service Directory header
37  */
38 struct bios32_SDheader
39 {
40     u_int8_t	sig[4];
41     u_int32_t	entry;
42     u_int8_t	revision;
43     u_int8_t	len;
44     u_int8_t	cksum;
45     u_int8_t	pad[5];
46 };
47 
48 /*
49  * PnP BIOS presence structure
50  */
51 struct PnPBIOS_table
52 {
53     u_int8_t	sig[4];			/* "$PnP */
54     u_int8_t	version;		/* should be 0x10 */
55     u_int8_t	len;    		/* total structure length */
56     u_int16_t	control;		/* BIOS feature flags */
57     u_int8_t	cksum;			/* checksum */
58     u_int32_t	evflagaddr;		/* address of event notificaton flag */
59     u_int16_t	rmentryoffset;		/* real-mode entry offset */
60     u_int16_t	rmentryseg;		/*                 segment */
61     u_int16_t	pmentryoffset;		/* protected-mode entry offset */
62     u_int32_t	pmentrybase;		/*                segment base */
63     u_int32_t	oemdevid;		/* motherboard EISA ID */
64     u_int16_t	rmbiosseg;		/* real-mode BIOS segment */
65     u_int32_t	pmdataseg;		/* protected-mode data segment */
66 } __packed;
67 
68 /*
69  * PnP BIOS return codes
70  */
71 #define PNP_SUCCESS				0x00
72 #define PNP_NOT_SET_STATICALLY			0x7f
73 #define PNP_UNKNOWN_FUNCTION			0x81
74 #define PNP_FUNCTION_NOT_SUPPORTED		0x82
75 #define PNP_INVALID_HANDLE			0x83
76 #define PNP_BAD_PARAMETER			0x84
77 #define PNP_SET_FAILED				0x85
78 #define PNP_EVENTS_NOT_PENDING			0x86
79 #define PNP_SYSTEM_NOT_DOCKED			0x87
80 #define PNP_NO_ISA_PNP_CARDS			0x88
81 #define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
82 #define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY	0x8a
83 #define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
84 #define PNP_BUFFER_TOO_SMALL			0x8c
85 #define PNP_USE_ESCD_SUPPORT			0x8d
86 #define PNP_MESSAGE_NOT_SUPPORTED		0x8e
87 #define PNP_HARDWARE_ERROR			0x8f
88 
89 /*
90  * DMI return codes
91  */
92 #define DMI_SUCCESS				0x00
93 #define DMI_UNKNOWN_FUNCTION			0x81
94 #define DMI_FUNCTION_NOT_SUPPORTED		0x82
95 #define DMI_INVALID_HANDLE			0x83
96 #define DMI_BAD_PARAMETER			0x84
97 #define DMI_INVALID_SUBFUNCTION			0x85
98 #define DMI_NO_CHANGE				0x86
99 #define DMI_ADD_STRUCTURE_FAILED		0x87
100 #define DMI_READ_ONLY				0x8d
101 #define DMI_LOCK_NOT_SUPPORTED			0x90
102 #define DMI_CURRENTLY_LOCKED			0x91
103 #define DMI_INVALID_LOCK			0x92
104 
105 /*
106  * format specifiers and defines for bios16()
107  *     s	= short (16 bits)
108  *     i	= int (32 bits)
109  *     p	= pointer (converted to seg:offset)
110  *     C,D,U 	= selector (corresponding to code/data/utility segment)
111  */
112 #define PNP_COUNT_DEVNODES	"sppD",		0x00
113 #define PNP_GET_DEVNODE		"sppsD",	0x01
114 #define PNP_SET_DEVNODE		"sspsD",	0x02
115 #define PNP_GET_EVENT		"spD",		0x03
116 #define PNP_SEND_MSG		"ssD",		0x04
117 #define PNP_GET_DOCK_INFO	"spD",		0x05
118 
119 #define PNP_SEL_PRIBOOT		"ssiiisspD",	0x07
120 #define PNP_GET_PRIBOOT		"sspppppD",	0x08
121 #define PNP_SET_RESINFO		"spD",		0x09
122 #define PNP_GET_RESINFO		"spD",		0x0A
123 #define PNP_GET_APM_ID		"sppD",		0x0B
124 
125 #define PNP_GET_ISA_INFO	"spD",		0x40
126 #define PNP_GET_ECSD_INFO	"spppD",	0x41
127 #define PNP_READ_ESCD		"spUD",		0x42
128 #define PNP_WRITE_ESCD		"spUD",		0x43
129 
130 #define PNP_GET_DMI_INFO	"spppppD",	0x50
131 #define PNP_GET_DMI_STRUCTURE	"sppUD",	0x51
132 #define PNP_SET_DMI_STRUCTURE	"sppsUD"	0x52
133 #define PNP_GET_DMI_CHANGE	"spUD"		0x53
134 #define PNP_DMI_CONTROL		"sspsUD"	0x54
135 #define PNP_GET_GPNV_INFO	"sppppD"	0x55
136 #define PNP_READ_GPNV_DATA	"ssppUD"	0x56
137 #define PNP_WRITE_GPNV_DATA	"sspsUD"	0x57
138 
139 #define PNP_BOOT_CHECK		"sp",		0x60
140 #define PNP_COUNT_IPL		"sppp",		0x61
141 #define PNP_GET_BOOTPRI		"spp",		0x62
142 #define PNP_SET_BOOTPRI		"sp",		0x63
143 #define PNP_GET_LASTBOOT	"sp",		0x64
144 #define PNP_GET_BOOTFIRST	"sp",		0x65
145 #define PNP_SET_BOOTFIRST	"sp",		0x66
146 
147 /*
148  * PCI BIOS functions
149  */
150 #define PCIBIOS_BIOS_PRESENT		0xb101
151 #define PCIBIOS_READ_CONFIG_BYTE	0xb108
152 #define PCIBIOS_READ_CONFIG_WORD	0xb109
153 #define PCIBIOS_READ_CONFIG_DWORD	0xb10a
154 #define PCIBIOS_WRITE_CONFIG_BYTE	0xb10b
155 #define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
156 #define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
157 #define PCIBIOS_GET_IRQ_ROUTING		0xb10e
158 #define PCIBIOS_ROUTE_INTERRUPT		0xb10f
159 
160 /*
161  * PCI interrupt routing table.
162  *
163  * $PIR in the BIOS segment contains a PIR_table
164  * int 1a:b106 returns PIR_table in buffer at es:(e)di
165  * int 1a:b18e returns PIR_table in buffer at es:(e)di
166  * int 1a:b406 returns es:di pointing to the BIOS PIR_table
167  */
168 struct PIR_header
169 {
170     int8_t	ph_signature[4];
171     u_int16_t	ph_version;
172     u_int16_t	ph_length;
173     u_int8_t	ph_router_bus;
174     u_int8_t	ph_router_dev_fn;
175     u_int16_t	ph_pci_irqs;
176     u_int16_t	ph_router_vendor;
177     u_int16_t	ph_router_device;
178     u_int32_t	ph_miniport;
179     u_int8_t	ph_res[11];
180     u_int8_t	ph_checksum;
181 } __packed;
182 
183 struct PIR_intpin
184 {
185     u_int8_t	link;
186     u_int16_t	irqs;
187 } __packed;
188 
189 struct PIR_entry
190 {
191     u_int8_t		pe_bus;
192     u_int8_t		pe_res1:3;
193     u_int8_t		pe_device:5;
194     struct PIR_intpin	pe_intpin[4];
195     u_int8_t	pe_slot;
196     u_int8_t	pe_res3;
197 } __packed;
198 
199 struct PIR_table
200 {
201     struct PIR_header	pt_header;
202     struct PIR_entry	pt_entry[0];
203 } __packed;
204 
205 /*
206  * Int 15:E820 'SMAP' structure
207  */
208 #define SMAP_SIG	0x534D4150			/* 'SMAP' */
209 
210 #define	SMAP_TYPE_MEMORY	1
211 #define	SMAP_TYPE_RESERVED	2
212 #define	SMAP_TYPE_ACPI_RECLAIM	3
213 #define	SMAP_TYPE_ACPI_NVS	4
214 #define	SMAP_TYPE_ACPI_ERROR	5
215 #define	SMAP_TYPE_DISABLED	6
216 #define	SMAP_TYPE_PMEM		7
217 #define	SMAP_TYPE_PRAM		12
218 
219 #define	SMAP_XATTR_ENABLED	0x00000001
220 #define	SMAP_XATTR_NON_VOLATILE	0x00000002
221 #define	SMAP_XATTR_MASK		(SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE)
222 
223 struct bios_smap {
224     u_int64_t	base;
225     u_int64_t	length;
226     u_int32_t	type;
227 } __packed;
228 
229 /* Structure extended to include extended attribute field in ACPI 3.0. */
230 struct bios_smap_xattr {
231     u_int64_t	base;
232     u_int64_t	length;
233     u_int32_t	type;
234     u_int32_t	xattr;
235 } __packed;
236 
237 #ifdef _KERNEL
238 #define BIOS_PADDRTOVADDR(x)	((x) + PMAP_MAP_LOW)
239 #define BIOS_VADDRTOPADDR(x)	((x) - PMAP_MAP_LOW)
240 
241 struct bios_oem_signature {
242 	char * anchor;		/* search anchor string in BIOS memory */
243 	size_t offset;		/* offset from anchor (may be negative) */
244 	size_t totlen;		/* total length of BIOS string to copy */
245 } __packed;
246 
247 struct bios_oem_range {
248 	u_int from;		/* shouldn't be below 0xe0000 */
249 	u_int to;		/* shouldn't be above 0xfffff */
250 } __packed;
251 
252 struct bios_oem {
253 	struct bios_oem_range range;
254 	struct bios_oem_signature signature[];
255 } __packed;
256 
257 struct segment_info {
258 	u_int	base;
259 	u_int	limit;
260 };
261 
262 #define BIOSCODE_FLAG	0x01
263 #define BIOSDATA_FLAG	0x02
264 #define BIOSUTIL_FLAG	0x04
265 #define BIOSARGS_FLAG	0x08
266 
267 struct bios_segments {
268 	struct	segment_info code32;		/* 32-bit code (mandatory) */
269 	struct	segment_info code16;		/* 16-bit code */
270 	struct	segment_info data;		/* 16-bit data */
271 	struct	segment_info util;		/* 16-bit utility */
272 	struct	segment_info args;		/* 16-bit args */
273 };
274 
275 struct bios_regs {
276 	u_int	eax;
277 	u_int	ebx;
278 	u_int	ecx;
279 	u_int	edx;
280 	u_int	esi;
281 	u_int	edi;
282 };
283 
284 struct bios_args {
285 	u_int	entry;				/* entry point of routine */
286 	struct	bios_regs r;
287 	struct	bios_segments seg;
288 };
289 
290 /*
291  * BIOS32 Service Directory entry.  Caller supplies name, bios32_SDlookup
292  * fills in the rest of the details.
293  */
294 struct bios32_SDentry
295 {
296     union
297     {
298 	u_int8_t	name[4];	/* service identifier */
299 	u_int32_t	id;		/* as a 32-bit value */
300     } ident;
301     u_int32_t	base;			/* base of service */
302     u_int32_t	len;			/* service length */
303     u_int32_t	entry;			/* entrypoint offset from base */
304     vm_offset_t	ventry;			/* entrypoint in kernel virtual segment */
305 };
306 
307 /*
308  * Exported lookup results
309  */
310 extern struct bios32_SDentry	PCIbios;
311 
312 int	bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
313 uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
314 	    int sigofs);
315 int	bios16(struct bios_args *, char *, ...);
316 int	bios16_call(struct bios_regs *, char *);
317 int	bios32(struct bios_regs *, u_int, u_short);
318 int	bios32_SDlookup(struct bios32_SDentry *ent);
319 void	set_bios_selectors(struct bios_segments *, int);
320 
321 #endif
322 
323 #endif /* _MACHINE_PC_BIOS_H_ */
324