Subversion Repositories Kolibri OS

Rev

Rev 2467 | Rev 3232 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2467 Rev 2987
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 2467 $
8
$Revision: 2987 $
9
 
9
 
10
 
10
 
11
align 4
11
align 4
12
proc alloc_page
12
proc alloc_page
13
 
13
 
14
        pushfd
14
        pushfd
15
        cli
15
        cli
16
        push    ebx
16
        push    ebx
17
;//-
17
;//-
18
        cmp     [pg_data.pages_free], 1
18
        cmp     [pg_data.pages_free], 1
19
        jle     .out_of_memory
19
        jle     .out_of_memory
20
;//-
20
;//-
21
 
21
 
22
        mov     ebx, [page_start]
22
        mov     ebx, [page_start]
23
        mov     ecx, [page_end]
23
        mov     ecx, [page_end]
24
.l1:
24
.l1:
25
        bsf     eax, [ebx];
25
        bsf     eax, [ebx];
26
        jnz     .found
26
        jnz     .found
27
        add     ebx, 4
27
        add     ebx, 4
28
        cmp     ebx, ecx
28
        cmp     ebx, ecx
29
        jb      .l1
29
        jb      .l1
30
        pop     ebx
30
        pop     ebx
31
        popfd
31
        popfd
32
        xor     eax, eax
32
        xor     eax, eax
33
        ret
33
        ret
34
.found:
34
.found:
35
;//-
35
;//-
36
        dec     [pg_data.pages_free]
36
        dec     [pg_data.pages_free]
37
        jz      .out_of_memory
37
        jz      .out_of_memory
38
;//-
38
;//-
39
        btr     [ebx], eax
39
        btr     [ebx], eax
40
        mov     [page_start], ebx
40
        mov     [page_start], ebx
41
        sub     ebx, sys_pgmap
41
        sub     ebx, sys_pgmap
42
        lea     eax, [eax+ebx*8]
42
        lea     eax, [eax+ebx*8]
43
        shl     eax, 12
43
        shl     eax, 12
44
;//-       dec [pg_data.pages_free]
44
;//-       dec [pg_data.pages_free]
45
        pop     ebx
45
        pop     ebx
46
        popfd
46
        popfd
47
        ret
47
        ret
48
;//-
48
;//-
49
.out_of_memory:
49
.out_of_memory:
50
        mov     [pg_data.pages_free], 1
50
        mov     [pg_data.pages_free], 1
51
        xor     eax, eax
51
        xor     eax, eax
52
        pop     ebx
52
        pop     ebx
53
        popfd
53
        popfd
54
        ret
54
        ret
55
;//-
55
;//-
56
endp
56
endp
57
 
57
 
58
align 4
58
align 4
59
proc alloc_pages stdcall, count:dword
59
proc alloc_pages stdcall, count:dword
60
        pushfd
60
        pushfd
61
        push    ebx
61
        push    ebx
62
        push    edi
62
        push    edi
63
        cli
63
        cli
64
        mov     eax, [count]
64
        mov     eax, [count]
65
        add     eax, 7
65
        add     eax, 7
66
        shr     eax, 3
66
        shr     eax, 3
67
        mov     [count], eax
67
        mov     [count], eax
68
;//-
68
;//-
69
        mov     ebx, [pg_data.pages_free]
69
        mov     ebx, [pg_data.pages_free]
70
        sub     ebx, 9
70
        sub     ebx, 9
71
        js      .out_of_memory
71
        js      .out_of_memory
72
        shr     ebx, 3
72
        shr     ebx, 3
73
        cmp     eax, ebx
73
        cmp     eax, ebx
74
        jg      .out_of_memory
74
        jg      .out_of_memory
75
;//-
75
;//-
76
        mov     ecx, [page_start]
76
        mov     ecx, [page_start]
77
        mov     ebx, [page_end]
77
        mov     ebx, [page_end]
78
.find:
78
.find:
79
        mov     edx, [count]
79
        mov     edx, [count]
80
        mov     edi, ecx
80
        mov     edi, ecx
81
.match:
81
.match:
82
        cmp     byte [ecx], 0xFF
82
        cmp     byte [ecx], 0xFF
83
        jne     .next
83
        jne     .next
84
        dec     edx
84
        dec     edx
85
        jz      .ok
85
        jz      .ok
86
        inc     ecx
86
        inc     ecx
87
        cmp     ecx, ebx
87
        cmp     ecx, ebx
88
        jb      .match
88
        jb      .match
89
.out_of_memory:
89
.out_of_memory:
90
.fail:
90
.fail:
91
        xor     eax, eax
91
        xor     eax, eax
92
        pop     edi
92
        pop     edi
93
        pop     ebx
93
        pop     ebx
94
        popfd
94
        popfd
95
        ret
95
        ret
96
.next:
96
.next:
97
        inc     ecx
97
        inc     ecx
98
        cmp     ecx, ebx
98
        cmp     ecx, ebx
99
        jb      .find
99
        jb      .find
100
        pop     edi
100
        pop     edi
101
        pop     ebx
101
        pop     ebx
102
        popfd
102
        popfd
103
        xor     eax, eax
103
        xor     eax, eax
104
        ret
104
        ret
105
.ok:
105
.ok:
106
        sub     ecx, edi
106
        sub     ecx, edi
107
        inc     ecx
107
        inc     ecx
108
        push    esi
108
        push    esi
109
        mov     esi, edi
109
        mov     esi, edi
110
        xor     eax, eax
110
        xor     eax, eax
111
        rep stosb
111
        rep stosb
112
        sub     esi, sys_pgmap
112
        sub     esi, sys_pgmap
113
        shl     esi, 3+12
113
        shl     esi, 3+12
114
        mov     eax, esi
114
        mov     eax, esi
115
        mov     ebx, [count]
115
        mov     ebx, [count]
116
        shl     ebx, 3
116
        shl     ebx, 3
117
        sub     [pg_data.pages_free], ebx
117
        sub     [pg_data.pages_free], ebx
118
        pop     esi
118
        pop     esi
119
        pop     edi
119
        pop     edi
120
        pop     ebx
120
        pop     ebx
121
        popfd
121
        popfd
122
        ret
122
        ret
123
endp
123
endp
124
 
124
 
125
align 4
125
align 4
126
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
126
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
127
        push    ebx
127
        push    ebx
128
        mov     eax, [phis_addr]
128
        mov     eax, [phis_addr]
129
        and     eax, not 0xFFF
129
        and     eax, not 0xFFF
130
        or      eax, [flags]
130
        or      eax, [flags]
131
        mov     ebx, [lin_addr]
131
        mov     ebx, [lin_addr]
132
        shr     ebx, 12
132
        shr     ebx, 12
133
        mov     [page_tabs+ebx*4], eax
133
        mov     [page_tabs+ebx*4], eax
134
        mov     eax, [lin_addr]
134
        mov     eax, [lin_addr]
135
        invlpg  [eax]
135
        invlpg  [eax]
136
        pop     ebx
136
        pop     ebx
137
        ret
137
        ret
138
endp
138
endp
139
 
139
 
140
align 4
140
align 4
141
map_space:    ;not implemented
141
map_space:    ;not implemented
142
 
142
 
143
 
143
 
144
        ret
144
        ret
145
 
145
 
146
 
146
 
147
align 4
147
align 4
148
proc free_page
148
proc free_page
149
;arg:  eax  page address
149
;arg:  eax  page address
150
        pushfd
150
        pushfd
151
        cli
151
        cli
152
        shr     eax, 12                       ;page index
152
        shr     eax, 12                       ;page index
153
        bts     dword [sys_pgmap], eax        ;that's all!
153
        bts     dword [sys_pgmap], eax        ;that's all!
154
        cmc
154
        cmc
155
        adc     [pg_data.pages_free], 0
155
        adc     [pg_data.pages_free], 0
156
        shr     eax, 3
156
        shr     eax, 3
157
        and     eax, not 3                    ;dword offset from page_map
157
        and     eax, not 3                    ;dword offset from page_map
158
        add     eax, sys_pgmap
158
        add     eax, sys_pgmap
159
        cmp     [page_start], eax
159
        cmp     [page_start], eax
160
        ja      @f
160
        ja      @f
161
        popfd
161
        popfd
162
        ret
162
        ret
163
@@:
163
@@:
164
        mov     [page_start], eax
164
        mov     [page_start], eax
165
        popfd
165
        popfd
166
        ret
166
        ret
167
endp
167
endp
168
 
168
 
169
align 4
169
align 4
170
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
170
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
171
 
171
 
172
        push    ebx
172
        push    ebx
173
        push    edi
173
        push    edi
174
        mov     eax, [size]
174
        mov     eax, [size]
175
        add     eax, [base]
175
        add     eax, [base]
176
        add     eax, 4095
176
        add     eax, 4095
177
        and     eax, -4096
177
        and     eax, -4096
178
        mov     ecx, [base]
178
        mov     ecx, [base]
179
        and     ecx, -4096
179
        and     ecx, -4096
180
        sub     eax, ecx
180
        sub     eax, ecx
181
        mov     [size], eax
181
        mov     [size], eax
182
 
182
 
183
        stdcall alloc_kernel_space, eax
183
        stdcall alloc_kernel_space, eax
184
        test    eax, eax
184
        test    eax, eax
185
        jz      .fail
185
        jz      .fail
186
        push    eax
186
        push    eax
187
 
187
 
188
        mov     edi, 0x1000
188
        mov     edi, 0x1000
189
        mov     ebx, eax
189
        mov     ebx, eax
190
        mov     ecx, [size]
190
        mov     ecx, [size]
191
        mov     edx, [base]
191
        mov     edx, [base]
192
        shr     eax, 12
192
        shr     eax, 12
193
        shr     ecx, 12
193
        shr     ecx, 12
194
        and     edx, -4096
194
        and     edx, -4096
195
        or      edx, [flags]
195
        or      edx, [flags]
196
@@:
196
@@:
197
        mov     [page_tabs+eax*4], edx
197
        mov     [page_tabs+eax*4], edx
198
        invlpg  [ebx]
198
        invlpg  [ebx]
199
        inc     eax
199
        inc     eax
200
        add     ebx, edi
200
        add     ebx, edi
201
        add     edx, edi
201
        add     edx, edi
202
        loop    @B
202
        loop    @B
203
 
203
 
204
        pop     eax
204
        pop     eax
205
        mov     edx, [base]
205
        mov     edx, [base]
206
        and     edx, 4095
206
        and     edx, 4095
207
        add     eax, edx
207
        add     eax, edx
208
.fail:
208
.fail:
209
        pop     edi
209
        pop     edi
210
        pop     ebx
210
        pop     ebx
211
        ret
211
        ret
212
endp
212
endp
213
 
213
 
214
; param
214
; param
215
;  eax= page base + page flags
215
;  eax= page base + page flags
216
;  ebx= linear address
216
;  ebx= linear address
217
;  ecx= count
217
;  ecx= count
218
 
218
 
219
align 4
219
align 4
220
commit_pages:
220
commit_pages:
221
        test    ecx, ecx
221
        test    ecx, ecx
222
        jz      .fail
222
        jz      .fail
223
 
223
 
224
        push    edi
224
        push    edi
225
        push    eax
225
        push    eax
226
        push    ecx
226
        push    ecx
227
        mov     ecx, pg_data.mutex
227
        mov     ecx, pg_data.mutex
228
        call    mutex_lock
228
        call    mutex_lock
229
        pop     ecx
229
        pop     ecx
230
        pop     eax
230
        pop     eax
231
 
231
 
232
        mov     edi, ebx
232
        mov     edi, ebx
233
        shr     edi, 12
233
        shr     edi, 12
234
        lea     edi, [page_tabs+edi*4]
234
        lea     edi, [page_tabs+edi*4]
235
@@:
235
@@:
236
        stosd
