Subversion Repositories Kolibri OS

Rev

Rev 6242 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
750 victor 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5565 serge 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
750 victor 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593 mikedld 7
 
465 serge 8
$Revision: 6339 $
9
 
593 mikedld 10
 
465 serge 11
MEM_WB     equ 6               ;write-back memory
12
MEM_WC     equ 1               ;write combined memory
13
MEM_UC     equ 0               ;uncached memory
14
 
15
align 4
16
proc mem_test
1103 diamond 17
; if we have BIOS with fn E820, skip the test
3908 Serge 18
        cmp     dword [BOOT_VARS-OS_BASE + 0x9100], 0
2434 Serge 19
        jnz     .ret
465 serge 20
 
2434 Serge 21
        mov     eax, cr0
22
        and     eax, not (CR0_CD+CR0_NW)
23
        or      eax, CR0_CD       ;disable caching
24
        mov     cr0, eax
25
        wbinvd                    ;invalidate cache
465 serge 26
 
2434 Serge 27
        xor     edi, edi
28
        mov     ebx, 'TEST'
465 serge 29
@@:
2434 Serge 30
        add     edi, 0x100000
31
        xchg    ebx, dword [edi]
32
        cmp     dword [edi], 'TEST'
33
        xchg    ebx, dword [edi]
34
        je      @b
465 serge 35
 
2434 Serge 36
        and     eax, not (CR0_CD+CR0_NW) ;enable caching
37
        mov     cr0, eax
3908 Serge 38
        inc     dword [BOOT_VARS-OS_BASE + 0x9100]
2434 Serge 39
        xor     eax, eax
3908 Serge 40
        mov     [BOOT_VARS-OS_BASE + 0x9104], eax
41
        mov     [BOOT_VARS-OS_BASE + 0x9108], eax
42
        mov     [BOOT_VARS-OS_BASE + 0x910C], edi
43
        mov     [BOOT_VARS-OS_BASE + 0x9110], eax
4423 Serge 44
        inc     eax
45
        mov     [BOOT_VARS-OS_BASE + 0x9114], eax
1103 diamond 46
.ret:
2434 Serge 47
        ret
465 serge 48
endp
49
 
50
align 4
51
proc init_mem
1103 diamond 52
; calculate maximum allocatable address and number of allocatable pages
3908 Serge 53
        mov     edi, BOOT_VARS-OS_BASE + 0x9104
2434 Serge 54
        mov     ecx, [edi-4]
55
        xor     esi, esi; esi will hold total amount of memory
56
        xor     edx, edx; edx will hold maximum allocatable address
1103 diamond 57
.calcmax:
58
; round all to pages
2434 Serge 59
        mov     eax, [edi]
2442 Serge 60
        cmp     [edi+16], byte 1
3908 Serge 61
        jne     .unusable
2442 Serge 62
 
2434 Serge 63
        test    eax, 0xFFF
64
        jz      @f
65
        neg     eax
66
        and     eax, 0xFFF
67
        add     [edi], eax
68
        adc     dword [edi+4], 0
69
        sub     [edi+8], eax
70
        sbb     dword [edi+12], 0
71
        jc      .unusable
1103 diamond 72
@@:
2434 Serge 73
        and     dword [edi+8], not 0xFFF
74
        jz      .unusable
1103 diamond 75
; ignore memory after 4 Gb
2434 Serge 76
        cmp     dword [edi+4], 0
77
        jnz     .unusable
78
        mov     eax, [edi]
79
        cmp     dword [edi+12], 0
80
        jnz     .overflow
81
        add     eax, [edi+8]
82
        jnc     @f
1103 diamond 83
.overflow:
2434 Serge 84
        mov     eax, 0xFFFFF000
1103 diamond 85
@@:
2434 Serge 86
        cmp     edx, eax
87
        jae     @f
88
        mov     edx, eax
1103 diamond 89
@@:
2434 Serge 90
        sub     eax, [edi]
91
        mov     [edi+8], eax
92
        add     esi, eax
