Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 2466 $
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_VAR-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_VAR-OS_BASE + 0x9100]
39
        xor     eax, eax
40
        mov     [BOOT_VAR-OS_BASE + 0x9104], eax
41
        mov     [BOOT_VAR-OS_BASE + 0x9108], eax
42
        mov     [BOOT_VAR-OS_BASE + 0x910C], edi
43
        mov     [BOOT_VAR-OS_BASE + 0x9110], eax
44
.ret:
45
        ret
46
endp
47
 
48
align 4
49
proc init_mem
50
; calculate maximum allocatable address and number of allocatable pages
51
        mov     edi, BOOT_VAR-OS_BASE + 0x9104
52
        mov     ecx, [edi-4]
53
        xor     esi, esi; esi will hold total amount of memory
54
        xor     edx, edx; edx will hold maximum allocatable address
55
.calcmax:
56
; round all to pages
57
        mov     eax, [edi]
2466 Serge 58
        cmp     [edi+16], byte 1
59
        jne     .unusable
60
 
2288 clevermous 61
        test    eax, 0xFFF
62
        jz      @f
63
        neg     eax
64
        and     eax, 0xFFF
65
        add     [edi], eax
66
        adc     dword [edi+4], 0
67
        sub     [edi+8], eax
68
        sbb     dword [edi+12], 0
69
        jc      .unusable
70
@@:
71
        and     dword [edi+8], not 0xFFF
72
        jz      .unusable
73
; ignore memory after 4 Gb
74
        cmp     dword [edi+4], 0
75
        jnz     .unusable
76
        mov     eax, [edi]
77
        cmp     dword [edi+12], 0
78
        jnz     .overflow
79
        add     eax, [edi+8]
80
        jnc     @f
81
.overflow:
82
        mov     eax, 0xFFFFF000
83
@@:
84
        cmp     edx, eax
85
        jae     @f
86
        mov     edx, eax
87
@@:
88
        sub     eax, [edi]
89
        mov     [edi+8], eax
90
        add     esi, eax
91
        jmp     .usable
92
.unusable:
2466 Serge 93
;        and     dword [edi+8], 0
2288 clevermous 94
.usable:
95
        add     edi, 20
96
        loop    .calcmax
97
.calculated:
98
        mov     [MEM_AMOUNT-OS_BASE], esi
99
        mov     [pg_data.mem_amount-OS_BASE], esi
100
        shr     esi, 12
101
        mov     [pg_data.pages_count-OS_BASE], esi
102
 
103
        shr     edx, 12
104
        add     edx, 31
105
        and     edx, not 31
106
        shr     edx, 3
107
        mov     [pg_data.pagemap_size-OS_BASE], edx
108
 
109
        add     edx, (sys_pgmap-OS_BASE)+4095
110
        and     edx, not 4095
111
        mov     [tmp_page_tabs], edx
112
 
113
        mov     edx, esi
114
        and     edx, -1024
115
        cmp     edx, (OS_BASE/4096)
116
        jbe     @F
117
        mov     edx, (OS_BASE/4096)
118
        jmp     .set
119
@@:
120
        cmp     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
121
        jae     .set
122
        mov     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
123
.set:
124
        mov     [pg_data.kernel_pages-OS_BASE], edx
125
        shr     edx, 10
126
        mov     [pg_data.kernel_tables-OS_BASE], edx
127
 
128
        xor     eax, eax
129
        mov     edi, sys_pgdir-OS_BASE
130
        mov     ecx, 4096/4
131
        cld
132
        rep stosd
133
 
134
        mov     edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
135
        bt      [cpu_caps-OS_BASE], CAPS_PSE
136
        jnc     .no_PSE
137
 
138
        mov     ebx, cr4
139
        or      ebx, CR4_PSE
140
        mov     eax, PG_LARGE+PG_SW
141
        mov     cr4, ebx
142
        dec     [pg_data.kernel_tables-OS_BASE]
143
 
144
        mov     [edx], eax
145
        add     edx, 4
146
 
147
        mov     edi, [tmp_page_tabs]
148
        jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
149
.no_PSE:
150
        mov     eax, PG_SW
151
        mov     ecx, [tmp_page_tabs]
152
        shr     ecx, 12
153
.map_low:
154
        mov     edi, [tmp_page_tabs]
155
@@:                                   ;
156
        stosd
157
        add     eax, 0x1000
158
        dec     ecx
159
        jnz     @B
160
 
161
.map_kernel_heap:
162
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
163
        shl     ecx, 10
164
        xor     eax, eax
165
        rep stosd