236
        stosd
237
        invlpg  [ebx]
237
        invlpg  [ebx]
238
        add     eax, 0x1000
238
        add     eax, 0x1000
239
        add     ebx, 0x1000
239
        add     ebx, 0x1000
240
        loop    @B
240
        loop    @B
241
 
241
 
242
        pop     edi
242
        pop     edi
243
 
243
 
244
        mov     ecx, pg_data.mutex
244
        mov     ecx, pg_data.mutex
245
        call    mutex_unlock
245
        call    mutex_unlock
246
.fail:
246
.fail:
247
        ret
247
        ret
248
 
248
 
249
 
249
 
250
; param
250
; param
251
;  eax= base
251
;  eax= base
252
;  ecx= count
252
;  ecx= count
253
 
253
 
254
align 4
254
align 4
255
release_pages:
255
release_pages:
256
 
256
 
257
        push    ebp
257
        push    ebp
258
        push    esi
258
        push    esi
259
        push    edi
259
        push    edi
260
        push    ebx
260
        push    ebx
261
 
261
 
262
        mov     esi, eax
262
        mov     esi, eax
263
        mov     edi, eax
263
        mov     edi, eax
264
 
264
 
265
        shr     esi, 12
265
        shr     esi, 12
266
        lea     esi, [page_tabs+esi*4]
266
        lea     esi, [page_tabs+esi*4]
267
 
267
 
268
        push    ecx
268
        push    ecx
269
        mov     ecx, pg_data.mutex
269
        mov     ecx, pg_data.mutex
270
        call    mutex_lock
270
        call    mutex_lock
271
        pop     ecx
271
        pop     ecx
272
 
272
 
273
        mov     ebp, [pg_data.pages_free]
273
        mov     ebp, [pg_data.pages_free]
274
        mov     ebx, [page_start]
274
        mov     ebx, [page_start]
275
        mov     edx, sys_pgmap
275
        mov     edx, sys_pgmap
276
@@:
276
@@:
277
        xor     eax, eax
277
        xor     eax, eax
278
        xchg    eax, [esi]
278
        xchg    eax, [esi]
279
        invlpg  [edi]
279
        invlpg  [edi]
280
 
280
 
281
        test    eax, 1
281
        test    eax, 1
282
        jz      .next
282
        jz      .next
283
 
283
 
284
        shr     eax, 12
284
        shr     eax, 12
285
        bts     [edx], eax
285
        bts     [edx], eax
286
        cmc
286
        cmc
287
        adc     ebp, 0
287
        adc     ebp, 0
288
        shr     eax, 3
288
        shr     eax, 3
289
        and     eax, -4
289
        and     eax, -4
290
        add     eax, edx
290
        add     eax, edx
291
        cmp     eax, ebx
291
        cmp     eax, ebx
292
        jae     .next
292
        jae     .next
293
 
293
 
294
        mov     ebx, eax
294
        mov     ebx, eax
295
.next:
295
.next:
296
        add     edi, 0x1000
296
        add     edi, 0x1000
297
        add     esi, 4
297
        add     esi, 4
298
        loop    @B
298
        loop    @B
299
 
299
 
300
        mov     [pg_data.pages_free], ebp
300
        mov     [pg_data.pages_free], ebp
301
        mov     ecx, pg_data.mutex
301
        mov     ecx, pg_data.mutex
302
        call    mutex_unlock
302
        call    mutex_unlock
303
 
303
 
304
        pop     ebx
304
        pop     ebx
305
        pop     edi
305
        pop     edi
306
        pop     esi
306
        pop     esi
307
        pop     ebp
307
        pop     ebp
308
        ret
308
        ret
309
 
309
 
310
; param
310
; param
311
;  eax= base
311
;  eax= base
312
;  ecx= count
312
;  ecx= count
313
 
313
 
314
align 4
314
align 4
315
unmap_pages:
315
unmap_pages:
316
 
316
 
317
        push    edi
317
        push    edi
318
 
318
 
319
        mov     edi, eax
319
        mov     edi, eax
320
        mov     edx, eax
320
        mov     edx, eax
321
 
321
 
322
        shr     edi, 10
322
        shr     edi, 10
323
        add     edi, page_tabs
323
        add     edi, page_tabs
324
 
324
 
325
        xor     eax, eax
325
        xor     eax, eax
326
@@:
326
@@:
327
        stosd
327
        stosd
328
        invlpg  [edx]
328
        invlpg  [edx]
329
        add     edx, 0x1000
329
        add     edx, 0x1000
330
        loop    @b
330
        loop    @b
331
 
331
 
332
        pop     edi
332
        pop     edi
333
        ret
333
        ret
334
 
334
 
335
 
335
 
336
align 4
336
align 4
337
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
337
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
338
        push    ebx
338
        push    ebx
339
        mov     ebx, [lin_addr]
339
        mov     ebx, [lin_addr]
340
        shr     ebx, 22
340
        shr     ebx, 22
341
        mov     eax, [phis_addr]
341
        mov     eax, [phis_addr]
342
        and     eax, not 0xFFF
342
        and     eax, not 0xFFF
343
        or      eax, PG_UW        ;+PG_NOCACHE
343
        or      eax, PG_UW        ;+PG_NOCACHE
344
        mov     dword [master_tab+ebx*4], eax
344
        mov     dword [master_tab+ebx*4], eax
345
        mov     eax, [lin_addr]
345
        mov     eax, [lin_addr]
346
        shr     eax, 10
346
        shr     eax, 10
347
        add     eax, page_tabs
347
        add     eax, page_tabs
348
        invlpg  [eax]
348
        invlpg  [eax]
349
        pop     ebx
349
        pop     ebx
350
        ret
350
        ret
351
endp
351
endp
352
 
352
 
353
align 4
353
align 4
354
proc init_LFB
354
proc init_LFB
355
           locals
355
           locals
356
             pg_count dd ?
356
             pg_count dd ?
357
           endl
357
           endl
358
 
358
 
359
        cmp     dword [LFBAddress], -1
359
        cmp     dword [LFBAddress], -1
360
        jne     @f
360
        jne     @f
361
        mov     [BOOT_VAR+BOOT_MTRR], byte 2
361
        mov     [BOOT_VAR+BOOT_MTRR], byte 2
362
; max VGA=640*480*4=1228800 bytes
362
; max VGA=640*480*4=1228800 bytes
363
; + 32*640*4=81920 bytes for mouse pointer
363
; + 32*640*4=81920 bytes for mouse pointer
364
        stdcall alloc_pages, ((1228800+81920)/4096)
364
        stdcall alloc_pages, ((1228800+81920)/4096)
365
 
365
 
366
        push    eax
366
        push    eax
367
        call    alloc_page
367
        call    alloc_page
368
        stdcall map_page_table, LFB_BASE, eax
368
        stdcall map_page_table, LFB_BASE, eax
369
        pop     eax
369
        pop     eax
370
        or      eax, PG_UW
370
        or      eax, PG_UW
371
        mov     ebx, LFB_BASE
371
        mov     ebx, LFB_BASE
372
; max VGA=640*480*4=1228800 bytes
372
; max VGA=640*480*4=1228800 bytes
373
; + 32*640*4=81920 bytes for mouse pointer
373
; + 32*640*4=81920 bytes for mouse pointer
374
        mov     ecx, (1228800+81920)/4096
374
        mov     ecx, (1228800+81920)/4096
375
        call    commit_pages
375
        call    commit_pages
376
        mov     [LFBAddress], dword LFB_BASE
376
        mov     [LFBAddress], dword LFB_BASE
377
        ret
377
        ret
378
@@:
378
@@:
379
        test    [SCR_MODE], word 0100000000000000b
379
        test    [SCR_MODE], word 0100000000000000b
380
        jnz     @f
380
        jnz     @f
381
        mov     [BOOT_VAR+BOOT_MTRR], byte 2
381
        mov     [BOOT_VAR+BOOT_MTRR], byte 2
382
        ret
382
        ret
383
@@:
383
@@:
384
        call    init_mtrr
384
        call    init_mtrr
385
 
385
 
386
        mov     edx, LFB_BASE
386
        mov     edx, LFB_BASE
387
        mov     esi, [LFBAddress]
387
        mov     esi, [LFBAddress]
388
        mov     edi, 0x00C00000
388
        mov     edi, 0x00C00000
389
        mov     dword [exp_lfb+4], edx
389
        mov     dword [exp_lfb+4], edx
390
 
390
 
391
        shr     edi, 12
391
        shr     edi, 12
392
        mov     [pg_count], edi
392
        mov     [pg_count], edi
393
        shr     edi, 10
393
        shr     edi, 10
394
 
394
 
395
        bt      [cpu_caps], CAPS_PSE
395
        bt      [cpu_caps], CAPS_PSE
396
        jnc     .map_page_tables
396
        jnc     .map_page_tables
397
        or      esi, PG_LARGE+PG_UW
397
        or      esi, PG_LARGE+PG_UW
398
        mov     edx, sys_pgdir+(LFB_BASE shr 20)
398
        mov     edx, sys_pgdir+(LFB_BASE shr 20)
399
@@:
399
@@:
400
        mov     [edx], esi
400
        mov     [edx], esi
401
        add     edx, 4
401
        add     edx, 4
402
        add     esi, 0x00400000
402
        add     esi, 0x00400000
403
        dec     edi
403
        dec     edi
404
        jnz     @B
404
        jnz     @B
405
 
405
 
406
        bt      [cpu_caps], CAPS_PGE
406
        bt      [cpu_caps], CAPS_PGE
407
        jnc     @F
407
        jnc     @F
408
        or      dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
408
        or      dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
409
@@:
409
@@:
410
        mov     dword [LFBAddress], LFB_BASE
410
        mov     dword [LFBAddress], LFB_BASE
411
        mov     eax, cr3      ;flush TLB
411
        mov     eax, cr3      ;flush TLB
412
        mov     cr3, eax
412
        mov     cr3, eax
413
        ret
413
        ret
414
 
414
 
415
.map_page_tables:
415
.map_page_tables:
416
 
416
 
417
@@:
417
@@:
418
        call    alloc_page
418
        call    alloc_page
419
        stdcall map_page_table, edx, eax
419
        stdcall map_page_table, edx, eax
420
        add     edx, 0x00400000
420
        add     edx, 0x00400000
421
        dec     edi
421
        dec     edi
422
        jnz     @B
422
        jnz     @B
423
 
423
 
424
        mov     eax, [LFBAddress]
424
        mov     eax, [LFBAddress]
425
        mov     edi, page_tabs + (LFB_BASE shr 10)
425
        mov     edi, page_tabs + (LFB_BASE shr 10)
426
        or      eax, PG_UW
426
        or      eax, PG_UW
427
        mov     ecx, [pg_count]
427
        mov     ecx, [pg_count]
428
        cld
428
        cld
429
@@:
429
@@:
430
        stosd
430
        stosd
431
        add     eax, 0x1000
431
        add     eax, 0x1000
432
        dec     ecx
432
        dec     ecx
433
        jnz     @B
433
        jnz     @B
434
 
434
 
435
        mov     dword [LFBAddress], LFB_BASE
435
        mov     dword [LFBAddress], LFB_BASE
436
        mov     eax, cr3      ;flush TLB
436
        mov     eax, cr3      ;flush TLB
437
        mov     cr3, eax
437
        mov     cr3, eax
438
 
438
 
439
        ret
439
        ret
440
endp
440
endp
441
 
441
 
442
align 4
442
align 4
443
proc new_mem_resize stdcall, new_size:dword
443
proc new_mem_resize stdcall, new_size:dword
-
 
444
 
-
 
445
        push    ebx
-
 
446
        push    esi
-
 
447
        push    edi
444
 
448
 
-
 
449
        mov     edx, [current_slot]
445
        mov     ecx, pg_data.mutex
