Subversion Repositories Kolibri OS

Rev

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