Subversion Repositories Kolibri OS

Rev

Rev 4429 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4429 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 4390 $
9
 
10
 
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
17
; if we have BIOS with fn E820, skip the test
18
        cmp     dword [BOOT_VARS-OS_BASE + 0x9100], 0
19
        jnz     .ret
20
 
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
26
 
27
        xor     edi, edi
28
        mov     ebx, 'TEST'
29
@@:
30
        add     edi, 0x100000
31
        xchg    ebx, dword [edi]
32
        cmp     dword [edi], 'TEST'
33
        xchg    ebx, dword [edi]
34
        je      @b
35
 
36
        and     eax, not (CR0_CD+CR0_NW) ;enable caching
37
        mov     cr0, eax
38
        inc     dword [BOOT_VARS-OS_BASE + 0x9100]
39
        xor     eax, eax
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
44
        inc     eax
45
        mov     [BOOT_VARS-OS_BASE + 0x9114], eax
46
.ret:
47
        ret
48
endp
49
 
50
align 4
51
proc init_mem
52
; calculate maximum allocatable address and number of allocatable pages
53
        mov     edi, BOOT_VARS-OS_BASE + 0x9104
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
57
.calcmax:
58
; round all to pages
59
        mov     eax, [edi]
60
        cmp     [edi+16], byte 1
61
        jne     .unusable
62
 
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
72
@@:
73
        and     dword [edi+8], not 0xFFF
74
        jz      .unusable
75
; ignore memory after 4 Gb
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
83
.overflow:
84
        mov     eax, 0xFFFFF000
85
@@:
86
        cmp     edx, eax
87
        jae     @f
88
        mov     edx, eax
89
@@:
90
        sub     eax, [edi]
91
        mov     [edi+8], eax
92
        add     esi, eax
93
        jmp     .usable
94
.unusable:
95
;        and     dword [edi+8], 0
96
.usable:
97
        add     edi, 20
98
        loop    .calcmax
99
.calculated:
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
104
 
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
110
 
111
        add     edx, (sys_pgmap-OS_BASE)+4095
112
        and     edx, not 4095
113
        mov     [tmp_page_tabs], edx
114
 
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
121
@@:
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
125
.set:
126
        mov     [pg_data.kernel_pages-OS_BASE], edx
127
        shr     edx, 10
128
        mov     [pg_data.kernel_tables-OS_BASE], edx
129
 
130
        xor     eax, eax
131
        mov     edi, sys_proc-OS_BASE
132
        mov     ecx, 8192/4
133
        cld
134
        rep stosd
135
 
136
        mov     edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 0x800; (OS_BASE shr 20)
137
        bt      [cpu_caps-OS_BASE], CAPS_PSE
138
        jnc     .no_PSE
139
 
140
        mov     ebx, cr4
141
        or      ebx, CR4_PSE
142
        mov     eax, PG_LARGE+PG_SW
143
        mov     cr4, ebx
144
        dec     [pg_data.kernel_tables-OS_BASE]
145
 
146
        mov     [edx], eax
147
        add     edx, 4
148
 
149
        mov     edi, [tmp_page_tabs]
150
        jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
151
.no_PSE:
152
        mov     eax, PG_SW
153
        mov     ecx, [tmp_page_tabs]
154
        shr     ecx, 12
155
.map_low:
156
        mov     edi, [tmp_page_tabs]
157
@@:                                   ;
158
        stosd
159
        add     eax, 0x1000
160
        dec     ecx
161
        jnz     @B
162
 
163
.map_kernel_heap:
164
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
165
        shl     ecx, 10
166
        xor     eax, eax
167
        rep stosd
168
 
169
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
170
        mov     eax, [tmp_page_tabs]
171
        or      eax, PG_SW
172
        mov     edi, edx
173
 
174
.map_kernel_tabs:
175
        stosd
176
        add     eax, 0x1000
177
        dec     ecx
