uefi64kos: Detect last PCI bus, use fastcall macro.

* Detect last PCI bus via PCI Root Bridge IO protocol (uefi64kos only).
 * fastcall macro by Tomasz is much cleaner than eficall from osdev board.

git-svn-id: svn://kolibrios.org@9227 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2021-11-01 02:04:30 +00:00
parent cffbb82ac5
commit 707e7037f0
10 changed files with 1034 additions and 358 deletions

View File

@ -28,6 +28,21 @@ ACCESS_SIZE.WORD = 2
ACCESS_SIZE.DWORD = 3
ACCESS_SIZE.QWORD = 4
struct ADDRESS_SPACE_RESOURCE_DESCRIPTOR
Type db ?
Length dw ?
ResourceType db ?
GeneralFlags db ?
SpecificFlags db ?
ends
struct QWORD_ADDRESS_SPACE_DESCRIPTOR ADDRESS_SPACE_RESOURCE_DESCRIPTOR
Granularity dq ?
RangeMinimum dq ?
RangeMaximum dq ?
TranslationOffset dq ?
AddressLength dq ?
ends
struct ACPI_RSDP
Signature DQ ?

View File

@ -0,0 +1,618 @@
; Macroinstructions for defining and calling procedures (x64 version)
macro invoke proc,[arg]
{ common fastcall [proc],arg }
macro fastcall proc,[arg]
{ common local stackspace,argscount,counter
if argscount < 4
stackspace = 4*8
else if argscount and 1
stackspace = (argscount+1)*8
else
stackspace = argscount*8
end if
counter = 0
if stackspace
if defined current@frame
if current@frame<stackspace
current@frame = stackspace
end if
else
if stackspace
sub rsp, stackspace
end if
end if
end if
forward
counter = counter + 1
define type@param
define definition@param arg
match =float value,definition@param
\{ define definition@param value
define type@param float \}
match =addr value,definition@param
\{ define definition@param value
define type@param addr \}
match any=,any,definition@param
\{ \local ..string,..continue
jmp ..continue
align sizeof.TCHAR
..string TCHAR definition@param,0
..continue:
define definition@param ..string
define type@param addr \}
match any,definition@param
\{ match \`any,any
\\{ \\local ..string,..continue
jmp ..continue
align sizeof.TCHAR
..string TCHAR definition@param,0
..continue:
define definition@param ..string
define type@param addr \\} \}
match param,definition@param
\{ local opcode,origin
size@param = 0
if param eqtype 0 | param eqtype 0f | type@param eq addr
size@param = 8
else if param eqtype byte 0 | param eqtype byte 0f
match prefix value,definition@param
\\{ if prefix eq qword
size@param = 8
else if prefix eq dword
size@param = 4
else if prefix eq word
size@param = 2
else if prefix eq byte
size@param = 1
end if \\}
else if ~ param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
virtual
origin = $
inc param
load opcode byte from origin
if opcode = 67h | opcode = 41h
load opcode byte from origin+1
end if
if opcode and 0F8h = 48h
size@param = 8
else if opcode = 66h
size@param = 2
else if opcode = 0FFh
size@param = 4
else
size@param = 1
end if
end virtual
end if
if counter = 1
if type@param eq float
if ~ param eq xmm0
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax, param
movd xmm0, eax
else
movd xmm0, param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax, param
movq xmm0, rax
else
movq xmm0, param
end if
end if
end if
if vararg@fastcall & ~ param eq rcx
movq rcx, xmm0
end if
else if type@param eq addr
if ~ param eq rcx
lea rcx, [param]
end if
else if size@param = 8
if ~ param eq rcx
mov rcx, param
end if
else if size@param = 4
if ~ param eq ecx
mov ecx, param
end if
else if size@param = 2
if ~ param eq cx
mov cx, param
end if
else if size@param = 1
if ~ param eq cl
mov cl, param
end if
end if
else if counter = 2
if type@param eq float
if ~ param eq xmm1
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax, param
movd xmm1, eax
else
movd xmm1, param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax, param
movq xmm1, rax
else
movq xmm1, param
end if
end if
end if
if vararg@fastcall & ~ param eq rdx
movq rdx, xmm1
end if
else if type@param eq addr
if ~ param eq rdx
lea rdx, [param]
end if
else if size@param = 8
if ~ param eq rdx
mov rdx, param
end if
else if size@param = 4
if ~ param eq edx
mov edx, param
end if
else if size@param = 2
if ~ param eq dx
mov dx, param
end if
else if size@param = 1
if ~ param eq dl
mov dl, param
end if
end if
else if counter = 3
if type@param eq float
if ~ param eq xmm2
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax, param
movd xmm2, eax
else
movd xmm2, param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax, param
movq xmm2, rax
else
movq xmm2, param
end if
end if
end if
if vararg@fastcall & ~ param eq r8
movq r8, xmm2
end if
else if type@param eq addr
if ~ param eq r8
lea r8, [param]
end if
else if size@param = 8
if ~ param eq r8
mov r8, param
end if
else if size@param = 4
if ~ param eq r8d
mov r8d, param
end if
else if size@param = 2
if ~ param eq r8w
mov r8w, param
end if
else if size@param = 1
if ~ param eq r8b
mov r8b, param
end if
end if
else if counter = 4
if type@param eq float
if ~ param eq xmm3
if size@param = 4
if param eqtype byte 0 | param eqtype byte 0f
mov eax, param
movd xmm3, eax
else
movd xmm3, param
end if
else
if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f
mov rax, param
movq xmm3, rax
else
movq xmm3, param
end if
end if
end if
if vararg@fastcall & ~ param eq r9
movq r9, xmm3
end if
else if type@param eq addr
if ~ param eq r9
lea r9, [param]
end if
else if size@param = 8
if ~ param eq r9
mov r9, param
end if
else if size@param = 4
if ~ param eq r9d
mov r9d, param
end if
else if size@param = 2
if ~ param eq r9w
mov r9w, param
end if
else if size@param = 1
if ~ param eq r9b
mov r9b, param
end if
end if
else
if type@param eq addr
lea rax, [param]
mov [rsp+(counter-1)*8], rax
else if param eqtype [0] | param eqtype byte [0]
if size@param = 8
mov rax, param
mov [rsp+(counter-1)*8], rax
else if size@param = 4
mov eax, param
mov [rsp+(counter-1)*8], eax
else if size@param = 2
mov ax, param
mov [rsp+(counter-1)*8], ax
else
mov al, param
mov [rsp+(counter-1)*8], al
end if
else if size@param = 8
virtual
origin = $
mov rax, param
load opcode byte from origin+1
end virtual
if opcode = 0B8h
mov rax, param
mov [rsp+(counter-1)*8], rax
else
mov qword [rsp+(counter-1)*8], param
end if
else if param in <xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15>
movq [rsp+(counter-1)*8], param
else
mov [rsp+(counter-1)*8], param
end if
end if \}
common
argscount = counter
call proc
if stackspace & ~defined current@frame
add rsp, stackspace
end if }
macro proc [args]
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ local loc,fill,counter
loc = (localbytes+15) and (not 15)
parmbase@proc equ rbp+16
localbase@proc equ rbp-loc
push rbp
mov rbp, rsp
if loc+fill
sub rsp, loc+fill
end if
counter = 0
irps reg, reglist \{ push reg
counter = counter+1 \}
fill = 8*(counter and 1) }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
leave
retn }
close@proc equ
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 10000b \}
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
virtual at parmbase@proc
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $-(parmbase@proc)
end virtual
name # % = parmbytes/8
all@vars equ
current = 0
macro locals
\{ virtual at localbase@proc+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(localbase@proc)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc
\{ localbytes = current
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if qqword eq type
dq ?,?,?,?
else if dqword eq type
dq ?,?
else if tbyte eq type
dq ?,?
else
dq ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dq ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val] { name def val }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match =label, def \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
struc label type { label . type }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else if size@initlocal - position@initlocal < 8
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
else
load qword@initlocal qword from name+position@initlocal
if ( qword@initlocal > 0 & qword@initlocal < 80000000h ) | ( qword@initlocal < 0 & qword@initlocal >= -80000000h )
current@initlocal = 8
else
current@initlocal = 4
dword@initlocal = qword@initlocal and 0FFFFFFFFh
end if
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal], byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal], word@initlocal
else if current@initlocal = 4
mov dword [name+position@initlocal], dword@initlocal
else
mov qword [name+position@initlocal], qword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count*2
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
rq count*4
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
rq count*2
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
rq count*4
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
dq ?,?,?,?
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
dq ?,?
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
dq ?,?,?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }
macro frame
{ local size,current
if size
sub rsp, size
end if
current = 0
current@frame equ current
size@frame equ size }
macro endf
{ size@frame = current@frame
if size@frame
add rsp, size@frame
end if
restore size@frame,current@frame }
macro static_rsp_prologue procname,flag,parmbytes,localbytes,reglist
{ local counter,loc,frame,current
counter = 0
irps reg, reglist \{ push reg
counter = counter+1 \}
loc = (localbytes+7) and (not 7)
if frame & (counter+loc shr 3+1) and 1
loc = loc + 8
end if
framebytes@proc equ frame+loc
if framebytes@proc
sub rsp, framebytes@proc
end if
localbase@proc equ rsp+frame
regsbase@proc equ rsp+frame+loc
parmbase@proc equ rsp+frame+loc+counter*8+8
current = 0
current@frame equ current
size@frame equ frame }
macro static_rsp_epilogue procname,flag,parmbytes,localbytes,reglist
{ if framebytes@proc
add rsp, framebytes@proc
end if
irps reg, reglist \{ reverse pop reg \}
retn }
macro static_rsp_close procname,flag,parmbytes,localbytes,reglist
{ size@frame = current@frame
restore size@frame,current@frame }
stdcall fix fastcall
macro cinvoke proc,[arg]
{ common ccall [proc],arg }
macro ccall proc,[arg]
{ common vararg@fastcall = 1
fastcall proc,arg
vararg@fastcall = 0 }
vararg@fastcall = 0

View File

@ -1,9 +1,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;; Written by Ivan Baravy ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Based on UEFI library for fasm by bzt, Public Domain. ;;
@ -96,6 +98,11 @@ EFI_BLOCK_IO_PROTOCOL_GUID equ 0x21,0x5b,0x4e,0x96,0x59,0x64,0xd2,0x11, \
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID equ 0xde,0xa9,0x42,0x90,0xdc,0x23,0x38,0x4a, \
0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID equ 0xBB, 0x7E, 0x70, 0x2F, \
0x1A, 0x4A, 0xd4, 0x11, \
0x9A, 0x38, 0x00, 0x90, \
0x27, 0x3F, 0xC1, 0x4D
EFI_FILE_MODE_READ = 1
EFI_FILE_MODE_WRITE = 2
EFI_FILE_MODE_CREATE = 0x8000000000000000
@ -270,3 +277,47 @@ struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
PixelInformation EFI_PIXEL_BITMASK
PixelsPerScanLine dd ?
ends
struct PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
Read DN ?
Write DN ?
ends
struct EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
ParentHandle DN ? ; EFI_HANDLE
PollMem DN ?
PollIo DN ?
Mem PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
Io PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
Pci PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
CopyMem DN ?
Map DN ?
Unmap DN ?
AllocateBuffer DN ?
FreeBuffer DN ?
Flush DN ?
GetAttributes DN ?
SetAttributes DN ?
Configuration DN ?
SegmentNumber dd ?
ends
struct EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR ; described in acpi spec
Type db ?
Length dw ?
ResourceType db ?
GeneralFlags db ?
SpecificFlags db ?
Granularity dq ?
RangeMinimum dq ?
RangeMaximum dq ?
TranslationOffset dq ?
AddressLength dq ?
ends
EFI_RESOURCE_DESCRIPTOR_TYPE.QWORD_ADDRESS_SPACE = 0x8a
EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG = 0x79
EFI_RESOURCE_TYPE.MEMORY = 0
EFI_RESOURCE_TYPE.IO = 1
EFI_RESOURCE_TYPE.BUS = 2

View File

@ -1,9 +1,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;; Written by Ivan Baravy ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Based on UEFI library for fasm by bzt, Public Domain. ;;
@ -51,8 +53,3 @@ struct EFI_LOADED_IMAGE_PROTOCOL
ImageDataType dd ?
UnLoad dd ?
ends
section '.text' code executable readable
uefifunc:
ret

View File

@ -1,9 +1,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;; Written by Ivan Baravy ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format pe efi
@ -560,11 +562,11 @@ main:
shl eax, 2
mov [edx+BOOT_LO.pitch], ax
mov byte[edx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism
mov byte[edx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them
mov byte[edx+BOOT_LO.pci_data+2], 0x10 ; PCI version
mov byte[edx+BOOT_LO.pci_data+3], 0x02
mov dword[edx+BOOT_LO.pci_data+4], 0xe3
mov [edx+BOOT_LO.pci_data.access_mechanism], 1
movzx eax, [pci_last_bus]
mov [edx+BOOT_LO.pci_data.last_bus], al
mov [edx+BOOT_LO.pci_data.version], 0x0300 ; PCI 3.0
mov [edx+BOOT_LO.pci_data.pm_entry], 0
; kernel
; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
@ -860,6 +862,7 @@ GDT:
gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID
sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
pcirbguid db EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
file_name du "\EFI\KOLIBRIOS\KOLIBRI.INI",0
kernel_name du "\EFI\KOLIBRIOS\KOLIBRI.KRN",0
@ -949,6 +952,8 @@ lip_interface dd 0
sfsp_interface dd 0
pci_last_bus db 254
esp_root dd ?
file_handle dd ?
file_buffer_size dd FILE_BUFFER_SIZE-1 ; leave the last byte for \0

View File

@ -1,9 +1,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;; Written by Ivan Baravy ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Based on UEFI library for fasm by bzt, Public Domain. ;;
@ -49,148 +51,3 @@ struct EFI_LOADED_IMAGE_PROTOCOL
ImageDataType dd ?
UnLoad dq ?
ends
macro eficall interface,function,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11
{
numarg = 0
if ~ arg11 eq
numarg = numarg + 1
if ~ arg11 eq rdi
mov rdi, arg11
end if
end if
if ~ arg10 eq
numarg = numarg + 1
if ~ arg10 eq rsi
mov rsi, arg10
end if
end if
if ~ arg9 eq
numarg = numarg + 1
if ~ arg9 eq r14
mov r14, arg9
end if
end if
if ~ arg8 eq
numarg = numarg + 1
if ~ arg8 eq r13
mov r13, arg8
end if
end if
if ~ arg7 eq
numarg = numarg + 1
if ~ arg7 eq r12
mov r12, arg7
end if
end if
if ~ arg6 eq
numarg = numarg + 1
if ~ arg6 eq r11
mov r11, arg6
end if
end if
if ~ arg5 eq
numarg = numarg + 1
if ~ arg5 eq r10
mov r10, arg5
end if
end if
if ~ arg4 eq
numarg = numarg + 1
if ~ arg4 eq r9
mov r9, arg4
end if
end if
if ~ arg3 eq
numarg = numarg + 1
if ~ arg3 eq r8
mov r8, arg3
end if
end if
if ~ arg2 eq
numarg = numarg + 1
if ~ arg2 eq rdx
mov rdx, arg2
end if
end if
if ~ arg1 eq
numarg = numarg + 1
if ~ arg1 eq rcx
mov rcx, arg1
end if
end if
xor eax, eax
mov al, numarg
if ~ interface eq rbx
mov rbx, interface
end if
mov rbx, [rbx + function]
call uefifunc
}
section '.text' code executable readable
uefifunc:
;save stack pointer
mov [uefi_rsptmp], rsp
;set up new aligned stack
and esp, 0xFFFFFFF0
;alignment check on arguments
bt eax, 0
jnc @f
push rax
;arguments
@@:
cmp al, 11
jb @f
push rdi
@@:
cmp al, 10
jb @f
push rsi
@@:
cmp al, 9
jb @f
push r14
@@:
cmp al, 8
jb @f
push r13
@@:
cmp al, 7
jb @f
push r12
@@:
cmp al, 6
jb @f
push r11
@@:
cmp al, 5
jb @f
push r10
@@:
;space for
;r9
;r8
;rdx
;rcx
sub rsp, 4*8
;call function
call rbx
;restore old stack
mov rsp, [uefi_rsptmp]
ret

View File

@ -1,9 +1,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;; Written by Ivan Baravy ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format pe64 efi
@ -13,14 +15,16 @@ section '.text' code executable readable
include '../../struct.inc'
include '../../macros.inc'
include '../../kglobals.inc'
fastcall fix fstcall
include 'proc64.inc'
include '../../const.inc'
purge DQ
include 'uefi64.inc'
MEMORY_MAP_SIZE = 0x10000
GOP_BUFFER_SIZE = 0x100
LIP_BUFFER_SIZE = 0x100
PROTOCOL_HANDLERS_BUFFER_SIZE = 0x100
FILE_BUFFER_SIZE = 0x1000
KERNEL_TRAMPOLINE = 0x8f80 ; just before BOOT_LO
@ -48,8 +52,10 @@ virtual at rsp+8
.size dq ?
.fatal dq ?
end virtual
eficall [.root], EFI_FILE_PROTOCOL.Open, [.root], file_handle, \
[.name], EFI_FILE_MODE_READ, 0
mov r10, [.root]
mov r11, [.name]
fstcall [r10+EFI_FILE_PROTOCOL.Open], r10, file_handle, \
r11, EFI_FILE_MODE_READ, 0
test eax, eax
jz @f
xor eax, eax
@ -57,19 +63,21 @@ end virtual
jnz .done
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_open_file
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
[.name]
mov r10, [.name]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, r10
jmp $
@@:
lea rax, [.size]
eficall [file_handle], EFI_FILE_PROTOCOL.Read, [file_handle], rax, \
[.buffer]
eficall [file_handle], EFI_FILE_PROTOCOL.Close, [file_handle]
lea rdx, [.size]
mov r8, [.buffer]
mov r10, [file_handle]
fstcall [r10+EFI_FILE_PROTOCOL.Read], [file_handle], rdx, r8
mov r10, [file_handle]
fstcall [r10+EFI_FILE_PROTOCOL.Close], [file_handle]
mov rax, [.size]
.done:
push rax
@ -79,13 +87,13 @@ end virtual
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_file_size
pop rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
pop rax
ret 8*5
@ -279,7 +287,7 @@ end virtual
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_parsing_config
pop rbx
mov rsi, KERNEL_BASE
@ -292,43 +300,43 @@ end virtual
read_options_from_config:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [efi_handle], lipuuid, \
fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], lip_guid, \
lip_interface
test eax, eax
jz @f
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_efi_lip_handle
pop rbx
jmp $
@@:
mov rax, [lip_interface]
mov r10, [lip_interface]
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, \
[rax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \
fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], \
[r10+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfsp_guid, \
sfsp_interface
test eax, eax
jz @f
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_lip_dev_sfsp
pop rbx
jmp $
@@:
eficall [sfsp_interface], EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume, \
mov r10, [sfsp_interface]
fstcall [r10+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], \
[sfsp_interface], esp_root
test eax, eax
jz @f
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_sfsp_openvolume
pop rbx
jmp $
@ -371,7 +379,7 @@ print_vmode:
call num2dec
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rdi rsi rdx rcx rbx rax
ret
@ -379,9 +387,10 @@ find_vmode_index_by_resolution:
mov [cfg_opt_used_resolution], 1
mov [cfg_opt_value_vmode], 0
.next_mode:
movzx eax, [cfg_opt_value_vmode]
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
[gop_interface], rax, gop_info_size, gop_info
movzx edx, [cfg_opt_value_vmode]
mov r10, [gop_interface]
fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
rdx, gop_info_size, gop_info
cmp rax, EFI_SUCCESS
jnz .error
mov rcx, [gop_info]
@ -409,11 +418,11 @@ find_vmode_index_by_resolution:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_no_such_vmode
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
jmp $
.error:
@ -422,11 +431,6 @@ find_vmode_index_by_resolution:
ask_for_params:
ret
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \
msg_ask_for_params
jmp $
xor ebx, ebx
.next_mode:
@ -436,8 +440,9 @@ ask_for_params:
call num2dec
push rbx
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
[gop_interface], rbx, gop_info_size, gop_info
mov r10, [gop_interface]
fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
rbx, gop_info_size, gop_info
cmp rax, EFI_SUCCESS
jnz .error
mov rcx, [gop_info]
@ -456,7 +461,7 @@ ask_for_params:
.skip:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
cmp rax, EFI_SUCCESS
jnz .error
@ -470,7 +475,7 @@ ask_for_params:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
eficall rbx, SIMPLE_INPUT_INTERFACE.Reset, rbx, 1
fstcall [rbx+SIMPLE_INPUT_INTERFACE.Reset], rbx, 1
cmp rax, EFI_SUCCESS
jnz .error
xor ecx, ecx
@ -478,7 +483,7 @@ ask_for_params:
push rcx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
eficall rbx, SIMPLE_INPUT_INTERFACE.ReadKeyStroke, rbx, msg
fstcall [rbx+SIMPLE_INPUT_INTERFACE.ReadKeyStroke], rbx, msg
pop rcx
mov rdx, EFI_DEVICE_ERROR
cmp rax, rdx
@ -501,32 +506,83 @@ ask_for_params:
.done:
ret
main:
detect_pci_config:
fstcall get_protocol_interface, pcirbiop_guid
mov [pcirbiop_interface], rax
mov r10, rax
fstcall [r10+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Configuration], r10, \
pcirbiop_resources
; fstcall dump_pci_resources
fstcall get_last_pci_bus
call clearbuf
movzx eax, [pci_last_bus]
mov rdi, msg
call num2hex
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_pci_last_bus
pop rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
ret
proc get_last_pci_bus
mov rsi, [pcirbiop_resources]
.next_resource:
cmp [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type], \
EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG
jz .not_found
mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum]
cmp [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType], \
EFI_RESOURCE_TYPE.BUS
jz .found
movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length]
lea rsi, [rsi+rax+3]
jmp .next_resource
.found:
mov [pci_last_bus], al
.not_found:
ret
endp
proc main _efi_handle, _efi_table
mov [efi_handle], rcx
mov [efi_table], rdx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset, rbx, 1
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], rbx, 1
test eax, eax
jz @f
jmp $ ; what can I do here?
@@:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_u4k_loaded
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_detect_pci_config
call detect_pci_config
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_read_options
call read_options_from_config
; read kernel file
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_load_kernel
push 1 ; fatal
push MAX_FILE_SIZE
@ -540,7 +596,7 @@ main:
; read ramdisk image
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_load_ramdisk
push 1 ; fatal
push MAX_FILE_SIZE
@ -554,11 +610,11 @@ main:
; alloc buffer for devices.dat
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_alloc_devicesdat
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.AllocatePages, \
fstcall [rbx+EFI_BOOT_SERVICES.AllocatePages], \
EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \
devicesdat_data
cmp eax, EFI_SUCCESS
@ -567,7 +623,7 @@ main:
; read devices.dat
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_load_devicesdat
push 0 ; not fatal
@ -582,111 +638,24 @@ main:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_locate_gop_handlers
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_locate_gop_interface
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.LocateHandle, \
EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \
gop_buffer_size, gop_buffer
mov [status], rax
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_gop_buffer_size
call clearbuf
mov rax, [gop_buffer_size]
mov rdi, msg
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
mov rax, [status]
test eax, eax
jz @f
call clearbuf
mov rdi, msg
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_error
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
jmp $
@@:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_look_for_gop_handler
mov rbx, gop_buffer
.next_gop_handle:
mov rax, rbx
mov rcx, gop_buffer
sub rax, rcx
cmp rax, [gop_buffer_size]
jb @f
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_error_out_of_handlers
pop rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg_error
pop rbx
jmp $
@@:
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
msg_query_handler
pop rbx
mov rax, rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.HandleProtocol, [rax], gopuuid, \
gop_interface
pop rbx
;mov rax, 0x8000_0000_0000_0003
test eax, eax
jz @f
call clearbuf
mov rdi, msg
call num2hex
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
pop rbx
add rbx, 8
jmp .next_gop_handle
@@:
fstcall get_protocol_interface, gop_guid
mov [gop_interface], rax
call find_rsdp
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_acpi_tables_done
cmp [cfg_opt_used_resolution], 0
jz .not_used_resolution
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_opt_resolution
call clearbuf
xor edx, edx
@ -699,7 +668,7 @@ main:
call num2dec
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
call find_vmode_index_by_resolution
.not_used_resolution:
cmp [cfg_opt_used_debug_print], 0
@ -714,9 +683,9 @@ main:
call ask_for_params
@@:
movzx ecx, [cfg_opt_value_vmode]
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode, \
[gop_interface], rcx
movzx edx, [cfg_opt_value_vmode]
mov r10, [gop_interface]
fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], [gop_interface], rdx
test eax, eax
jz @f
call clearbuf
@ -724,10 +693,10 @@ main:
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
jmp $
@@:
@ -738,8 +707,9 @@ main:
mov [fb_base], rdi
mov ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode]
eficall [gop_interface], EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode, \
[gop_interface], rbx, gop_info_size, gop_info
mov rax, [gop_interface]
fstcall [rax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
rbx, gop_info_size, gop_info
test eax, eax
jz @f
jmp .error
@ -754,26 +724,26 @@ main:
shl eax, 2
mov [rdx+BOOT_LO.pitch], ax
mov byte[rdx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism
mov byte[rdx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them
mov byte[rdx+BOOT_LO.pci_data+2], 0x10 ; PCI version
mov byte[rdx+BOOT_LO.pci_data+3], 0x02
mov dword[rdx+BOOT_LO.pci_data+4], 0xe3
mov [rdx+BOOT_LO.pci_data.access_mechanism], 1
movzx eax, [pci_last_bus]
mov [rdx+BOOT_LO.pci_data.last_bus], al
mov [rdx+BOOT_LO.pci_data.version], 0x0300 ; PCI 3.0
mov [rdx+BOOT_LO.pci_data.pm_entry], 0
; kernel
; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; 450000/0x1000, EFI_ALLOCATE_ADDRESS
; ramdisk
; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS
call calc_memmap
; call dump_memmap
; fstcall dump_memmap
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.ExitBootServices, [efi_handle], \
fstcall [rbx+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \
[memory_map_key]
call halt_on_error
@ -843,10 +813,10 @@ main:
.error:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
jmp $
endp
halt_on_error:
test eax, eax
@ -856,20 +826,118 @@ halt_on_error:
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
jmp $
@@:
ret
proc get_protocol_interface uses rbx, _guid
mov [_guid], rcx
mov [prot_handlers_buffer_size], PROTOCOL_HANDLERS_BUFFER_SIZE
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
fstcall [rbx+EFI_BOOT_SERVICES.LocateHandle], \
EFI_LOCATE_SEARCH_TYPE.ByProtocol, [_guid], 0, \
prot_handlers_buffer_size, prot_handlers_buffer
mov [status], rax
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_protocol_buffer_size
call clearbuf
mov rax, [prot_handlers_buffer_size]
mov rdi, msg
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
mov rax, [status]
test eax, eax
jz @f
call clearbuf
mov rdi, msg
call num2hex
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
jmp $
@@:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_look_for_handler
mov rbx, prot_handlers_buffer
.try_next_handle:
mov rax, rbx
mov rcx, prot_handlers_buffer
sub rax, rcx
cmp rax, [prot_handlers_buffer_size]
jb @f
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error_out_of_handlers
pop rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_error
pop rbx
jmp $
@@:
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_query_handler
pop rbx
mov r10, rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], qword[r10], [_guid], \
prot_interface
pop rbx
;mov rax, 0x8000_0000_0000_0003
test eax, eax
jz @f
call clearbuf
mov rdi, msg
call num2hex
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
add rbx, 8
jmp .try_next_handle
@@:
mov rax, [prot_interface]
ret
endp
find_rsdp:
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_look_for_rsdp
pop rbx
@ -895,16 +963,66 @@ find_rsdp:
.all_tables_done:
ret
proc dump_pci_resources
xor eax, eax
mov rsi, [pcirbiop_resources]
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_dump_pci_resources
pop rbx
.next_resource:
call clearbuf
movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type]
cmp eax, EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG
jz .done
mov rdi, msg
call num2hex
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
call clearbuf
movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType]
mov rdi, msg
call num2dec
mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMinimum]
mov rdi, msg+2*2
call num2hex
mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum]
mov rdi, msg+19*2
call num2hex
mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.TranslationOffset]
mov rdi, msg+36*2
call num2hex
mov rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.AddressLength]
mov rdi, msg+53*2
call num2hex
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
movzx eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length]
add eax, 3
add rsi, rax
jmp .next_resource
.done:
ret
endp
calc_memmap:
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.AllocatePages, EFI_ALLOCATE_ANY_PAGES, \
fstcall [rbx+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \
EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map
call halt_on_error
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
eficall rbx, EFI_BOOT_SERVICES.GetMemoryMap, memory_map_size, \
fstcall [rbx+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \
[memory_map], memory_map_key, descriptor_size, descriptor_ver
call halt_on_error
@ -920,7 +1038,7 @@ calc_memmap:
jb .next_descr
ret
dump_memmap:
proc dump_memmap
xor eax, eax
mov rsi, BOOT_LO.memmap_blocks
mov ebx, [rax+BOOT_LO.memmap_block_cnt]
@ -932,13 +1050,13 @@ dump_memmap:
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, \
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
msg_memmap
pop rbx
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
call clearbuf
.next_mapping:
@ -961,13 +1079,13 @@ dump_memmap:
push rbx
mov rbx, [efi_table]
mov rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
eficall rbx, EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString, rbx, msg
fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
pop rbx
add rsi, sizeof.e820entry
jmp .next_mapping
.done:
ret
endp
; linux/arch/x86/platform/efi/efi.c
; do_add_efi_memmap
@ -1108,9 +1226,10 @@ assert $ < BOOT_LO
kernel_trampoline.size = $ - KERNEL_TRAMPOLINE
section '.rodata' data readable
gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID
sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
gop_guid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
lip_guid db EFI_LOADED_IMAGE_PROTOCOL_GUID
sfsp_guid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
pcirbiop_guid db EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
file_name du '\EFI\KOLIBRIOS\KOLIBRI.INI',0
kernel_name du '\EFI\KOLIBRIOS\KOLIBRI.KRN',0
@ -1157,6 +1276,9 @@ cfg_opt_cmnt_imgfrom db "# Where to load ramdisk image from",0
cfg_opt_cmnt_syspath db "# Path to /sys directory",0
msg_u4k_loaded du "uefi64kos loaded",13,10,0
msg_detect_pci_config du "Detect PCI configuration",13,10,0
msg_dump_pci_resources du "Dump PCI resources",13,10,0
msg_pci_last_bus du "Last PCI bus",13,10,0
msg_read_options du "Read options from config file",13,10,0
msg_file_size du "File size:",13,10,0
msg_parsing_config du "Parsing config file",13,10,0
@ -1164,8 +1286,8 @@ msg_load_kernel du "Load kernel",13,10,0
msg_load_ramdisk du "Load ramdisk",13,10,0
msg_load_devicesdat du "Load DEVICES.DAT",13,10,0
msg_alloc_devicesdat du "Allocate memory for DEVICES.DAT",13,10,0
msg_locate_gop_handlers du "Locate GOP handlers",13,10,0
msg_look_for_gop_handler du "Look for GOP handler",13,10,0
msg_locate_gop_interface du "Locate GOP interface",13,10,0
msg_look_for_handler du "Look for protocol handler",13,10,0
msg_query_handler du "Query handler",13,10,0
msg_query_vmode du "Query vmode",13,10,0
msg_vmode_found du "Video mode found",13,10,0
@ -1175,7 +1297,7 @@ msg_acpi_tables_done du "ACPI tables done",13,10,0
msg_ask_for_params du "Ask for params",13,10,0
msg_set_graphic_mode du "Set graphic mode",13,10,0
msg_success du "Success!",13,10,0
msg_gop_buffer_size du "GOP buffer size",13,10,0
msg_protocol_buffer_size du "Protocol buffer size",13,10,0
msg_opt_resolution du "Option resolution: ",0
msg_memmap du "Memmap",13,10,0
msg_error du "Error!",13,10,0
@ -1188,22 +1310,19 @@ msg_error_open_file du "Error: can't open file ",0
msg_error_exit_boot_services du "Error: Exit boot services",13,10,0
msg du 79 dup " ",13,10,0
section '.data' data readable writeable
efi_handle dq 0
efi_table dq 0
uefi_rsptmp dq 0
;uefi_rsptmp dq 0
fb_base dq 0
gop_buffer_size dq GOP_BUFFER_SIZE
gop_handle dq 0
prot_handlers_buffer_size dq ?
prot_interface dq ?
gop_interface dq 0
gop_info_size dq 0
gop_info dq 0
lip_buffer_size dq LIP_BUFFER_SIZE
lip_handle dq 0
lip_interface dq 0
sfsp_interface dq 0
@ -1212,6 +1331,10 @@ esp_root dq ?
file_handle dq ?
file_buffer_size dq FILE_BUFFER_SIZE-1 ; leave the last byte for \0
pcirbiop_interface dq ?
pcirbiop_resources dq ?
pci_last_bus db 254
cfg_opt_used_resolution db 0
cfg_opt_used_acpi db 0
cfg_opt_used_debug_print db 0
@ -1241,7 +1364,9 @@ efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO
efi_fs_info EFI_FILE_SYSTEM_INFO
memory_map dq ?
gop_buffer rq GOP_BUFFER_SIZE/8
prot_handlers_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
;gop_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
pcirbio_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
devicesdat_data dq 0xffffffff
devicesdat_size dq 0x1000
status dq ?

View File

@ -24,15 +24,15 @@ init_pci_16:
xor ax, ax
mov es, ax
mov byte [es:BOOT_LO.pci_data], 1;default mechanism:1
mov [es:BOOT_LO.pci_data.access_mechanism], 1;default mechanism:1
mov ax, 0xb101
int 0x1a
or ah, ah
jnz pci16skip
mov [es:BOOT_LO.pci_data+1], cl;last PCI bus in system
mov word[es:BOOT_LO.pci_data+2], bx
mov dword[es:BOOT_LO.pci_data+4], edi
mov [es:BOOT_LO.pci_data.last_bus], cl
mov [es:BOOT_LO.pci_data.version], bx
mov [es:BOOT_LO.pci_data.pm_entry], edi
; we have a PCI BIOS, so check which configuration mechanism(s)
; it supports
@ -41,7 +41,8 @@ init_pci_16:
jnz pci16skip
test al, 2
jz pci16skip
mov byte [es:BOOT_LO.pci_data], 2; if (al&3)==2 => mechanism 2
; if (al&3)==2 => mechanism 2
mov [es:BOOT_LO.pci_data.access_mechanism], 2
pci16skip:

View File

@ -101,17 +101,17 @@ pci_api_drv:
pci_fn_0:
; PCI function 0: get pci version (AH.AL)
movzx eax, word [BOOT.pci_data+2]
movzx eax, [BOOT.pci_data.version]
ret
pci_fn_1:
; PCI function 1: get last bus in AL
mov al, [BOOT.pci_data+1]
mov al, [BOOT.pci_data.last_bus]
ret
pci_fn_2:
; PCI function 2: get pci access mechanism
mov al, [BOOT.pci_data]
mov al, [BOOT.pci_data.access_mechanism]
ret
pci_service_not_supported:
@ -156,7 +156,7 @@ align 4
pci_read_reg:
push ebx esi
cmp byte [BOOT.pci_data], 2;what mechanism will we use?
cmp [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
je pci_read_reg_2
; mechanism 1
@ -260,7 +260,7 @@ align 4
pci_write_reg:
push esi ebx
cmp byte [BOOT.pci_data], 2;what mechanism will we use?
cmp [BOOT.pci_data.access_mechanism], 2; what mechanism will we use?
je pci_write_reg_2
; mechanism 1
@ -519,9 +519,9 @@ sys_pcibios:
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [BOOT.pci_data]
mov bx, word[BOOT.pci_data + 2]
mov cl, [BOOT.pci_data + 1]
mov al, [BOOT.pci_data.access_mechanism]
mov bx, word[BOOT.pci_data.version]
mov cl, [BOOT.pci_data.last_bus]
xor ah, ah
jmp .return_abcd
@ -665,7 +665,7 @@ end virtual
.next_func:
inc dword [.devfn]
mov ah, [.bus]
cmp ah, [BOOT.pci_data+1]
cmp ah, [BOOT.pci_data.last_bus]
jbe .loop
.nomemory:
leave

View File

@ -700,6 +700,13 @@ RD_LOAD_FROM_MEMORY = 3
RD_LOAD_FROM_FORMAT = 4
RD_LOAD_FROM_NONE = 5
struct boot_pci_data
access_mechanism db ?
last_bus db ?
version dw ? ; bcd minor, then major
pm_entry dd ? ; physical address of protected-mode entry point
ends
struct boot_data
bpp db ? ; bits per pixel
pitch dw ? ; scanline length
@ -717,7 +724,7 @@ struct boot_data
; LAUNCHER) after kernel is loaded
debug_print db ? ; if nonzero, duplicates debug output to the screen
dma db ? ; DMA write: 1=yes, 2=no
pci_data rb 8
pci_data boot_pci_data
rb 8
shutdown_type db ? ; see sysfn 18.9
rb 15