450
        cmp     [edx+APPDATA.heap_base], 0
446
        call    mutex_lock
451
        jne     .exit
447
 
452
 
448
        mov     edi, [new_size]
453
        mov     edi, [new_size]
449
        add     edi, 4095
454
        add     edi, 4095
450
        and     edi, not 4095
455
        and     edi, not 4095
451
        mov     [new_size], edi
456
        mov     [new_size], edi
452
 
-
 
453
        mov     edx, [current_slot]
-
 
454
        cmp     [edx+APPDATA.heap_base], 0
-
 
455
        jne     .exit
-
 
456
 
457
 
457
        mov     esi, [edx+APPDATA.mem_size]
458
        mov     esi, [edx+APPDATA.mem_size]
458
        add     esi, 4095
459
        add     esi, 4095
459
        and     esi, not 4095
460
        and     esi, not 4095
460
 
461
 
461
        cmp     edi, esi
462
        cmp     edi, esi
462
        jae     .expand
463
        ja      .expand
-
 
464
        je      .exit
-
 
465
 
463
 
466
        mov     ebx, edi
464
        shr     edi, 12
467
        shr     edi, 12
-
 
468
        shr     esi, 12
-
 
469
 
-
 
470
        mov     ecx, pg_data.mutex
465
        shr     esi, 12
471
        call    mutex_lock
466
@@:
472
@@:
467
        mov     eax, [app_page_tabs+edi*4]
473
        mov     eax, [app_page_tabs+edi*4]
468
        test    eax, 1
474
        test    eax, 1
469
        jz      .next
475
        jz      .next
-
 
476
 
470
        mov     dword [app_page_tabs+edi*4], 2
477
        mov     dword [app_page_tabs+edi*4], 0
471
        mov     ebx, edi
-
 
472
        shl     ebx, 12
-
 
473
        push    eax
-
 
474
        invlpg  [ebx]
478
        invlpg  [ebx]
475
        pop     eax
-
 
476
        call    free_page
479
        call    free_page
477
 
480
 
478
.next:
481
.next:
-
 
482
        inc     edi
479
        add     edi, 1
483
        add     ebx, 0x1000
480
        cmp     edi, esi
484
        cmp     edi, esi
481
        jb      @B
485
        jb      @B
482
 
-
 
483
.update_size:
-
 
484
        mov     ebx, [new_size]
-
 
485
        call    update_mem_size
-
 
486
 
486
 
487
        mov     ecx, pg_data.mutex
487
        mov     ecx, pg_data.mutex
488
        call    mutex_unlock
488
        call    mutex_unlock
-
 
489
 
-
 
490
.update_size:
-
 
491
        mov     edx, [current_slot]
-
 
492
        mov     ebx, [new_size]
-
 
493
        call    update_mem_size
-
 
494
.exit:
-
 
495
        pop     edi
-
 
496
        pop     esi
489
 
497
        pop     ebx
490
        xor     eax, eax
498
        xor     eax, eax
-
 
499
        ret
491
        ret
500
 
-
 
501
.expand:
492
.expand:
502
 
-
 
503
        mov     ecx, pg_data.mutex
493
 
504
        call    mutex_lock
-
 
505
 
-
 
506
        xchg    esi, edi
-
 
507
 
494
        push    esi
508
        push    esi                   ;new size
495
        push    edi
509
        push    edi                   ;old size
496
 
510
 
497
        add     edi, 0x3FFFFF
511
        add     edi, 0x3FFFFF
498
        and     edi, not(0x3FFFFF)
512
        and     edi, not(0x3FFFFF)
499
        add     esi, 0x3FFFFF
513
        add     esi, 0x3FFFFF
500
        and     esi, not(0x3FFFFF)
514
        and     esi, not(0x3FFFFF)
501
 
515
 
502
        cmp     esi, edi
516
        cmp     edi, esi
503
        jae     .grow
-
 
504
 
-
 
505
        xchg    esi, edi
-
 
506
 
517
        jae     .grow
507
@@:
518
 @@:
508
        call    alloc_page
519
        call    alloc_page
509
        test    eax, eax
520
        test    eax, eax
510
        jz      .exit_pop
521
        jz      .exit_fail
511
 
522
 
512
        stdcall map_page_table, edi, eax
523
        stdcall map_page_table, edi, eax
513
 
524
 
514
        push    edi
525
        push    edi
515
        shr     edi, 10
526
        shr     edi, 10
516
        add     edi, page_tabs
527
        add     edi, page_tabs
517
        mov     ecx, 1024
528
        mov     ecx, 1024
518
        xor     eax, eax
529
        xor     eax, eax
519
        cld
530
        cld
520
        rep stosd
531
        rep stosd
521
        pop     edi
532
        pop     edi
522
 
533
 
523
        add     edi, 0x00400000
534
        add     edi, 0x00400000
524
        cmp     edi, esi
535
        cmp     edi, esi
525
        jb      @B
536
        jb      @B
526
.grow:
537
.grow:
527
;//-
-
 
528
        pop     edi
-
 
529
        push    edi
-
 
530
        mov     esi, [pg_data.pages_free]
538
        pop     edi                   ;old size
531
        sub     esi, 1
-
 
532
        shr     edi, 12
-
 
533
        cmp     esi, edi
-
 
534
        jle     .out_of_memory
-
 
535
;//-
-
 
536
        pop     edi
-
 
537
        pop     esi
-
 
538
@@:
-
 
539
        call    alloc_page
-
 
540
        test    eax, eax
-
 
541
        jz      .exit
-
 
542
        stdcall map_page, esi, eax, dword PG_UW
539
        pop     ecx                   ;new size
543
 
540
 
544
        push    edi
541
        shr     edi, 10
545
        mov     edi, esi
542
        shr     ecx, 10
-
 
543
        sub     ecx, edi
546
        xor     eax, eax
544
        shr     ecx, 2                ;pages count
-
 
545
        mov     eax, 2
547
        mov     ecx, 1024
546
 
548
        cld
547
        add     edi, app_page_tabs
549
        rep stosd
-
 
550
        pop     edi
548
        rep stosd
551
 
549
 
552
        add     esi, 0x1000
-
 
553
        cmp     esi, edi
550
        mov     ecx, pg_data.mutex
554
        jb      @B
551
        call    mutex_unlock
555
 
552
 
556
        jmp     .update_size
-
 
557
;//-
-
 
558
.exit_pop:
-
 
559
.out_of_memory:
-
 
560
;//-
-
 
561
        pop     edi
553
        jmp     .update_size
562
        pop     esi
554
 
563
.exit:
555
.exit_fail:
564
        mov     ecx, pg_data.mutex
556
        mov     ecx, pg_data.mutex
565
        call    mutex_unlock
557
        call    mutex_unlock
-
 
558
 
-
 
559
        add     esp, 8
-
 
560
        pop     edi
-
 
561
        pop     esi
566
 
562
        pop     ebx
567
        xor     eax, eax
563
        xor     eax, eax
568
        inc     eax
564
        inc     eax
569
        ret
565
        ret
570
endp
566
endp
-
 
567
 
-
 
568
 
571
 
569
align 4
572
update_mem_size:
570
update_mem_size:
573
; in: edx = slot base
571
; in: edx = slot base
574
;     ebx = new memory size
572
;     ebx = new memory size
575
; destroys eax,ecx,edx
573
; destroys eax,ecx,edx
576
 
574
 
577
        mov     [APPDATA.mem_size+edx], ebx
575
        mov     [APPDATA.mem_size+edx], ebx
578
;search threads and update
576
;search threads and update
579
;application memory size infomation
577
;application memory size infomation
580
        mov     ecx, [APPDATA.dir_table+edx]
578
        mov     ecx, [APPDATA.dir_table+edx]
581
        mov     eax, 2
579
        mov     eax, 2
582
 
580
 
583
.search_threads:
581
.search_threads:
584
;eax = current slot
582
;eax = current slot
585
;ebx = new memory size
583
;ebx = new memory size
586
;ecx = page directory
584
;ecx = page directory
587
        cmp     eax, [TASK_COUNT]
585
        cmp     eax, [TASK_COUNT]
588
        jg      .search_threads_end
586
        jg      .search_threads_end
589
        mov     edx, eax
587
        mov     edx, eax
590
        shl     edx, 5
588
        shl     edx, 5
591
        cmp     word [CURRENT_TASK+edx+TASKDATA.state], 9  ;if slot empty?
589
        cmp     word [CURRENT_TASK+edx+TASKDATA.state], 9  ;if slot empty?
592
        jz      .search_threads_next
590
        jz      .search_threads_next
593
        shl     edx, 3
591
        shl     edx, 3
594
        cmp     [SLOT_BASE+edx+APPDATA.dir_table], ecx      ;if it is our thread?
592
        cmp     [SLOT_BASE+edx+APPDATA.dir_table], ecx      ;if it is our thread?
595
        jnz     .search_threads_next
593
        jnz     .search_threads_next
596
        mov     [SLOT_BASE+edx+APPDATA.mem_size], ebx      ;update memory size
594
        mov     [SLOT_BASE+edx+APPDATA.mem_size], ebx      ;update memory size
597
.search_threads_next:
595
.search_threads_next:
598
        inc     eax
596
        inc     eax
599
        jmp     .search_threads
597
        jmp     .search_threads
600
.search_threads_end:
598
.search_threads_end:
601
        ret
599
        ret
602
 
600
 
603
; param
601
; param
604
;  eax= linear address
602
;  eax= linear address
605
;
603
;
606
; retval
604
; retval
607
;  eax= phisical page address
605
;  eax= phisical page address
608
 
606
 
609
align 4
607
align 4
610
get_pg_addr:
608
get_pg_addr:
611
        shr     eax, 12
609
        shr     eax, 12
612
        mov     eax, [page_tabs+eax*4]
610
        mov     eax, [page_tabs+eax*4]
613
        and     eax, 0xFFFFF000
611
        and     eax, 0xFFFFF000
614
        ret
612
        ret
615
 
613
 
616
 
614
 
617
align 4
615
align 4
618
; Now it is called from core/sys32::exc_c (see stack frame there)
616
; Now it is called from core/sys32::exc_c (see stack frame there)
619
proc page_fault_handler
617
proc page_fault_handler
620
 
618
 
621
    .err_addr   equ ebp-4
619
    .err_addr   equ ebp-4
622
 
620
 
