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