Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2016. 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. $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
  36.  
  37. align 4
  38. system_shutdown:          ; shut down the system
  39.  
  40.         cmp     byte [BOOT.shutdown_type], SYSTEM_SHUTDOWN
  41.         jb      @F
  42.         cmp     byte [BOOT.shutdown_type], SYSTEM_RESTART
  43.         jbe     .valid
  44. @@:
  45.         ret
  46. .valid:
  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.  
  83.         cli
  84.         call    IRQ_mask_all
  85.  
  86.         mov     eax, dword[BOOT.shutdown_type]
  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.  
  115.         cmp     byte [BOOT_LO.shutdown_type], SYSTEM_SHUTDOWN
  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:
  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:
  221.         jmp     0x50000
  222.  
  223. align 4
  224. restart_code_start:
  225. org 0x50000
  226.  
  227.         cmp     byte [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.