Rev 6317 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
5565 | serge | 3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
431 | serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
164 | serge | 7 | |
593 | mikedld | 8 | $Revision: 6339 $ |
9 | |||
10 | |||
164 | serge | 11 | align 4 |
12 | proc alloc_page |
||
13 | |||
2434 | Serge | 14 | pushfd |
15 | cli |
||
16 | push ebx |
||
1461 | diamond | 17 | ;//- |
2434 | Serge | 18 | cmp [pg_data.pages_free], 1 |
19 | jle .out_of_memory |
||
1461 | diamond | 20 | ;//- |
21 | |||
2434 | Serge | 22 | mov ebx, [page_start] |
23 | mov ecx, [page_end] |
||
164 | serge | 24 | .l1: |
2434 | Serge | 25 | bsf eax, [ebx]; |
26 | jnz .found |
||
27 | add ebx, 4 |
||
28 | cmp ebx, ecx |
||
29 | jb .l1 |
||
30 | pop ebx |
||
31 | popfd |
||
32 | xor eax, eax |
||
33 | ret |
||
164 | serge | 34 | .found: |
1629 | serge | 35 | ;//- |
2434 | Serge | 36 | dec [pg_data.pages_free] |
37 | jz .out_of_memory |
||
1461 | diamond | 38 | ;//- |
2434 | Serge | 39 | btr [ebx], eax |
40 | mov [page_start], ebx |
||
41 | sub ebx, sys_pgmap |
||
42 | lea eax, [eax+ebx*8] |
||
43 | shl eax, 12 |
||
1461 | diamond | 44 | ;//- dec [pg_data.pages_free] |
2434 | Serge | 45 | pop ebx |
46 | popfd |
||
47 | ret |
||
1461 | diamond | 48 | ;//- |
49 | .out_of_memory: |
||
2434 | Serge | 50 | mov [pg_data.pages_free], 1 |
51 | xor eax, eax |
||
52 | pop ebx |
||
53 | popfd |
||
54 | ret |
||
1461 | diamond | 55 | ;//- |
164 | serge | 56 | endp |
57 | |||
58 | align 4 |
||
59 | proc alloc_pages stdcall, count:dword |
||
2434 | Serge | 60 | pushfd |
61 | push ebx |
||
62 | push edi |
||
63 | cli |
||
64 | mov eax, [count] |
||
65 | add eax, 7 |
||
66 | shr eax, 3 |
||
67 | mov [count], eax |
||
1461 | diamond | 68 | ;//- |
2434 | Serge | 69 | mov ebx, [pg_data.pages_free] |
70 | sub ebx, 9 |
||
71 | js .out_of_memory |
||
72 | shr ebx, 3 |
||
73 | cmp eax, ebx |
||
74 | jg .out_of_memory |
||
1461 | diamond | 75 | ;//- |
2434 | Serge | 76 | mov ecx, [page_start] |
77 | mov ebx, [page_end] |
||
164 | serge | 78 | .find: |
2434 | Serge | 79 | mov edx, [count] |
80 | mov edi, ecx |
||
164 | serge | 81 | .match: |
2434 | Serge | 82 | cmp byte [ecx], 0xFF |
83 | jne .next |
||
84 | dec edx |
||
85 | jz .ok |
||
86 | inc ecx |
||
87 | cmp ecx, ebx |
||
88 | jb .match |
||
1461 | diamond | 89 | .out_of_memory: |
660 | serge | 90 | .fail: |
2434 | Serge | 91 | xor eax, eax |
92 | pop edi |
||
93 | pop ebx |
||
94 | popfd |
||
95 | ret |
||
164 | serge | 96 | .next: |
2434 | Serge | 97 | inc ecx |
98 | cmp ecx, ebx |
||
99 | jb .find |
||
100 | pop edi |
||
101 | pop ebx |
||
102 | popfd |
||
103 | xor eax, eax |
||
104 | ret |
||
164 | serge | 105 | .ok: |
2434 | Serge | 106 | sub ecx, edi |
107 | inc ecx |
||
108 | push esi |
||
109 | mov esi, edi |
||
110 | xor eax, eax |
||
111 | rep stosb |
||
112 | sub esi, sys_pgmap |
||
113 | shl esi, 3+12 |
||
114 | mov eax, esi |
||
115 | mov ebx, [count] |
||
116 | shl ebx, 3 |
||
117 | sub [pg_data.pages_free], ebx |
||
118 | pop esi |
||
119 | pop edi |
||
120 | pop ebx |
||
121 | popfd |
||
122 | ret |
||
164 | serge | 123 | endp |
124 | |||
125 | align 4 |
||
5201 | serge | 126 | ;proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword |
127 | map_page: |
||
2434 | Serge | 128 | push ebx |
5596 | serge | 129 | mov eax, [esp+12] ; phis_addr |
5201 | serge | 130 | or eax, [esp+16] ; flags |
5565 | serge | 131 | and eax, [pte_valid_mask] |
5201 | serge | 132 | mov ebx, [esp+8] ; lin_addr |
2434 | Serge | 133 | shr ebx, 12 |
6339 | serge | 134 | mov [page_tabs+ebx*8], eax |
5201 | serge | 135 | mov eax, [esp+8] ; lin_addr |
136 | pop ebx |
||
2434 | Serge | 137 | invlpg [eax] |
5201 | serge | 138 | ret 12 |
164 | serge | 139 | |
140 | align 4 |
||
281 | serge | 141 | map_space: ;not implemented |
142 | |||
143 | |||
2434 | Serge | 144 | ret |
281 | serge | 145 | |
146 | |||
147 | align 4 |
||
164 | serge | 148 | proc free_page |
149 | ;arg: eax page address |
||
2434 | Serge | 150 | pushfd |
151 | cli |
||
152 | shr eax, 12 ;page index |
||
153 | bts dword [sys_pgmap], eax ;that's all! |
||
154 | cmc |
||
155 | adc [pg_data.pages_free], 0 |
||
156 | shr eax, 3 |
||
157 | and eax, not 3 ;dword offset from page_map |
||
158 | add eax, sys_pgmap |
||
159 | cmp [page_start], eax |
||
160 | ja @f |
||
161 | popfd |
||
162 | ret |
||
164 | serge | 163 | @@: |
2434 | Serge | 164 | mov [page_start], eax |
165 | popfd |
||
166 | ret |
||
164 | serge | 167 | endp |
168 | |||
2434 | Serge | 169 | align 4 |
741 | serge | 170 | proc map_io_mem stdcall, base:dword, size:dword, flags:dword |
171 | |||
2434 | Serge | 172 | push ebx |
173 | push edi |
||
174 | mov eax, [size] |
||
175 | add eax, [base] |
||
176 | add eax, 4095 |
||
177 | and eax, -4096 |
||
178 | mov ecx, [base] |
||
179 | and ecx, -4096 |
||
180 | sub eax, ecx |
||
181 | mov [size], eax |
||
2217 | Serge | 182 | |
2434 | Serge | 183 | stdcall alloc_kernel_space, eax |
184 | test eax, eax |
||
185 | jz .fail |
||
186 | push eax |
||
741 | serge | 187 | |
2434 | Serge | 188 | mov edi, 0x1000 |
189 | mov ebx, eax |
||
190 | mov ecx, [size] |
||
191 | mov edx, [base] |
||
192 | shr eax, 12 |
||
193 | shr ecx, 12 |
||
194 | or edx, [flags] |
||
5565 | serge | 195 | and edx, [pte_valid_mask] |
741 | serge | 196 | @@: |
6339 | serge | 197 | mov [page_tabs+eax*8], edx |
198 | mov [page_tabs+eax*8+4], dword 0 |
||
2434 | Serge | 199 | invlpg [ebx] |
200 | inc eax |
||
201 | add ebx, edi |
||
202 | add edx, edi |
||
203 | loop @B |
||
741 | serge | 204 | |
2434 | Serge | 205 | pop eax |
206 | mov edx, [base] |
||
207 | and edx, 4095 |
||
208 | add eax, edx |
||
741 | serge | 209 | .fail: |
2434 | Serge | 210 | pop edi |
211 | pop ebx |
||
212 | ret |
||
741 | serge | 213 | endp |
214 | |||
279 | serge | 215 | ; param |
328 | serge | 216 | ; eax= page base + page flags |
819 | serge | 217 | ; ebx= linear address |
281 | serge | 218 | ; ecx= count |
219 | |||
220 | align 4 |
||
328 | serge | 221 | commit_pages: |
2434 | Serge | 222 | test ecx, ecx |
223 | jz .fail |
||
281 | serge | 224 | |
2434 | Serge | 225 | push edi |
226 | push eax |
||
227 | push ecx |
||
228 | mov ecx, pg_data.mutex |
||
229 | call mutex_lock |
||
230 | pop ecx |
||
231 | pop eax |
||
2130 | serge | 232 | |
5565 | serge | 233 | and eax, [pte_valid_mask ] |
2434 | Serge | 234 | mov edi, ebx |
235 | shr edi, 12 |
||
6339 | serge | 236 | lea edi, [page_tabs+edi*8] |
2130 | serge | 237 | @@: |
6339 | serge | 238 | mov [edi], eax |
239 | mov [edi+4], dword 0 |
||
2434 | Serge | 240 | invlpg [ebx] |
241 | add eax, 0x1000 |
||
242 | add ebx, 0x1000 |
||
6339 | serge | 243 | add edi, 8 |
2434 | Serge | 244 | loop @B |
328 | serge | 245 | |
2434 | Serge | 246 | pop edi |
2130 | serge | 247 | |
2434 | Serge | 248 | mov ecx, pg_data.mutex |
249 | call mutex_unlock |
||
328 | serge | 250 | .fail: |
2434 | Serge | 251 | ret |
281 | serge | 252 | |
328 | serge | 253 | |
281 | serge | 254 | ; param |
279 | serge | 255 | ; eax= base |
281 | serge | 256 | ; ecx= count |
279 | serge | 257 | |
164 | serge | 258 | align 4 |
279 | serge | 259 | release_pages: |
321 | diamond | 260 | |
2434 | Serge | 261 | push ebp |
262 | push esi |
||
263 | push edi |
||
264 | push ebx |
||
279 | serge | 265 | |
2434 | Serge | 266 | mov esi, eax |
267 | mov edi, eax |
||
279 | serge | 268 | |
2434 | Serge | 269 | shr esi, 12 |
6339 | serge | 270 | lea esi, [page_tabs+esi*8] |
328 | serge | 271 | |
2434 | Serge | 272 | push ecx |
273 | mov ecx, pg_data.mutex |
||
274 | call mutex_lock |
||
275 | pop ecx |
||
2130 | serge | 276 | |
2434 | Serge | 277 | mov ebp, [pg_data.pages_free] |
278 | mov ebx, [page_start] |
||
279 | mov edx, sys_pgmap |
||
279 | serge | 280 | @@: |
2434 | Serge | 281 | xor eax, eax |
282 | xchg eax, [esi] |
||
283 | invlpg [edi] |
||
279 | serge | 284 | |
2434 | Serge | 285 | test eax, 1 |
286 | jz .next |
||
279 | serge | 287 | |
2434 | Serge | 288 | shr eax, 12 |
289 | bts [edx], eax |
||
290 | cmc |
||
291 | adc ebp, 0 |
||
292 | shr eax, 3 |
||
293 | and eax, -4 |
||
294 | add eax, edx |
||
295 | cmp eax, ebx |
||
296 | jae .next |
||
279 | serge | 297 | |
2434 | Serge | 298 | mov ebx, eax |
279 | serge | 299 | .next: |
2434 | Serge | 300 | add edi, 0x1000 |
6339 | serge | 301 | add esi, 8 |
2434 | Serge | 302 | loop @B |
2130 | serge | 303 | |
2434 | Serge | 304 | mov [pg_data.pages_free], ebp |
305 | mov ecx, pg_data.mutex |
||
306 | call mutex_unlock |
||
2130 | serge | 307 | |
2434 | Serge | 308 | pop ebx |
309 | pop edi |
||
310 | pop esi |
||
311 | pop ebp |
||
312 | ret |
||
279 | serge | 313 | |
819 | serge | 314 | ; param |
315 | ; eax= base |
||
316 | ; ecx= count |
||
317 | |||
279 | serge | 318 | align 4 |
819 | serge | 319 | unmap_pages: |
320 | |||
2434 | Serge | 321 | push edi |
819 | serge | 322 | |
2434 | Serge | 323 | mov edi, eax |
324 | mov edx, eax |
||
819 | serge | 325 | |
6339 | serge | 326 | shr edi, 9 |
2434 | Serge | 327 | add edi, page_tabs |
819 | serge | 328 | |
2434 | Serge | 329 | xor eax, eax |
819 | serge | 330 | @@: |
2434 | Serge | 331 | stosd |
6339 | serge | 332 | stosd |
2434 | Serge | 333 | invlpg [edx] |
334 | add edx, 0x1000 |
||
335 | loop @b |
||
819 | serge | 336 | |
2434 | Serge | 337 | pop edi |
338 | ret |
||
819 | serge | 339 | |
340 | |||
341 | align 4 |
||
188 | serge | 342 | proc map_page_table stdcall, lin_addr:dword, phis_addr:dword |
2434 | Serge | 343 | push ebx |
344 | mov ebx, [lin_addr] |
||
6339 | serge | 345 | shr ebx, 21 |
2434 | Serge | 346 | mov eax, [phis_addr] |
347 | and eax, not 0xFFF |
||
5565 | serge | 348 | or eax, PG_UWR |
6339 | serge | 349 | mov [master_tab+ebx*8], eax |
350 | mov [master_tab+ebx*8+4], dword 0 |
||
2434 | Serge | 351 | mov eax, [lin_addr] |
6339 | serge | 352 | shr eax, 9 |
2434 | Serge | 353 | add eax, page_tabs |
354 | invlpg [eax] |
||
355 | pop ebx |
||
356 | ret |
||
164 | serge | 357 | endp |
358 | |||
5201 | serge | 359 | uglobal |
360 | sb16_buffer_allocated db 0 |
||
361 | endg |
||
362 | |||
363 | ; Allocates [.size] bytes so that the target memory block |
||
364 | ; is inside one 64K page for 24-bit DMA controller, |
||
365 | ; that is, somewhere between 00xx0000h and 00xxFFFFh. |
||
366 | proc alloc_dma24 |
||
367 | ; Implementation note. |
||
368 | ; The only user of that function is SB16 driver, |
||
369 | ; so just return a statically allocated buffer. |
||
370 | virtual at esp |
||
371 | dd ? ; return address |
||
372 | .size dd ? |
||
373 | end virtual |
||
374 | cmp [sb16_buffer_allocated], 0 |
||
375 | jnz .fail |
||
376 | inc [sb16_buffer_allocated] |
||
377 | mov eax, SB16Buffer |
||
378 | ret 4 |
||
379 | .fail: |
||
380 | xor eax, eax |
||
381 | ret 4 |
||
382 | endp |
||
383 | |||
384 | ; Allocates a physical page for master page table |
||
385 | ; that duplicates first Mb of OS_BASE at address 0; |
||
386 | ; used for starting APs and for shutting down, |
||
387 | ; where it is important to execute code in trivial-mapped pages. |
||
388 | ; Returns eax = allocated physical page. |
||
389 | proc create_trampoline_pgmap |
||
390 | ; The only non-trivial moment: |
||
391 | ; we need a linear address to fill information, |
||
392 | ; but we don't need it outside of this function, |
||
393 | ; so we're returning physical address. |
||
394 | ; Therefore, allocate memory with kernel_alloc, |
||
395 | ; this will allocate physical page and a linear address somewhere, |
||
396 | ; and deallocate only linear address with free_kernel_space. |
||
397 | stdcall kernel_alloc, 0x1000 |
||
398 | mov edi, eax |
||
399 | mov esi, master_tab |
||
400 | mov ecx, 1024 |
||
401 | rep movsd |
||
402 | mov ecx, [master_tab+(OS_BASE shr 20)] |
||
403 | mov [eax], ecx |
||
404 | mov edi, eax |
||
405 | call get_pg_addr |
||
406 | push eax |
||
407 | stdcall free_kernel_space, edi |
||
408 | pop eax |
||
409 | ret |
||
410 | endp |
||
411 | |||
164 | serge | 412 | align 4 |
413 | proc new_mem_resize stdcall, new_size:dword |
||
414 | |||
2987 | Serge | 415 | push ebx |
416 | push esi |
||
417 | push edi |
||
164 | serge | 418 | |
2987 | Serge | 419 | mov edx, [current_slot] |
5201 | serge | 420 | mov ebx, [edx+APPDATA.process] |
421 | |||
422 | cmp [ebx+PROC.heap_base], 0 |
||
2987 | Serge | 423 | jne .exit |
424 | |||
2434 | Serge | 425 | mov edi, [new_size] |
426 | add edi, 4095 |
||
427 | and edi, not 4095 |
||
428 | mov [new_size], edi |
||
164 | serge | 429 | |
5201 | serge | 430 | mov esi, [ebx+PROC.mem_used] |
2434 | Serge | 431 | add esi, 4095 |
432 | and esi, not 4095 |
||
164 | serge | 433 | |
2434 | Serge | 434 | cmp edi, esi |
2987 | Serge | 435 | ja .expand |
436 | je .exit |
||
164 | serge | 437 | |
2987 | Serge | 438 | mov ebx, edi |
2434 | Serge | 439 | shr edi, 12 |
440 | shr esi, 12 |
||
2987 | Serge | 441 | |
442 | mov ecx, pg_data.mutex |
||
443 | call mutex_lock |
||
164 | serge | 444 | @@: |
6339 | serge | 445 | mov eax, [app_page_tabs+edi*8] |
2434 | Serge | 446 | test eax, 1 |
447 | jz .next |
||
2987 | Serge | 448 | |
6339 | serge | 449 | mov dword [app_page_tabs+edi*8], 0 |
2434 | Serge | 450 | invlpg [ebx] |
451 | call free_page |
||
164 | serge | 452 | |
2434 | Serge | 453 | .next: |
2987 | Serge | 454 | inc edi |
455 | add ebx, 0x1000 |
||
2434 | Serge | 456 | cmp edi, esi |
457 | jb @B |
||
164 | serge | 458 | |
2987 | Serge | 459 | mov ecx, pg_data.mutex |
460 | call mutex_unlock |
||
461 | |||
164 | serge | 462 | .update_size: |
2987 | Serge | 463 | mov edx, [current_slot] |
2434 | Serge | 464 | mov ebx, [new_size] |
5201 | serge | 465 | mov edx, [edx+APPDATA.process] |
466 | mov [edx+PROC.mem_used], ebx |
||
2987 | Serge | 467 | .exit: |
468 | pop edi |
||
469 | pop esi |
||
470 | pop ebx |
||
2434 | Serge | 471 | xor eax, eax |
472 | ret |
||
2987 | Serge | 473 | |
164 | serge | 474 | .expand: |
475 | |||
2987 | Serge | 476 | mov ecx, pg_data.mutex |
477 | call mutex_lock |
||
164 | serge | 478 | |
2987 | Serge | 479 | xchg esi, edi |
480 | |||
481 | push esi ;new size |
||
482 | push edi ;old size |
||
483 | |||
6339 | serge | 484 | add edi, 0x1FFFFF |
485 | and edi, not(0x1FFFFF) |
||
486 | add esi, 0x1FFFFF |
||
487 | and esi, not(0x1FFFFF) |
||
164 | serge | 488 | |
2987 | Serge | 489 | cmp edi, esi |
2434 | Serge | 490 | jae .grow |
2987 | Serge | 491 | @@: |
2434 | Serge | 492 | call alloc_page |
493 | test eax, eax |
||
2987 | Serge | 494 | jz .exit_fail |
164 | serge | 495 | |
2434 | Serge | 496 | stdcall map_page_table, edi, eax |
164 | serge | 497 | |
2434 | Serge | 498 | push edi |
6339 | serge | 499 | shr edi, 9 |
2434 | Serge | 500 | add edi, page_tabs |
501 | mov ecx, 1024 |
||
502 | xor eax, eax |
||
503 | cld |
||
504 | rep stosd |
||
505 | pop edi |
||
164 | serge | 506 | |
6339 | serge | 507 | add edi, 0x00200000 |
2434 | Serge | 508 | cmp edi, esi |
509 | jb @B |
||
164 | serge | 510 | .grow: |
2987 | Serge | 511 | pop edi ;old size |
512 | pop ecx ;new size |
||
164 | serge | 513 | |
2987 | Serge | 514 | shr edi, 10 |
515 | shr ecx, 10 |
||
516 | sub ecx, edi |
||
517 | shr ecx, 2 ;pages count |
||
518 | mov eax, 2 |
||
519 | |||
520 | add edi, app_page_tabs |
||
2434 | Serge | 521 | rep stosd |
164 | serge | 522 | |
2987 | Serge | 523 | mov ecx, pg_data.mutex |
524 | call mutex_unlock |
||
164 | serge | 525 | |
2434 | Serge | 526 | jmp .update_size |
2987 | Serge | 527 | |
528 | .exit_fail: |
||
2434 | Serge | 529 | mov ecx, pg_data.mutex |
530 | call mutex_unlock |
||
2130 | serge | 531 | |
2987 | Serge | 532 | add esp, 8 |
533 | pop edi |
||
534 | pop esi |
||
535 | pop ebx |
||
2434 | Serge | 536 | xor eax, eax |
537 | inc eax |
||
538 | ret |
||
164 | serge | 539 | endp |
540 | |||
2987 | Serge | 541 | |
285 | serge | 542 | ; param |
543 | ; eax= linear address |
||
544 | ; |
||
545 | ; retval |
||
546 | ; eax= phisical page address |
||
547 | |||
164 | serge | 548 | align 4 |
285 | serge | 549 | get_pg_addr: |
3232 | Serge | 550 | sub eax, OS_BASE |
551 | cmp eax, 0x400000 |
||
552 | jb @f |
||
2434 | Serge | 553 | shr eax, 12 |
6339 | serge | 554 | mov eax, [page_tabs+(eax+(OS_BASE shr 12))*8] |
3232 | Serge | 555 | @@: |
2434 | Serge | 556 | and eax, 0xFFFFF000 |
557 | ret |
||
164 | serge | 558 | |
465 | serge | 559 | |
188 | serge | 560 | align 4 |
1105 | Galkov | 561 | ; Now it is called from core/sys32::exc_c (see stack frame there) |
164 | serge | 562 | proc page_fault_handler |
465 | serge | 563 | |
1056 | Galkov | 564 | .err_addr equ ebp-4 |
709 | diamond | 565 | |
1105 | Galkov | 566 | push ebx ;save exception number (#PF) |
1056 | Galkov | 567 | mov ebp, esp |
568 | mov ebx, cr2 |
||
1105 | Galkov | 569 | push ebx ;that is locals: .err_addr = cr2 |
1056 | Galkov | 570 | inc [pg_data.pages_faults] |
465 | serge | 571 | |
1056 | Galkov | 572 | mov eax, [pf_err_code] |
164 | serge | 573 | |
1056 | Galkov | 574 | cmp ebx, OS_BASE ;ebx == .err_addr |
3555 | Serge | 575 | jb .user_space ;страница в памяти приложения ; |
188 | serge | 576 | |
1056 | Galkov | 577 | cmp ebx, page_tabs |
3555 | Serge | 578 | jb .kernel_space ;страница в памяти ядра |
164 | serge | 579 | |
1056 | Galkov | 580 | cmp ebx, kernel_tabs |
3555 | Serge | 581 | jb .alloc;.app_tabs ;таблицы страниц приложения ; |
582 | ;просто создадим одну |
||
1056 | Galkov | 583 | .core_tabs: |
584 | .fail: ;simply return to caller |
||
585 | mov esp, ebp |
||
1105 | Galkov | 586 | pop ebx ;restore exception number (#PF) |
1056 | Galkov | 587 | ret |
378 | serge | 588 | |
164 | serge | 589 | .user_space: |
5565 | serge | 590 | test eax, PG_READ |
3555 | Serge | 591 | jnz .err_access ;Страница присутствует |
592 | ;Ошибка доступа ? |
||
465 | serge | 593 | |
1056 | Galkov | 594 | shr ebx, 12 |
595 | mov ecx, ebx |
||
6339 | serge | 596 | shr ecx, 9 |
597 | mov edx, [master_tab+ecx*8] |
||
5565 | serge | 598 | test edx, PG_READ |
3555 | Serge | 599 | jz .fail ;таблица страниц не создана |
600 | ;неверный адрес в программе |
||
172 | serge | 601 | |
6339 | serge | 602 | mov eax, [page_tabs+ebx*8] |
1056 | Galkov | 603 | test eax, 2 |
3555 | Serge | 604 | jz .fail ;адрес не зарезервирован для ; |
605 | ;использования. Ошибка |
||
188 | serge | 606 | .alloc: |
1056 | Galkov | 607 | call alloc_page |
608 | test eax, eax |
||
609 | jz .fail |
||
164 | serge | 610 | |
5565 | serge | 611 | stdcall map_page, [.err_addr], eax, PG_UWR |
164 | serge | 612 | |
1056 | Galkov | 613 | mov edi, [.err_addr] |
614 | and edi, 0xFFFFF000 |
||
615 | mov ecx, 1024 |
||
616 | xor eax, eax |
||
617 | ;cld ;caller is duty for this |
||
2434 | Serge | 618 | rep stosd |
1056 | Galkov | 619 | .exit: ;iret with repeat fault instruction |
2434 | Serge | 620 | add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
1056 | Galkov | 621 | restore_ring3_context |
622 | iretd |
||
465 | serge | 623 | |
1289 | diamond | 624 | .err_access: |
625 | ; access denied? this may be a result of copy-on-write protection for DLL |
||
626 | ; check list of HDLLs |
||
627 | and ebx, not 0xFFF |
||
5201 | serge | 628 | mov eax, [current_process] |
629 | mov eax, [eax+PROC.dlls_list_ptr] |
||
1311 | diamond | 630 | test eax, eax |
631 | jz .fail |
||
632 | mov esi, [eax+HDLL.fd] |
||
1289 | diamond | 633 | .scan_hdll: |
634 | cmp esi, eax |
||
635 | jz .fail |
||
636 | mov edx, ebx |
||
637 | sub edx, [esi+HDLL.base] |
||
638 | cmp edx, [esi+HDLL.size] |
||
639 | jb .fault_in_hdll |
||
640 | .scan_hdll.next: |
||
1311 | diamond | 641 | mov esi, [esi+HDLL.fd] |
1289 | diamond | 642 | jmp .scan_hdll |
643 | .fault_in_hdll: |
||
644 | ; allocate new page, map it as rw and copy data |
||
645 | call alloc_page |
||
646 | test eax, eax |
||
647 | jz .fail |
||
5565 | serge | 648 | stdcall map_page, ebx, eax, PG_UWR |
1289 | diamond | 649 | mov edi, ebx |
650 | mov ecx, 1024 |
||
651 | sub ebx, [esi+HDLL.base] |
||
652 | mov esi, [esi+HDLL.parent] |
||
653 | mov esi, [esi+DLLDESCR.data] |
||
654 | add esi, ebx |
||
2434 | Serge | 655 | rep movsd |
1289 | diamond | 656 | jmp .exit |
465 | serge | 657 | |
658 | .kernel_space: |
||
5565 | serge | 659 | test eax, PG_READ |
3555 | Serge | 660 | jz .fail ;страница не присутствует |
465 | serge | 661 | |
2434 | Serge | 662 | test eax, 12 ;U/S (+below) |
3555 | Serge | 663 | jnz .fail ;приложение обратилось к памяти |
664 | ;ядра |
||
1056 | Galkov | 665 | ;test eax, 8 |
3555 | Serge | 666 | ;jnz .fail ;установлен зарезервированный бит |
667 | ;в таблицах страниц. добавлено в P4/Xeon |
||
465 | serge | 668 | |
3555 | Serge | 669 | ;попытка записи в защищённую страницу ядра |
465 | serge | 670 | |
1056 | Galkov | 671 | cmp ebx, tss._io_map_0 |
672 | jb .fail |
||
465 | serge | 673 | |
1056 | Galkov | 674 | cmp ebx, tss._io_map_0+8192 |
675 | jae .fail |
||
465 | serge | 676 | |
677 | ; io permission map |
||
678 | ; copy-on-write protection |
||
679 | |||
1056 | Galkov | 680 | call alloc_page |
681 | test eax, eax |
||
682 | jz .fail |
||
465 | serge | 683 | |
1056 | Galkov | 684 | push eax |
5565 | serge | 685 | stdcall map_page, [.err_addr], eax, dword PG_SWR |
1056 | Galkov | 686 | pop eax |
687 | mov edi, [.err_addr] |
||
688 | and edi, -4096 |
||
689 | lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 |
||
465 | serge | 690 | |
1056 | Galkov | 691 | mov ebx, esi |
692 | shr ebx, 12 |
||
693 | mov edx, [current_slot] |
||
5565 | serge | 694 | or eax, PG_SWR |
1056 | Galkov | 695 | mov [edx+APPDATA.io_map+ebx*4], eax |
465 | serge | 696 | |
1056 | Galkov | 697 | add esi, [default_io_map] |
698 | mov ecx, 4096/4 |
||
699 | ;cld ;caller is duty for this |
||
2434 | Serge | 700 | rep movsd |
1056 | Galkov | 701 | jmp .exit |
164 | serge | 702 | endp |
703 | |||
1314 | diamond | 704 | ; returns number of mapped bytes |
5201 | serge | 705 | proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\ |
1314 | diamond | 706 | ofs:dword,buf_size:dword,req_access:dword |
5201 | serge | 707 | locals |
708 | count dd ? |
||
709 | process dd ? |
||
710 | endl |
||
6339 | serge | 711 | xchg bx, bx |
5201 | serge | 712 | mov [count], 0 |
2434 | Serge | 713 | cmp [buf_size], 0 |
714 | jz .exit |
||
164 | serge | 715 | |
2434 | Serge | 716 | mov eax, [slot] |
717 | shl eax, 8 |
||
5201 | serge | 718 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
719 | test eax, eax |
||
720 | jz .exit |
||
164 | serge | 721 | |
5201 | serge | 722 | mov [process], eax |
2434 | Serge | 723 | mov ebx, [ofs] |
724 | shr ebx, 22 |
||
5201 | serge | 725 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
726 | mov esi, [ipc_ptab] |
||
2434 | Serge | 727 | and eax, 0xFFFFF000 |
728 | jz .exit |
||
5565 | serge | 729 | stdcall map_page, esi, eax, PG_SWR |
2434 | Serge | 730 | @@: |
731 | mov edi, [lin_addr] |
||
732 | and edi, 0xFFFFF000 |
||
733 | mov ecx, [buf_size] |
||
734 | add ecx, 4095 |
||
735 | shr ecx, 12 |
||
5201 | serge | 736 | inc ecx ; ??????????? |
164 | serge | 737 | |
2434 | Serge | 738 | mov edx, [ofs] |
739 | shr edx, 12 |
||
740 | and edx, 0x3FF |
||
1314 | diamond | 741 | .map: |
2434 | Serge | 742 | stdcall safe_map_page, [slot], [req_access], [ofs] |
743 | jnc .exit |
||
5201 | serge | 744 | add [count], PAGE_SIZE |
745 | add [ofs], PAGE_SIZE |
||
2434 | Serge | 746 | dec ecx |
747 | jz .exit |
||
5201 | serge | 748 | |
749 | add edi, PAGE_SIZE |
||
2434 | Serge | 750 | inc edx |
5201 | serge | 751 | cmp edx, 1024 |
2434 | Serge | 752 | jnz .map |
5201 | serge | 753 | |
2434 | Serge | 754 | inc ebx |
5201 | serge | 755 | mov eax, [process] |
756 | mov eax, [eax+PROC.pdt_0+ebx*4] |
||
2434 | Serge | 757 | and eax, 0xFFFFF000 |
758 | jz .exit |
||
5201 | serge | 759 | |
5565 | serge | 760 | stdcall map_page, esi, eax, PG_SWR |
2434 | Serge | 761 | xor edx, edx |
762 | jmp .map |
||
164 | serge | 763 | .exit: |
5201 | serge | 764 | mov eax, [count] |
2434 | Serge | 765 | ret |
164 | serge | 766 | endp |
767 | |||
1314 | diamond | 768 | proc map_memEx stdcall, lin_addr:dword,slot:dword,\ |
769 | ofs:dword,buf_size:dword,req_access:dword |
||
5201 | serge | 770 | locals |
771 | count dd ? |
||
772 | process dd ? |
||
773 | endl |
||
1314 | diamond | 774 | |
5201 | serge | 775 | mov [count], 0 |
2434 | Serge | 776 | cmp [buf_size], 0 |
777 | jz .exit |
||
164 | serge | 778 | |
2434 | Serge | 779 | mov eax, [slot] |
780 | shl eax, 8 |
||
5201 | serge | 781 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
782 | test eax, eax |
||
783 | jz .exit |
||
164 | serge | 784 | |
5201 | serge | 785 | mov [process], eax |
2434 | Serge | 786 | mov ebx, [ofs] |
787 | shr ebx, 22 |
||
5201 | serge | 788 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
789 | mov esi, [proc_mem_tab] |
||
2434 | Serge | 790 | and eax, 0xFFFFF000 |
791 | jz .exit |
||
5565 | serge | 792 | stdcall map_page, esi, eax, PG_SWR |
2434 | Serge | 793 | @@: |
794 | mov edi, [lin_addr] |
||
795 | and edi, 0xFFFFF000 |
||
796 | mov ecx, [buf_size] |
||
797 | add ecx, 4095 |
||
798 | shr ecx, 12 |
||
5201 | serge | 799 | inc ecx ; ??????????? |
164 | serge | 800 | |
2434 | Serge | 801 | mov edx, [ofs] |
802 | shr edx, 12 |
||
803 | and edx, 0x3FF |
||
1314 | diamond | 804 | .map: |
2434 | Serge | 805 | stdcall safe_map_page, [slot], [req_access], [ofs] |
806 | jnc .exit |
||
5201 | serge | 807 | add [count], PAGE_SIZE |
808 | add [ofs], PAGE_SIZE |
||
809 | dec ecx |
||
810 | jz .exit |
||
811 | |||
812 | add edi, PAGE_SIZE |
||
2434 | Serge | 813 | inc edx |
5201 | serge | 814 | cmp edx, 1024 |
2434 | Serge | 815 | jnz .map |
5201 | serge | 816 | |
817 | inc ebx |
||
818 | mov eax, [process] |
||
819 | mov eax, [eax+PROC.pdt_0+ebx*4] |
||
820 | and eax, 0xFFFFF000 |
||
821 | jz .exit |
||
822 | |||
5565 | serge | 823 | stdcall map_page, esi, eax, PG_SWR |
5201 | serge | 824 | xor edx, edx |
825 | jmp .map |
||
164 | serge | 826 | .exit: |
5201 | serge | 827 | mov eax, [count] |
2434 | Serge | 828 | ret |
164 | serge | 829 | endp |
830 | |||
1314 | diamond | 831 | ; in: esi+edx*4 = pointer to page table entry |
832 | ; in: [slot], [req_access], [ofs] on the stack |
||
833 | ; in: edi = linear address to map |
||
834 | ; out: CF cleared <=> failed |
||
835 | ; destroys: only eax |
||
836 | proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
||
6339 | serge | 837 | mov eax, [esi+edx*8] |
5565 | serge | 838 | test al, PG_READ |
2434 | Serge | 839 | jz .not_present |
840 | test al, PG_WRITE |
||
841 | jz .resolve_readonly |
||
1314 | diamond | 842 | ; normal case: writable page, just map with requested access |
843 | .map: |
||
2434 | Serge | 844 | stdcall map_page, edi, eax, [req_access] |
845 | stc |
||
1314 | diamond | 846 | .fail: |
2434 | Serge | 847 | ret |
1314 | diamond | 848 | .not_present: |
849 | ; check for alloc-on-demand page |
||
2434 | Serge | 850 | test al, 2 |
851 | jz .fail |
||
1314 | diamond | 852 | ; allocate new page, save it to source page table |
2434 | Serge | 853 | push ecx |
854 | call alloc_page |
||
855 | pop ecx |
||
856 | test eax, eax |
||
857 | jz .fail |
||
5565 | serge | 858 | or al, PG_UWR |
6339 | serge | 859 | mov [esi+edx*8], eax |
2434 | Serge | 860 | jmp .map |
1314 | diamond | 861 | .resolve_readonly: |
862 | ; readonly page, probably copy-on-write |
||
863 | ; check: readonly request of readonly page is ok |
||
2434 | Serge | 864 | test [req_access], PG_WRITE |
865 | jz .map |
||
1314 | diamond | 866 | ; find control structure for this page |
2434 | Serge | 867 | pushf |
868 | cli |
||
869 | cld |
||
870 | push ebx ecx |
||
871 | mov eax, [slot] |
||
872 | shl eax, 8 |
||
5201 | serge | 873 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
874 | mov eax, [eax+PROC.dlls_list_ptr] |
||
2434 | Serge | 875 | test eax, eax |
876 | jz .no_hdll |
||
877 | mov ecx, [eax+HDLL.fd] |
||
1314 | diamond | 878 | .scan_hdll: |
2434 | Serge | 879 | cmp ecx, eax |
880 | jz .no_hdll |
||
881 | mov ebx, [ofs] |
||
882 | and ebx, not 0xFFF |
||
883 | sub ebx, [ecx+HDLL.base] |
||
884 | cmp ebx, [ecx+HDLL.size] |
||
885 | jb .hdll_found |
||
886 | mov ecx, [ecx+HDLL.fd] |
||
887 | jmp .scan_hdll |
||
1314 | diamond | 888 | .no_hdll: |
2434 | Serge | 889 | pop ecx ebx |
890 | popf |
||
891 | clc |
||
892 | ret |
||
1314 | diamond | 893 | .hdll_found: |
894 | ; allocate page, save it in page table, map it, copy contents from base |
||
2434 | Serge | 895 | mov eax, [ecx+HDLL.parent] |
896 | add ebx, [eax+DLLDESCR.data] |
||
897 | call alloc_page |
||
898 | test eax, eax |
||
899 | jz .no_hdll |
||
5565 | serge | 900 | or al, PG_UWR |
6339 | serge | 901 | mov [esi+edx*8], eax |
2434 | Serge | 902 | stdcall map_page, edi, eax, [req_access] |
903 | push esi edi |
||
904 | mov esi, ebx |
||
905 | mov ecx, 4096/4 |
||
906 | rep movsd |
||
907 | pop edi esi |
||
908 | pop ecx ebx |
||
909 | popf |
||
910 | stc |
||
911 | ret |
||
1314 | diamond | 912 | endp |
164 | serge | 913 | |
914 | sys_IPC: |
||
915 | ;input: |
||
1496 | Lrz | 916 | ; ebx=1 - set ipc buffer area |
917 | ; ecx=address of buffer |
||
918 | ; edx=size of buffer |
||
164 | serge | 919 | ; eax=2 - send message |
920 | ; ebx=PID |
||
921 | ; ecx=address of message |
||
922 | ; edx=size of message |
||
923 | |||
2434 | Serge | 924 | dec ebx |
925 | jnz @f |
||
164 | serge | 926 | |
2434 | Serge | 927 | mov eax, [current_slot] |
1496 | Lrz | 928 | pushf |
929 | cli |
||
2434 | Serge | 930 | mov [eax+APPDATA.ipc_start], ecx ;set fields in extended information area |
931 | mov [eax+APPDATA.ipc_size], edx |
||
164 | serge | 932 | |
2434 | Serge | 933 | add edx, ecx |
934 | add edx, 4095 |
||
935 | and edx, not 4095 |
||
164 | serge | 936 | |
2434 | Serge | 937 | .touch: |
938 | mov eax, [ecx] |
||
939 | add ecx, 0x1000 |
||
940 | cmp ecx, edx |
||
941 | jb .touch |
||
164 | serge | 942 | |
1496 | Lrz | 943 | popf |
2434 | Serge | 944 | mov [esp+32], ebx ;ebx=0 |
1496 | Lrz | 945 | ret |
164 | serge | 946 | |
1496 | Lrz | 947 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
948 | ;2 |
||
949 | @@: |
||
2434 | Serge | 950 | dec ebx |
951 | jnz @f |
||
164 | serge | 952 | |
1496 | Lrz | 953 | stdcall sys_ipc_send, ecx, edx, esi |
2434 | Serge | 954 | mov [esp+32], eax |
1496 | Lrz | 955 | ret |
956 | @@: |
||
2434 | Serge | 957 | or eax, -1 |
958 | mov [esp+32], eax |
||
1496 | Lrz | 959 | ret |
960 | |||
164 | serge | 961 | proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
962 | locals |
||
963 | dst_slot dd ? |
||
964 | dst_offset dd ? |
||
965 | buf_size dd ? |
||
536 | diamond | 966 | used_buf dd ? |
164 | serge | 967 | endl |
968 | |||
2434 | Serge | 969 | pushf |
970 | cli |
||
164 | serge | 971 | |
2434 | Serge | 972 | mov eax, [PID] |
973 | call pid_to_slot |
||
974 | test eax, eax |
||
975 | jz .no_pid |
||
164 | serge | 976 | |
2434 | Serge | 977 | mov [dst_slot], eax |
978 | shl eax, 8 |
||
5201 | serge | 979 | mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined? |
2434 | Serge | 980 | test edi, edi |
981 | jz .no_ipc_area |
||
164 | serge | 982 | |
2434 | Serge | 983 | mov ebx, edi |
984 | and ebx, 0xFFF |
||
985 | mov [dst_offset], ebx |
||
164 | serge | 986 | |
5201 | serge | 987 | mov esi, [eax+SLOT_BASE+APPDATA.ipc_size] |
2434 | Serge | 988 | mov [buf_size], esi |
164 | serge | 989 | |
2434 | Serge | 990 | mov ecx, [ipc_tmp] |
991 | cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page |
||
992 | jbe @f |
||
993 | push esi edi |
||
994 | add esi, 0x1000 |
||
995 | stdcall alloc_kernel_space, esi |
||
996 | mov ecx, eax |
||
997 | pop edi esi |
||
536 | diamond | 998 | @@: |
2434 | Serge | 999 | mov [used_buf], ecx |
5201 | serge | 1000 | stdcall map_mem_ipc, ecx, [dst_slot], \ |
5565 | serge | 1001 | edi, esi, PG_SWR |
164 | serge | 1002 | |
2434 | Serge | 1003 | mov edi, [dst_offset] |
1004 | add edi, [used_buf] |
||
1005 | cmp dword [edi], 0 |
||
1006 | jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
||
227 | serge | 1007 | |
2434 | Serge | 1008 | mov edx, dword [edi+4] |
1009 | lea ebx, [edx+8] |
||
1010 | add ebx, [msg_size] |
||
1011 | cmp ebx, [buf_size] |
||
1012 | ja .buffer_overflow ;esi<0 - not enough memory in buffer |
||
227 | serge | 1013 | |
2434 | Serge | 1014 | mov dword [edi+4], ebx |
1015 | mov eax, [TASK_BASE] |
||
1016 | mov eax, [eax+0x04] ;eax - our PID |
||
1017 | add edi, edx |
||
1018 | mov [edi], eax |
||
1019 | mov ecx, [msg_size] |
||
164 | serge | 1020 | |
2434 | Serge | 1021 | mov [edi+4], ecx |
1022 | add edi, 8 |
||
1023 | mov esi, [msg_addr] |
||
465 | serge | 1024 | ; add esi, new_app_base |
2434 | Serge | 1025 | cld |
1026 | rep movsb |
||
164 | serge | 1027 | |
2434 | Serge | 1028 | mov ebx, [ipc_tmp] |
1029 | mov edx, ebx |
||
1030 | shr ebx, 12 |
||
1031 | xor eax, eax |
||
6339 | serge | 1032 | mov [page_tabs+ebx*8], eax |
1033 | mov [page_tabs+ebx*8+4], eax |
||
2434 | Serge | 1034 | invlpg [edx] |
164 | serge | 1035 | |
2434 | Serge | 1036 | mov ebx, [ipc_pdir] |
1037 | mov edx, ebx |
||
1038 | shr ebx, 12 |
||
1039 | xor eax, eax |
||
6339 | serge | 1040 | mov [page_tabs+ebx*8], eax |
1041 | mov [page_tabs+ebx*8+4], eax |
||
2434 | Serge | 1042 | invlpg [edx] |
164 | serge | 1043 | |
2434 | Serge | 1044 | mov ebx, [ipc_ptab] |
1045 | mov edx, ebx |
||
1046 | shr ebx, 12 |
||
1047 | xor eax, eax |
||
6339 | serge | 1048 | mov [page_tabs+ebx*8], eax |
1049 | mov [page_tabs+ebx*8+4], eax |
||
2434 | Serge | 1050 | invlpg [edx] |
164 | serge | 1051 | |
2434 | Serge | 1052 | mov eax, [dst_slot] |
1053 | shl eax, 8 |
||
1054 | or [eax+SLOT_BASE+0xA8], dword 0x40 |
||
1055 | push 0 |
||
1056 | jmp .ret |
||
164 | serge | 1057 | .no_pid: |
2434 | Serge | 1058 | popf |
1059 | mov eax, 4 |
||
1060 | ret |
||
164 | serge | 1061 | .no_ipc_area: |
2434 | Serge | 1062 | popf |
1063 | xor eax, eax |
||
1064 | inc eax |
||
1065 | ret |
||
164 | serge | 1066 | .ipc_blocked: |
2434 | Serge | 1067 | push 2 |
1068 | jmp .ret |
||
164 | serge | 1069 | .buffer_overflow: |
2434 | Serge | 1070 | push 3 |
536 | diamond | 1071 | .ret: |
2434 | Serge | 1072 | mov eax, [used_buf] |
1073 | cmp eax, [ipc_tmp] |
||
5201 | serge | 1074 | je @f |
2434 | Serge | 1075 | stdcall free_kernel_space, eax |
536 | diamond | 1076 | @@: |
2434 | Serge | 1077 | pop eax |
1078 | popf |
||
1079 | ret |
||
164 | serge | 1080 | endp |
1081 | |||
1082 | align 4 |
||
170 | serge | 1083 | sysfn_meminfo: |
2434 | Serge | 1084 | cmp ecx, OS_BASE |
1085 | jae .fail |
||
172 | serge | 1086 | |
2434 | Serge | 1087 | mov eax, [pg_data.pages_count] |
1088 | mov [ecx], eax |
||
1089 | shl eax, 12 |
||
1090 | mov [esp+32], eax |
||
1091 | mov eax, [pg_data.pages_free] |
||
1092 | mov [ecx+4], eax |
||
1093 | mov eax, [pg_data.pages_faults] |
||
1094 | mov [ecx+8], eax |
||
1095 | mov eax, [heap_size] |
||
1096 | mov [ecx+12], eax |
||
1097 | mov eax, [heap_free] |
||
1098 | mov [ecx+16], eax |
||
1099 | mov eax, [heap_blocks] |
||
1100 | mov [ecx+20], eax |
||
1101 | mov eax, [free_blocks] |
||
1102 | mov [ecx+24], eax |
||
1103 | ret |
||
172 | serge | 1104 | .fail: |
2434 | Serge | 1105 | or dword [esp+32], -1 |
1106 | ret |
||
1629 | serge | 1107 | |
164 | serge | 1108 | align 4 |
940 | serge | 1109 | f68: |
2434 | Serge | 1110 | cmp ebx, 4 |
1111 | jbe sys_sheduler |
||
164 | serge | 1112 | |
2434 | Serge | 1113 | cmp ebx, 11 |
1114 | jb .fail |
||
164 | serge | 1115 | |
3908 | Serge | 1116 | cmp ebx, 27 |
2434 | Serge | 1117 | ja .fail |
940 | serge | 1118 | |
2434 | Serge | 1119 | jmp dword [f68call+ebx*4-11*4] |
940 | serge | 1120 | .11: |
2434 | Serge | 1121 | call init_heap |
1122 | mov [esp+32], eax |
||
1123 | ret |
||
940 | serge | 1124 | .12: |
2434 | Serge | 1125 | stdcall user_alloc, ecx |
1126 | mov [esp+32], eax |
||
1127 | ret |
||
940 | serge | 1128 | .13: |
2434 | Serge | 1129 | stdcall user_free, ecx |
1130 | mov [esp+32], eax |
||
1131 | ret |
||
940 | serge | 1132 | .14: |
2434 | Serge | 1133 | cmp ecx, OS_BASE |
1134 | jae .fail |
||
1135 | mov edi, ecx |
||
1136 | call get_event_ex |
||
1137 | mov [esp+32], eax |
||
1138 | ret |
||
940 | serge | 1139 | .16: |
2434 | Serge | 1140 | test ecx, ecx |
1141 | jz .fail |
||
1142 | cmp ecx, OS_BASE |
||
1143 | jae .fail |
||
1144 | stdcall get_service, ecx |
||
1145 | mov [esp+32], eax |
||
1146 | ret |
||
940 | serge | 1147 | .17: |
2434 | Serge | 1148 | call srv_handlerEx ;ecx |
1149 | mov [esp+32], eax |
||
1150 | ret |
||
940 | serge | 1151 | .19: |
2434 | Serge | 1152 | cmp ecx, OS_BASE |
1153 | jae .fail |
||
1154 | stdcall load_library, ecx |
||
1155 | mov [esp+32], eax |
||
1156 | ret |
||
940 | serge | 1157 | .20: |
2434 | Serge | 1158 | mov eax, edx |
1159 | mov ebx, ecx |
||
1160 | call user_realloc ;in: eax = pointer, ebx = new size |
||
1161 | mov [esp+32], eax |
||
1162 | ret |
||
940 | serge | 1163 | .21: |
2434 | Serge | 1164 | cmp ecx, OS_BASE |
1165 | jae .fail |
||
740 | serge | 1166 | |
2987 | Serge | 1167 | cmp edx, OS_BASE |
2434 | Serge | 1168 | jae .fail |
1316 | serge | 1169 | |
4423 | Serge | 1170 | stdcall load_pe_driver, ecx, edx |
2434 | Serge | 1171 | mov [esp+32], eax |
1172 | ret |
||
940 | serge | 1173 | .22: |
2434 | Serge | 1174 | cmp ecx, OS_BASE |
1175 | jae .fail |
||
740 | serge | 1176 | |
2434 | Serge | 1177 | stdcall shmem_open, ecx, edx, esi |
1178 | mov [esp+24], edx |
||
1179 | mov [esp+32], eax |
||
1180 | ret |
||
740 | serge | 1181 | |
943 | serge | 1182 | .23: |
2434 | Serge | 1183 | cmp ecx, OS_BASE |
1184 | jae .fail |
||
943 | serge | 1185 | |
2434 | Serge | 1186 | stdcall shmem_close, ecx |
1187 | mov [esp+32], eax |
||
1188 | ret |
||
1275 | serge | 1189 | .24: |
2434 | Serge | 1190 | mov eax, [current_slot] |
1191 | xchg ecx, [eax+APPDATA.exc_handler] |
||
1192 | xchg edx, [eax+APPDATA.except_mask] |
||
1193 | mov [esp+32], ecx ; reg_eax+8 |
||
1194 | mov [esp+20], edx ; reg_ebx+8 |
||
1195 | ret |
||
1275 | serge | 1196 | .25: |
2434 | Serge | 1197 | cmp ecx, 32 |
1198 | jae .fail |
||
1199 | mov eax, [current_slot] |
||
1200 | btr [eax+APPDATA.except_mask], ecx |
||
1201 | setc byte[esp+32] |
||
1202 | jecxz @f |
||
1203 | bts [eax+APPDATA.except_mask], ecx |
||
1275 | serge | 1204 | @@: |
2434 | Serge | 1205 | ret |
943 | serge | 1206 | |
2434 | Serge | 1207 | .26: |
1208 | stdcall user_unmap, ecx, edx, esi |
||
1209 | mov [esp+32], eax |
||
1210 | ret |
||
1211 | |||
3908 | Serge | 1212 | .27: |
1213 | cmp ecx, OS_BASE |
||
1214 | jae .fail |
||
1215 | |||
1216 | stdcall load_file_umode, ecx |
||
1217 | mov [esp+24], edx |
||
1218 | mov [esp+32], eax |
||
1219 | ret |
||
1220 | |||
164 | serge | 1221 | .fail: |
2434 | Serge | 1222 | xor eax, eax |
1223 | mov [esp+32], eax |
||
1224 | ret |
||
164 | serge | 1225 | |
5596 | serge | 1226 | |
164 | serge | 1227 | align 4 |
5596 | serge | 1228 | f68call: ; keep this table closer to main code |
1229 | |||
1629 | serge | 1230 | dd f68.11 ; init_heap |
1231 | dd f68.12 ; user_alloc |
||
1232 | dd f68.13 ; user_free |
||
1233 | dd f68.14 ; get_event_ex |
||
1234 | dd f68.fail ; moved to f68.24 |
||
1235 | dd f68.16 ; get_service |
||
1236 | dd f68.17 ; call_service |
||
1237 | dd f68.fail ; moved to f68.25 |
||
1238 | dd f68.19 ; load_dll |
||
1239 | dd f68.20 ; user_realloc |
||
1240 | dd f68.21 ; load_driver |
||
1241 | dd f68.22 ; shmem_open |
||
1242 | dd f68.23 ; shmem_close |
||
2434 | Serge | 1243 | dd f68.24 ; set exception handler |
1244 | dd f68.25 ; unmask exception |
||
1245 | dd f68.26 ; user_unmap |
||
3908 | Serge | 1246 | dd f68.27 ; load_file_umode |
1629 | serge | 1247 | |
5596 | serge | 1248 | |
1629 | serge | 1249 | align 4 |
4423 | Serge | 1250 | proc load_pe_driver stdcall, file:dword, cmdline:dword |
1251 | push esi |
||
819 | serge | 1252 | |
2434 | Serge | 1253 | stdcall load_PE, [file] |
1254 | test eax, eax |
||
1255 | jz .fail |
||
819 | serge | 1256 | |
2434 | Serge | 1257 | mov esi, eax |
4423 | Serge | 1258 | push [cmdline] |
1259 | push DRV_ENTRY |
||
1260 | call eax |
||
1261 | pop ecx |
||
1262 | pop ecx |
||
2434 | Serge | 1263 | test eax, eax |
1264 | jz .fail |
||
819 | serge | 1265 | |
2434 | Serge | 1266 | mov [eax+SRV.entry], esi |
4423 | Serge | 1267 | pop esi |
2434 | Serge | 1268 | ret |
819 | serge | 1269 | |
1270 | .fail: |
||
2434 | Serge | 1271 | xor eax, eax |
4423 | Serge | 1272 | pop esi |
2434 | Serge | 1273 | ret |
819 | serge | 1274 | endp |
1275 | |||
1276 | align 4 |
||
520 | serge | 1277 | proc create_ring_buffer stdcall, size:dword, flags:dword |
1278 | locals |
||
1279 | buf_ptr dd ? |
||
1280 | endl |
||
237 | serge | 1281 | |
2434 | Serge | 1282 | mov eax, [size] |
1283 | test eax, eax |
||
1284 | jz .fail |
||
520 | serge | 1285 | |
2434 | Serge | 1286 | add eax, eax |
1287 | stdcall alloc_kernel_space, eax |
||
1288 | test eax, eax |
||
1289 | jz .fail |
||
520 | serge | 1290 | |
2434 | Serge | 1291 | push ebx |
662 | serge | 1292 | |
2434 | Serge | 1293 | mov [buf_ptr], eax |
520 | serge | 1294 | |
2434 | Serge | 1295 | mov ebx, [size] |
1296 | shr ebx, 12 |
||
1297 | push ebx |
||
520 | serge | 1298 | |
2434 | Serge | 1299 | stdcall alloc_pages, ebx |
1300 | pop ecx |
||
520 | serge | 1301 | |
2434 | Serge | 1302 | test eax, eax |
1303 | jz .mm_fail |
||
520 | serge | 1304 | |
2434 | Serge | 1305 | push edi |
662 | serge | 1306 | |
2434 | Serge | 1307 | or eax, [flags] |
1308 | mov edi, [buf_ptr] |
||
1309 | mov ebx, [buf_ptr] |
||
1310 | mov edx, ecx |
||
1311 | shl edx, 2 |
||
1312 | shr edi, 10 |
||
520 | serge | 1313 | @@: |
2434 | Serge | 1314 | mov [page_tabs+edi], eax |
1315 | mov [page_tabs+edi+edx], eax |
||
1316 | invlpg [ebx] |
||
1317 | invlpg [ebx+0x10000] |
||
1318 | add eax, 0x1000 |
||
1319 | add ebx, 0x1000 |
||
1320 | add edi, 4 |
||
1321 | dec ecx |
||
1322 | jnz @B |
||
520 | serge | 1323 | |
2434 | Serge | 1324 | mov eax, [buf_ptr] |
1325 | pop edi |
||
1326 | pop ebx |
||
1327 | ret |
||
520 | serge | 1328 | .mm_fail: |
2434 | Serge | 1329 | stdcall free_kernel_space, [buf_ptr] |
1330 | xor eax, eax |
||
1331 | pop ebx |
||
520 | serge | 1332 | .fail: |
2434 | Serge | 1333 | ret |
520 | serge | 1334 | endp |
2442 | Serge | 1335 | |
1336 | |||
1337 | align 4 |
||
2467 | Serge | 1338 | proc print_mem |
2442 | Serge | 1339 | mov edi, BOOT_VAR + 0x9104 |
1340 | mov ecx, [edi-4] |
||
1341 | test ecx, ecx |
||
3908 | Serge | 1342 | jz .done |
2442 | Serge | 1343 | |
1344 | @@: |
||
3908 | Serge | 1345 | mov eax, [edi] |
1346 | mov edx, [edi+4] |
||
1347 | add eax, [edi+8] |
||
1348 | adc edx, [edi+12] |
||
2442 | Serge | 1349 | |
1350 | DEBUGF 1, "K : E820 %x%x - %x%x type %d\n", \ |
||
1351 | [edi+4], [edi],\ |
||
1352 | edx, eax, [edi+16] |
||
1353 | add edi, 20 |
||
1354 | dec ecx |
||
1355 | jnz @b |
||
1356 | .done: |
||
1357 | ret |
||
2467 | Serge | 1358 | endp0>>=> |