93
        jmp     .usable
1103 diamond 94
.unusable:
2465 Serge 95
;        and     dword [edi+8], 0
1103 diamond 96
.usable:
2434 Serge 97
        add     edi, 20
98
        loop    .calcmax
1103 diamond 99
.calculated:
2434 Serge 100
        mov     [MEM_AMOUNT-OS_BASE], esi
101
        mov     [pg_data.mem_amount-OS_BASE], esi
102
        shr     esi, 12
103
        mov     [pg_data.pages_count-OS_BASE], esi
465 serge 104
 
2434 Serge 105
        shr     edx, 12
106
        add     edx, 31
107
        and     edx, not 31
108
        shr     edx, 3
109
        mov     [pg_data.pagemap_size-OS_BASE], edx
465 serge 110
 
2434 Serge 111
        add     edx, (sys_pgmap-OS_BASE)+4095
112
        and     edx, not 4095
113
        mov     [tmp_page_tabs], edx
513 serge 114
 
2434 Serge 115
        mov     edx, esi
116
        and     edx, -1024
117
        cmp     edx, (OS_BASE/4096)
118
        jbe     @F
119
        mov     edx, (OS_BASE/4096)
120
        jmp     .set
1130 diamond 121
@@:
2434 Serge 122
        cmp     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
123
        jae     .set
124
        mov     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
1130 diamond 125
.set:
2434 Serge 126
        mov     [pg_data.kernel_pages-OS_BASE], edx
6339 serge 127
        shr     edx, 9
2434 Serge 128
        mov     [pg_data.kernel_tables-OS_BASE], edx
465 serge 129
 
6339 serge 130
        mov     edx, sys_pml2
131
        mov     edi, 0x0070000  ;sys_proc+PROC.pdt_0-OS_BASE
2434 Serge 132
        bt      [cpu_caps-OS_BASE], CAPS_PSE
133
        jnc     .no_PSE
465 serge 134
 
2434 Serge 135
        mov     ebx, cr4
6339 serge 136
        or      ebx, CR4_PSE+CR4_PAE
5565 serge 137
        mov     eax, PDE_LARGE+PG_SWR
2434 Serge 138
        mov     cr4, ebx
139
        dec     [pg_data.kernel_tables-OS_BASE]
465 serge 140
 
2434 Serge 141
        mov     [edx], eax
6339 serge 142
        mov     [edi], eax
143
        add     edx, 8
144
        add     edi, 8
145
        add     eax, 0x200000
146
        mov     [edx], eax
147
        mov     [edi], eax
148
        add     edx, 8
465 serge 149
 
2434 Serge 150
        jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
1455 art_zh 151
.no_PSE:
5565 serge 152
        mov     eax, PG_SWR
2434 Serge 153
        mov     ecx, [tmp_page_tabs]
154
        shr     ecx, 12
1455 art_zh 155
.map_low:
2434 Serge 156
        mov     edi, [tmp_page_tabs]
1455 art_zh 157
@@:                                   ;
2434 Serge 158
        stosd
159
        add     eax, 0x1000
160
        dec     ecx
161
        jnz     @B
1455 art_zh 162
 
163
.map_kernel_heap:
465 serge 164
 
2434 Serge 165
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
166
        mov     eax, [tmp_page_tabs]
5565 serge 167
        or      eax, PG_SWR
2212 Serge 168
 
465 serge 169
.map_kernel_tabs:
6339 serge 170
        mov     [edx], eax
2434 Serge 171
        add     eax, 0x1000
6339 serge 172
        add     edx, 8
2434 Serge 173
        dec     ecx
174
        jnz     .map_kernel_tabs
465 serge 175
 
6339 serge 176
        mov     dword [sys_pml2+8192-20*8], sys_proc+PROC.pdt_0+PG_SWR-OS_BASE
177
        mov     dword [sys_pml2+8192-19*8], sys_proc+PROC.pdt_0+4096+PG_SWR-OS_BASE
