Subversion Repositories Kolibri OS

Rev

Rev 8111 | Details | Compare with Previous | Last modification | View Log | RSS feed

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