Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8110 → Rev 8111

/kernel/trunk/init.inc
410,43 → 410,66
ret
endp
 
iglobal
align 4
acpi_lapic_base dd 0xfee00000 ; default local apic base
endg
 
uglobal
align 4
acpi_rsdp rd 1
acpi_rsdt rd 1
acpi_madt rd 1
 
acpi_dev_data rd 1
acpi_dev_size rd 1
 
acpi_rsdt_base rd 1
acpi_fadt_base rd 1
acpi_dsdt_base rd 1
acpi_dsdt_size rd 1
acpi_madt_base rd 1
acpi_ioapic_base rd MAX_IOAPICS
acpi_hpet_base rd 1
hpet_base rd 1
hpet_period rd 1
hpet_timers rd 1
hpet_tsc_start rd 2
cpu_count rd 1
smpt rd 16
endg
 
ACPI_HI_RSDP_WINDOW_START = 0x000E0000
ACPI_HI_RSDP_WINDOW_END = 0x00100000
ACPI_RSDP_CHECKSUM_LENGTH = 20
 
ACPI_HPET_SIGN = 'HPET'
ACPI_MADT_SIGN = 'APIC'
ACPI_FADT_SIGN = 'FACP'
proc acpi_locate_tables uses ebx esi edi
mov ebx, [ebx+ACPI_RSDP.RsdtAddress]
mov [acpi_rsdt_base-OS_BASE], ebx
mov eax, [ebx+ACPI_RSDT.Length]
mov [acpi_rsdt_size-OS_BASE], eax
 
mov esi, [acpi_rsdt_base-OS_BASE]
mov ecx, [esi+ACPI_RSDT.Length]
lea edi, [esi+ecx]
add esi, sizeof.ACPI_TABLE
movi ecx, 1
.next_table:
cmp esi, edi
jae .done
lodsd
cmp [eax+ACPI_TABLE.Signature], 'SSDT' ; skip DSDT if present
jz .ssdt ; read it from FADT
cmp [eax+ACPI_TABLE.Signature], 'FACP' ; this is FADT
jz .fadt
cmp [eax+ACPI_TABLE.Signature], 'APIC' ; this is MADT
jz .madt
cmp [eax+ACPI_TABLE.Signature], 'HPET'
jz .hpet
jmp .next_table
.ssdt:
mov [acpi_ssdt_base+ecx*4-OS_BASE], eax
mov eax, [eax+ACPI_TABLE.Length]
mov [acpi_ssdt_size+ecx*4-OS_BASE], eax
inc ecx
jmp .next_table
.fadt:
mov [acpi_fadt_base-OS_BASE], eax
cmp [eax+ACPI_FADT.DSDT], 0
jz @f
mov edx, [eax+ACPI_FADT.DSDT]
mov [acpi_ssdt_base-OS_BASE], edx
mov edx, [edx+ACPI_TABLE.Length]
mov [acpi_ssdt_size-OS_BASE], edx
@@:
mov eax, [eax+ACPI_TABLE.Length]
mov [acpi_fadt_size-OS_BASE], eax
jmp .next_table
.madt:
mov [acpi_madt_base-OS_BASE], eax
mov eax, [eax+ACPI_TABLE.Length]
mov [acpi_madt_size-OS_BASE], eax
jmp .next_table
.hpet:
mov [acpi_hpet_base-OS_BASE], eax
mov eax, [eax+ACPI_TABLE.Length]
mov [acpi_hpet_size-OS_BASE], eax
jmp .next_table
.done:
mov [acpi_ssdt_cnt-OS_BASE], ecx
ret
endp
 
acpi_locate:
push ebx
474,7 → 497,11
call .check
end if
.done:
mov eax, ebx
mov [acpi_rsdp_base-OS_BASE], ebx
test ebx, ebx
jz @f
call acpi_locate_tables
@@:
pop edi
pop ebx
ret
502,185 → 529,3
jb .check
xor ebx, ebx
ret
 
align 4
rsdt_find: ;ecx= rsdt edx= SIG
push ebx
push esi
 
lea ebx, [ecx+36]
mov esi, [ecx+4]
add esi, ecx
align 4
.next:
mov eax, [ebx]
cmp [eax], edx
je .done
 
add ebx, 4
cmp ebx, esi
jb .next
 
xor eax, eax
pop esi
pop ebx
ret
 
