forked from Manuel/meeting-assistant
80 lines
2.2 KiB
NASM
80 lines
2.2 KiB
NASM
; Bare 64-KiB BIOS for the existing Linux QEMU binary, not macOS firmware.
|
|
; Assemble: nasm -f bin -o ci-cpu-preflight.bin macos-tcg-cpu-preflight.asm
|
|
; No disks/network. isa-debug-exit returns 33 only after AVX + AVX2 execute
|
|
; and the upper 128-bit lane contains the expected arithmetic result.
|
|
; Unsupported instructions/triple faults cannot produce the success code.
|
|
BITS 16
|
|
ORG 0
|
|
start:
|
|
cli
|
|
cld
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov ss, ax
|
|
mov sp, 0x8000
|
|
|
|
; QEMU zeroes fresh RAM. Identity-map the first 2 MiB through three tables.
|
|
mov dword [0x1000], 0x2003
|
|
mov dword [0x2000], 0x3003
|
|
mov dword [0x3000], 0x0083
|
|
lgdt [cs:gdt_descriptor]
|
|
mov eax, 0x40620 ; PAE, OSFXSR, OSXMMEXCPT, OSXSAVE
|
|
mov cr4, eax
|
|
mov eax, 0x1000
|
|
mov cr3, eax
|
|
mov ecx, 0xc0000080 ; EFER.LME
|
|
rdmsr
|
|
or eax, 0x100
|
|
wrmsr
|
|
mov eax, cr0
|
|
and eax, ~0x0c ; clear EM and TS before vector instructions
|
|
or eax, 0x80000003 ; paging, protected mode, monitor coprocessor
|
|
mov cr0, eax
|
|
jmp dword 0x08:(0xf0000 + long_mode)
|
|
|
|
ALIGN 8
|
|
gdt:
|
|
dq 0
|
|
dq 0x00af9a000000ffff ; ring-0 long-mode code, base 0
|
|
dq 0x00cf92000000ffff ; ring-0 data, base 0
|
|
gdt_descriptor:
|
|
dw gdt_descriptor - gdt - 1
|
|
dd 0xf0000 + gdt
|
|
|
|
BITS 64
|
|
long_mode:
|
|
mov ax, 0x10
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov ss, ax
|
|
mov rsp, 0x8000
|
|
xor ecx, ecx
|
|
mov eax, 7 ; XCR0 enables x87, SSE and AVX state
|
|
xor edx, edx
|
|
xsetbv
|
|
vxorps ymm0, ymm0, ymm0 ; AVX, including the upper YMM lane
|
|
vpcmpeqd ymm1, ymm1, ymm1 ; AVX2: all eight int32 lanes become -1
|
|
vpsrld ymm1, ymm1, 31 ; AVX2: all lanes become 1
|
|
vpaddd ymm2, ymm1, ymm1 ; AVX2: all lanes become 2
|
|
vextracti128 xmm3, ymm2, 1 ; AVX2: inspect the upper half, not only SSE
|
|
vmovd eax, xmm3
|
|
cmp eax, 2
|
|
jne fail
|
|
vzeroupper
|
|
mov eax, 0x10 ; QEMU debugexit computes (value << 1) | 1
|
|
jmp exit_qemu
|
|
fail:
|
|
mov eax, 0x11
|
|
exit_qemu:
|
|
mov dx, 0xf4
|
|
out dx, eax
|
|
hlt
|
|
jmp $
|
|
|
|
; CPU reset starts at the last 16 bytes; reload the real-mode CS base.
|
|
BITS 16
|
|
TIMES 0xfff0 - ($ - $$) db 0xff
|
|
jmp 0xf000:start
|
|
TIMES 0x10000 - ($ - $$) db 0xff
|