* Sync to trunk HEAD (r53318).
[reactos.git] / boot / freeldr / freeldr / arch / i386 / i386pnp.S
1 /*
2 * FreeLoader
3 * Copyright (C) 2003 Eric Kohl
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <asm.inc>
21 #include <arch/pc/x86common.h>
22
23 .code32
24
25
26 /*
27 * U32 PnpBiosSupported(VOID);
28 *
29 * RETURNS:
30 */
31 _pnp_bios_entry_point:
32 .long 0
33 _pnp_bios_data_segment:
34 .word 0
35
36 PUBLIC _PnpBiosSupported
37 _PnpBiosSupported:
38
39 push edi
40 push esi
41 push ecx
42 push edx
43
44 xor edi, edi
45
46 /* init esi */
47 mov esi, HEX(0F0000)
48
49 pnp_again:
50 mov eax, [esi]
51 cmp eax, HEX(506E5024) /* "$PnP" */
52 je pnp_found
53
54 cmp esi, HEX(0FFFF0)
55 je pnp_not_found
56
57 pnp_add:
58 add esi, 16
59 jmp pnp_again
60
61 pnp_found:
62 /* first calculate the checksum */
63 push esi
64
65 push HEX(21)
66 pop ecx
67 xor edx, edx
68
69 pnp_loop:
70 lodsb
71 add dl, al
72 loop pnp_loop
73
74 test dl, dl
75 pop esi
76 jnz pnp_add
77
78 mov edi, esi
79
80 /* Calculate the bios entry point (far pointer) */
81 xor eax, eax
82 mov ax, [esi + 15]
83 shl eax, 16
84 mov ax, [esi + 0x0D]
85 mov _pnp_bios_entry_point, eax
86
87 /* Store bios data segment */
88 mov ax, [esi + 0x1B]
89 mov _pnp_bios_data_segment, ax
90
91 pnp_not_found:
92 mov eax, edi
93
94 pop edx
95 pop ecx
96 pop esi
97 pop edi
98
99 ret
100
101
102 /*
103 * U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, U32 *NodeCount);
104 *
105 * RETURNS:
106 */
107 _pnp_result:
108 .long 0
109 _pnp_node_size:
110 .word 0
111 _pnp_node_count:
112 .word 0
113
114 PUBLIC _PnpBiosGetDeviceNodeCount
115 _PnpBiosGetDeviceNodeCount:
116
117 push ebp
118 mov ebp, esp
119
120 pusha
121 push es
122
123 call switch_to_real
124 .code16
125
126 mov ax, word ptr [_pnp_bios_data_segment]
127 push ax
128
129 push cs
130 mov ax, offset _pnp_node_size
131 push ax
132
133 push cs
134 mov ax, offset _pnp_node_count
135 push ax
136
137 push 0
138
139 call dword ptr [_pnp_bios_entry_point]
140 add sp, 12
141
142 movzx ecx, ax
143 mov _pnp_result, ecx
144
145
146 call switch_to_prot
147 .code32
148
149 mov esi, [ebp + 8]
150 mov ax, _pnp_node_size
151 movzx ecx, ax
152 mov [esi], ecx
153
154 mov esi, [ebp + 12]
155 mov ax, _pnp_node_count
156 movzx ecx, ax
157 mov [esi], eax
158
159 pop es
160 popa
161
162 mov esp, ebp
163 pop ebp
164
165 mov eax, _pnp_result
166
167 ret
168
169
170 /*
171 * U32 PnpBiosGetDeviceNode(U8 *NodeId, U8 *NodeBuffer);
172 *
173 * RETURNS:
174 */
175 _pnp_buffer_segment:
176 .word 0
177 _pnp_buffer_offset:
178 .word 0
179
180 _pnp_node_number:
181 .byte 0
182
183 EXTERN(_PnpBiosGetDeviceNode)
184 .code32
185
186 push ebp
187 mov ebp, esp
188
189 pusha
190 push es
191
192 /* get current node number */
193 mov esi, [ebp + 8]
194 mov al, [esi]
195 mov _pnp_node_number, al
196
197 /* convert pointer to node buffer to segment/offset */
198 mov eax, [ebp + 12]
199 shr eax, 4
200 and eax, 0xf000
201 mov _pnp_buffer_segment, ax
202 mov eax, [ebp + 12]
203 and eax, 0xffff
204 mov _pnp_buffer_offset, ax
205
206 call switch_to_real
207 .code16
208
209 /* push bios segment */
210 mov ax, word ptr [_pnp_bios_data_segment]
211 push ax
212
213 /* push control flag */
214 push 1
215
216 /* push pointer to node buffer (segment/offset) */
217 mov ax, word ptr [_pnp_buffer_segment]
218 push ax
219 mov ax, word ptr [_pnp_buffer_offset]
220 push ax
221
222 /* push pointer to node number (segment/offset) */
223 push cs
224 mov ax, offset _pnp_node_number
225 push ax
226
227 /* push function number */
228 push 1
229
230 /* call entry point */
231 call dword ptr [_pnp_bios_entry_point]
232 add sp, 14
233
234 movzx ecx, ax
235 mov _pnp_result, ecx
236
237 call switch_to_prot
238 .code32
239
240 /* update node number */
241 mov esi, [ebp + 8]
242 mov al, _pnp_node_number
243 mov [esi], al
244
245 pop es
246 popa
247
248 mov esp, ebp
249 pop ebp
250
251 mov eax, _pnp_result
252
253 ret
254
255 /* EOF */