178
        mov     dword [sys_pml2+8192-18*8], sys_pml2+PG_SWR
179
        mov     dword [sys_pml2+8192-17*8], sys_pml2+4096+PG_SWR
465 serge 180
 
6339 serge 181
        mov     [sys_pml3-OS_BASE],   0x0070000+PG_READ   ;sys_proc+PROC.pdt_0+PG_UWR-OS_BASE
182
        mov     [sys_pml3+8-OS_BASE], 0x0071000+PG_READ   ;sys_proc+PROC.pdt_0+4096+PG_UWR-OS_BASE
183
        mov     [sys_pml3+16-OS_BASE],0x0072000+PG_READ    ;sys_pml2+PG_SWR
184
        mov     [sys_pml3+24-OS_BASE],0x0073000+PG_READ    ;sys_pml2+4096+PG_SWR
185
 
2434 Serge 186
        ret
465 serge 187
endp
188
 
189
align 4
190
proc init_page_map
1103 diamond 191
; mark all memory as unavailable
2434 Serge 192
        mov     edi, sys_pgmap-OS_BASE
193
        mov     ecx, [pg_data.pagemap_size-OS_BASE]
194
        shr     ecx, 2
195
        xor     eax, eax
196
        cld
197
        rep stosd
465 serge 198
 
1103 diamond 199
; scan through memory map and mark free areas as available
3908 Serge 200
        mov     ebx, BOOT_VARS-OS_BASE + 0x9104
2434 Serge 201
        mov     edx, [ebx-4]
1103 diamond 202
.scanmap:
2465 Serge 203
        cmp     [ebx+16], byte 1
204
        jne     .next
205
 
2434 Serge 206
        mov     ecx, [ebx+8]
207
        shr     ecx, 12; ecx = number of pages
208
        jz      .next
209
        mov     edi, [ebx]
210
        shr     edi, 12; edi = first page
211
        mov     eax, edi
212
        shr     edi, 5
213
        shl     edi, 2
214
        add     edi, sys_pgmap-OS_BASE
215
        and     eax, 31
216
        jz      .startok
217
        add     ecx, eax
218
        sub     ecx, 32
219
        jbe     .onedword
220
        push    ecx
221
        mov     ecx, eax
222
        or      eax, -1
223
        shl     eax, cl
224
        or      [edi], eax
225
        add     edi, 4
226
        pop     ecx
1103 diamond 227
.startok:
2434 Serge 228
        push    ecx
229
        shr     ecx, 5
230
        or      eax, -1
231
        rep stosd
232
        pop     ecx
233
        and     ecx, 31
234
        neg     eax
235
        shl     eax, cl
236
        dec     eax
237
        or      [edi], eax
238
        jmp     .next
1103 diamond 239
.onedword:
2434 Serge 240
        add     ecx, 32
241
        sub     ecx, eax
1103 diamond 242
@@:
2434 Serge 243
        bts     [edi], eax
244
        inc     eax
245
        loop    @b
1103 diamond 246
.next:
2434 Serge 247
        add     ebx, 20
248
        dec     edx
249
        jnz     .scanmap
1103 diamond 250
 
251
; mark kernel memory as allocated (unavailable)
2434 Serge 252
        mov     ecx, [tmp_page_tabs]
253
        mov     edx, [pg_data.pages_count-OS_BASE]
254
        shr     ecx, 12
255
        add     ecx, [pg_data.kernel_tables-OS_BASE]
256
        sub     edx, ecx
257
        mov     [pg_data.pages_free-OS_BASE], edx
465 serge 258
 
2434 Serge 259
        mov     edi, sys_pgmap-OS_BASE
260
        mov     ebx, ecx
261
        shr     ecx, 5
262
        xor     eax, eax
263
        rep stosd
465 serge 264
 
2434 Serge 265
        not     eax
266
        mov     ecx, ebx
267
        and     ecx, 31
268
        shl     eax, cl
269
        and     [edi], eax
270
        add     edi, OS_BASE
271
        mov     [page_start-OS_BASE], edi;