623
        push    ebx               ;save exception number (#PF)
621
        push    ebx               ;save exception number (#PF)
624
        mov     ebp, esp
622
        mov     ebp, esp
625
        mov     ebx, cr2
623
        mov     ebx, cr2
626
        push    ebx               ;that is locals: .err_addr = cr2
624
        push    ebx               ;that is locals: .err_addr = cr2
627
        inc     [pg_data.pages_faults]
625
        inc     [pg_data.pages_faults]
628
 
626
 
629
        mov     eax, [pf_err_code]
627
        mov     eax, [pf_err_code]
630
 
628
 
631
        cmp     ebx, OS_BASE      ;ebx == .err_addr
629
        cmp     ebx, OS_BASE      ;ebx == .err_addr
632
        jb      .user_space       ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
630
        jb      .user_space       ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
633
 
631
 
634
        cmp     ebx, page_tabs
632
        cmp     ebx, page_tabs
635
        jb      .kernel_space     ;ñòðàíèöà â ïàìÿòè ÿäðà
633
        jb      .kernel_space     ;ñòðàíèöà â ïàìÿòè ÿäðà
636
 
634
 
637
        cmp     ebx, kernel_tabs
635
        cmp     ebx, kernel_tabs
638
        jb      .alloc;.app_tabs  ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
636
        jb      .alloc;.app_tabs  ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
639
                                  ;ïðîñòî ñîçäàäèì îäíó
637
                                  ;ïðîñòî ñîçäàäèì îäíó
640
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
638
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
641
        cmp     ebx, LFB_BASE
639
        cmp     ebx, LFB_BASE
642
        jb      .core_tabs        ;òàáëèöû ñòðàíèö ÿäðà
640
        jb      .core_tabs        ;òàáëèöû ñòðàíèö ÿäðà
643
                                  ;Îøèáêà
641
                                  ;Îøèáêà
644
  .lfb:
642
  .lfb:
645
                                  ;îáëàñòü LFB
643
                                  ;îáëàñòü LFB
646
                                  ;Îøèáêà
644
                                  ;Îøèáêà
647
        jmp     .fail
645
        jmp     .fail
648
end if
646
end if
649
.core_tabs:
647
.core_tabs:
650
.fail:  ;simply return to caller
648
.fail:  ;simply return to caller
651
        mov     esp, ebp
649
        mov     esp, ebp
652
        pop     ebx               ;restore exception number (#PF)
650
        pop     ebx               ;restore exception number (#PF)
653
        ret
651
        ret
654
 
652
 
655
;        xchg bx, bx
653
;        xchg bx, bx
656
;        add     esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
654
;        add     esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
657
;        restore_ring3_context
655
;        restore_ring3_context
658
;        iretd
656
;        iretd
659
 
657
 
660
.user_space:
658
.user_space:
661
        test    eax, PG_MAP
659
        test    eax, PG_MAP
662
        jnz     .err_access       ;Ñòðàíèöà ïðèñóòñòâóåò
660
        jnz     .err_access       ;Ñòðàíèöà ïðèñóòñòâóåò
663
                                  ;Îøèáêà äîñòóïà ?
661
                                  ;Îøèáêà äîñòóïà ?
664
 
662
 
665
        shr     ebx, 12
663
        shr     ebx, 12
666
        mov     ecx, ebx
664
        mov     ecx, ebx
667
        shr     ecx, 10
665
        shr     ecx, 10
668
        mov     edx, [master_tab+ecx*4]
666
        mov     edx, [master_tab+ecx*4]
669
        test    edx, PG_MAP
667
        test    edx, PG_MAP
670
        jz      .fail             ;òàáëèöà ñòðàíèö íå ñîçäàíà
668
        jz      .fail             ;òàáëèöà ñòðàíèö íå ñîçäàíà
671
                                  ;íåâåðíûé àäðåñ â ïðîãðàììå
669
                                  ;íåâåðíûé àäðåñ â ïðîãðàììå
672
 
670
 
673
        mov     eax, [page_tabs+ebx*4]
671
        mov     eax, [page_tabs+ebx*4]
674
        test    eax, 2
672
        test    eax, 2
675
        jz      .fail             ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
673
        jz      .fail             ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
676
                                  ;èñïîëüçîâàíèÿ. Îøèáêà
674
                                  ;èñïîëüçîâàíèÿ. Îøèáêà
677
.alloc:
675
.alloc:
678
        call    alloc_page
676
        call    alloc_page
679
        test    eax, eax
677
        test    eax, eax
680
        jz      .fail
678
        jz      .fail
681
 
679
 
682
        stdcall map_page, [.err_addr], eax, PG_UW
680
        stdcall map_page, [.err_addr], eax, PG_UW
683
 
681
 
684
        mov     edi, [.err_addr]
682
        mov     edi, [.err_addr]
685
        and     edi, 0xFFFFF000
683
        and     edi, 0xFFFFF000
686
        mov     ecx, 1024
684
        mov     ecx, 1024
687
        xor     eax, eax
685
        xor     eax, eax
688
       ;cld     ;caller is duty for this
686
       ;cld     ;caller is duty for this
689
        rep stosd
687
        rep stosd
690
.exit:  ;iret with repeat fault instruction
688
.exit:  ;iret with repeat fault instruction
691
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
689
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
692
        restore_ring3_context
690
        restore_ring3_context
693
        iretd
691
        iretd
694
 
692
 
695
.err_access:
693
.err_access:
696
; access denied? this may be a result of copy-on-write protection for DLL
694
; access denied? this may be a result of copy-on-write protection for DLL
697
; check list of HDLLs
695
; check list of HDLLs
698
        and     ebx, not 0xFFF
696
        and     ebx, not 0xFFF
699
        mov     eax, [CURRENT_TASK]
697
        mov     eax, [CURRENT_TASK]
700
        shl     eax, 8
698
        shl     eax, 8
701
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
699
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
702
        test    eax, eax
700
        test    eax, eax
703
        jz      .fail
701
        jz      .fail
704
        mov     esi, [eax+HDLL.fd]
702
        mov     esi, [eax+HDLL.fd]
705
.scan_hdll:
703
.scan_hdll:
706
        cmp     esi, eax
704
        cmp     esi, eax
707
        jz      .fail
705
        jz      .fail
708
        mov     edx, ebx
706
        mov     edx, ebx
709
        sub     edx, [esi+HDLL.base]
707
        sub     edx, [esi+HDLL.base]
710
        cmp     edx, [esi+HDLL.size]
708
        cmp     edx, [esi+HDLL.size]
711
        jb      .fault_in_hdll
709
        jb      .fault_in_hdll
712
.scan_hdll.next:
710
.scan_hdll.next:
713
        mov     esi, [esi+HDLL.fd]
711
        mov     esi, [esi+HDLL.fd]
714
        jmp     .scan_hdll
712
        jmp     .scan_hdll
715
.fault_in_hdll:
713
.fault_in_hdll:
716
; allocate new page, map it as rw and copy data
714
; allocate new page, map it as rw and copy data
717
        call    alloc_page
715
        call    alloc_page
718
        test    eax, eax
716
        test    eax, eax
719
        jz      .fail
717
        jz      .fail
720
        stdcall map_page, ebx, eax, PG_UW
718
        stdcall map_page, ebx, eax, PG_UW
721
        mov     edi, ebx
719
        mov     edi, ebx
722
        mov     ecx, 1024
720
        mov     ecx, 1024
723
        sub     ebx, [esi+HDLL.base]
721
        sub     ebx, [esi+HDLL.base]
724
        mov     esi, [esi+HDLL.parent]
722
        mov     esi, [esi+HDLL.parent]
725
        mov     esi, [esi+DLLDESCR.data]
723
        mov     esi, [esi+DLLDESCR.data]
726
        add     esi, ebx
724
        add     esi, ebx
727
        rep movsd
725
        rep movsd
728
        jmp     .exit
726
        jmp     .exit
729
 
727
 
730
.kernel_space:
728
.kernel_space:
731
        test    eax, PG_MAP
729
        test    eax, PG_MAP
732
        jz      .fail   ;ñòðàíèöà íå ïðèñóòñòâóåò
730
        jz      .fail   ;ñòðàíèöà íå ïðèñóòñòâóåò
733
 
731
 
734
        test    eax, 12 ;U/S (+below)
732
        test    eax, 12 ;U/S (+below)
735
        jnz     .fail   ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
733
        jnz     .fail   ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
736
                        ;ÿäðà
734
                        ;ÿäðà
737
       ;test    eax, 8
735
       ;test    eax, 8
738
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
736
       ;jnz     .fail   ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
739
                        ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
737
                        ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
740
 
738
 
741
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
739
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
742
 
740
 
743
        cmp     ebx, tss._io_map_0
741
        cmp     ebx, tss._io_map_0
744
        jb      .fail
742
        jb      .fail
745
 
743
 
746
        cmp     ebx, tss._io_map_0+8192
744
        cmp     ebx, tss._io_map_0+8192
747
        jae     .fail
745
        jae     .fail
748
 
746
 
749
; io permission map
747
; io permission map
750
; copy-on-write protection
748
; copy-on-write protection
751
 
749
 
752
        call    alloc_page
750
        call    alloc_page
753
        test    eax, eax
751
        test    eax, eax
754
        jz      .fail
752
        jz      .fail
755
 
753
 
756
        push    eax
754
        push    eax
757
        stdcall map_page, [.err_addr], eax, dword PG_SW
755
        stdcall map_page, [.err_addr], eax, dword PG_SW
758
        pop     eax
756
        pop     eax
759
        mov     edi, [.err_addr]
757
        mov     edi, [.err_addr]
760
        and     edi, -4096
758
        and     edi, -4096
761
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
759
        lea     esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
762
 
760
 
763
        mov     ebx, esi
761
        mov     ebx, esi
764
        shr     ebx, 12
762
        shr     ebx, 12
765
        mov     edx, [current_slot]
763
        mov     edx, [current_slot]
766
        or      eax, PG_SW
764
        or      eax, PG_SW
767
        mov     [edx+APPDATA.io_map+ebx*4], eax
765
        mov     [edx+APPDATA.io_map+ebx*4], eax
768
 
766
 
769
        add     esi, [default_io_map]
767
        add     esi, [default_io_map]
770
        mov     ecx, 4096/4
768
        mov     ecx, 4096/4
771
       ;cld     ;caller is duty for this
769
       ;cld     ;caller is duty for this
772
        rep movsd
770
        rep movsd
773
        jmp     .exit
771
        jmp     .exit
774
endp
772
endp
775
 
773
 
776
; returns number of mapped bytes
774
; returns number of mapped bytes
777
proc map_mem stdcall, lin_addr:dword,slot:dword,\
775
proc map_mem stdcall, lin_addr:dword,slot:dword,\
778
                      ofs:dword,buf_size:dword,req_access:dword
776
                      ofs:dword,buf_size:dword,req_access:dword
779
        push    0 ; initialize number of mapped bytes
777
        push    0 ; initialize number of mapped bytes
780
 
778
 
781
        cmp     [buf_size], 0
779
        cmp     [buf_size], 0
782
        jz      .exit
780
        jz      .exit
783
 
781
 
784
        mov     eax, [slot]
782
        mov     eax, [slot]
785
        shl     eax, 8
783
        shl     eax, 8
786
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
784
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
787
        and     eax, 0xFFFFF000
785
        and     eax, 0xFFFFF000
788
 
786
 
789
        stdcall map_page, [ipc_pdir], eax, PG_UW
787
        stdcall map_page, [ipc_pdir], eax, PG_UW
790
        mov     ebx, [ofs]
788
        mov     ebx, [ofs]
791
        shr     ebx, 22
789
        shr     ebx, 22
792
        mov     esi, [ipc_pdir]
790
        mov     esi, [ipc_pdir]
793
        mov     edi, [ipc_ptab]
791
        mov     edi, [ipc_ptab]
794
        mov     eax, [esi+ebx*4]
792
        mov     eax, [esi+ebx*4]
795
        and     eax, 0xFFFFF000
793
        and     eax, 0xFFFFF000
796
        jz      .exit
794
        jz      .exit
797
        stdcall map_page, edi, eax, PG_UW
795
        stdcall map_page, edi, eax, PG_UW
798
;           inc ebx
796
;           inc ebx
799
;           add edi, 0x1000
797
;           add edi, 0x1000
800
;           mov eax, [esi+ebx*4]
798
;           mov eax, [esi+ebx*4]
801
;           test eax, eax
799
;           test eax, eax
802
;           jz @f
800
;           jz @f
803
;          and eax, 0xFFFFF000
801
;          and eax, 0xFFFFF000
804
;           stdcall map_page, edi, eax
802
;           stdcall map_page, edi, eax
805
 
803
 
806
@@:
804
@@:
807
        mov     edi, [lin_addr]
805
        mov     edi, [lin_addr]
808
        and     edi, 0xFFFFF000
806
        and     edi, 0xFFFFF000
809
        mov     ecx, [buf_size]
807
        mov     ecx, [buf_size]
810
        add     ecx, 4095
808
        add     ecx, 4095
811
        shr     ecx, 12
809
        shr     ecx, 12
812
        inc     ecx
810
        inc     ecx
813
 
811
 
814
        mov     edx, [ofs]
812
        mov     edx, [ofs]
815
        shr     edx, 12
813
        shr     edx, 12
816
        and     edx, 0x3FF
814
        and     edx, 0x3FF
817
        mov     esi, [ipc_ptab]
815
        mov     esi, [ipc_ptab]
818
 
816
 
819
.map:
817
.map:
820
        stdcall safe_map_page, [slot], [req_access], [ofs]
818
        stdcall safe_map_page, [slot], [req_access], [ofs]
821
        jnc     .exit
819
        jnc     .exit
822
        add     dword [ebp-4], 4096
820
        add     dword [ebp-4], 4096
823
        add     [ofs], 4096
821
        add     [ofs], 4096
824
        dec     ecx
822
        dec     ecx
825
        jz      .exit
823
        jz      .exit
826
        add     edi, 0x1000
824
        add     edi, 0x1000
827
        inc     edx
825
        inc     edx
828
        cmp     edx, 0x400
826
        cmp     edx, 0x400
829
        jnz     .map
827
        jnz     .map
830
        inc     ebx
828
        inc     ebx
831
        mov     eax, [ipc_pdir]
829
        mov     eax, [ipc_pdir]
832
        mov     eax, [eax+ebx*4]
830
        mov     eax, [eax+ebx*4]
833
        and     eax, 0xFFFFF000
831
        and     eax, 0xFFFFF000
834
        jz      .exit
832
        jz      .exit
835
        stdcall map_page, esi, eax, PG_UW
833
        stdcall map_page, esi, eax, PG_UW
836
        xor     edx, edx
834
        xor     edx, edx
837
        jmp     .map
835
        jmp     .map
838
 
836
 
839
.exit:
837
.exit:
840
        pop     eax
838
        pop     eax
841
        ret
839
        ret
842
endp
840
endp
843
 
841
 
844
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
842
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
845
                        ofs:dword,buf_size:dword,req_access:dword
843
                        ofs:dword,buf_size:dword,req_access:dword
846
        push    0 ; initialize number of mapped bytes
844
        push    0 ; initialize number of mapped bytes
847
 
845
 
848
        cmp     [buf_size], 0
846
        cmp     [buf_size], 0
849
        jz      .exit
847
        jz      .exit
850
 
848
 
851
        mov     eax, [slot]
849
        mov     eax, [slot]
852
        shl     eax, 8
850
        shl     eax, 8
853
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
851
        mov     eax, [SLOT_BASE+eax+APPDATA.dir_table]
854
        and     eax, 0xFFFFF000
852
        and     eax, 0xFFFFF000
855
 
853
 
856
        stdcall map_page, [proc_mem_pdir], eax, PG_UW
854
        stdcall map_page, [proc_mem_pdir], eax, PG_UW
857
        mov     ebx, [ofs]
855
        mov     ebx, [ofs]
858
        shr     ebx, 22
856
        shr     ebx, 22
859
        mov     esi, [proc_mem_pdir]
857
        mov     esi, [proc_mem_pdir]
860
        mov     edi, [proc_mem_tab]
858
        mov     edi, [proc_mem_tab]
861
        mov     eax, [esi+ebx*4]
859
        mov     eax, [esi+ebx*4]
862
        and     eax, 0xFFFFF000
860
        and     eax, 0xFFFFF000
863
        test    eax, eax
861
        test    eax, eax
864
        jz      .exit
862
        jz      .exit
865
        stdcall map_page, edi, eax, PG_UW
863
        stdcall map_page, edi, eax, PG_UW
866
 
864
 
867
@@:
865
@@:
868
        mov     edi, [lin_addr]
866
        mov     edi, [lin_addr]
869
        and     edi, 0xFFFFF000
867
        and     edi, 0xFFFFF000
870
        mov     ecx, [buf_size]
868
        mov     ecx, [buf_size]
871
        add     ecx, 4095
869
        add     ecx, 4095
872
        shr     ecx, 12
870
        shr     ecx, 12
873
        inc     ecx
871
        inc     ecx
874
 
872
 
875
        mov     edx, [ofs]
873
        mov     edx, [ofs]
876
        shr     edx, 12
874
        shr     edx, 12
877
        and     edx, 0x3FF
875
        and     edx, 0x3FF
878
        mov     esi, [proc_mem_tab]
876
        mov     esi, [proc_mem_tab]
879
 
877
 
880
.map:
878
.map:
881
        stdcall safe_map_page, [slot], [req_access], [ofs]
879
        stdcall safe_map_page, [slot], [req_access], [ofs]
882
        jnc     .exit
880
        jnc     .exit
883
        add     dword [ebp-4], 0x1000
881
        add     dword [ebp-4], 0x1000
884
        add     edi, 0x1000
882
        add     edi, 0x1000
885
        add     [ofs], 0x1000
883
        add     [ofs], 0x1000
886
        inc     edx
884
        inc     edx
887
        dec     ecx
885
        dec     ecx
888
        jnz     .map
886
        jnz     .map
889
.exit:
887
.exit:
890
        pop     eax
888
        pop     eax
891
        ret
889
        ret
892
endp
890
endp
893
 
891
 
894
; in: esi+edx*4 = pointer to page table entry
892
; in: esi+edx*4 = pointer to page table entry
895
; in: [slot], [req_access], [ofs] on the stack
893
; in: [slot], [req_access], [ofs] on the stack
896
; in: edi = linear address to map
894
; in: edi = linear address to map
897
; out: CF cleared <=> failed
895
; out: CF cleared <=> failed
898
; destroys: only eax
896
; destroys: only eax
899
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
897
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
900
        mov     eax, [esi+edx*4]
898
        mov     eax, [esi+edx*4]
901
        test    al, PG_MAP
899
        test    al, PG_MAP
902
        jz      .not_present
900
        jz      .not_present
903
        test    al, PG_WRITE
901
        test    al, PG_WRITE
904
        jz      .resolve_readonly
902
        jz      .resolve_readonly
905
; normal case: writable page, just map with requested access
903
; normal case: writable page, just map with requested access
906
.map:
904
.map:
907
        stdcall map_page, edi, eax, [req_access]
905
        stdcall map_page, edi, eax, [req_access]
908
        stc
906
        stc
909
.fail:
907
.fail:
910
        ret
908
        ret
911
.not_present:
909
.not_present:
912
; check for alloc-on-demand page
910
; check for alloc-on-demand page
913
        test    al, 2
911
        test    al, 2
914
        jz      .fail
912
        jz      .fail
915
; allocate new page, save it to source page table
913
; allocate new page, save it to source page table
916
        push    ecx
914
        push    ecx
917
        call    alloc_page
915
        call    alloc_page
918
        pop     ecx
916
        pop     ecx
919
        test    eax, eax
917
        test    eax, eax
920
        jz      .fail
918
        jz      .fail
921
        or      al, PG_UW
919
        or      al, PG_UW
922
        mov     [esi+edx*4], eax
920
        mov     [esi+edx*4], eax
923
        jmp     .map
921
        jmp     .map
924
.resolve_readonly:
922
.resolve_readonly:
925
; readonly page, probably copy-on-write
923
; readonly page, probably copy-on-write
926
; check: readonly request of readonly page is ok
924
; check: readonly request of readonly page is ok
927
        test    [req_access], PG_WRITE
925
        test    [req_access], PG_WRITE
928
        jz      .map
926
        jz      .map
929
; find control structure for this page
927
; find control structure for this page
930
        pushf
928
        pushf
931
        cli
929
        cli
932
        cld
930
        cld
933
        push    ebx ecx
931
        push    ebx ecx
934
        mov     eax, [slot]
932
        mov     eax, [slot]
935
        shl     eax, 8
933
        shl     eax, 8
936
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
934
        mov     eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
937
        test    eax, eax
935
        test    eax, eax
938
        jz      .no_hdll
936
        jz      .no_hdll
939
        mov     ecx, [eax+HDLL.fd]
937
        mov     ecx, [eax+HDLL.fd]
940
.scan_hdll:
938
.scan_hdll:
941
        cmp     ecx, eax
939
        cmp     ecx, eax
942
        jz      .no_hdll
940
        jz      .no_hdll
943
        mov     ebx, [ofs]
941
        mov     ebx, [ofs]
944
        and     ebx, not 0xFFF
942
        and     ebx, not 0xFFF
945
        sub     ebx, [ecx+HDLL.base]
943
        sub     ebx, [ecx+HDLL.base]
946
        cmp     ebx, [ecx+HDLL.size]
944
        cmp     ebx, [ecx+HDLL.size]
947
        jb      .hdll_found
945
        jb      .hdll_found
948
        mov     ecx, [ecx+HDLL.fd]
946
        mov     ecx, [ecx+HDLL.fd]
949
        jmp     .scan_hdll
947
        jmp     .scan_hdll
950
.no_hdll:
948
.no_hdll:
951
        pop     ecx ebx
949
        pop     ecx ebx
952
        popf
950
        popf
953
        clc
951
        clc
954
        ret
952
        ret
955
.hdll_found:
953
.hdll_found:
956
; allocate page, save it in page table, map it, copy contents from base
954
; allocate page, save it in page table, map it, copy contents from base
957
        mov     eax, [ecx+HDLL.parent]
955
        mov     eax, [ecx+HDLL.parent]
958
        add     ebx, [eax+DLLDESCR.data]
956
        add     ebx, [eax+DLLDESCR.data]
959
        call    alloc_page
957
        call    alloc_page
960
        test    eax, eax
958
        test    eax, eax
961
        jz      .no_hdll
959
        jz      .no_hdll
962
        or      al, PG_UW
960
        or      al, PG_UW
963
        mov     [esi+edx*4], eax
961
        mov     [esi+edx*4], eax
964
        stdcall map_page, edi, eax, [req_access]
962
        stdcall map_page, edi, eax, [req_access]
965
        push    esi edi
963
        push    esi edi
966
        mov     esi, ebx
964
        mov     esi, ebx
967
        mov     ecx, 4096/4
965
        mov     ecx, 4096/4
968
        rep movsd
966
        rep movsd
969
        pop     edi esi
967
        pop     edi esi
970
        pop     ecx ebx
968
        pop     ecx ebx
971
        popf
969
        popf
972
        stc
970
        stc
973
        ret
971
        ret
974
endp
972
endp
975
 
973
 
976
sys_IPC:
974
sys_IPC:
977
;input:
975
;input:
978
;  ebx=1 - set ipc buffer area
976
;  ebx=1 - set ipc buffer area
979
;    ecx=address of buffer
977
;    ecx=address of buffer
980
;    edx=size of buffer
978
;    edx=size of buffer
981
;  eax=2 - send message
979
;  eax=2 - send message
982
;    ebx=PID
980
;    ebx=PID
983
;    ecx=address of message
981
;    ecx=address of message
984
;    edx=size of message
982
;    edx=size of message
985
 
983
 
986
        dec     ebx
984
        dec     ebx
987
        jnz     @f
985
        jnz     @f
988
 
986
 
989
        mov     eax, [current_slot]
987
        mov     eax, [current_slot]
990
        pushf
988
        pushf
991
        cli
989
        cli
992
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
990
        mov     [eax+APPDATA.ipc_start], ecx    ;set fields in extended information area
993
        mov     [eax+APPDATA.ipc_size], edx
991
        mov     [eax+APPDATA.ipc_size], edx
994
 
992
 
995
        add     edx, ecx
993
        add     edx, ecx
996
        add     edx, 4095
994
        add     edx, 4095
997
        and     edx, not 4095
995
        and     edx, not 4095
998
 
996
 
999
.touch:
997
.touch:
1000
        mov     eax, [ecx]
998
        mov     eax, [ecx]
1001
        add     ecx, 0x1000
999
        add     ecx, 0x1000
1002
        cmp     ecx, edx
1000
        cmp     ecx, edx
1003
        jb      .touch
1001
        jb      .touch
1004
 
1002
 
1005
        popf
1003
        popf
1006
        mov     [esp+32], ebx   ;ebx=0
1004
        mov     [esp+32], ebx   ;ebx=0
1007
        ret
1005
        ret
1008
 
1006
 
1009
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1007
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1010
;2
1008
;2
1011
@@:
1009
@@:
1012
        dec     ebx
1010
        dec     ebx
1013
        jnz     @f
1011
        jnz     @f
1014
 
1012
 
1015
        stdcall sys_ipc_send, ecx, edx, esi
1013
        stdcall sys_ipc_send, ecx, edx, esi
1016
        mov     [esp+32], eax
1014
        mov     [esp+32], eax
1017
        ret
1015
        ret
1018
@@:
1016
@@:
1019
        or      eax, -1
1017
        or      eax, -1
1020
        mov     [esp+32], eax
1018
        mov     [esp+32], eax
1021
        ret
1019
        ret
1022
 
1020
 
1023
;align 4
1021
;align 4
1024
;proc set_ipc_buff
1022
;proc set_ipc_buff
1025
 
1023
 
1026
;           mov  eax,[current_slot]
1024
;           mov  eax,[current_slot]
1027
;           pushf
1025
;           pushf
1028
;           cli
1026
;           cli
1029
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
1027
;           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
1030
;           mov  [eax+APPDATA.ipc_size],ecx
1028
;           mov  [eax+APPDATA.ipc_size],ecx
1031
;
1029
;
1032
;           add ecx, ebx
1030
;           add ecx, ebx
1033
;           add ecx, 4095
1031
;           add ecx, 4095
1034
;           and ecx, not 4095
1032
;           and ecx, not 4095
1035
;
1033
;
1036
;.touch:    mov eax, [ebx]
1034
;.touch:    mov eax, [ebx]
1037
;           add ebx, 0x1000
1035
;           add ebx, 0x1000
1038
;           cmp ebx, ecx
1036
;           cmp ebx, ecx
1039
;           jb  .touch
1037
;           jb  .touch
1040
;
1038
;
1041
;           popf
1039
;           popf
1042
;           xor eax, eax
1040
;           xor eax, eax
1043
;           ret
1041
;           ret
1044
;endp
1042
;endp
1045
 
1043
 
1046
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1044
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1047
           locals
1045
           locals
1048
             dst_slot   dd ?
1046
             dst_slot   dd ?
1049
             dst_offset dd ?
1047
             dst_offset dd ?
1050
             buf_size   dd ?
1048
             buf_size   dd ?
1051
             used_buf   dd ?
1049
             used_buf   dd ?
1052
           endl
1050
           endl
1053
 
1051
 
1054
        pushf
1052
        pushf
1055
        cli
1053
        cli
1056
 
1054
 
1057
        mov     eax, [PID]
1055
        mov     eax, [PID]
1058
        call    pid_to_slot
1056
        call    pid_to_slot
1059
        test    eax, eax
1057
        test    eax, eax
1060
        jz      .no_pid
1058
        jz      .no_pid
1061
 
1059
 
1062
        mov     [dst_slot], eax
1060
        mov     [dst_slot], eax
1063
        shl     eax, 8
1061
        shl     eax, 8
1064
        mov     edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
1062
        mov     edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
1065
        test    edi, edi
1063
        test    edi, edi
1066
        jz      .no_ipc_area
1064
        jz      .no_ipc_area
1067
 
1065
 
1068
        mov     ebx, edi
1066
        mov     ebx, edi
1069
        and     ebx, 0xFFF
1067
        and     ebx, 0xFFF
1070
        mov     [dst_offset], ebx
1068
        mov     [dst_offset], ebx
1071
 
1069
 
1072
        mov     esi, [eax+SLOT_BASE+0xa4]
1070
        mov     esi, [eax+SLOT_BASE+0xa4]
1073
        mov     [buf_size], esi
1071
        mov     [buf_size], esi
1074
 
1072
 
1075
        mov     ecx, [ipc_tmp]
1073
        mov     ecx, [ipc_tmp]
1076
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1074
        cmp     esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
1077
        jbe     @f
1075
        jbe     @f
1078
        push    esi edi
1076
        push    esi edi
1079
        add     esi, 0x1000
1077
        add     esi, 0x1000
1080
        stdcall alloc_kernel_space, esi
1078
        stdcall alloc_kernel_space, esi
1081
        mov     ecx, eax
1079
        mov     ecx, eax
1082
        pop     edi esi
1080
        pop     edi esi
1083
@@:
1081
@@:
1084
        mov     [used_buf], ecx
1082
        mov     [used_buf], ecx
1085
        stdcall map_mem, ecx, [dst_slot], \
1083
        stdcall map_mem, ecx, [dst_slot], \
1086
                edi, esi, PG_SW
1084
                edi, esi, PG_SW
1087
 
1085
 
1088
        mov     edi, [dst_offset]
1086
        mov     edi, [dst_offset]
1089
        add     edi, [used_buf]
1087
        add     edi, [used_buf]
1090
        cmp     dword [edi], 0
1088
        cmp     dword [edi], 0
1091
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
1089
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
1092
 
1090
 
1093
        mov     edx, dword [edi+4]
1091
        mov     edx, dword [edi+4]
1094
        lea     ebx, [edx+8]
1092
        lea     ebx, [edx+8]
1095
        add     ebx, [msg_size]
1093
        add     ebx, [msg_size]
1096
        cmp     ebx, [buf_size]
1094
        cmp     ebx, [buf_size]
1097
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
1095
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
1098
 
1096
 
1099
        mov     dword [edi+4], ebx
1097
        mov     dword [edi+4], ebx
1100
        mov     eax, [TASK_BASE]
1098
        mov     eax, [TASK_BASE]
1101
        mov     eax, [eax+0x04]        ;eax - our PID
1099
        mov     eax, [eax+0x04]        ;eax - our PID
1102
        add     edi, edx
1100
        add     edi, edx
1103
        mov     [edi], eax
1101
        mov     [edi], eax
1104
        mov     ecx, [msg_size]
1102
        mov     ecx, [msg_size]
1105
 
1103
 
1106
        mov     [edi+4], ecx
1104
        mov     [edi+4], ecx
1107
        add     edi, 8
1105
        add     edi, 8
1108
        mov     esi, [msg_addr]
1106
        mov     esi, [msg_addr]
1109
       ;    add esi, new_app_base
1107
       ;    add esi, new_app_base
1110
        cld
1108
        cld
1111
        rep movsb
1109
        rep movsb
1112
 
1110
 
1113
        mov     ebx, [ipc_tmp]
1111
        mov     ebx, [ipc_tmp]
1114
        mov     edx, ebx
1112
        mov     edx, ebx
1115
        shr     ebx, 12
1113
        shr     ebx, 12
1116
        xor     eax, eax
1114
        xor     eax, eax
1117
        mov     [page_tabs+ebx*4], eax
1115
        mov     [page_tabs+ebx*4], eax
1118
        invlpg  [edx]
1116
        invlpg  [edx]
1119
 
1117
 
1120
        mov     ebx, [ipc_pdir]
1118
        mov     ebx, [ipc_pdir]
1121
        mov     edx, ebx
1119
        mov     edx, ebx
1122
        shr     ebx, 12
1120
        shr     ebx, 12
1123
        xor     eax, eax
1121
        xor     eax, eax
1124
        mov     [page_tabs+ebx*4], eax
1122
        mov     [page_tabs+ebx*4], eax
1125
        invlpg  [edx]
1123
        invlpg  [edx]
1126
 
1124
 
1127
        mov     ebx, [ipc_ptab]
1125
        mov     ebx, [ipc_ptab]
1128
        mov     edx, ebx
1126
        mov     edx, ebx
1129
        shr     ebx, 12
1127
        shr     ebx, 12
1130
        xor     eax, eax
1128
        xor     eax, eax
1131
        mov     [page_tabs+ebx*4], eax
1129
        mov     [page_tabs+ebx*4], eax
1132
        invlpg  [edx]
1130
        invlpg  [edx]
1133
 
1131
 
1134
        mov     eax, [dst_slot]
1132
        mov     eax, [dst_slot]
1135
        shl     eax, 8
1133
        shl     eax, 8
1136
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1134
        or      [eax+SLOT_BASE+0xA8], dword 0x40
1137
        cmp     dword [check_idle_semaphore], 20
1135
        cmp     dword [check_idle_semaphore], 20
1138
        jge     .ipc_no_cis
1136
        jge     .ipc_no_cis
1139
 
1137
 
1140
        mov     dword [check_idle_semaphore], 5
1138
        mov     dword [check_idle_semaphore], 5
1141
.ipc_no_cis:
1139
.ipc_no_cis:
1142
        push    0
1140
        push    0
1143
        jmp     .ret
1141
        jmp     .ret
1144
.no_pid:
1142
.no_pid:
1145
        popf
1143
        popf
1146
        mov     eax, 4
1144
        mov     eax, 4
1147
        ret
1145
        ret
1148
.no_ipc_area:
1146
.no_ipc_area:
1149
        popf
1147
        popf
1150
        xor     eax, eax
1148
        xor     eax, eax
1151
        inc     eax
1149
        inc     eax
1152
        ret
1150
        ret
1153
.ipc_blocked:
1151
.ipc_blocked:
1154
        push    2
1152
        push    2
1155
        jmp     .ret
1153
        jmp     .ret
1156
.buffer_overflow:
1154
.buffer_overflow:
1157
        push    3
1155
        push    3
1158
.ret:
1156
.ret:
1159
        mov     eax, [used_buf]
1157
        mov     eax, [used_buf]
1160
        cmp     eax, [ipc_tmp]
1158
        cmp     eax, [ipc_tmp]
1161
        jz      @f
1159
        jz      @f
1162
        stdcall free_kernel_space, eax
1160
        stdcall free_kernel_space, eax
1163
@@:
1161
@@:
1164
        pop     eax
1162
        pop     eax
1165
        popf
1163
        popf
1166
        ret
1164
        ret
1167
endp
1165
endp
1168
 
1166
 
1169
align 4
1167
align 4
1170
sysfn_meminfo:
1168
sysfn_meminfo:
1171
 
1169
 
1172
        ;   add ecx, new_app_base
1170
        ;   add ecx, new_app_base
1173
        cmp     ecx, OS_BASE
1171
        cmp     ecx, OS_BASE
1174
        jae     .fail
1172
        jae     .fail
1175
 
1173
 
1176
        mov     eax, [pg_data.pages_count]
1174
        mov     eax, [pg_data.pages_count]
1177
        mov     [ecx], eax
1175
        mov     [ecx], eax
1178
        shl     eax, 12
1176
        shl     eax, 12
1179
        mov     [esp+32], eax
1177
        mov     [esp+32], eax
1180
        mov     eax, [pg_data.pages_free]
1178
        mov     eax, [pg_data.pages_free]
1181
        mov     [ecx+4], eax
1179
        mov     [ecx+4], eax
1182
        mov     eax, [pg_data.pages_faults]
1180
        mov     eax, [pg_data.pages_faults]
1183
        mov     [ecx+8], eax
1181
        mov     [ecx+8], eax
1184
        mov     eax, [heap_size]
1182
        mov     eax, [heap_size]
1185
        mov     [ecx+12], eax
1183
        mov     [ecx+12], eax
1186
        mov     eax, [heap_free]
1184
        mov     eax, [heap_free]
1187
        mov     [ecx+16], eax
1185
        mov     [ecx+16], eax
1188
        mov     eax, [heap_blocks]
1186
        mov     eax, [heap_blocks]
1189
        mov     [ecx+20], eax
1187
        mov     [ecx+20], eax
1190
        mov     eax, [free_blocks]
1188
        mov     eax, [free_blocks]
1191
        mov     [ecx+24], eax
1189
        mov     [ecx+24], eax
1192
        ret
1190
        ret
1193
.fail:
1191
.fail:
1194
        or      dword [esp+32], -1
1192
        or      dword [esp+32], -1
1195
        ret
1193
        ret
1196
 
1194
 
1197
align 4
1195
align 4
1198
f68:
1196
f68:
1199
        cmp     ebx, 4
1197
        cmp     ebx, 4
1200
        jbe     sys_sheduler
1198
        jbe     sys_sheduler
1201
 
1199
 
1202
        cmp     ebx, 11
1200
        cmp     ebx, 11
1203
        jb      .fail
1201
        jb      .fail
1204
 
1202
 
1205
        cmp     ebx, 25
1203
        cmp     ebx, 25
1206
        ja      .fail
1204
        ja      .fail
1207
 
1205
 
1208
        jmp     dword [f68call+ebx*4-11*4]
1206
        jmp     dword [f68call+ebx*4-11*4]
1209
.11:
1207
.11:
1210
        call    init_heap
1208
        call    init_heap
1211
        mov     [esp+32], eax
1209
        mov     [esp+32], eax
1212
        ret
1210
        ret
1213
.12:
1211
.12:
1214
        stdcall user_alloc, ecx
1212
        stdcall user_alloc, ecx
1215
        mov     [esp+32], eax
1213
        mov     [esp+32], eax
1216
        ret
1214
        ret
1217
.13:
1215
.13:
1218
        stdcall user_free, ecx
1216
        stdcall user_free, ecx
1219
        mov     [esp+32], eax
1217
        mov     [esp+32], eax
1220
        ret
1218
        ret
1221
.14:
1219
.14:
1222
        cmp     ecx, OS_BASE
1220
        cmp     ecx, OS_BASE
1223
        jae     .fail
1221
        jae     .fail
1224
        mov     edi, ecx
1222
        mov     edi, ecx
1225
        call    get_event_ex
1223
        call    get_event_ex
1226
        mov     [esp+32], eax
1224
        mov     [esp+32], eax
1227
        ret
1225
        ret
1228
.16:
1226
.16:
1229
        test    ecx, ecx
1227
        test    ecx, ecx
1230
        jz      .fail
1228
        jz      .fail
1231
        cmp     ecx, OS_BASE
1229
        cmp     ecx, OS_BASE
1232
        jae     .fail
1230
        jae     .fail
1233
        stdcall get_service, ecx
1231
        stdcall get_service, ecx
1234
        mov     [esp+32], eax
1232
        mov     [esp+32], eax
1235
        ret
1233
        ret
1236
.17:
1234
.17:
1237
        call    srv_handlerEx   ;ecx
1235
        call    srv_handlerEx   ;ecx
1238
        mov     [esp+32], eax
1236
        mov     [esp+32], eax
1239
        ret
1237
        ret
1240
.19:
1238
.19:
1241
        cmp     ecx, OS_BASE
1239
        cmp     ecx, OS_BASE
1242
        jae     .fail
1240
        jae     .fail
1243
        stdcall load_library, ecx
1241
        stdcall load_library, ecx
1244
        mov     [esp+32], eax
1242
        mov     [esp+32], eax
1245
        ret
1243
        ret
1246
.20:
1244
.20:
1247
        mov     eax, edx
1245
        mov     eax, edx
1248
        mov     ebx, ecx
1246
        mov     ebx, ecx
1249
        call    user_realloc            ;in: eax = pointer, ebx = new size
1247
        call    user_realloc            ;in: eax = pointer, ebx = new size
1250
        mov     [esp+32], eax
1248
        mov     [esp+32], eax
1251
        ret
1249
        ret
1252
.21:
1250
.21:
1253
        cmp     ecx, OS_BASE
1251
        cmp     ecx, OS_BASE
1254
        jae     .fail
1252
        jae     .fail
1255
 
1253
 
1256
        cmp     ebx, OS_BASE
1254
        cmp     edx, OS_BASE
1257
        jae     .fail
1255
        jae     .fail
1258
 
1256
 
1259
        mov     edi, edx
1257
        mov     edi, edx
1260
        stdcall load_PE, ecx
1258
        stdcall load_PE, ecx
1261
        mov     esi, eax
1259
        mov     esi, eax
1262
        test    eax, eax
1260
        test    eax, eax
1263
        jz      @F
1261
        jz      @F
1264
 
1262
 
1265
        push    edi
1263
        push    edi
1266
        push    DRV_ENTRY
1264
        push    DRV_ENTRY
1267
        call    eax
1265
        call    eax
1268
        add     esp, 8
1266
        add     esp, 8
1269
        test    eax, eax
1267
        test    eax, eax
1270
        jz      @F
1268
        jz      @F
1271
 
1269
 
1272
        mov     [eax+SRV.entry], esi
1270
        mov     [eax+SRV.entry], esi
1273
 
1271
 
1274
@@:
1272
@@:
1275
        mov     [esp+32], eax
1273
        mov     [esp+32], eax
1276
        ret
1274
        ret
1277
.22:
1275
.22:
1278
        cmp     ecx, OS_BASE
1276
        cmp     ecx, OS_BASE
1279
        jae     .fail
1277
        jae     .fail
1280
 
1278
 
1281
        stdcall shmem_open, ecx, edx, esi
1279
        stdcall shmem_open, ecx, edx, esi
1282
        mov     [esp+24], edx
1280
        mov     [esp+24], edx
1283
        mov     [esp+32], eax
1281
        mov     [esp+32], eax
1284
        ret
1282
        ret
1285
 
1283
 
1286
.23:
1284
.23:
1287
        cmp     ecx, OS_BASE
1285
        cmp     ecx, OS_BASE
1288
        jae     .fail
1286
        jae     .fail
1289
 
1287
 
1290
        stdcall shmem_close, ecx
1288
        stdcall shmem_close, ecx
1291
        mov     [esp+32], eax
1289
        mov     [esp+32], eax
1292
        ret
1290
        ret
1293
.24:
1291
.24:
1294
        mov     eax, [current_slot]
1292
        mov     eax, [current_slot]
1295
        xchg    ecx, [eax+APPDATA.exc_handler]
1293
        xchg    ecx, [eax+APPDATA.exc_handler]
1296
        xchg    edx, [eax+APPDATA.except_mask]
1294
        xchg    edx, [eax+APPDATA.except_mask]
1297
        mov     [esp+32], ecx ; reg_eax+8
1295
        mov     [esp+32], ecx ; reg_eax+8
1298
        mov     [esp+20], edx ; reg_ebx+8
1296
        mov     [esp+20], edx ; reg_ebx+8
1299
        ret
1297
        ret
1300
.25:
1298
.25:
1301
        cmp     ecx, 32
1299
        cmp     ecx, 32
1302
        jae     .fail
1300
        jae     .fail
1303
        mov     eax, [current_slot]
1301
        mov     eax, [current_slot]
1304
        btr     [eax+APPDATA.except_mask], ecx
1302
        btr     [eax+APPDATA.except_mask], ecx
1305
        setc    byte[esp+32]
1303
        setc    byte[esp+32]
1306
        jecxz   @f
1304
        jecxz   @f
1307
        bts     [eax+APPDATA.except_mask], ecx
1305
        bts     [eax+APPDATA.except_mask], ecx
1308
@@:
1306
@@:
1309
        ret
1307
        ret
1310
 
1308
 
1311
.26:
1309
.26:
1312
        stdcall user_unmap, ecx, edx, esi
1310
        stdcall user_unmap, ecx, edx, esi
1313
        mov     [esp+32], eax
1311
        mov     [esp+32], eax
1314
        ret
1312
        ret
1315
 
1313
 
1316
.fail:
1314
.fail:
1317
        xor     eax, eax
1315
        xor     eax, eax
1318
        mov     [esp+32], eax
1316
        mov     [esp+32], eax
1319
        ret
1317
        ret
1320
 
1318
 
1321
 
1319
 
1322
align 4
1320
align 4
1323
f68call:   ; keep this table closer to main code
1321
f68call:   ; keep this table closer to main code
1324
 
1322
 
1325
           dd f68.11   ; init_heap
1323
           dd f68.11   ; init_heap
1326
           dd f68.12   ; user_alloc
1324
           dd f68.12   ; user_alloc
1327
           dd f68.13   ; user_free
1325
           dd f68.13   ; user_free
1328
           dd f68.14   ; get_event_ex
1326
           dd f68.14   ; get_event_ex
1329
           dd f68.fail ; moved to f68.24
1327
           dd f68.fail ; moved to f68.24
1330
           dd f68.16   ; get_service
1328
           dd f68.16   ; get_service
1331
           dd f68.17   ; call_service
1329
           dd f68.17   ; call_service
1332
           dd f68.fail ; moved to f68.25
1330
           dd f68.fail ; moved to f68.25
1333
           dd f68.19   ; load_dll
1331
           dd f68.19   ; load_dll
1334
           dd f68.20   ; user_realloc
1332
           dd f68.20   ; user_realloc
1335
           dd f68.21   ; load_driver
1333
           dd f68.21   ; load_driver
1336
           dd f68.22   ; shmem_open
1334
           dd f68.22   ; shmem_open
1337
           dd f68.23   ; shmem_close
1335
           dd f68.23   ; shmem_close
1338
           dd f68.24   ; set exception handler
1336
           dd f68.24   ; set exception handler
1339
           dd f68.25   ; unmask exception
1337
           dd f68.25   ; unmask exception
1340
           dd f68.26   ; user_unmap
1338
           dd f68.26   ; user_unmap
1341
 
1339
 
1342
 
1340
 
1343
align 4
1341
align 4
1344
proc load_pe_driver stdcall, file:dword
1342
proc load_pe_driver stdcall, file:dword
1345
 
1343
 
1346
        stdcall load_PE, [file]
1344
        stdcall load_PE, [file]
1347
        test    eax, eax
1345
        test    eax, eax
1348
        jz      .fail
1346
        jz      .fail
1349
 
1347
 
1350
        mov     esi, eax
1348
        mov     esi, eax
1351
        stdcall eax, DRV_ENTRY
1349
        stdcall eax, DRV_ENTRY
1352
        test    eax, eax
1350
        test    eax, eax
1353
        jz      .fail
1351
        jz      .fail
1354
 
1352
 
1355
        mov     [eax+SRV.entry], esi
1353
        mov     [eax+SRV.entry], esi
1356
        ret
1354
        ret
1357
 
1355
 
1358
.fail:
1356
.fail:
1359
        xor     eax, eax
1357
        xor     eax, eax
1360
        ret
1358
        ret
1361
endp
1359
endp
1362
 
1360
 
1363
 
1361
 
1364
align 4
1362
align 4
1365
proc init_mtrr
1363
proc init_mtrr
1366
 
1364
 
1367
        cmp     [BOOT_VAR+BOOT_MTRR], byte 2
1365
        cmp     [BOOT_VAR+BOOT_MTRR], byte 2
1368
        je      .exit
1366
        je      .exit
1369
 
1367
 
1370
        bt      [cpu_caps], CAPS_MTRR
1368
        bt      [cpu_caps], CAPS_MTRR
1371
        jnc     .exit
1369
        jnc     .exit
1372
 
1370
 
1373
        mov     eax, cr0
1371
        mov     eax, cr0
1374
        or      eax, 0x60000000 ;disable caching
1372
        or      eax, 0x60000000 ;disable caching
1375
        mov     cr0, eax
1373
        mov     cr0, eax
1376
        wbinvd                  ;invalidate cache
1374
        wbinvd                  ;invalidate cache
1377
 
1375
 
1378
        mov     ecx, 0x2FF
1376
        mov     ecx, 0x2FF
1379
        rdmsr                   ;
1377
        rdmsr                   ;
1380
; has BIOS already initialized MTRRs?
1378
; has BIOS already initialized MTRRs?
1381
        test    ah, 8
1379
        test    ah, 8
1382
        jnz     .skip_init
1380
        jnz     .skip_init
1383
; rarely needed, so mainly placeholder
1381
; rarely needed, so mainly placeholder
1384
; main memory - cached
1382
; main memory - cached
1385
        push    eax
1383
        push    eax
1386
 
1384
 
1387
        mov     eax, [MEM_AMOUNT]
1385
        mov     eax, [MEM_AMOUNT]
1388
; round eax up to next power of 2
1386
; round eax up to next power of 2
1389
        dec     eax
1387
        dec     eax
1390
        bsr     ecx, eax
1388
        bsr     ecx, eax
1391
        mov     ebx, 2
1389
        mov     ebx, 2
1392
        shl     ebx, cl
1390
        shl     ebx, cl
1393
        dec     ebx
1391
        dec     ebx
1394
; base of memory range = 0, type of memory range = MEM_WB
1392
; base of memory range = 0, type of memory range = MEM_WB
1395
        xor     edx, edx
1393
        xor     edx, edx
1396
        mov     eax, MEM_WB
1394
        mov     eax, MEM_WB
1397
        mov     ecx, 0x200
1395
        mov     ecx, 0x200
1398
        wrmsr
1396
        wrmsr
1399
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1397
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
1400
        mov     eax, 0xFFFFFFFF
1398
        mov     eax, 0xFFFFFFFF
1401
        mov     edx, 0x0000000F
1399
        mov     edx, 0x0000000F
1402
        sub     eax, ebx
1400
        sub     eax, ebx
1403
        sbb     edx, 0
1401
        sbb     edx, 0
1404
        or      eax, 0x800
1402
        or      eax, 0x800
1405
        inc     ecx
1403
        inc     ecx
1406
        wrmsr
1404
        wrmsr
1407
; clear unused MTRRs
1405
; clear unused MTRRs
1408
        xor     eax, eax
1406
        xor     eax, eax
1409
        xor     edx, edx
1407
        xor     edx, edx
1410
@@:
1408
@@:
1411
        wrmsr
1409
        wrmsr
1412
        inc     ecx
1410
        inc     ecx
1413
        cmp     ecx, 0x210
1411
        cmp     ecx, 0x210
1414
        jb      @b
1412
        jb      @b
1415
; enable MTRRs
1413
; enable MTRRs
1416
        pop     eax
1414
        pop     eax
1417
        or      ah, 8
1415
        or      ah, 8
1418
        and     al, 0xF0; default memtype = UC
1416
        and     al, 0xF0; default memtype = UC
1419
        mov     ecx, 0x2FF
1417
        mov     ecx, 0x2FF
1420
        wrmsr
1418
        wrmsr
1421
.skip_init:
1419
.skip_init:
1422
        stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
1420
        stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
1423
 
1421
 
1424
        wbinvd                  ;again invalidate
1422
        wbinvd                  ;again invalidate
1425
 
1423
 
1426
        mov     eax, cr0
1424
        mov     eax, cr0
1427
        and     eax, not 0x60000000
1425
        and     eax, not 0x60000000
1428
        mov     cr0, eax        ; enable caching
1426
        mov     cr0, eax        ; enable caching
1429
.exit:
1427
.exit:
1430
        ret
1428
        ret
1431
endp
1429
endp
1432
 
1430
 
1433
align 4
1431
align 4
1434
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1432
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
1435
; find unused register
1433
; find unused register
1436
        mov     ecx, 0x201
1434
        mov     ecx, 0x201
1437
@@:
1435
@@:
1438
        rdmsr
1436
        rdmsr
1439
        dec     ecx
1437
        dec     ecx
1440
        test    ah, 8
1438
        test    ah, 8
1441
        jz      .found
1439
        jz      .found
1442
        rdmsr
1440
        rdmsr
1443
        mov     al, 0; clear memory type field
1441
        mov     al, 0; clear memory type field
1444
        cmp     eax, [base]
1442
        cmp     eax, [base]
1445
        jz      .ret
1443
        jz      .ret
1446
        add     ecx, 3
1444
        add     ecx, 3
1447
        cmp     ecx, 0x210
1445
        cmp     ecx, 0x210
1448
        jb      @b
1446
        jb      @b
1449
; no free registers, ignore the call
1447
; no free registers, ignore the call
1450
.ret:
1448
.ret:
1451
        ret
1449
        ret
1452
.found:
1450
.found:
1453
; found, write values
1451
; found, write values
1454
        xor     edx, edx
1452
        xor     edx, edx
1455
        mov     eax, [base]
1453
        mov     eax, [base]
1456
        or      eax, [mem_type]
1454
        or      eax, [mem_type]
1457
        wrmsr
1455
        wrmsr
1458
 
1456
 
1459
        mov     ebx, [size]
1457
        mov     ebx, [size]
1460
        dec     ebx
1458
        dec     ebx
1461
        mov     eax, 0xFFFFFFFF
1459
        mov     eax, 0xFFFFFFFF
1462
        mov     edx, 0x00000000
1460
        mov     edx, 0x0000000F
1463
        sub     eax, ebx
1461
        sub     eax, ebx
1464
        sbb     edx, 0
1462
        sbb     edx, 0
1465
        or      eax, 0x800
1463
        or      eax, 0x800
1466
        inc     ecx
1464
        inc     ecx
1467
        wrmsr
1465
        wrmsr
1468
        ret
1466
        ret
1469
endp
1467
endp
1470
 
1468
 
1471
align 4
1469
align 4
1472
proc stall stdcall, delay:dword
1470
proc stall stdcall, delay:dword
1473
        push    ecx
1471
        push    ecx
1474
        push    edx
1472
        push    edx
1475
        push    ebx
1473
        push    ebx
1476
        push    eax
1474
        push    eax
1477
 
1475
 
1478
        mov     eax, [delay]
1476
        mov     eax, [delay]
1479
        mul     [stall_mcs]
1477
        mul     [stall_mcs]
1480
        mov     ebx, eax      ;low
1478
        mov     ebx, eax      ;low
1481
        mov     ecx, edx      ;high
1479
        mov     ecx, edx      ;high
1482
        rdtsc
1480
        rdtsc
1483
        add     ebx, eax
1481
        add     ebx, eax
1484
        adc     ecx, edx
1482
        adc     ecx, edx
1485
@@:
1483
@@:
1486
        rdtsc
1484
        rdtsc
1487
        sub     eax, ebx
1485
        sub     eax, ebx
1488
        sbb     edx, ecx
1486
        sbb     edx, ecx
1489
        jb      @B
1487
        jb      @B
1490
 
1488
 
1491
        pop     eax
1489
        pop     eax
1492
        pop     ebx
1490
        pop     ebx
1493
        pop     edx
1491
        pop     edx
1494
        pop     ecx
1492
        pop     ecx
1495
        ret
1493
        ret
1496
endp
1494
endp
1497
 
1495
 
1498
align 4
1496
align 4
1499
proc create_ring_buffer stdcall, size:dword, flags:dword
1497
proc create_ring_buffer stdcall, size:dword, flags:dword
1500
           locals
1498
           locals
1501
             buf_ptr  dd ?
1499
             buf_ptr  dd ?
1502
           endl
1500
           endl
1503
 
1501
 
1504
        mov     eax, [size]
1502
        mov     eax, [size]
1505
        test    eax, eax
1503
        test    eax, eax
1506
        jz      .fail
1504
        jz      .fail
1507
 
1505
 
1508
        add     eax, eax
1506
        add     eax, eax
1509
        stdcall alloc_kernel_space, eax
1507
        stdcall alloc_kernel_space, eax
1510
        test    eax, eax
1508
        test    eax, eax
1511
        jz      .fail
1509
        jz      .fail
1512
 
1510
 
1513
        push    ebx
1511
        push    ebx
1514
 
1512
 
1515
        mov     [buf_ptr], eax
1513
        mov     [buf_ptr], eax
1516
 
1514
 
1517
        mov     ebx, [size]
1515
        mov     ebx, [size]
1518
        shr     ebx, 12
1516
        shr     ebx, 12
1519
        push    ebx
1517
        push    ebx
1520
 
1518
 
1521
        stdcall alloc_pages, ebx
1519
        stdcall alloc_pages, ebx
1522
        pop     ecx
1520
        pop     ecx
1523
 
1521
 
1524
        test    eax, eax
1522
        test    eax, eax
1525
        jz      .mm_fail
1523
        jz      .mm_fail
1526
 
1524
 
1527
        push    edi
1525
        push    edi
1528
 
1526
 
1529
        or      eax, [flags]
1527
        or      eax, [flags]
1530
        mov     edi, [buf_ptr]
1528
        mov     edi, [buf_ptr]
1531
        mov     ebx, [buf_ptr]
1529
        mov     ebx, [buf_ptr]
1532
        mov     edx, ecx
1530
        mov     edx, ecx
1533
        shl     edx, 2
1531
        shl     edx, 2
1534
        shr     edi, 10
1532
        shr     edi, 10
1535
@@:
1533
@@:
1536
        mov     [page_tabs+edi], eax
1534
        mov     [page_tabs+edi], eax
1537
        mov     [page_tabs+edi+edx], eax
1535
        mov     [page_tabs+edi+edx], eax
1538
        invlpg  [ebx]
1536
        invlpg  [ebx]
1539
        invlpg  [ebx+0x10000]
1537
        invlpg  [ebx+0x10000]
1540
        add     eax, 0x1000
1538
        add     eax, 0x1000
1541
        add     ebx, 0x1000
1539
        add     ebx, 0x1000
1542
        add     edi, 4
1540
        add     edi, 4
1543
        dec     ecx
1541
        dec     ecx
1544
        jnz     @B
1542
        jnz     @B
1545
 
1543
 
1546
        mov     eax, [buf_ptr]
1544
        mov     eax, [buf_ptr]
1547
        pop     edi
1545
        pop     edi
1548
        pop     ebx
1546
        pop     ebx
1549
        ret
1547
        ret
1550
.mm_fail:
1548
.mm_fail:
1551
        stdcall free_kernel_space, [buf_ptr]
1549
        stdcall free_kernel_space, [buf_ptr]
1552
        xor     eax, eax
1550
        xor     eax, eax
1553
        pop     ebx
1551
        pop     ebx
1554
.fail:
1552
.fail:
1555
        ret
1553
        ret
1556
endp
1554
endp
1557
 
1555
 
1558
 
1556
 
1559
align 4
1557
align 4
1560
proc print_mem
1558
proc print_mem
1561
        mov     edi, BOOT_VAR + 0x9104
1559
        mov     edi, BOOT_VAR + 0x9104
1562
        mov     ecx, [edi-4]
1560
        mov     ecx, [edi-4]
1563
        test    ecx, ecx
1561
        test    ecx, ecx
1564
        jz     .done
1562
        jz     .done
1565
 
1563
 
1566
@@:
1564
@@:
1567
        mov eax, [edi]
1565
        mov eax, [edi]
1568
        mov edx, [edi+4]
1566
        mov edx, [edi+4]
1569
        add eax, [edi+8]
1567
        add eax, [edi+8]
1570
        adc edx, [edi+12]
1568
        adc edx, [edi+12]
1571
 
1569
 
1572
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1570
        DEBUGF  1, "K : E820 %x%x - %x%x type %d\n", \
1573
                    [edi+4], [edi],\
1571
                    [edi+4], [edi],\
1574
                    edx, eax, [edi+16]
1572
                    edx, eax, [edi+16]
1575
        add     edi, 20
1573
        add     edi, 20
1576
        dec     ecx
1574
        dec     ecx
1577
        jnz     @b
1575
        jnz     @b
1578
.done:
1576
.done:
1579
        ret
1577
        ret
1580
endp
1578
endp