Subversion Repositories Kolibri OS

Rev

Rev 7132 | Go to most recent revision | 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: 7734 $
15
 
7734 dunkaist 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
36
 
6244 serge 37
align 4
38
system_shutdown:          ; shut down the system
39
 
7132 dunkaist 40
        cmp     byte [BOOT.shutdown_type], SYSTEM_SHUTDOWN
7121 dunkaist 41
        jb      @F
7132 dunkaist 42
        cmp     byte [BOOT.shutdown_type], SYSTEM_RESTART
7121 dunkaist 43
        jbe     .valid
44
@@:
6244 serge 45
        ret
7121 dunkaist 46
.valid:
6244 serge 47
        call    stop_all_services
48
 
49
yes_shutdown_param:
50
; Shutdown other CPUs, if initialized
51
        cmp     [ap_initialized], 0
52
        jz      .no_shutdown_cpus
53
        mov     edi, [LAPIC_BASE]
54
        add     edi, 300h
55
        mov     esi, smpt+4
56
        mov     ebx, [cpu_count]
57
        dec     ebx
58
.shutdown_cpus_loop:
59
        lodsd
60
        push    esi
61
        xor     esi, esi
62
        inc     esi
63
        shl     eax, 24
64
        mov     [edi+10h], eax
65
; assert INIT IPI
66
        mov     dword [edi], 0C500h
67
        call    delay_ms
68
@@:
69
        test    dword [edi], 1000h
70
        jnz     @b
71
; deassert INIT IPI
72
        mov     dword [edi], 8500h
73
        call    delay_ms
74
@@:
75
        test    dword [edi], 1000h
76
        jnz     @b
77
; don't send STARTUP IPI: let other CPUs be in wait-for-startup state
78
        pop     esi
79
        dec     ebx
80
        jnz     .shutdown_cpus_loop
81
.no_shutdown_cpus:
82
 
5032 clevermous 83
        cli
6244 serge 84
        call    IRQ_mask_all
85
 
7132 dunkaist 86
        mov     eax, dword[BOOT.shutdown_type]
6244 serge 87
        cmp     al, SYSTEM_RESTART
88
        jne     @F
89
 
90
; load kernel.mnt to _CLEAN_ZONE
91
        mov     ebx, kernel_file_load
92
        pushad
93
        call    file_system_lfn
94
        popad
95
@@:
96
        mov     esi, OS_BASE+restart_code_start ; move kernel re-starter to 0x5000:0
97
        mov     edi, OS_BASE+0x50000
98
        mov     ecx, (restart_code_end - restart_code_start)/4
99
        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
 
7132 dunkaist 115
        cmp     byte [BOOT_LO.shutdown_type], SYSTEM_SHUTDOWN
6244 serge 116
        jne     no_acpi_power_off
117
 
118
; system_power_off
119
 
120
        mov     ebx, [acpi_fadt_base-OS_BASE]
121
        cmp     dword [ebx], 'FACP'
122
        jne     no_acpi_power_off
123
        mov     esi, [acpi_dsdt_base-OS_BASE]
124
        cmp     dword [esi], 'DSDT'
125
        jne     no_acpi_power_off
126
        mov     eax, [esi+4] ; DSDT length
127
        sub     eax, 36+4
128
        jbe     no_acpi_power_off
129
        add     esi, 36
130
.scan_dsdt:
131
        cmp     dword [esi], '_S5_'
132
        jnz     .scan_dsdt_cont
133
        cmp     byte [esi+4], 12h ; DefPackage opcode
134
        jnz     .scan_dsdt_cont
135
        mov     dl, [esi+6]
136
        cmp     dl, 4 ; _S5_ package must contain 4 bytes
137
                      ; ...in theory; in practice, VirtualBox has 2 bytes
138
        ja      .scan_dsdt_cont
139
        cmp     dl, 1
140
        jb      .scan_dsdt_cont
141
        lea     esi, [esi+7]
142
        xor     ecx, ecx
143
        cmp     byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
144
        jz      @f
145
        cmp     byte [esi], 0xA
146
        jnz     no_acpi_power_off
147
        inc     esi
148
        mov     cl, [esi]
149
@@:
150
        inc     esi
151
        cmp     dl, 2
152
        jb      @f
153
        cmp     byte [esi], 0
154
        jz      @f
155
        cmp     byte [esi], 0xA
156
        jnz     no_acpi_power_off
157
        inc     esi
158
        mov     ch, [esi]
159
@@:
160
        jmp     do_acpi_power_off
161
.scan_dsdt_cont:
162
        inc     esi
163
        dec     eax
164
        jnz     .scan_dsdt
165
        jmp     no_acpi_power_off
166
do_acpi_power_off:
167
        mov     edx, [ebx+48]
168
        test    edx, edx
169
        jz      .nosmi
170
        mov     al, [ebx+52]
171
        out     dx, al
172
        mov     edx, [ebx+64]
173
@@:
174
        in      ax, dx
175
        test    al, 1
176
        jz      @b
177
.nosmi:
178
        and     cx, 0x0707
179
        shl     cx, 2
180
        or      cx, 0x2020
181
        mov     edx, [ebx+64]
182
        in      ax, dx
183
        and     ax, 203h
184
        or      ah, cl
185
        out     dx, ax
186
        mov     edx, [ebx+68]
187
        test    edx, edx
188
        jz      @f
189
        in      ax, dx
190
        and     ax, 203h
191
        or      ah, ch
192
        out     dx, ax
193
@@:
194
        jmp     $
195
 
196
no_acpi_power_off:
7734 dunkaist 197
        cmp     byte[BOOT_LO.shutdown_type], SYSTEM_REBOOT
198
        jnz     no_acpi_reboot
199
        ; try to reboot via ACPI fixed features
200
        mov     ebx, [acpi_fadt_base-OS_BASE]
201
        cmp     dword[ebx], 'FACP'
202
        jne     no_acpi_power_off
203
        test    dword[ebx+0x70], 1 SHL 10    ; RESET_REG_SUP
204
        jz      no_acpi_reboot
205
        cmp     [ebx+0x74+GAS.asid], ASID.SYSTEM_IO
206
        jnz     no_acpi_reboot
207
        cmp     [ebx+0x74+GAS.bit_width], 8
208
        jnz     no_acpi_reboot
209
        cmp     [ebx+0x74+GAS.bit_offset], 0
210
        jnz     no_acpi_reboot
211
        cmp     [ebx+0x74+GAS.access_size], ACCESS_SIZE.BYTE
212
        ja      no_acpi_reboot
213
        cmp     [ebx+0x74+GAS.address.hi], 0
214
        jnz     no_acpi_reboot
215
        mov     edx, [ebx+0x74+GAS.address.lo]
216
        movzx   eax, byte[ebx+0x80]
217
        out     dx, al
218
        jmp     $
219
        ; unreachable
220
no_acpi_reboot:
6244 serge 221
        jmp     0x50000
222
 
223
align 4
224
restart_code_start:
225
org 0x50000
226
 
7132 dunkaist 227
        cmp     byte [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