465 serge 272
 
2434 Serge 273
        mov     ebx, sys_pgmap
274
        add     ebx, [pg_data.pagemap_size-OS_BASE]
275
        mov     [page_end-OS_BASE], ebx
465 serge 276
 
2434 Serge 277
        ret
465 serge 278
endp
279
 
280
align 4
586 serge 281
 
282
init_BIOS32:
2434 Serge 283
        mov     edi, 0xE0000
586 serge 284
.pcibios_nxt:
2434 Serge 285
        cmp     dword[edi], '_32_'; "magic" word
286
        je      .BIOS32_found
586 serge 287
.pcibios_nxt2:
2434 Serge 288
        add     edi, 0x10
289
        cmp     edi, 0xFFFF0
290
        je      .BIOS32_not_found
291
        jmp     .pcibios_nxt
292
.BIOS32_found:                  ; magic word found, check control summ
586 serge 293
 
2434 Serge 294
        movzx   ecx, byte[edi + 9]
295
        shl     ecx, 4
296
        mov     esi, edi
297
        xor     eax, eax
298
        cld      ; paranoia
299
@@:
300
        lodsb
301
        add     ah, al
302
        loop    @b
303
        jnz     .pcibios_nxt2; control summ must be zero
586 serge 304
    ; BIOS32 service found !
2434 Serge 305
        mov     ebp, [edi + 4]
306
        mov     [bios32_entry], ebp
586 serge 307
    ; check PCI BIOS present
2434 Serge 308
        mov     eax, '$PCI'
309
        xor     ebx, ebx
310
        push    cs  ; special for 'ret far' from  BIOS
311
        call    ebp
312
        test    al, al
313
        jnz     .PCI_BIOS32_not_found
586 serge 314
 
3555 Serge 315
 ; здесь создаются дискрипторы для PCI BIOS
586 serge 316
 
2434 Serge 317
        add     ebx, OS_BASE
318
        dec     ecx
319
        mov     [(pci_code_32-OS_BASE)], cx   ;limit 0-15
320
        mov     [(pci_data_32-OS_BASE)], cx   ;limit 0-15
586 serge 321
 
2434 Serge 322
        mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
323
        mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
586 serge 324
 
2434 Serge 325
        shr     ebx, 16
326
        mov     [(pci_code_32-OS_BASE)+4], bl ;base  16-23
327
        mov     [(pci_data_32-OS_BASE)+4], bl ;base  16-23
586 serge 328
 
2434 Serge 329
        shr     ecx, 16
330
        and     cl, 0x0F
331
        mov     ch, bh
332
        add     cx, D32
333
        mov     [(pci_code_32-OS_BASE)+6], cx ;lim   16-19 &
334
        mov     [(pci_data_32-OS_BASE)+6], cx ;base  24-31
586 serge 335
 
2434 Serge 336
        mov     [(pci_bios_entry-OS_BASE)], edx
586 serge 337
         ; jmp .end
338
.PCI_BIOS32_not_found:
3555 Serge 339
        ; здесь должна заполнятся pci_emu_dat
586 serge 340
.BIOS32_not_found:
341
.end:
2434 Serge 342
        ret
586 serge 343
 
344
align 4
465 serge 345
proc test_cpu
346
           locals
347
              cpu_type   dd ?
348
           endl
349
 
2434 Serge 350
        xor     eax, eax
351
        mov     [cpu_type], eax
352
        mov     [cpu_caps-OS_BASE], eax
353
        mov     [cpu_caps+4-OS_BASE], eax
5201 serge 354
        mov     [cpu_phys_addr_width-OS_BASE], 32
465 serge 355
 
2434 Serge 356
        pushfd
357
        pop     eax
358
        mov     ecx, eax
359
        xor     eax, 0x40000
360
        push    eax
361
        popfd
362
        pushfd
363
        pop     eax
364
        xor     eax, ecx
365
        mov     [cpu_type], CPU_386
366
        jz      .end_cpuid
367
        push    ecx
