Subversion Repositories Kolibri OS

Rev

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

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