166
 
167
        mov     ecx, [pg_data.kernel_tables-OS_BASE]
168
        mov     eax, [tmp_page_tabs]
169
        or      eax, PG_SW
170
        mov     edi, edx
171
 
172
.map_kernel_tabs:
173
        stosd
174
        add     eax, 0x1000
175
        dec     ecx
176
        jnz     .map_kernel_tabs
177
 
178
        mov     dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
179
 
180
        mov     edi, (sys_pgdir-OS_BASE)
181
        lea     esi, [edi+(OS_BASE shr 20)]
182
        movsd
183
        movsd
184
        ret
185
endp
186
 
187
align 4
188
proc init_page_map
189
; mark all memory as unavailable
190
        mov     edi, sys_pgmap-OS_BASE
191
        mov     ecx, [pg_data.pagemap_size-OS_BASE]
192
        shr     ecx, 2
193
        xor     eax, eax
194
        cld
195
        rep stosd
196
 
197
; scan through memory map and mark free areas as available
198
        mov     ebx, BOOT_VAR-OS_BASE + 0x9104
199
        mov     edx, [ebx-4]
200
.scanmap:
2466 Serge 201
        cmp     [ebx+16], byte 1
202
        jne     .next
203
 
2288 clevermous 204
        mov     ecx, [ebx+8]
205
        shr     ecx, 12; ecx = number of pages
206
        jz      .next
207
        mov     edi, [ebx]
208
        shr     edi, 12; edi = first page
209
        mov     eax, edi
210
        shr     edi, 5
211
        shl     edi, 2
212
        add     edi, sys_pgmap-OS_BASE
213
        and     eax, 31
214
        jz      .startok
215
        add     ecx, eax
216
        sub     ecx, 32
217
        jbe     .onedword
218
        push    ecx
219
        mov     ecx, eax
220
        or      eax, -1
221
        shl     eax, cl
222
        or      [edi], eax
223
        add     edi, 4
224
        pop     ecx
225
.startok:
226
        push    ecx
227
        shr     ecx, 5
228
        or      eax, -1
229
        rep stosd
230
        pop     ecx
231
        and     ecx, 31
232
        neg     eax
233
        shl     eax, cl
234
        dec     eax
235
        or      [edi], eax
236
        jmp     .next
237
.onedword:
238
        add     ecx, 32
239
        sub     ecx, eax
240
@@:
241
        bts     [edi], eax
242
        inc     eax
243
        loop    @b
244
.next:
245
        add     ebx, 20
246
        dec     edx
247
        jnz     .scanmap
248
 
249
; mark kernel memory as allocated (unavailable)
250
        mov     ecx, [tmp_page_tabs]
251
        mov     edx, [pg_data.pages_count-OS_BASE]
252
        shr     ecx, 12
253
        add     ecx, [pg_data.kernel_tables-OS_BASE]
254
        sub     edx, ecx
255
        mov     [pg_data.pages_free-OS_BASE], edx
256
 
257
        mov     edi, sys_pgmap-OS_BASE
258
        mov     ebx, ecx
259
        shr     ecx, 5
260
        xor     eax, eax
261
        rep stosd
262
 
263
        not     eax
264
        mov     ecx, ebx
265
        and     ecx, 31
266
        shl     eax, cl
267
        and     [edi], eax
268
        add     edi, OS_BASE
269
        mov     [page_start-OS_BASE], edi;
270
 
271
        mov     ebx, sys_pgmap
272
        add     ebx, [pg_data.pagemap_size-OS_BASE]
273
        mov     [page_end-OS_BASE], ebx
274
 
275
        ret
276
endp
277
 
278
align 4
279
 
280
init_BIOS32:
281
        mov     edi, 0xE0000
282
.pcibios_nxt:
283
        cmp     dword[edi], '_32_'; "magic" word
284
        je      .BIOS32_found
285
.pcibios_nxt2:
286
        add     edi, 0x10
287
        cmp     edi, 0xFFFF0
288
        je      .BIOS32_not_found
289
        jmp     .pcibios_nxt
290
.BIOS32_found:                  ; magic word found, check control summ
291
 
292
        movzx   ecx, byte[edi + 9]
293
        shl     ecx, 4
294
        mov     esi, edi
295
        xor     eax, eax
296
        cld      ; paranoia
297
@@:
298
        lodsb
299
        add     ah, al
300
        loop    @b
301
        jnz     .pcibios_nxt2; control summ must be zero
302
    ; BIOS32 service found !
303
        mov     ebp, [edi + 4]
