Rev 7734 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7734 | Rev 8111 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; Shutdown for Menuet ;; |
6 | ;; Shutdown for Menuet ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Distributed under General Public License ;; |
8 | ;; Distributed under General Public License ;; |
9 | ;; See file COPYING for details. ;; |
9 | ;; See file COPYING for details. ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
10 | ;; Copyright 2003 Ville Turjanmaa ;; |
11 | ;; ;; |
11 | ;; ;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | 13 | ||
14 | $Revision: 7734 $ |
- | |
15 | - | ||
16 | ; ACPI Generic Address Structure |
- | |
17 | struct GAS |
- | |
18 | asid db ? ; address space id |
- | |
19 | bit_width db ? |
- | |
20 | bit_offset db ? |
- | |
21 | access_size db ? |
- | |
22 | address DQ ? |
- | |
23 | ends |
- | |
24 | - | ||
25 | ASID.SYSTEM_MEMORY = 0 |
- | |
26 | ASID.SYSTEM_IO = 1 |
- | |
27 | ASID.PCI_CONFIG = 2 |
- | |
28 | ASID.PCI_EC = 3 |
- | |
29 | ASID.PCI_SMBUS = 4 |
- | |
30 | - | ||
31 | ACCESS_SIZE.UNDEFINED = 0 |
- | |
32 | ACCESS_SIZE.BYTE = 1 |
- | |
33 | ACCESS_SIZE.WORD = 2 |
- | |
34 | ACCESS_SIZE.DWORD = 3 |
- | |
35 | ACCESS_SIZE.QWORD = 4 |
14 | $Revision: 8111 $ |
36 | 15 | ||
37 | align 4 |
16 | align 4 |
38 | system_shutdown: ; shut down the system |
17 | system_shutdown: ; shut down the system |
39 | 18 | ||
40 | cmp byte [BOOT.shutdown_type], SYSTEM_SHUTDOWN |
19 | cmp [BOOT.shutdown_type], SYSTEM_SHUTDOWN |
41 | jb @F |
20 | jb @F |
42 | cmp byte [BOOT.shutdown_type], SYSTEM_RESTART |
21 | cmp [BOOT.shutdown_type], SYSTEM_RESTART |
43 | jbe .valid |
22 | jbe .valid |
44 | @@: |
23 | @@: |
45 | ret |
24 | ret |
46 | .valid: |
25 | .valid: |
47 | call stop_all_services |
26 | call stop_all_services |
48 | 27 | ||
49 | yes_shutdown_param: |
28 | yes_shutdown_param: |
50 | ; Shutdown other CPUs, if initialized |
29 | ; Shutdown other CPUs, if initialized |
51 | cmp [ap_initialized], 0 |
30 | cmp [ap_initialized], 0 |
52 | jz .no_shutdown_cpus |
31 | jz .no_shutdown_cpus |
53 | mov edi, [LAPIC_BASE] |
32 | mov edi, [LAPIC_BASE] |
54 | add edi, 300h |
33 | add edi, 300h |
55 | mov esi, smpt+4 |
34 | mov esi, smpt+4 |
56 | mov ebx, [cpu_count] |
35 | mov ebx, [cpu_count] |
57 | dec ebx |
36 | dec ebx |
58 | .shutdown_cpus_loop: |
37 | .shutdown_cpus_loop: |
59 | lodsd |
38 | lodsd |
60 | push esi |
39 | push esi |
61 | xor esi, esi |
40 | xor esi, esi |
62 | inc esi |
41 | inc esi |
63 | shl eax, 24 |
42 | shl eax, 24 |
64 | mov [edi+10h], eax |
43 | mov [edi+10h], eax |
65 | ; assert INIT IPI |
44 | ; assert INIT IPI |
66 | mov dword [edi], 0C500h |
45 | mov dword [edi], 0C500h |
67 | call delay_ms |
46 | call delay_ms |
68 | @@: |
47 | @@: |
69 | test dword [edi], 1000h |
48 | test dword [edi], 1000h |
70 | jnz @b |
49 | jnz @b |
71 | ; deassert INIT IPI |
50 | ; deassert INIT IPI |
72 | mov dword [edi], 8500h |
51 | mov dword [edi], 8500h |
73 | call delay_ms |
52 | call delay_ms |
74 | @@: |
53 | @@: |
75 | test dword [edi], 1000h |
54 | test dword [edi], 1000h |
76 | jnz @b |
55 | jnz @b |
77 | ; don't send STARTUP IPI: let other CPUs be in wait-for-startup state |
56 | ; don't send STARTUP IPI: let other CPUs be in wait-for-startup state |
78 | pop esi |
57 | pop esi |
79 | dec ebx |
58 | dec ebx |
80 | jnz .shutdown_cpus_loop |
59 | jnz .shutdown_cpus_loop |
81 | .no_shutdown_cpus: |
60 | .no_shutdown_cpus: |
82 | 61 | ||
83 | cli |
62 | cli |
84 | call IRQ_mask_all |
63 | call IRQ_mask_all |
85 | 64 | ||
86 | mov eax, dword[BOOT.shutdown_type] |
65 | movzx eax, [BOOT.shutdown_type] |
87 | cmp al, SYSTEM_RESTART |
66 | cmp al, SYSTEM_RESTART |
88 | jne @F |
67 | jne @F |
89 | 68 | ||
90 | ; load kernel.mnt to _CLEAN_ZONE |
69 | ; load kernel.mnt to _CLEAN_ZONE |
91 | mov ebx, kernel_file_load |
70 | mov ebx, kernel_file_load |
92 | pushad |
71 | pushad |
93 | call file_system_lfn |
72 | call file_system_lfn |
94 | popad |
73 | popad |
95 | @@: |
74 | @@: |
96 | mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0 |
75 | mov esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0 |
97 | mov edi, OS_BASE+0x50000 |
76 | mov edi, OS_BASE+0x50000 |
98 | mov ecx, (restart_code_end - restart_code_start)/4 |
77 | mov ecx, (restart_code_end - restart_code_start)/4 |
99 | rep movsd |
78 | rep movsd |
100 | - | ||
101 | call create_trampoline_pgmap |
- | |
102 | mov cr3, eax |
- | |
103 | jmp @F |
- | |
104 | org $-OS_BASE |
- | |
105 | @@: |
- | |
106 | - | ||
107 | ;disable paging |
- | |
108 | - | ||
109 | mov eax, cr0 |
- | |
110 | and eax, 0x7FFFFFFF |
- | |
111 | mov cr0, eax |
- | |
112 | mov eax, cr3 |
- | |
113 | mov cr3, eax |
- | |
114 | 79 | ||
115 | cmp byte [BOOT_LO.shutdown_type], SYSTEM_SHUTDOWN |
80 | cmp [BOOT.shutdown_type], SYSTEM_SHUTDOWN |
116 | jne no_acpi_power_off |
81 | jne not_power_off |
117 | 82 | ||
118 | ; system_power_off |
83 | ; system_power_off |
119 | 84 | ||
- | 85 | mov ebx, [acpi_fadt_base] |
|
- | 86 | test ebx, ebx |
|
120 | mov ebx, [acpi_fadt_base-OS_BASE] |
87 | jz no_acpi |
121 | cmp dword [ebx], 'FACP' |
88 | cmp [ebx+ACPI_TABLE.Signature], 'FACP' |
122 | jne no_acpi_power_off |
89 | jne no_acpi |
- | 90 | mov esi, [acpi_ssdt_base] ; first SSDT is DSDT |
|
- | 91 | test esi, esi |
|
123 | mov esi, [acpi_dsdt_base-OS_BASE] |
92 | jz no_acpi |
124 | cmp dword [esi], 'DSDT' |
93 | cmp [esi+ACPI_TABLE.Signature], 'DSDT' |
125 | jne no_acpi_power_off |
94 | jne no_acpi |
126 | mov eax, [esi+4] ; DSDT length |
95 | mov eax, [esi+ACPI_TABLE.Length] |
127 | sub eax, 36+4 |
96 | sub eax, 36+4 |
128 | jbe no_acpi_power_off |
97 | jbe no_acpi |
129 | add esi, 36 |
98 | add esi, 36 |
130 | .scan_dsdt: |
99 | .scan_dsdt: |
131 | cmp dword [esi], '_S5_' |
100 | cmp dword [esi], '_S5_' |
132 | jnz .scan_dsdt_cont |
101 | jnz .scan_dsdt_cont |
133 | cmp byte [esi+4], 12h ; DefPackage opcode |
102 | cmp byte [esi+4], 12h ; DefPackage opcode |
134 | jnz .scan_dsdt_cont |
103 | jnz .scan_dsdt_cont |
135 | mov dl, [esi+6] |
104 | mov dl, [esi+6] |
136 | cmp dl, 4 ; _S5_ package must contain 4 bytes |
105 | cmp dl, 4 ; _S5_ package must contain 4 bytes |
137 | ; ...in theory; in practice, VirtualBox has 2 bytes |
106 | ; ...in theory; in practice, VirtualBox has 2 bytes |
138 | ja .scan_dsdt_cont |
107 | ja .scan_dsdt_cont |
139 | cmp dl, 1 |
108 | cmp dl, 1 |
140 | jb .scan_dsdt_cont |
109 | jb .scan_dsdt_cont |
141 | lea esi, [esi+7] |
110 | lea esi, [esi+7] |
142 | xor ecx, ecx |
111 | xor ecx, ecx |
143 | cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx |
112 | cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx |
144 | jz @f |
113 | jz @f |
145 | cmp byte [esi], 0xA |
114 | cmp byte [esi], 0xA |
146 | jnz no_acpi_power_off |
115 | jnz no_acpi |
147 | inc esi |
116 | inc esi |
148 | mov cl, [esi] |
117 | mov cl, [esi] |
149 | @@: |
118 | @@: |
150 | inc esi |
119 | inc esi |
151 | cmp dl, 2 |
120 | cmp dl, 2 |
152 | jb @f |
121 | jb @f |
153 | cmp byte [esi], 0 |
122 | cmp byte [esi], 0 |
154 | jz @f |
123 | jz @f |
155 | cmp byte [esi], 0xA |
124 | cmp byte [esi], 0xA |
156 | jnz no_acpi_power_off |
125 | jnz no_acpi |
157 | inc esi |
126 | inc esi |
158 | mov ch, [esi] |
127 | mov ch, [esi] |
159 | @@: |
128 | @@: |
160 | jmp do_acpi_power_off |
129 | jmp do_acpi_power_off |
161 | .scan_dsdt_cont: |
130 | .scan_dsdt_cont: |
162 | inc esi |
131 | inc esi |
163 | dec eax |
132 | dec eax |
164 | jnz .scan_dsdt |
133 | jnz .scan_dsdt |
165 | jmp no_acpi_power_off |
134 | jmp no_acpi |
166 | do_acpi_power_off: |
135 | do_acpi_power_off: |
167 | mov edx, [ebx+48] |
136 | mov edx, [ebx+ACPI_FADT.SMI_CMD] |
168 | test edx, edx |
137 | test edx, edx |
169 | jz .nosmi |
138 | jz .nosmi |
170 | mov al, [ebx+52] |
139 | mov al, [ebx+ACPI_FADT.ACPI_ENABLE] |
171 | out dx, al |
140 | out dx, al |
172 | mov edx, [ebx+64] |
141 | mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] |
173 | @@: |
142 | @@: |
174 | in ax, dx |
143 | in ax, dx |
175 | test al, 1 |
144 | test al, 1 |
176 | jz @b |
145 | jz @b |
177 | .nosmi: |
146 | .nosmi: |
178 | and cx, 0x0707 |
147 | and cx, 0x0707 |
179 | shl cx, 2 |
148 | shl cx, 2 |
180 | or cx, 0x2020 |
149 | or cx, 0x2020 |
181 | mov edx, [ebx+64] |
150 | mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] |
182 | in ax, dx |
151 | in ax, dx |
183 | and ax, 203h |
152 | and ax, 203h |
184 | or ah, cl |
153 | or ah, cl |
185 | out dx, ax |
154 | out dx, ax |
186 | mov edx, [ebx+68] |
155 | mov edx, [ebx+ACPI_FADT.PM1b_CNT_BLK] |
187 | test edx, edx |
156 | test edx, edx |
188 | jz @f |
157 | jz @f |
189 | in ax, dx |
158 | in ax, dx |
190 | and ax, 203h |
159 | and ax, 203h |
191 | or ah, ch |
160 | or ah, ch |
192 | out dx, ax |
161 | out dx, ax |
193 | @@: |
162 | @@: |
194 | jmp $ |
163 | jmp no_acpi |
195 | 164 | ||
196 | no_acpi_power_off: |
165 | not_power_off: |
197 | cmp byte[BOOT_LO.shutdown_type], SYSTEM_REBOOT |
166 | cmp [BOOT.shutdown_type], SYSTEM_REBOOT |
198 | jnz no_acpi_reboot |
167 | jnz not_reboot |
199 | ; try to reboot via ACPI fixed features |
168 | ; try to reboot via ACPI fixed features |
200 | mov ebx, [acpi_fadt_base-OS_BASE] |
169 | mov ebx, [acpi_fadt_base] |
- | 170 | test ebx, ebx |
|
- | 171 | jz no_acpi |
|
201 | cmp dword[ebx], 'FACP' |
172 | cmp [ebx+ACPI_TABLE.Signature], 'FACP' |
- | 173 | jne no_acpi |
|
- | 174 | cmp [ebx+ACPI_FADT.Length], ACPI_FADT.RESET_VALUE |
|
202 | jne no_acpi_power_off |
175 | jbe no_acpi |
203 | test dword[ebx+0x70], 1 SHL 10 ; RESET_REG_SUP |
176 | test [ebx+ACPI_FADT.Flags], 1 SHL 10 ; reset_reg_supported |
204 | jz no_acpi_reboot |
177 | jz no_acpi |
205 | cmp [ebx+0x74+GAS.asid], ASID.SYSTEM_IO |
178 | cmp [ebx+ACPI_FADT.RESET_REG.ASID], ASID.SYSTEM_IO |
206 | jnz no_acpi_reboot |
179 | jnz no_acpi |
207 | cmp [ebx+0x74+GAS.bit_width], 8 |
180 | cmp [ebx+ACPI_FADT.RESET_REG.BitWidth], 8 |
208 | jnz no_acpi_reboot |
181 | jnz no_acpi |
209 | cmp [ebx+0x74+GAS.bit_offset], 0 |
182 | cmp [ebx+ACPI_FADT.RESET_REG.BitOffset], 0 |
210 | jnz no_acpi_reboot |
183 | jnz no_acpi |
211 | cmp [ebx+0x74+GAS.access_size], ACCESS_SIZE.BYTE |
184 | cmp [ebx+ACPI_FADT.RESET_REG.AccessSize], ACCESS_SIZE.BYTE |
212 | ja no_acpi_reboot |
185 | ja no_acpi |
213 | cmp [ebx+0x74+GAS.address.hi], 0 |
186 | cmp [ebx+ACPI_FADT.RESET_REG.Address.hi], 0 |
- | 187 | jnz no_acpi |
|
214 | jnz no_acpi_reboot |
188 | ; 'enable' ACPI |
215 | mov edx, [ebx+0x74+GAS.address.lo] |
189 | mov edx, [ebx+ACPI_FADT.SMI_CMD] |
- | 190 | test edx, edx |
|
- | 191 | jz .nosmi |
|
216 | movzx eax, byte[ebx+0x80] |
192 | mov al, [ebx+ACPI_FADT.ACPI_ENABLE] |
- | 193 | out dx, al |
|
- | 194 | mov edx, [ebx+ACPI_FADT.PM1a_CNT_BLK] |
|
- | 195 | @@: |
|
- | 196 | in ax, dx |
|
217 | out dx, al |
197 | test al, 1 |
- | 198 | jz @b |
|
- | 199 | .nosmi: |
|
- | 200 | ||
- | 201 | mov edx, [ebx+ACPI_FADT.RESET_REG.Address.lo] |
|
- | 202 | movzx eax, [ebx+ACPI_FADT.RESET_VALUE] |
|
218 | jmp $ |
203 | out dx, al |
- | 204 | jmp no_acpi |
|
219 | ; unreachable |
205 | |
- | 206 | not_reboot: |
|
- | 207 | no_acpi: |
|
- | 208 | call create_trampoline_pgmap |
|
- | 209 | mov cr3, eax |
|
- | 210 | jmp @F |
|
- | 211 | org $-OS_BASE |
|
- | 212 | @@: |
|
- | 213 | ||
- | 214 | ;disable paging |
|
- | 215 | ||
- | 216 | mov eax, cr0 |
|
- | 217 | and eax, 0x7FFFFFFF |
|
- | 218 | mov cr0, eax |
|
- | 219 | mov eax, cr3 |
|
- | 220 | mov cr3, eax |
|
220 | no_acpi_reboot: |
221 | |
221 | jmp 0x50000 |
222 | jmp 0x50000 |
222 | 223 | ||
223 | align 4 |
224 | align 4 |
224 | restart_code_start: |
225 | restart_code_start: |
225 | org 0x50000 |
226 | org 0x50000 |
226 | 227 | ||
227 | cmp byte [BOOT_LO.shutdown_type], SYSTEM_RESTART |
228 | cmp [BOOT_LO.shutdown_type], SYSTEM_RESTART |
228 | jne @F |
229 | jne @F |
229 | 230 | ||
230 | mov esi, _CLEAN_ZONE-OS_BASE |
231 | mov esi, _CLEAN_ZONE-OS_BASE |
231 | mov edi, 0x10000 |
232 | mov edi, 0x10000 |
232 | mov ecx, 0x31000/4 |
233 | mov ecx, 0x31000/4 |
233 | cld |
234 | cld |
234 | rep movsd |
235 | rep movsd |
235 | @@: |
236 | @@: |
236 | 237 | ||
237 | xor ebx, ebx |
238 | xor ebx, ebx |
238 | xor edx, edx |
239 | xor edx, edx |
239 | xor ecx, ecx |
240 | xor ecx, ecx |
240 | xor esi, esi |
241 | xor esi, esi |
241 | xor edi, edi |
242 | xor edi, edi |
242 | xor ebp, ebp |
243 | xor ebp, ebp |
243 | lidt [.idt] |
244 | lidt [.idt] |
244 | lgdt [.gdt] |
245 | lgdt [.gdt] |
245 | jmp 8:@f |
246 | jmp 8:@f |
246 | align 8 |
247 | align 8 |
247 | .gdt: |
248 | .gdt: |
248 | ; selector 0 - not used |
249 | ; selector 0 - not used |
249 | dw 23 |
250 | dw 23 |
250 | dd .gdt |
251 | dd .gdt |
251 | dw 0 |
252 | dw 0 |
252 | ; selector 8 - code from 5000:0000 to 1000:FFFF |
253 | ; selector 8 - code from 5000:0000 to 1000:FFFF |
253 | dw 0FFFFh |
254 | dw 0FFFFh |
254 | dw 0 |
255 | dw 0 |
255 | db 5 |
256 | db 5 |
256 | db 10011011b |
257 | db 10011011b |
257 | db 00000000b |
258 | db 00000000b |
258 | db 0 |
259 | db 0 |
259 | ; selector 10h - data from 1000:0000 to 1000:FFFF |
260 | ; selector 10h - data from 1000:0000 to 1000:FFFF |
260 | dw 0FFFFh |
261 | dw 0FFFFh |
261 | dw 0 |
262 | dw 0 |
262 | db 1 |
263 | db 1 |
263 | db 10010011b |
264 | db 10010011b |
264 | db 00000000b |
265 | db 00000000b |
265 | db 0 |
266 | db 0 |
266 | .idt: |
267 | .idt: |
267 | dw 256*4 |
268 | dw 256*4 |
268 | dd 0 |
269 | dd 0 |
269 | org $ - 0x50000 |
270 | org $ - 0x50000 |
270 | use16 |
271 | use16 |
271 | @@: |
272 | @@: |
272 | mov ax, 10h |
273 | mov ax, 10h |
273 | mov ds, ax |
274 | mov ds, ax |
274 | mov es, ax |
275 | mov es, ax |
275 | mov fs, ax |
276 | mov fs, ax |
276 | mov gs, ax |
277 | mov gs, ax |
277 | mov ss, ax |
278 | mov ss, ax |
278 | 279 | ||
279 | mov eax, cr0 |
280 | mov eax, cr0 |
280 | and eax, not 80000001h |
281 | and eax, not 80000001h |
281 | mov cr0, eax |
282 | mov cr0, eax |
282 | jmp 0x5000:.real_mode |
283 | jmp 0x5000:.real_mode |
283 | 284 | ||
284 | align 4 |
285 | align 4 |
285 | .real_mode: |
286 | .real_mode: |
286 | 287 | ||
287 | ; setup stack |
288 | ; setup stack |
288 | 289 | ||
289 | mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 |
290 | mov ax, (TMP_STACK_TOP and 0xF0000) shr 4 |
290 | mov ss, ax |
291 | mov ss, ax |
291 | mov esp, TMP_STACK_TOP and 0xFFFF |
292 | mov esp, TMP_STACK_TOP and 0xFFFF |
292 | 293 | ||
293 | ;remap IRQs |
294 | ;remap IRQs |
294 | mov al, 0x11 |
295 | mov al, 0x11 |
295 | out 0x20, al |
296 | out 0x20, al |
296 | out 0xA0, al |
297 | out 0xA0, al |
297 | 298 | ||
298 | mov al, 0x08 |
299 | mov al, 0x08 |
299 | out 0x21, al |
300 | out 0x21, al |
300 | mov al, 0x70 |
301 | mov al, 0x70 |
301 | out 0xA1, al |
302 | out 0xA1, al |
302 | 303 | ||
303 | mov al, 0x04 |
304 | mov al, 0x04 |
304 | out 0x21, al |
305 | out 0x21, al |
305 | mov al, 0x02 |
306 | mov al, 0x02 |
306 | out 0xA1, al |
307 | out 0xA1, al |
307 | 308 | ||
308 | mov al, 0x01 |
309 | mov al, 0x01 |
309 | out 0x21, al |
310 | out 0x21, al |
310 | out 0xA1, al |
311 | out 0xA1, al |
311 | 312 | ||
312 | mov al, 0xB8 |
313 | mov al, 0xB8 |
313 | out 0x21, al |
314 | out 0x21, al |
314 | mov al, 0xBD |
315 | mov al, 0xBD |
315 | out 0xA1, al |
316 | out 0xA1, al |
316 | 317 | ||
317 | mov al, 00110100b |
318 | mov al, 00110100b |
318 | out 43h, al |
319 | out 43h, al |
319 | mov al, 0xFF |
320 | mov al, 0xFF |
320 | out 40h, al |
321 | out 40h, al |
321 | out 40h, al |
322 | out 40h, al |
322 | 323 | ||
323 | xor ax, ax |
324 | xor ax, ax |
324 | mov ds, ax |
325 | mov ds, ax |
325 | mov al, [BOOT_LO.shutdown_type] |
326 | mov al, [BOOT_LO.shutdown_type] |
326 | cmp al, SYSTEM_RESTART |
327 | cmp al, SYSTEM_RESTART |
327 | je .restart |
328 | je .restart |
328 | 329 | ||
329 | cmp al, SYSTEM_SHUTDOWN |
330 | cmp al, SYSTEM_SHUTDOWN |
330 | je .APM_PowerOff |
331 | je .APM_PowerOff |
331 | 332 | ||
332 | mov word[0x0472], 0x1234 |
333 | mov word[0x0472], 0x1234 |
333 | jmp 0xF000:0xFFF0 |
334 | jmp 0xF000:0xFFF0 |
334 | 335 | ||
335 | .APM_PowerOff: |
336 | .APM_PowerOff: |
336 | mov ax, 5304h |
337 | mov ax, 5304h |
337 | xor bx, bx |
338 | xor bx, bx |
338 | int 15h |
339 | int 15h |
339 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
340 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
340 | mov ax, 0x5300 |
341 | mov ax, 0x5300 |
341 | xor bx, bx |
342 | xor bx, bx |
342 | int 0x15 |
343 | int 0x15 |
343 | push ax |
344 | push ax |
344 | 345 | ||
345 | mov ax, 0x5301 |
346 | mov ax, 0x5301 |
346 | xor bx, bx |
347 | xor bx, bx |
347 | int 0x15 |
348 | int 0x15 |
348 | 349 | ||
349 | mov ax, 0x5308 |
350 | mov ax, 0x5308 |
350 | mov bx, 1 |
351 | mov bx, 1 |
351 | mov cx, bx |
352 | mov cx, bx |
352 | int 0x15 |
353 | int 0x15 |
353 | 354 | ||
354 | mov ax, 0x530E |
355 | mov ax, 0x530E |
355 | xor bx, bx |
356 | xor bx, bx |
356 | pop cx |
357 | pop cx |
357 | int 0x15 |
358 | int 0x15 |
358 | 359 | ||
359 | mov ax, 0x530D |
360 | mov ax, 0x530D |
360 | mov bx, 1 |
361 | mov bx, 1 |
361 | mov cx, bx |
362 | mov cx, bx |
362 | int 0x15 |
363 | int 0x15 |
363 | 364 | ||
364 | mov ax, 0x530F |
365 | mov ax, 0x530F |
365 | mov bx, 1 |
366 | mov bx, 1 |
366 | mov cx, bx |
367 | mov cx, bx |
367 | int 0x15 |
368 | int 0x15 |
368 | 369 | ||
369 | mov ax, 0x5307 |
370 | mov ax, 0x5307 |
370 | mov bx, 1 |
371 | mov bx, 1 |
371 | mov cx, 3 |
372 | mov cx, 3 |
372 | int 0x15 |
373 | int 0x15 |
373 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
374 | ;!!!!!!!!!!!!!!!!!!!!!!!! |
374 | jmp $ |
375 | jmp $ |
375 | 376 | ||
376 | .restart: |
377 | .restart: |
377 | 378 | ||
378 | ; (hint by Black_mirror) |
379 | ; (hint by Black_mirror) |
379 | ; We must read data from keyboard port, |
380 | ; We must read data from keyboard port, |
380 | ; because there may be situation when previous keyboard interrupt is lost |
381 | ; because there may be situation when previous keyboard interrupt is lost |
381 | ; (due to return to real mode and IRQ reprogramming) |
382 | ; (due to return to real mode and IRQ reprogramming) |
382 | ; and next interrupt will not be generated (as keyboard waits for handling) |
383 | ; and next interrupt will not be generated (as keyboard waits for handling) |
383 | 384 | ||
384 | mov cx, 16 |
385 | mov cx, 16 |
385 | @@: |
386 | @@: |
386 | in al, 0x64 |
387 | in al, 0x64 |
387 | test al, 1 |
388 | test al, 1 |
388 | jz @F |
389 | jz @F |
389 | in al, 0x60 |
390 | in al, 0x60 |
390 | loop @B |
391 | loop @B |
391 | @@: |
392 | @@: |
392 | 393 | ||
393 | ; bootloader interface |
394 | ; bootloader interface |
394 | push 0x1000 |
395 | push 0x1000 |
395 | pop ds |
396 | pop ds |
396 | push 0 |
397 | push 0 |
397 | pop es |
398 | pop es |
398 | mov si, [es:BOOT_LO.kernel_restart] |
399 | mov si, [es:BOOT_LO.kernel_restart] |
399 | mov ax, 'KL' |
400 | mov ax, 'KL' |
400 | jmp 0x1000:0000 |
401 | jmp 0x1000:0000 |
401 | 402 | ||
402 | align 4 |
403 | align 4 |
403 | org restart_code_start + $ |
404 | org restart_code_start + $ |
404 | restart_code_end: |
405 | restart_code_end: |
405 | 406 | ||
406 | org $+OS_BASE |
407 | org $+OS_BASE |
407 | use32 |
408 | use32 |