2 * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include <KernelExport.h>
8 #include <vm/vm_types.h>
10 #include <arch/x86/bios.h>
15 # define TRACE(x) dprintf x
23 uint8 entry_point_checksum
;
24 uint8 entry_point_length
;
30 uint8 formatted_area
[5];
32 // this part is the legacy DMI compatible structure
33 uint8 dmi_anchor_string
[5];
34 uint8 intermediate_checksum
;
35 uint16 structure_table_size
;
36 uint32 structure_table
;
37 uint16 num_structures
;
43 uint32 service_directory
;
45 uint8 size
; // in "paragraph" (16 byte) units
58 static addr_t sBios32ServiceDirectory
;
62 check_checksum(addr_t base
, size_t length
)
64 uint8
*bytes
= (uint8
*)base
;
67 for (uint32 i
= 0; i
< length
; i
++)
78 /** This function fills the provided bios32_service structure with
79 * the values that identify BIOS service.
80 * Returns B_OK on successful completion, otherwise B_ERROR if
81 * the BIOS32 service directory is not available, or B_BAD_VALUE
82 * in case the identifier is not known or present.
86 get_bios32_service(uint32 identifier
, struct bios32_service
*service
)
88 TRACE(("get_bios32_service(identifier = %#lx)\n", identifier
));
90 if (sBios32ServiceDirectory
== 0)
93 uint32 eax
= 0, ebx
= 0, ecx
= 0, edx
= 0;
95 asm("movl %4, %%eax; " // set service parameters
98 "pushl %%cs; " // emulate far call by register
100 "movl %%eax, %0; " // save return values
104 : "=m" (eax
), "=m" (ebx
), "=m" (ecx
), "=m" (edx
)
105 : "m" (identifier
), "m" (sBios32ServiceDirectory
)
106 : "eax", "ebx", "ecx", "edx", "memory");
108 if ((eax
& 0xff) != 0)
113 service
->offset
= edx
;
122 // map BIOS area 0xe0000 - 0xfffff
123 area_id biosArea
= map_physical_memory("pc bios", 0xe0000, 0x20000,
124 B_ANY_KERNEL_ADDRESS
| B_MTR_WB
,
125 B_KERNEL_READ_AREA
| B_KERNEL_WRITE_AREA
, (void **)&gBiosBase
);
129 TRACE(("PC BIOS mapped to %p\n", (void *)gBiosBase
));
131 // ToDo: add driver settings support to disable the services below
133 // search for available BIOS services
135 addr_t base
= gBiosBase
;
136 addr_t end
= base
+ 0x20000;
139 switch (*(uint32
*)base
) {
141 if (check_checksum(base
, sizeof(struct bios32
))) {
142 struct bios32
*bios32
= (struct bios32
*)base
;
144 TRACE(("bios32 revision %d\n", bios32
->revision
));
145 TRACE(("bios32 service directory at: %lx\n", bios32
->service_directory
));
147 if (bios32
->service_directory
>= 0xe0000
148 && bios32
->service_directory
<= 0xfffff)
149 sBios32ServiceDirectory
= gBiosBase
- 0xe0000 + bios32
->service_directory
;
153 // SMBIOS contains the legacy DMI structure, so we have to
154 // make sure it won't be found
156 TRACE(("probably found SMBIOS structure.\n"));
159 TRACE(("probably found DMI legacy structure.\n"));
163 // get on to next "paragraph"