304
        mov     [bios32_entry], ebp
305
    ; check PCI BIOS present
306
        mov     eax, '$PCI'
307
        xor     ebx, ebx
308
        push    cs  ; special for 'ret far' from  BIOS
309
        call    ebp
310
        test    al, al
311
        jnz     .PCI_BIOS32_not_found
312
 
313
 ; здесь создаются дискрипторы для PCI BIOS
314
 
315
        add     ebx, OS_BASE
316
        dec     ecx
317
        mov     [(pci_code_32-OS_BASE)], cx   ;limit 0-15
318
        mov     [(pci_data_32-OS_BASE)], cx   ;limit 0-15
319
 
320
        mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
321
        mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
322
 
323
        shr     ebx, 16
324
        mov     [(pci_code_32-OS_BASE)+4], bl ;base  16-23
325
        mov     [(pci_data_32-OS_BASE)+4], bl ;base  16-23
326
 
327
        shr     ecx, 16
328
        and     cl, 0x0F
329
        mov     ch, bh
330
        add     cx, D32
331
        mov     [(pci_code_32-OS_BASE)+6], cx ;lim   16-19 &
332
        mov     [(pci_data_32-OS_BASE)+6], cx ;base  24-31
333
 
334
        mov     [(pci_bios_entry-OS_BASE)], edx
335
         ; jmp .end
336
.PCI_BIOS32_not_found:
337
        ; здесь должна заполнятся pci_emu_dat
338
.BIOS32_not_found:
339
.end:
340
        ret
341
 
342
align 4
343
proc test_cpu
344
           locals
345
              cpu_type   dd ?
346
              cpu_id     dd ?
347
              cpu_Intel  dd ?
348
              cpu_AMD    dd ?
349
           endl
350
 
351
        xor     eax, eax
352
        mov     [cpu_type], eax
353
        mov     [cpu_caps-OS_BASE], eax
354
        mov     [cpu_caps+4-OS_BASE], eax
355
 
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
369
 
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
379
        mov     [cpu_id], 1
380
 
381
        xor     eax, eax
382
        cpuid
383
 
384
        mov     [cpu_vendor-OS_BASE], ebx
385
        mov     [cpu_vendor+4-OS_BASE], edx
386
        mov     [cpu_vendor+8-OS_BASE], ecx
387
        cmp     ebx, dword [intel_str-OS_BASE]
388
        jne     .check_AMD
389
        cmp     edx, dword [intel_str+4-OS_BASE]
390
        jne     .check_AMD
391
        cmp     ecx, dword [intel_str+8-OS_BASE]
392
        jne     .check_AMD
393
        mov     [cpu_Intel], 1
394
        cmp     eax, 1
395
        jl      .end_cpuid
396
        mov     eax, 1
397
        cpuid
398
        mov     [cpu_sign-OS_BASE], eax
399
        mov     [cpu_info-OS_BASE], ebx
400
        mov     [cpu_caps-OS_BASE], edx
401
        mov     [cpu_caps+4-OS_BASE], ecx
402
 
403
        shr     eax, 8
404
        and     eax, 0x0f
405
        ret
406
.end_cpuid:
407
        mov     eax, [cpu_type]
408
        ret
409
 
410
.check_AMD:
411
        cmp     ebx, dword [AMD_str-OS_BASE]
412
        jne     .unknown
413
        cmp     edx, dword [AMD_str+4-OS_BASE]
414
        jne     .unknown
415
        cmp     ecx, dword [AMD_str+8-OS_BASE]
416
        jne     .unknown
417
        mov     [cpu_AMD], 1
418
        cmp     eax, 1
419
        jl      .unknown
420
        mov     eax, 1
421
        cpuid
422
        mov     [cpu_sign-OS_BASE], eax
423
        mov     [cpu_info-OS_BASE], ebx
424
        mov     [cpu_caps-OS_BASE], edx
425
        mov     [cpu_caps+4-OS_BASE], ecx
426
        shr     eax, 8
427
        and     eax, 0x0f
428
        ret
429
.unknown:
430
        mov     eax, 1
431
        cpuid
432
        mov     [cpu_sign-OS_BASE], eax
433
        mov     [cpu_info-OS_BASE], ebx
434
        mov     [cpu_caps-OS_BASE], edx
435
        mov     [cpu_caps+4-OS_BASE], ecx
436
        shr     eax, 8
437
        and     eax, 0x0f
438
        ret
439
endp
440
 
2443 Serge 441
iglobal
442
align 4
443
acpi_lapic_base   dd 0xfee00000   ; default local apic base
444
endg
445
 