178
        jnz     .map_kernel_tabs
179
 
180
        mov     dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SW-OS_BASE
181
 
182
        mov     edi, (sys_proc+PROC.pdt_0-OS_BASE)
183
        lea     esi, [edi+(OS_BASE shr 20)]
184
        movsd
185
        movsd
186
        ret
187
endp
188
 
189
align 4
190
proc init_page_map
191
; mark all memory as unavailable
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
198
 
199
; scan through memory map and mark free areas as available
200
        mov     ebx, BOOT_VARS-OS_BASE + 0x9104
201
        mov     edx, [ebx-4]
202
.scanmap:
203
        cmp     [ebx+16], byte 1
204
        jne     .next
205
 
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
227
.startok:
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
239
.onedword:
240
        add     ecx, 32
241
        sub     ecx, eax
242
@@:
243
        bts     [edi], eax
244
        inc     eax
245
        loop    @b
246
.next:
247
        add     ebx, 20
248
        dec     edx
249
        jnz     .scanmap
250
 
251
; mark kernel memory as allocated (unavailable)
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
258
 
259
        mov     edi, sys_pgmap-OS_BASE
260
        mov     ebx, ecx
261
        shr     ecx, 5
262
        xor     eax, eax
263
        rep stosd
264
 
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;
272
 
273
        mov     ebx, sys_pgmap
274
        add     ebx, [pg_data.pagemap_size-OS_BASE]
275
        mov     [page_end-OS_BASE], ebx
276
 
277
        ret
278
endp
279
 
280
align 4
281
 
282
init_BIOS32:
283
        mov     edi, 0xE0000
284
.pcibios_nxt:
285
        cmp     dword[edi], '_32_'; "magic" word
286
        je      .BIOS32_found
287
.pcibios_nxt2:
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
293
 
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
304
    ; BIOS32 service found !
305
        mov     ebp, [edi + 4]
306
        mov     [bios32_entry], ebp
307
    ; check PCI BIOS present
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
314
 
315
 ; здесь создаются дискрипторы для PCI BIOS
316
 
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
321
 
322
        mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
323
        mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
324
 
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
328
 
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
335
 
336
        mov     [(pci_bios_entry-OS_BASE)], edx
337
         ; jmp .end
338
.PCI_BIOS32_not_found:
339
        ; здесь должна заполнятся pci_emu_dat
340
.BIOS32_not_found:
341
.end:
342
        ret
343
 
344
align 4
345
proc test_cpu
346
           locals
347
              cpu_type   dd ?
348
              cpu_id     dd ?
349
              cpu_Intel  dd ?
350
              cpu_AMD    dd ?
351
           endl
352
 
353
        xor     eax, eax
354
        mov     [cpu_type], eax
355
        mov     [cpu_caps-OS_BASE], eax
356
        mov     [cpu_caps+4-OS_BASE], eax
4923 Serge 357
        mov     [cpu_phys_addr_width-OS_BASE], 32
4429 Serge 358
 
359
        pushfd
360
        pop     eax
361
        mov     ecx, eax
362
        xor     eax, 0x40000
363
        push    eax
364
        popfd
365
        pushfd
366
        pop     eax
367
        xor     eax, ecx
368
        mov     [cpu_type], CPU_386
369
        jz      .end_cpuid
370
        push    ecx
371
        popfd
372
 
373
        mov     [cpu_type], CPU_486
374
        mov     eax, ecx
375
        xor     eax, 0x200000
376
        push    eax
377
        popfd
378
        pushfd
379
        pop     eax
380
        xor     eax, ecx
381
        je      .end_cpuid
382
 
383
        xor     eax, eax
384
        cpuid
385
 
386
        mov     [cpu_vendor-OS_BASE], ebx
387
        mov     [cpu_vendor+4-OS_BASE], edx
388
        mov     [cpu_vendor+8-OS_BASE], ecx