368
        popfd
465 serge 369
 
2434 Serge 370
        mov     [cpu_type], CPU_486
371
        mov     eax, ecx
372
        xor     eax, 0x200000
373
        push    eax
374
        popfd
375
        pushfd
376
        pop     eax
377
        xor     eax, ecx
378
        je      .end_cpuid
465 serge 379
 
2434 Serge 380
        xor     eax, eax
381
        cpuid
465 serge 382
 
2434 Serge 383
        mov     [cpu_vendor-OS_BASE], ebx
384
        mov     [cpu_vendor+4-OS_BASE], edx
385
        mov     [cpu_vendor+8-OS_BASE], ecx
5201 serge 386
 
2434 Serge 387
        cmp     eax, 1
388
        jl      .end_cpuid
389
        mov     eax, 1
390
        cpuid
391
        mov     [cpu_sign-OS_BASE], eax
392
        mov     [cpu_info-OS_BASE], ebx
393
        mov     [cpu_caps-OS_BASE], edx
394
        mov     [cpu_caps+4-OS_BASE], ecx
465 serge 395
 
5201 serge 396
        bt      edx, CAPS_PAE
397
        jnc     @f
398
        mov     [cpu_phys_addr_width-OS_BASE], 36
399
@@:
400
        mov     eax, 0x80000000
401
        cpuid
402
        cmp     eax, 0x80000008
403
        jb      @f
404
        mov     eax, 0x80000008
405
        cpuid
406
        mov     [cpu_phys_addr_width-OS_BASE], al
407
@@:
408
 
409
        mov     eax, [cpu_sign-OS_BASE]
2434 Serge 410
        shr     eax, 8
411
        and     eax, 0x0f
412
        ret
465 serge 413
.end_cpuid:
2434 Serge 414
        mov     eax, [cpu_type]
415
        ret
465 serge 416
endp
417
 
2439 Serge 418
iglobal
419
align 4
420
acpi_lapic_base   dd 0xfee00000   ; default local apic base
421
endg
422
 
2212 Serge 423
uglobal
424
align 4
425
acpi_rsdp         rd 1
426
acpi_rsdt         rd 1
427
acpi_madt         rd 1
1455 art_zh 428
 
2219 Serge 429
acpi_dev_data     rd 1
430
acpi_dev_size     rd 1
431
 
2212 Serge 432
acpi_rsdt_base    rd 1
3725 Serge 433
acpi_fadt_base    rd 1
434
acpi_dsdt_base    rd 1
435
acpi_dsdt_size    rd 1
2212 Serge 436
acpi_madt_base    rd 1
437
acpi_ioapic_base  rd 1
5629 serge 438
acpi_hpet_base    rd 1
439
hpet_base         rd 1
440
hpet_period       rd 1
5645 serge 441
hpet_timers       rd 1
5984 serge 442
hpet_tsc_start    rd 2
2439 Serge 443
cpu_count         rd 1
444
smpt              rd 16
2212 Serge 445
endg
446
 
447
ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
448
ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
449
ACPI_RSDP_CHECKSUM_LENGTH  equ 20
5629 serge 450
 
451
ACPI_HPET_SIGN             equ 0x54455048
2212 Serge 452
ACPI_MADT_SIGN             equ 0x43495041
3725 Serge 453
ACPI_FADT_SIGN             equ 0x50434146
2212 Serge 454
 
455
 
456
acpi_locate:
2434 Serge 457
        push    ebx
6240 serge 458
        push    edi
459
 
460
        movzx   ebx, word [0x40E]
461
        shl     ebx, 4
462
        lea     ecx, [ebx+1024]
463
        call    .check
464
 
465
        test    ebx, ebx
6242 serge 466
        jz      @F
467
        jmp     .done
6240 serge 468
 
6242 serge 469
@@:
2434 Serge 470
        mov     ebx, ACPI_HI_RSDP_WINDOW_START
6240 serge 471
        mov     edi, ACPI_HI_RSDP_WINDOW_END
472
        call    .check