.done:
mov eax, [ebx]
pop esi
pop ebx
ret
 
align 4
check_acpi:
 
call acpi_locate
test eax, eax
jz .done
 
mov [acpi_rsdp-OS_BASE], eax
mov ecx, [eax+16]
mov edx, ACPI_FADT_SIGN
mov [acpi_rsdt_base-OS_BASE], ecx
call rsdt_find
mov [acpi_fadt_base-OS_BASE], eax
test eax, eax
jz @f
 
mov eax, [eax+40]
mov [acpi_dsdt_base-OS_BASE], eax
mov eax, [eax+4]
mov [acpi_dsdt_size-OS_BASE], eax
@@:
mov edx, ACPI_HPET_SIGN
mov ecx, [acpi_rsdt_base-OS_BASE]
call rsdt_find
test eax, eax
jz @F
 
mov [acpi_hpet_base-OS_BASE], eax
mov eax, [eax+44]
mov [hpet_base-OS_BASE], eax
@@:
mov edx, ACPI_MADT_SIGN
mov ecx, [acpi_rsdt_base-OS_BASE]
call rsdt_find
test eax, eax
jz .done
 
mov [acpi_madt_base-OS_BASE], eax
mov ecx, [eax+36]
mov [acpi_lapic_base-OS_BASE], ecx
 
mov edi, smpt-OS_BASE
mov ebx, [ecx+0x20]
shr ebx, 24 ; read APIC ID
 
mov [edi], ebx ; bootstrap always first
inc [cpu_count-OS_BASE]
add edi, 4
 
mov [ioapic_cnt-OS_BASE], 0
lea edx, [eax+44]
mov ecx, [eax+4]
add ecx, eax
.check:
mov eax, [edx]
cmp al, 0
je .lapic
cmp al, 1
je .io_apic
jmp .next
.lapic:
shr eax, 24 ; get APIC ID
cmp eax, ebx ; skip self
je .next
 
test [edx+4], byte 1 ; is enabled ?
jz .next
 
cmp [cpu_count-OS_BASE], 16
jae .next
 
stosd ; store APIC ID
inc [cpu_count-OS_BASE]
.next:
mov eax, [edx]
movzx eax, ah
add edx, eax
cmp edx, ecx
jb .check
.done:
ret
 
.io_apic:
mov eax, [ioapic_cnt-OS_BASE]
push dword[edx+4]
pop [acpi_ioapic_base-OS_BASE+eax*4]
push dword[edx+8]
pop [ioapic_gsi_base-OS_BASE+eax*4]
inc [ioapic_cnt-OS_BASE]
jmp .next
 
HPET_PERIOD = 0x0004
HPET_CFG_ENABLE = 0x0001
HPET_CFG = 0x0010
HPET_COUNTER = 0x00f0
HPET_T0_CFG = 0x0100
 
HPET_TN_LEVEL = 0x0002
HPET_TN_ENABLE = 0x0004
HPET_TN_FSB = 0x4000
 
align 4
init_hpet:
mov ebx, [hpet_base-OS_BASE]
test ebx, ebx
jz .done
 
mov eax, [ebx]
and ah, 0x1F
inc ah
movzx eax, ah
mov [hpet_timers-OS_BASE], eax
mov ecx, eax
 
mov eax, [ebx+HPET_PERIOD]
xor edx, edx
shld edx, eax, 10
shl eax, 10
mov esi, 1000000
div esi
mov [hpet_period-OS_BASE], eax
 
mov esi, [ebx+HPET_CFG]
and esi, not HPET_CFG_ENABLE
mov [ebx+HPET_CFG], esi ;stop main counter
 
lea edx, [ebx+HPET_T0_CFG]
@@:
jcxz @F
mov eax, [edx]
and eax, not (HPET_TN_ENABLE+HPET_TN_LEVEL+HPET_TN_FSB)
mov [edx], eax
add edx, 0x20
dec ecx
jmp @B
@@:
mov [ebx+HPET_COUNTER], ecx ;reset main counter
mov [ebx+HPET_COUNTER+4], ecx
 
or esi, HPET_CFG_ENABLE
mov [ebx+HPET_CFG], esi ;and start again
 
.done:
rdtsc
mov [hpet_tsc_start-OS_BASE], eax
mov [hpet_tsc_start+4-OS_BASE], edx
 
ret