389
        cmp     ebx, dword [intel_str-OS_BASE]
390
        jne     .check_AMD
391
        cmp     edx, dword [intel_str+4-OS_BASE]
392
        jne     .check_AMD
393
        cmp     ecx, dword [intel_str+8-OS_BASE]
394
        jne     .check_AMD
395
        mov     [cpu_Intel], 1
396
        cmp     eax, 1
397
        jl      .end_cpuid
398
        mov     eax, 1
399
        cpuid
400
        mov     [cpu_sign-OS_BASE], eax
401
        mov     [cpu_info-OS_BASE], ebx
402
        mov     [cpu_caps-OS_BASE], edx
403
        mov     [cpu_caps+4-OS_BASE], ecx
404
 
4923 Serge 405
        bt      edx, CAPS_PAE
406
        jnc     @f
407
        mov     [cpu_phys_addr_width-OS_BASE], 36
408
@@:
409
        mov     eax, 0x80000000
410
        cpuid
411
        cmp     eax, 0x80000008
412
        jb      @f
413
        mov     eax, 0x80000008
414
        cpuid
415
        mov     [cpu_phys_addr_width-OS_BASE], al
416
@@:
417
 
418
        mov     eax, [cpu_sign-OS_BASE]
4429 Serge 419
        shr     eax, 8
420
        and     eax, 0x0f
421
        ret
422
.end_cpuid:
423
        mov     eax, [cpu_type]
424
        ret
425
 
426
.check_AMD:
427
        cmp     ebx, dword [AMD_str-OS_BASE]
428
        jne     .unknown
429
        cmp     edx, dword [AMD_str+4-OS_BASE]
430
        jne     .unknown
431
        cmp     ecx, dword [AMD_str+8-OS_BASE]
432
        jne     .unknown
433
        mov     [cpu_AMD], 1
434
        cmp     eax, 1
435
        jl      .unknown
436
        mov     eax, 1
437
        cpuid
438
        mov     [cpu_sign-OS_BASE], eax
439
        mov     [cpu_info-OS_BASE], ebx
440
        mov     [cpu_caps-OS_BASE], edx
441
        mov     [cpu_caps+4-OS_BASE], ecx
442
        shr     eax, 8
443
        and     eax, 0x0f
444
        ret
445
.unknown:
446
        mov     eax, 1
447
        cpuid
448
        mov     [cpu_sign-OS_BASE], eax
449
        mov     [cpu_info-OS_BASE], ebx
450
        mov     [cpu_caps-OS_BASE], edx
451
        mov     [cpu_caps+4-OS_BASE], ecx
452
        shr     eax, 8
453
        and     eax, 0x0f
454
        ret
455
endp
456
 
457
iglobal
458
align 4
459
acpi_lapic_base   dd 0xfee00000   ; default local apic base
460
endg
461
 
462
uglobal
463
align 4
464
acpi_rsdp         rd 1
465
acpi_rsdt         rd 1
466
acpi_madt         rd 1
467
 
468
acpi_dev_data     rd 1
469
acpi_dev_size     rd 1
470
 
471
acpi_rsdt_base    rd 1
472
acpi_fadt_base    rd 1
473
acpi_dsdt_base    rd 1
474
acpi_dsdt_size    rd 1
475
acpi_madt_base    rd 1
476
acpi_ioapic_base  rd 1
477
 
478
cpu_count         rd 1
479
smpt              rd 16
480
endg
481
 
482
ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
483
ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
484
ACPI_RSDP_CHECKSUM_LENGTH  equ 20
485
ACPI_MADT_SIGN             equ 0x43495041
486
ACPI_FADT_SIGN             equ 0x50434146
487
 
488
 
489
acpi_locate:
490
        push    ebx
491
        mov     ebx, ACPI_HI_RSDP_WINDOW_START
492
.check:
493
        cmp     [ebx], dword 0x20445352
494
        jne     .next