473
.done:
474
        mov     eax, ebx
475
        pop     edi
476
        pop     ebx
477
        ret
478
 
2212 Serge 479
.check:
2434 Serge 480
        cmp     [ebx], dword 0x20445352
481
        jne     .next
482
        cmp     [ebx+4], dword 0x20525450
483
        jne     .next
2212 Serge 484
 
2434 Serge 485
        mov     edx, ebx
486
        mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
487
        xor     eax, eax
2212 Serge 488
.sum:
2434 Serge 489
        add     al, [edx]
490
        inc     edx
491
        loop    .sum
2212 Serge 492
 
2434 Serge 493
        test    al, al
494
        jnz     .next
2212 Serge 495
        ret
496
.next:
2434 Serge 497
        add     ebx, 16
6240 serge 498
        cmp     ebx, edi
2434 Serge 499
        jb      .check
6240 serge 500
        xor     ebx, ebx
2212 Serge 501
        ret
502
 
503
align 4
504
rsdt_find:           ;ecx= rsdt edx= SIG
2434 Serge 505
        push    ebx
506
        push    esi
2212 Serge 507
 
2434 Serge 508
        lea     ebx, [ecx+36]
509
        mov     esi, [ecx+4]
510
        add     esi, ecx
2439 Serge 511
align 4
2212 Serge 512
.next:
2434 Serge 513
        mov     eax, [ebx]
514
        cmp     [eax], edx
515
        je      .done
2212 Serge 516
 
2434 Serge 517
        add     ebx, 4
518
        cmp     ebx, esi
519
        jb      .next
2212 Serge 520
 
2434 Serge 521
        xor     eax, eax
522
        pop     esi
523
        pop     ebx
2212 Serge 524
        ret
525
 
526
.done:
2434 Serge 527
        mov     eax, [ebx]
528
        pop     esi
529
        pop     ebx
2212 Serge 530
        ret
531
 
2439 Serge 532
align 4
2212 Serge 533
check_acpi:
534
 
2434 Serge 535
        call    acpi_locate
536
        test    eax, eax
537
        jz      .done
2212 Serge 538
 
2434 Serge 539
        mov     ecx, [eax+16]
5629 serge 540
        mov     edx, ACPI_FADT_SIGN
2434 Serge 541
        mov     [acpi_rsdt_base-OS_BASE], ecx
542
        call    rsdt_find
3725 Serge 543
        mov     [acpi_fadt_base-OS_BASE], eax
2434 Serge 544
        test    eax, eax
3725 Serge 545
        jz      @f
546
 
547
        mov     eax, [eax+40]
548
        mov     [acpi_dsdt_base-OS_BASE], eax
549
        mov     eax, [eax+4]
550
        mov     [acpi_dsdt_size-OS_BASE], eax
5629 serge 551
@@:
552
        mov     edx, ACPI_HPET_SIGN
553
        mov     ecx, [acpi_rsdt_base-OS_BASE]
554
        call    rsdt_find
555
        test    eax, eax
556
        jz      @F
3725 Serge 557
 
5629 serge 558
        mov     [acpi_hpet_base-OS_BASE], eax
559
        mov     eax, [eax+44]
560
        mov     [hpet_base-OS_BASE], eax
3725 Serge 561
@@:
562
        mov     edx, ACPI_MADT_SIGN
563
        mov     ecx, [acpi_rsdt_base-OS_BASE]
564
        call    rsdt_find
565
        test    eax, eax
2434 Serge 566
        jz      .done
2212 Serge 567
 
2434 Serge 568
        mov     [acpi_madt_base-OS_BASE], eax
569
        mov     ecx, [eax+36]
570
        mov     [acpi_lapic_base-OS_BASE], ecx
2212 Serge 571
 
2439 Serge 572
        mov     edi, smpt-OS_BASE
573
        mov     ebx, [ecx+0x20]
574
        shr     ebx, 24              ; read APIC ID
575
 
576
        mov     [edi], ebx           ; bootstrap always first