2288 clevermous 446
uglobal
447
align 4
448
acpi_rsdp         rd 1
449
acpi_rsdt         rd 1
450
acpi_madt         rd 1
451
 
452
acpi_dev_data     rd 1
453
acpi_dev_size     rd 1
454
 
455
acpi_rsdt_base    rd 1
456
acpi_madt_base    rd 1
457
acpi_ioapic_base  rd 1
2443 Serge 458
 
459
cpu_count         rd 1
460
smpt              rd 16
2288 clevermous 461
endg
462
 
463
ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
464
ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
465
ACPI_RSDP_CHECKSUM_LENGTH  equ 20
466
ACPI_MADT_SIGN             equ 0x43495041
467
 
468
 
469
acpi_locate:
470
        push    ebx
471
        mov     ebx, ACPI_HI_RSDP_WINDOW_START
472
.check:
473
        cmp     [ebx], dword 0x20445352
474
        jne     .next
475
        cmp     [ebx+4], dword 0x20525450
476
        jne     .next
477
 
478
        mov     edx, ebx
479
        mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
480
        xor     eax, eax
481
.sum:
482
        add     al, [edx]
483
        inc     edx
484
        loop    .sum
485
 
486
        test    al, al
487
        jnz     .next
488
 
489
        mov     eax, ebx
490
        pop     ebx
491
        ret
492
.next:
493
        add     ebx, 16
494
        cmp     ebx, ACPI_HI_RSDP_WINDOW_END
495
        jb      .check
496
 
497
        pop     ebx
498
        xor     eax, eax
499
        ret
500
 
501
align 4
502
rsdt_find:           ;ecx= rsdt edx= SIG
503
        push    ebx
504
        push    esi
505
 
506
        lea     ebx, [ecx+36]
507
        mov     esi, [ecx+4]
508
        add     esi, ecx
2443 Serge 509
align 4
2288 clevermous 510
.next:
511
        mov     eax, [ebx]
512
        cmp     [eax], edx
513
        je      .done
514
 
515
        add     ebx, 4
516
        cmp     ebx, esi
517
        jb      .next
518
 
519
        xor     eax, eax
520
        pop     esi
521
        pop     ebx
522
        ret
523
 
524
.done:
525
        mov     eax, [ebx]
526
        pop     esi
527
        pop     ebx
528
        ret
529
 
530
align 4
531
check_acpi:
532
 
533
        call    acpi_locate
534
        test    eax, eax
535
        jz      .done
536
 
537
        mov     ecx, [eax+16]
538
        mov     edx, ACPI_MADT_SIGN
539
        mov     [acpi_rsdt_base-OS_BASE], ecx
540
        call    rsdt_find
541
        test    eax, eax
542
        jz      .done
543
 
544
        mov     [acpi_madt_base-OS_BASE], eax
545
        mov     ecx, [eax+36]
546
        mov     [acpi_lapic_base-OS_BASE], ecx
547
 
2443 Serge 548
        mov     edi, smpt-OS_BASE
549
        mov     ebx, [ecx+0x20]
550
        shr     ebx, 24              ; read APIC ID
551
 
552
        mov     [edi], ebx           ; bootstrap always first
553
        inc     [cpu_count-OS_BASE]
554
        add     edi, 4
555
 
2288 clevermous 556
        lea     edx, [eax+44]
557
        mov     ecx, [eax+4]
558
        add     ecx, eax
559
.check:
560
        mov     eax, [edx]
2443 Serge 561
        cmp     al, 0
562
        jne     .io_apic
2288 clevermous 563
 
2443 Serge 564
        shr     eax, 24              ; get APIC ID
565
        cmp     eax, ebx             ; skip self
566
        je      .next
567
 
568
        test    [edx+4], byte 1      ; is enabled ?
569
        jz      .next
570
 
571
        cmp     [cpu_count-OS_BASE], 16
572
        jae     .next
573
 
574
        stosd                        ; store APIC ID
575
        inc     [cpu_count-OS_BASE]
2288 clevermous 576
.next:
2443 Serge 577
        mov     eax, [edx]
2288 clevermous 578
        movzx   eax, ah
579
        add     edx, eax
580
        cmp     edx, ecx
581
        jb      .check
582
.done:
583
        ret
2443 Serge 584
 
585
.io_apic:
586
        cmp     al, 1
587
        jne     .next
588
 
2288 clevermous 589
        mov     eax, [edx+4]
590
        mov     [acpi_ioapic_base-OS_BASE], eax
2443 Serge 591
        jmp     .next