495
        cmp     [ebx+4], dword 0x20525450
496
        jne     .next
497
 
498
        mov     edx, ebx
499
        mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
500
        xor     eax, eax
501
.sum:
502
        add     al, [edx]
503
        inc     edx
504
        loop    .sum
505
 
506
        test    al, al
507
        jnz     .next
508
 
509
        mov     eax, ebx
510
        pop     ebx
511
        ret
512
.next:
513
        add     ebx, 16
514
        cmp     ebx, ACPI_HI_RSDP_WINDOW_END
515
        jb      .check
516
 
517
        pop     ebx
518
        xor     eax, eax
519
        ret
520
 
521
align 4
522
rsdt_find:           ;ecx= rsdt edx= SIG
523
        push    ebx
524
        push    esi
525
 
526
        lea     ebx, [ecx+36]
527
        mov     esi, [ecx+4]
528
        add     esi, ecx
529
align 4
530
.next:
531
        mov     eax, [ebx]
532
        cmp     [eax], edx
533
        je      .done
534
 
535
        add     ebx, 4
536
        cmp     ebx, esi
537
        jb      .next
538
 
539
        xor     eax, eax
540
        pop     esi
541
        pop     ebx
542
        ret
543
 
544
.done:
545
        mov     eax, [ebx]
546
        pop     esi
547
        pop     ebx
548
        ret
549
 
550
align 4
551
check_acpi:
552
 
553
        call    acpi_locate
554
        test    eax, eax
555
        jz      .done
556
 
557
        mov     ecx, [eax+16]
558
        mov     edx, 0x50434146
559
        mov     [acpi_rsdt_base-OS_BASE], ecx
560
        call    rsdt_find
561
        mov     [acpi_fadt_base-OS_BASE], eax
562
        test    eax, eax
563
        jz      @f
564
 
565
        mov     eax, [eax+40]
566
        mov     [acpi_dsdt_base-OS_BASE], eax
567
        mov     eax, [eax+4]
568
        mov     [acpi_dsdt_size-OS_BASE], eax
569
 
570
@@:
571
        mov     edx, ACPI_MADT_SIGN
572
        mov     ecx, [acpi_rsdt_base-OS_BASE]
573
        call    rsdt_find
574
        test    eax, eax
575
        jz      .done
576
 
577
        mov     [acpi_madt_base-OS_BASE], eax
578
        mov     ecx, [eax+36]
579
        mov     [acpi_lapic_base-OS_BASE], ecx
580
 
581
        mov     edi, smpt-OS_BASE
582
        mov     ebx, [ecx+0x20]
583
        shr     ebx, 24              ; read APIC ID
584
 
585
        mov     [edi], ebx           ; bootstrap always first
586
        inc     [cpu_count-OS_BASE]
587
        add     edi, 4
588
 
589
        lea     edx, [eax+44]
590
        mov     ecx, [eax+4]
591
        add     ecx, eax
592
.check:
593
        mov     eax, [edx]
594
        cmp     al, 0
595
        jne     .io_apic
596
 
597
        shr     eax, 24              ; get APIC ID
598
        cmp     eax, ebx             ; skip self
599
        je      .next
600
 
601
        test    [edx+4], byte 1      ; is enabled ?
602
        jz      .next
603
 
604
        cmp     [cpu_count-OS_BASE], 16
605
        jae     .next
606
 
607
        stosd                        ; store APIC ID
608
        inc     [cpu_count-OS_BASE]
609
.next:
610
        mov     eax, [edx]
611
        movzx   eax, ah
612
        add     edx, eax
613
        cmp     edx, ecx
614
        jb      .check
615
.done:
616
        ret
617
 
618
.io_apic:
619
        cmp     al, 1
620
        jne     .next
621
 
622
        mov     eax, [edx+4]
623
        mov     [acpi_ioapic_base-OS_BASE], eax
624
        jmp     .next