2441 Serge 577
        inc     [cpu_count-OS_BASE]
2439 Serge 578
        add     edi, 4
579
 
2434 Serge 580
        lea     edx, [eax+44]
581
        mov     ecx, [eax+4]
582
        add     ecx, eax
2212 Serge 583
.check:
2434 Serge 584
        mov     eax, [edx]
2439 Serge 585
        cmp     al, 0
586
        jne     .io_apic
2212 Serge 587
 
2439 Serge 588
        shr     eax, 24              ; get APIC ID
589
        cmp     eax, ebx             ; skip self
590
        je      .next
591
 
592
        test    [edx+4], byte 1      ; is enabled ?
593
        jz      .next
594
 
595
        cmp     [cpu_count-OS_BASE], 16
596
        jae     .next
597
 
598
        stosd                        ; store APIC ID
599
        inc     [cpu_count-OS_BASE]
2212 Serge 600
.next:
2439 Serge 601
        mov     eax, [edx]
2434 Serge 602
        movzx   eax, ah
603
        add     edx, eax
604
        cmp     edx, ecx
605
        jb      .check
2212 Serge 606
.done:
607
        ret
2439 Serge 608
 
609
.io_apic:
610
        cmp     al, 1
611
        jne     .next
612
 
2434 Serge 613
        mov     eax, [edx+4]
614
        mov     [acpi_ioapic_base-OS_BASE], eax
2439 Serge 615
        jmp     .next
5629 serge 616
 
5984 serge 617
HPET_PERIOD             equ 0x0004
618
HPET_CFG_ENABLE         equ 0x0001
619
HPET_CFG                equ 0x0010
620
HPET_COUNTER            equ 0x00f0
621
HPET_T0_CFG             equ 0x0100
5629 serge 622
 
5984 serge 623
HPET_TN_LEVEL           equ 0x0002
624
HPET_TN_ENABLE          equ 0x0004
625
HPET_TN_FSB             equ 0x4000
626
 
5629 serge 627
align 4
628
init_hpet:
629
        mov     ebx, [hpet_base-OS_BASE]
5645 serge 630
        test    ebx, ebx
5984 serge 631
        jz      .done
5629 serge 632
 
5645 serge 633
        mov     eax, [ebx]
634
        and     ah, 0x1F
635
        inc     ah
636
        movzx   eax, ah
637
        mov     [hpet_timers-OS_BASE], eax
5984 serge 638
        mov     ecx, eax
5645 serge 639
 
5629 serge 640
        mov     eax, [ebx+HPET_PERIOD]
5984 serge 641
        xor     edx, edx
642
        shld    edx, eax, 10
643
        shl     eax, 10
644
        mov     esi, 1000000
645
        div     esi
646
        mov     [hpet_period-OS_BASE], eax
5629 serge 647
 
5984 serge 648
        mov     esi, [ebx+HPET_CFG]
649
        and     esi, not HPET_CFG_ENABLE
650
        mov     [ebx+HPET_CFG], esi             ;stop main counter
5629 serge 651
 
5984 serge 652
        lea     edx, [ebx+HPET_T0_CFG]
653
@@:
654
        jcxz    @F
655
        mov     eax, [edx]
656
        and     eax, not (HPET_TN_ENABLE+HPET_TN_LEVEL+HPET_TN_FSB)
657
        mov     [edx], eax
658
        add     edx, 0x20
659
        dec     ecx
660
        jmp     @B
661
@@:
662
        mov     [ebx+HPET_COUNTER], ecx         ;reset main counter
663
        mov     [ebx+HPET_COUNTER+4], ecx
5629 serge 664
 
5984 serge 665
        or      esi, HPET_CFG_ENABLE
666
        mov     [ebx+HPET_CFG], esi             ;and start again
667
 
668
.done:
669
        rdtsc
670
        mov     [hpet_tsc_start-OS_BASE], eax
671
        mov     [hpet_tsc_start+4-OS_BASE], edx
672
 
5629 serge 673
        ret
674