По поводу выключения я потрошил колибри. Конечно, там нету AML интерпретатора. Они тупо ищут в таблице сигнатуру пакета.
Код:
xor rax, rax
mov rsi, [DSDTAddr] ; Load DSDT addr
lodsd ; Signature
lodsd ; Length
mov rcx, rax
add rsi, 24 ; go to first def blocks
.ScanDSDT:
cmp dword [rsi], '_S5_'
jnz .ScanDSDTCont
cmp byte [rsi+4], 12h ; DefPackage opcode
jnz .ScanDSDTCont
mov dl, [rsi+6]
cmp dl, 4 ; _S5_ package must contain 4 bytes
; ...in theory; in practice, VirtualBox has 2 bytes
ja .ScanDSDTCont
cmp dl, 1
jb .ScanDSDTCont
lea rsi, [rsi+7] ; scan package:
xor rbx, rbx
cmp byte [rsi], 0 ; 0 means zero byte, 0Ah xx means byte xx
jz @f
cmp byte [rsi], 0xA
jnz .NoACPIOff
inc rsi
mov bl, [rsi] ; low byte
@@:
inc rsi
cmp dl, 2
jb @f
cmp byte [rsi], 0
jz @f
cmp byte [rsi], 0xA
jnz .NoACPIOff
inc rsi
mov bh, [rsi] ; high byte (if exists)
@@:
jmp .ACPIPowerOff
.ScanDSDTCont:
inc rsi
loop .ScanDSDT
; Found a command
.ACPIPowerOff:
mov rdi, [FADTAddr]
mov edx, [rdi+48]
and bx, 0x0707
shl bx, 2
or bx, 0x2020
mov edx, [rdi+64]
in ax, dx
and ax, 203h
or ah, bl
out dx, ax
mov edx, [rdi+68]
test edx, edx
jz @f
in ax, dx
and ax, 203h
or ah, bh
out dx, ax
@@:
jmp $
.NoACPIOff:
ret
Хотя часть этого шаманства (в конце, уже при выключении) я не особо понимаю. Сие есть временная заглушка, пока не возьмусь за хоть как-нибудь работающий интерпретатор.
Такой метод выключения срабатывает. С громким "Пииууу...." от резко отключенного питания на вращающихся хардах и другом оборудовании. Вообщем как будто выдернули шнур питания.
[offtop] Надо будет потестировать на моем новом компе. Там при выключении через зажатие кнопки питания комп вырубается, но через 5 секунд врубается по новой. Вполне возможно, тут не прокатит этот "ломовой" перевод в S5. [/offtop]