VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/apm_pm.asm@ 78374

Last change on this file since 78374 was 76968, checked in by vboxsync, 6 years ago

BIOS: Skip HLT instruction in protected-mode APM idle call. Avoids Windows 3.1 Standard mode (including Windows 3.1 installer) crashing when power.drv is used (see bugref:6549).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1; $Id:
2;; @file
3; Protected-mode APM implementation.
4;
5
6;
7; Copyright (C) 2006-2019 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17
18
19include commondefs.inc
20
21;; 16-bit protected mode APM entry point
22
23_TEXT segment public 'CODE'
24
25extern _apm_function:near ; implemented in C code
26
27
28public apm_pm16_entry
29
30SET_DEFAULT_CPU_286
31
32
33; APM function dispatch table
34apm_disp:
35 dw offset apmf_disconnect ; 04h
36 dw offset apmf_idle ; 05h
37 dw offset apmf_busy ; 06h
38 dw offset apmf_set_state ; 07h
39 dw offset apmf_enable ; 08h
40 dw offset apmf_restore ; 09h
41 dw offset apmf_get_status ; 0Ah
42 dw offset apmf_get_event ; 0Bh
43 dw offset apmf_pwr_state ; 0Ch
44 dw offset apmf_dev_pm ; 0Dh
45 dw offset apmf_version ; 0Eh
46 dw offset apmf_engage ; 0Fh
47 dw offset apmf_get_caps ; 10h
48apm_disp_end:
49
50;
51; APM worker routine. Function code in AL; it is assumed that AL >= 4.
52; Caller must preserve BP.
53;
54apm_worker proc near
55
56 sti ; TODO ?? necessary ??
57
58 push ax ; check if function is supported...
59 xor ah, ah
60 sub al, 4
61 mov bp, ax
62 shl bp, 1
63 cmp al, (apm_disp_end - apm_disp) / 2
64 pop ax
65 mov ah, 53h ; put back APM function
66 jae apmw_bad_func ; validate function range
67
68 jmp apm_disp[bp] ; and dispatch
69
70apmf_disconnect: ; function 04h
71 jmp apmw_success
72
73apmf_idle: ; function 05h
74 ;
75 ; Windows 3.1 POWER.DRV in Standard mode calls into APM
76 ; with CPL=3. If that happens, the HLT instruction will fault
77 ; and Windows will crash. To prevent that, we check the CPL
78 ; and do nothing (better than crashing).
79 ;
80 push cs
81 pop ax
82 test ax, 3 ; CPL > 0?
83 jnz apmw_success
84 sti
85 hlt
86 jmp apmw_success
87
88apmf_busy: ; function 06h
89; jmp apmw_success
90
91apmf_set_state: ; function 07h
92; jmp apmw_success
93
94apmf_enable: ; function 08h
95 jmp apmw_success
96
97apmf_restore: ; function 09h
98; jmp apmw_success
99
100apmf_get_status: ; function 0Ah
101 jmp apmw_bad_func
102
103apmf_get_event: ; function 0Bh
104 mov ah, 80h
105 jmp apmw_failure
106
107apmf_pwr_state: ; function 0Ch
108
109apmf_dev_pm: ; function 0Dh
110 jmp apmw_bad_func
111
112apmf_version: ; function 0Eh
113 mov ax, 0102h
114 jmp apmw_success
115
116apmf_engage: ; function 0Fh
117 ; TODO do something?
118 jmp apmw_success
119
120apmf_get_caps: ; function 10h
121 mov bl, 0 ; no batteries
122 mov cx, 0 ; no special caps
123 jmp apmw_success
124
125apmw_success:
126 clc ; successful return
127 ret
128
129apmw_bad_func:
130 mov ah, 09h ; unrecognized device ID - generic
131
132apmw_failure:
133 stc ; error for unsupported functions
134 ret
135
136apm_worker endp
137
138
139;; 16-bit protected mode APM entry point
140
141;; According to the APM spec, only CS (16-bit code selector) is defined.
142;; The data selector can be derived from it.
143
144apm_pm16_entry:
145
146 mov ah, 2 ; mark as originating in 16-bit PM
147
148 ; fall through
149
150apm_pm16_entry_from_32:
151
152 push ds ; save registers
153 push bp
154
155 push cs
156 pop bp
157 add bp, 8 ; calculate data selector
158 mov ds, bp ; load data segment
159
160 call apm_worker ; call APM handler
161
162 pop bp
163 pop ds ; restore registers
164
165 retf ; return to caller - 16-bit return
166 ; even to 32-bit thunk!
167
168_TEXT ends
169
170
171if VBOX_BIOS_CPU ge 80386
172
173.386
174
175BIOS32 segment public 'CODE' use32
176
177public apm_pm32_entry
178
179;; 32-bit protected mode APM entry point and thunk
180
181;; According to the APM spec, only CS (32-bit) is defined. 16-bit code
182;; selector and the data selector can be derived from it.
183
184;; WARNING: To simplify matters, we use 16-bit far return to go from 32-bit
185;; code to 16-bit and back. As a consequence, the 32-bit APM code must lie
186;; below 64K boundary in the 32-bit APM code segment.
187
188apm_pm32_entry:
189
190 push ebp ; ebp is not used by APM
191
192 mov bp, cs ; return address for 16-bit code
193 push bp
194 mov ebp, apm_pm32_back
195 push bp ; Note: 16:16 address!
196
197 push cs
198 pop ebp
199 add ebp, 8 ; calculate 16-bit code selector
200 push bp ; push 16-bit code selector
201
202 mov ebp, apm_pm16_entry_from_32
203 push bp ; push 16-bit offset
204
205 mov ah, 3 ; mark as originating in 32-bit PM
206
207 db 66h ; force a 16-bit return
208 retf ; off to 16-bit code...
209
210apm_pm32_back: ; return here from 16-bit code
211
212 pop ebp ; restore scratch register
213 retf
214
215BIOS32 ends
216
217endif ; 32-bit code
218
219 end
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette