Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
  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.  
  15. align 4
  16. system_shutdown:          ; shut down the system
  17.  
  18.         cmp     [BOOT.shutdown_type], SYSTEM_SHUTDOWN
  19.         jb      @F
  20.         cmp     [BOOT.shutdown_type], SYSTEM_RESTART
  21.         jbe     .valid
  22. @@:
  23.         ret
  24. .valid:
  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.  
  61.         cli
  62.         call    IRQ_mask_all
  63.  
  64.         movzx   eax, [BOOT.shutdown_type]
  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.  
  79.         cmp     [BOOT.shutdown_type], SYSTEM_SHUTDOWN
  80.         jne     not_power_off
  81.  
  82. ; system_power_off
  83.  
  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]
  95.         sub     eax, 36+4
  96.         jbe     no_acpi
  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
  114.         jnz     no_acpi
  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
  124.         jnz     no_acpi
  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
  133.         jmp     no_acpi
  134. do_acpi_power_off:
  135.         mov     edx, [ebx+ACPI_FADT.SMI_CMD]
  136.         test    edx, edx
  137.         jz      .nosmi
  138.         mov     al, [ebx+ACPI_FADT.ACPI_ENABLE]
  139.         out     dx, al
  140.         mov     edx, [ebx+ACPI_FADT.PM1a_CNT_BLK]
  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
  149.         mov     edx, [ebx+ACPI_FADT.PM1a_CNT_BLK]
  150.         in      ax, dx
  151.         and     ax, 203h
  152.         or      ah, cl
  153.         out     dx, ax
  154.         mov     edx, [ebx+ACPI_FADT.PM1b_CNT_BLK]
  155.         test    edx, edx
  156.         jz      @f
  157.         in      ax, dx
  158.         and     ax, 203h
  159.         or      ah, ch
  160.         out     dx, ax
  161. @@:
  162.         jmp     no_acpi
  163.  
  164. not_power_off:
  165.         cmp     [BOOT.shutdown_type], SYSTEM_REBOOT
  166.         jnz     not_reboot
  167.         ; try to reboot via ACPI fixed features
  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]
  192.         out     dx, al
  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.  
  221.         jmp     0x50000
  222.  
  223. align 4
  224. restart_code_start:
  225. org 0x50000
  226.  
  227.         cmp     [BOOT_LO.shutdown_type], SYSTEM_RESTART
  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]
  245.         jmp     8:@f
  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
  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
  278.  
  279.         mov     eax, cr0
  280.         and     eax, not 80000001h
  281.         mov     cr0, eax
  282.         jmp     0x5000:.real_mode
  283.  
  284. align 4
  285. .real_mode:
  286.  
  287. ; setup stack
  288.  
  289.         mov     ax, (TMP_STACK_TOP and 0xF0000) shr 4
  290.         mov     ss, ax
  291.         mov     esp, TMP_STACK_TOP and 0xFFFF
  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.  
  317.         mov     al, 00110100b
  318.         out     43h, al
  319.         mov     al, 0xFF
  320.         out     40h, al
  321.         out     40h, al
  322.  
  323.         xor     ax, ax
  324.         mov     ds, ax
  325.         mov     al, [BOOT_LO.shutdown_type]
  326.         cmp     al, SYSTEM_RESTART
  327.         je      .restart
  328.  
  329.         cmp     al, SYSTEM_SHUTDOWN
  330.         je      .APM_PowerOff
  331.  
  332.         mov     word[0x0472], 0x1234
  333.         jmp     0xF000:0xFFF0
  334.  
  335. .APM_PowerOff:
  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. ;!!!!!!!!!!!!!!!!!!!!!!!!
  374.         jmp     $
  375.  
  376. .restart:
  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)
  383.  
  384.         mov     cx, 16
  385. @@:
  386.         in      al, 0x64
  387.         test    al, 1
  388.         jz      @F
  389.         in      al, 0x60
  390.         loop    @B
  391. @@:
  392.  
  393. ; bootloader interface
  394.         push    0x1000
  395.         pop     ds
  396.         push    0
  397.         pop     es
  398.         mov     si, [es:BOOT_LO.kernel_restart]
  399.         mov     ax, 'KL'
  400.         jmp     0x1000:0000
  401.  
  402. align 4
  403. org restart_code_start + $
  404. restart_code_end:
  405.  
  406. org $+OS_BASE
  407. use32
  408.