Rev 9917 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9917 | Rev 10002 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2022. 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: 9917 $ |
8 | $Revision: 10002 $ |
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 | map_page: |
127 | map_page: |
128 | push ebx |
128 | push ebx |
129 | mov eax, [esp+12] ; phis_addr |
129 | mov eax, [esp+12] ; phis_addr |
130 | or eax, [esp+16] ; flags |
130 | or eax, [esp+16] ; flags |
131 | and eax, [pte_valid_mask] |
131 | and eax, [pte_valid_mask] |
132 | mov ebx, [esp+8] ; lin_addr |
132 | mov ebx, [esp+8] ; lin_addr |
133 | shr ebx, 12 |
133 | shr ebx, 12 |
134 | mov [page_tabs + ebx*4], eax |
134 | mov [page_tabs + ebx*4], eax |
135 | mov eax, [esp+8] ; lin_addr |
135 | mov eax, [esp+8] ; lin_addr |
136 | pop ebx |
136 | pop ebx |
137 | invlpg [eax] |
137 | invlpg [eax] |
138 | ret 12 |
138 | ret 12 |
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, PAGE_SIZE-1 |
176 | add eax, PAGE_SIZE-1 |
177 | and eax, -PAGE_SIZE |
177 | and eax, -PAGE_SIZE |
178 | mov ecx, [base] |
178 | mov ecx, [base] |
179 | and ecx, -PAGE_SIZE |
179 | and ecx, -PAGE_SIZE |
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, PAGE_SIZE |
188 | mov edi, PAGE_SIZE |
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 | or edx, [flags] |
194 | or edx, [flags] |
195 | and edx, [pte_valid_mask] |
195 | and edx, [pte_valid_mask] |
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, PAGE_SIZE-1 |
206 | and edx, PAGE_SIZE-1 |
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 | and eax, [pte_valid_mask ] |
232 | and eax, [pte_valid_mask ] |
233 | mov edi, ebx |
233 | mov edi, ebx |
234 | shr edi, 12 |
234 | shr edi, 12 |
235 | lea edi, [page_tabs + edi*4] |
235 | lea edi, [page_tabs + edi*4] |
236 | @@: |
236 | @@: |
237 | stosd |
237 | stosd |
238 | invlpg [ebx] |
238 | invlpg [ebx] |
239 | add eax, PAGE_SIZE |
239 | add eax, PAGE_SIZE |
240 | add ebx, PAGE_SIZE |
240 | add ebx, PAGE_SIZE |
241 | loop @B |
241 | loop @B |
242 | 242 | ||
243 | pop edi |
243 | pop edi |
244 | 244 | ||
245 | mov ecx, pg_data.mutex |
245 | mov ecx, pg_data.mutex |
246 | call mutex_unlock |
246 | call mutex_unlock |
247 | .fail: |
247 | .fail: |
248 | ret |
248 | ret |
249 | 249 | ||
250 | 250 | ||
251 | ; param |
251 | ; param |
252 | ; eax= base |
252 | ; eax= base |
253 | ; ecx= count |
253 | ; ecx= count |
254 | 254 | ||
255 | align 4 |
255 | align 4 |
256 | release_pages: |
256 | release_pages: |
257 | 257 | ||
258 | push ebp |
258 | push ebp |
259 | push esi |
259 | push esi |
260 | push edi |
260 | push edi |
261 | push ebx |
261 | push ebx |
262 | 262 | ||
263 | mov esi, eax |
263 | mov esi, eax |
264 | mov edi, eax |
264 | mov edi, eax |
265 | 265 | ||
266 | shr esi, 12 |
266 | shr esi, 12 |
267 | lea esi, [page_tabs + esi*4] |
267 | lea esi, [page_tabs + esi*4] |
268 | 268 | ||
269 | push ecx |
269 | push ecx |
270 | mov ecx, pg_data.mutex |
270 | mov ecx, pg_data.mutex |
271 | call mutex_lock |
271 | call mutex_lock |
272 | pop ecx |
272 | pop ecx |
273 | 273 | ||
274 | mov ebp, [pg_data.pages_free] |
274 | mov ebp, [pg_data.pages_free] |
275 | mov ebx, [page_start] |
275 | mov ebx, [page_start] |
276 | mov edx, sys_pgmap |
276 | mov edx, sys_pgmap |
277 | @@: |
277 | @@: |
278 | xor eax, eax |
278 | xor eax, eax |
279 | xchg eax, [esi] |
279 | xchg eax, [esi] |
280 | invlpg [edi] |
280 | invlpg [edi] |
281 | 281 | ||
282 | test eax, 1 |
282 | test eax, 1 |
283 | jz .next |
283 | jz .next |
284 | 284 | ||
285 | shr eax, 12 |
285 | shr eax, 12 |
286 | bts [edx], eax |
286 | bts [edx], eax |
287 | cmc |
287 | cmc |
288 | adc ebp, 0 |
288 | adc ebp, 0 |
289 | shr eax, 3 |
289 | shr eax, 3 |
290 | and eax, -4 |
290 | and eax, -4 |
291 | add eax, edx |
291 | add eax, edx |
292 | cmp eax, ebx |
292 | cmp eax, ebx |
293 | jae .next |
293 | jae .next |
294 | 294 | ||
295 | mov ebx, eax |
295 | mov ebx, eax |
296 | .next: |
296 | .next: |
297 | add edi, PAGE_SIZE |
297 | add edi, PAGE_SIZE |
298 | add esi, 4 |
298 | add esi, 4 |
299 | loop @B |
299 | loop @B |
300 | 300 | ||
301 | mov [pg_data.pages_free], ebp |
301 | mov [pg_data.pages_free], ebp |
302 | mov ecx, pg_data.mutex |
302 | mov ecx, pg_data.mutex |
303 | call mutex_unlock |
303 | call mutex_unlock |
304 | 304 | ||
305 | pop ebx |
305 | pop ebx |
306 | pop edi |
306 | pop edi |
307 | pop esi |
307 | pop esi |
308 | pop ebp |
308 | pop ebp |
309 | ret |
309 | ret |
310 | 310 | ||
311 | ; param |
311 | ; param |
312 | ; eax= base |
312 | ; eax= base |
313 | ; ecx= count |
313 | ; ecx= count |
314 | 314 | ||
315 | align 4 |
315 | align 4 |
316 | unmap_pages: |
316 | unmap_pages: |
317 | 317 | ||
318 | push edi |
318 | push edi |
319 | 319 | ||
320 | mov edi, eax |
320 | mov edi, eax |
321 | mov edx, eax |
321 | mov edx, eax |
322 | 322 | ||
323 | shr edi, 10 |
323 | shr edi, 10 |
324 | add edi, page_tabs |
324 | add edi, page_tabs |
325 | 325 | ||
326 | xor eax, eax |
326 | xor eax, eax |
327 | @@: |
327 | @@: |
328 | stosd |
328 | stosd |
329 | invlpg [edx] |
329 | invlpg [edx] |
330 | add edx, PAGE_SIZE |
330 | add edx, PAGE_SIZE |
331 | loop @b |
331 | loop @b |
332 | 332 | ||
333 | pop edi |
333 | pop edi |
334 | ret |
334 | ret |
335 | 335 | ||
336 | 336 | ||
337 | align 4 |
337 | align 4 |
338 | proc map_page_table stdcall, lin_addr:dword, phis_addr:dword |
338 | proc map_page_table stdcall, lin_addr:dword, phis_addr:dword |
339 | push ebx |
339 | push ebx |
340 | mov ebx, [lin_addr] |
340 | mov ebx, [lin_addr] |
341 | shr ebx, 22 |
341 | shr ebx, 22 |
342 | mov eax, [phis_addr] |
342 | mov eax, [phis_addr] |
343 | and eax, -PAGE_SIZE |
343 | and eax, -PAGE_SIZE |
344 | or eax, PG_UWR |
344 | or eax, PG_UWR |
345 | mov dword [master_tab + ebx*4], eax |
345 | mov dword [master_tab + ebx*4], eax |
346 | mov eax, [lin_addr] |
346 | mov eax, [lin_addr] |
347 | shr eax, 10 |
347 | shr eax, 10 |
348 | add eax, page_tabs |
348 | add eax, page_tabs |
349 | invlpg [eax] |
349 | invlpg [eax] |
350 | pop ebx |
350 | pop ebx |
351 | ret |
351 | ret |
352 | endp |
352 | endp |
353 | 353 | ||
354 | uglobal |
354 | uglobal |
355 | sb16_buffer_allocated db 0 |
355 | sb16_buffer_allocated db 0 |
356 | endg |
356 | endg |
357 | 357 | ||
358 | ; Allocates [.size] bytes so that the target memory block |
358 | ; Allocates [.size] bytes so that the target memory block |
359 | ; is inside one 64K page for 24-bit DMA controller, |
359 | ; is inside one 64K page for 24-bit DMA controller, |
360 | ; that is, somewhere between 00xx0000h and 00xxFFFFh. |
360 | ; that is, somewhere between 00xx0000h and 00xxFFFFh. |
361 | proc alloc_dma24 |
361 | proc alloc_dma24 |
362 | ; Implementation note. |
362 | ; Implementation note. |
363 | ; The only user of that function is SB16 driver, |
363 | ; The only user of that function is SB16 driver, |
364 | ; so just return a statically allocated buffer. |
364 | ; so just return a statically allocated buffer. |
365 | virtual at esp |
365 | virtual at esp |
366 | dd ? ; return address |
366 | dd ? ; return address |
367 | .size dd ? |
367 | .size dd ? |
368 | end virtual |
368 | end virtual |
369 | cmp [sb16_buffer_allocated], 0 |
369 | cmp [sb16_buffer_allocated], 0 |
370 | jnz .fail |
370 | jnz .fail |
371 | inc [sb16_buffer_allocated] |
371 | inc [sb16_buffer_allocated] |
372 | mov eax, SB16Buffer |
372 | mov eax, SB16Buffer |
373 | ret 4 |
373 | ret 4 |
374 | .fail: |
374 | .fail: |
375 | xor eax, eax |
375 | xor eax, eax |
376 | ret 4 |
376 | ret 4 |
377 | endp |
377 | endp |
378 | 378 | ||
379 | ; Allocates a physical page for master page table |
379 | ; Allocates a physical page for master page table |
380 | ; that duplicates first Mb of OS_BASE at address 0; |
380 | ; that duplicates first Mb of OS_BASE at address 0; |
381 | ; used for starting APs and for shutting down, |
381 | ; used for starting APs and for shutting down, |
382 | ; where it is important to execute code in trivial-mapped pages. |
382 | ; where it is important to execute code in trivial-mapped pages. |
383 | ; Returns eax = allocated physical page. |
383 | ; Returns eax = allocated physical page. |
384 | proc create_trampoline_pgmap |
384 | proc create_trampoline_pgmap |
385 | ; The only non-trivial moment: |
385 | ; The only non-trivial moment: |
386 | ; we need a linear address to fill information, |
386 | ; we need a linear address to fill information, |
387 | ; but we don't need it outside of this function, |
387 | ; but we don't need it outside of this function, |
388 | ; so we're returning physical address. |
388 | ; so we're returning physical address. |
389 | ; Therefore, allocate memory with kernel_alloc, |
389 | ; Therefore, allocate memory with kernel_alloc, |
390 | ; this will allocate physical page and a linear address somewhere, |
390 | ; this will allocate physical page and a linear address somewhere, |
391 | ; and deallocate only linear address with free_kernel_space. |
391 | ; and deallocate only linear address with free_kernel_space. |
392 | stdcall kernel_alloc, PAGE_SIZE |
392 | stdcall kernel_alloc, PAGE_SIZE |
393 | mov edi, eax |
393 | mov edi, eax |
394 | mov esi, master_tab |
394 | mov esi, master_tab |
395 | mov ecx, PAGE_SIZE/4 |
395 | mov ecx, PAGE_SIZE/4 |
396 | rep movsd |
396 | rep movsd |
397 | mov ecx, [master_tab + (OS_BASE shr 20)] |
397 | mov ecx, [master_tab + (OS_BASE shr 20)] |
398 | mov [eax], ecx |
398 | mov [eax], ecx |
399 | mov edi, eax |
399 | mov edi, eax |
400 | call get_pg_addr |
400 | call get_pg_addr |
401 | push eax |
401 | push eax |
402 | stdcall free_kernel_space, edi |
402 | stdcall free_kernel_space, edi |
403 | pop eax |
403 | pop eax |
404 | ret |
404 | ret |
405 | endp |
405 | endp |
406 | 406 | ||
407 | align 4 |
407 | align 4 |
408 | proc new_mem_resize stdcall, new_size:dword |
408 | proc new_mem_resize stdcall, new_size:dword |
409 | 409 | ||
410 | push ebx |
410 | push ebx |
411 | push esi |
411 | push esi |
412 | push edi |
412 | push edi |
413 | 413 | ||
414 | mov edx, [current_slot] |
414 | mov edx, [current_slot] |
415 | mov ebx, [edx + APPDATA.process] |
415 | mov ebx, [edx + APPDATA.process] |
416 | 416 | ||
417 | cmp [ebx + PROC.heap_base], 0 |
417 | cmp [ebx + PROC.heap_base], 0 |
418 | jne .exit |
418 | jne .exit |
419 | 419 | ||
420 | mov edi, [new_size] |
420 | mov edi, [new_size] |
421 | add edi, PAGE_SIZE-1 |
421 | add edi, PAGE_SIZE-1 |
422 | and edi, -PAGE_SIZE |
422 | and edi, -PAGE_SIZE |
423 | mov [new_size], edi |
423 | mov [new_size], edi |
424 | 424 | ||
425 | mov esi, [ebx + PROC.mem_used] |
425 | mov esi, [ebx + PROC.mem_used] |
426 | add esi, PAGE_SIZE-1 |
426 | add esi, PAGE_SIZE-1 |
427 | and esi, -PAGE_SIZE |
427 | and esi, -PAGE_SIZE |
428 | 428 | ||
429 | cmp edi, esi |
429 | cmp edi, esi |
430 | ja .expand |
430 | ja .expand |
431 | je .exit |
431 | je .exit |
432 | 432 | ||
433 | mov ebx, edi |
433 | mov ebx, edi |
434 | shr edi, 12 |
434 | shr edi, 12 |
435 | shr esi, 12 |
435 | shr esi, 12 |
436 | 436 | ||
437 | mov ecx, pg_data.mutex |
437 | mov ecx, pg_data.mutex |
438 | call mutex_lock |
438 | call mutex_lock |
439 | @@: |
439 | @@: |
440 | mov eax, [app_page_tabs + edi*4] |
440 | mov eax, [app_page_tabs + edi*4] |
441 | test eax, 1 |
441 | test eax, 1 |
442 | jz .next |
442 | jz .next |
443 | 443 | ||
444 | mov dword [app_page_tabs + edi*4], 0 |
444 | mov dword [app_page_tabs + edi*4], 0 |
445 | invlpg [ebx] |
445 | invlpg [ebx] |
446 | call free_page |
446 | call free_page |
447 | 447 | ||
448 | .next: |
448 | .next: |
449 | inc edi |
449 | inc edi |
450 | add ebx, PAGE_SIZE |
450 | add ebx, PAGE_SIZE |
451 | cmp edi, esi |
451 | cmp edi, esi |
452 | jb @B |
452 | jb @B |
453 | 453 | ||
454 | mov ecx, pg_data.mutex |
454 | mov ecx, pg_data.mutex |
455 | call mutex_unlock |
455 | call mutex_unlock |
456 | 456 | ||
457 | .update_size: |
457 | .update_size: |
458 | mov edx, [current_slot] |
458 | mov edx, [current_slot] |
459 | mov ebx, [new_size] |
459 | mov ebx, [new_size] |
460 | mov edx, [edx + APPDATA.process] |
460 | mov edx, [edx + APPDATA.process] |
461 | mov [edx + PROC.mem_used], ebx |
461 | mov [edx + PROC.mem_used], ebx |
462 | .exit: |
462 | .exit: |
463 | pop edi |
463 | pop edi |
464 | pop esi |
464 | pop esi |
465 | pop ebx |
465 | pop ebx |
466 | xor eax, eax |
466 | xor eax, eax |
467 | ret |
467 | ret |
468 | 468 | ||
469 | .expand: |
469 | .expand: |
470 | 470 | ||
471 | mov ecx, pg_data.mutex |
471 | mov ecx, pg_data.mutex |
472 | call mutex_lock |
472 | call mutex_lock |
473 | 473 | ||
474 | xchg esi, edi |
474 | xchg esi, edi |
475 | 475 | ||
476 | push esi ;new size |
476 | push esi ;new size |
477 | push edi ;old size |
477 | push edi ;old size |
478 | 478 | ||
479 | add edi, 0x3FFFFF |
479 | add edi, 0x3FFFFF |
480 | and edi, not(0x3FFFFF) |
480 | and edi, not(0x3FFFFF) |
481 | add esi, 0x3FFFFF |
481 | add esi, 0x3FFFFF |
482 | and esi, not(0x3FFFFF) |
482 | and esi, not(0x3FFFFF) |
483 | 483 | ||
484 | cmp edi, esi |
484 | cmp edi, esi |
485 | jae .grow |
485 | jae .grow |
486 | @@: |
486 | @@: |
487 | call alloc_page |
487 | call alloc_page |
488 | test eax, eax |
488 | test eax, eax |
489 | jz .exit_fail |
489 | jz .exit_fail |
490 | 490 | ||
491 | stdcall map_page_table, edi, eax |
491 | stdcall map_page_table, edi, eax |
492 | 492 | ||
493 | push edi |
493 | push edi |
494 | shr edi, 10 |
494 | shr edi, 10 |
495 | add edi, page_tabs |
495 | add edi, page_tabs |
496 | mov ecx, 1024 |
496 | mov ecx, 1024 |
497 | xor eax, eax |
497 | xor eax, eax |
498 | cld |
498 | cld |
499 | rep stosd |
499 | rep stosd |
500 | pop edi |
500 | pop edi |
501 | 501 | ||
502 | add edi, 0x00400000 |
502 | add edi, 0x00400000 |
503 | cmp edi, esi |
503 | cmp edi, esi |
504 | jb @B |
504 | jb @B |
505 | .grow: |
505 | .grow: |
506 | pop edi ;old size |
506 | pop edi ;old size |
507 | pop ecx ;new size |
507 | pop ecx ;new size |
508 | 508 | ||
509 | shr edi, 10 |
509 | shr edi, 10 |
510 | shr ecx, 10 |
510 | shr ecx, 10 |
511 | sub ecx, edi |
511 | sub ecx, edi |
512 | shr ecx, 2 ;pages count |
512 | shr ecx, 2 ;pages count |
513 | mov eax, 2 |
513 | mov eax, 2 |
514 | 514 | ||
515 | add edi, app_page_tabs |
515 | add edi, app_page_tabs |
516 | rep stosd |
516 | rep stosd |
517 | 517 | ||
518 | mov ecx, pg_data.mutex |
518 | mov ecx, pg_data.mutex |
519 | call mutex_unlock |
519 | call mutex_unlock |
520 | 520 | ||
521 | jmp .update_size |
521 | jmp .update_size |
522 | 522 | ||
523 | .exit_fail: |
523 | .exit_fail: |
524 | mov ecx, pg_data.mutex |
524 | mov ecx, pg_data.mutex |
525 | call mutex_unlock |
525 | call mutex_unlock |
526 | 526 | ||
527 | add esp, 8 |
527 | add esp, 8 |
528 | pop edi |
528 | pop edi |
529 | pop esi |
529 | pop esi |
530 | pop ebx |
530 | pop ebx |
531 | xor eax, eax |
531 | xor eax, eax |
532 | inc eax |
532 | inc eax |
533 | ret |
533 | ret |
534 | endp |
534 | endp |
535 | 535 | ||
536 | 536 | ||
537 | ; param |
537 | ; param |
538 | ; eax= linear address |
538 | ; eax= linear address |
539 | ; |
539 | ; |
540 | ; retval |
540 | ; retval |
541 | ; eax= physical page address |
541 | ; eax= physical page address |
542 | 542 | ||
543 | align 4 |
543 | align 4 |
544 | get_pg_addr: |
544 | get_pg_addr: |
545 | sub eax, OS_BASE |
545 | sub eax, OS_BASE |
546 | cmp eax, 0x400000 |
546 | cmp eax, 0x400000 |
547 | jb @f |
547 | jb @f |
548 | shr eax, 12 |
548 | shr eax, 12 |
549 | mov eax, [page_tabs + (eax+(OS_BASE shr 12))*4] |
549 | mov eax, [page_tabs + (eax+(OS_BASE shr 12))*4] |
550 | @@: |
550 | @@: |
551 | and eax, -PAGE_SIZE |
551 | and eax, -PAGE_SIZE |
552 | ret |
552 | ret |
553 | 553 | ||
554 | 554 | ||
555 | align 4 |
555 | align 4 |
556 | ; Now it is called from core/sys32::exc_c (see stack frame there) |
556 | ; Now it is called from core/sys32::exc_c (see stack frame there) |
557 | proc page_fault_handler |
557 | proc page_fault_handler |
558 | 558 | ||
559 | .err_addr equ ebp-4 |
559 | .err_addr equ ebp-4 |
560 | 560 | ||
561 | push ebx ;save exception number (#PF) |
561 | push ebx ;save exception number (#PF) |
562 | mov ebp, esp |
562 | mov ebp, esp |
563 | mov ebx, cr2 |
563 | mov ebx, cr2 |
564 | push ebx ;that is locals: .err_addr = cr2 |
564 | push ebx ;that is locals: .err_addr = cr2 |
565 | inc [pg_data.pages_faults] |
565 | inc [pg_data.pages_faults] |
566 | 566 | ||
567 | mov eax, [pf_err_code] |
567 | mov eax, [pf_err_code] |
568 | 568 | ||
569 | cmp ebx, OS_BASE ;ebx == .err_addr |
569 | cmp ebx, OS_BASE ;ebx == .err_addr |
570 | jb .user_space ;page in application memory |
570 | jb .user_space ;page in application memory |
571 | 571 | ||
572 | cmp ebx, page_tabs |
572 | cmp ebx, page_tabs |
573 | jb .kernel_space ;page in kernel memory |
573 | jb .kernel_space ;page in kernel memory |
574 | 574 | ||
575 | cmp ebx, kernel_tabs |
575 | cmp ebx, kernel_tabs |
576 | jb .alloc;.app_tabs ;page tables of application ; |
576 | jb .alloc;.app_tabs ;page tables of application ; |
577 | ;simply create one |
577 | ;simply create one |
578 | .core_tabs: |
578 | .core_tabs: |
579 | .fail: ;simply return to caller |
579 | .fail: ;simply return to caller |
580 | mov esp, ebp |
580 | mov esp, ebp |
581 | pop ebx ;restore exception number (#PF) |
581 | pop ebx ;restore exception number (#PF) |
582 | ret |
582 | ret |
583 | 583 | ||
584 | .user_space: |
584 | .user_space: |
585 | test eax, PG_READ |
585 | test eax, PG_READ |
586 | jnz .err_access ;Page presents |
586 | jnz .err_access ;Page presents |
587 | ;Access error ? |
587 | ;Access error ? |
588 | 588 | ||
589 | shr ebx, 12 |
589 | shr ebx, 12 |
590 | mov ecx, ebx |
590 | mov ecx, ebx |
591 | shr ecx, 10 |
591 | shr ecx, 10 |
592 | mov edx, [master_tab + ecx*4] |
592 | mov edx, [master_tab + ecx*4] |
593 | test edx, PG_READ |
593 | test edx, PG_READ |
594 | jz .fail ;page table is not created |
594 | jz .fail ;page table is not created |
595 | ;incorrect address in program |
595 | ;incorrect address in program |
596 | 596 | ||
597 | mov eax, [page_tabs + ebx*4] |
597 | mov eax, [page_tabs + ebx*4] |
598 | test eax, 2 |
598 | test eax, 2 |
599 | jz .fail ;address is not reserved for usage. Error |
599 | jz .fail ;address is not reserved for usage. Error |
600 | 600 | ||
601 | .alloc: |
601 | .alloc: |
602 | call alloc_page |
602 | call alloc_page |
603 | test eax, eax |
603 | test eax, eax |
604 | jz .fail |
604 | jz .fail |
605 | 605 | ||
606 | stdcall map_page, [.err_addr], eax, PG_UWR |
606 | stdcall map_page, [.err_addr], eax, PG_UWR |
607 | 607 | ||
608 | mov edi, [.err_addr] |
608 | mov edi, [.err_addr] |
609 | and edi, -PAGE_SIZE |
609 | and edi, -PAGE_SIZE |
610 | mov ecx, 1024 |
610 | mov ecx, 1024 |
611 | xor eax, eax |
611 | xor eax, eax |
612 | ;cld ;caller is duty for this |
612 | ;cld ;caller is duty for this |
613 | rep stosd |
613 | rep stosd |
614 | .exit: ;iret with repeat fault instruction |
614 | .exit: ;iret with repeat fault instruction |
615 | add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
615 | add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
616 | restore_ring3_context |
616 | restore_ring3_context |
617 | iretd |
617 | iretd |
618 | 618 | ||
619 | .err_access: |
619 | .err_access: |
620 | ; access denied? this may be a result of copy-on-write protection for DLL |
620 | ; access denied? this may be a result of copy-on-write protection for DLL |
621 | ; check list of HDLLs |
621 | ; check list of HDLLs |
622 | and ebx, -PAGE_SIZE |
622 | and ebx, -PAGE_SIZE |
623 | mov eax, [current_process] |
623 | mov eax, [current_process] |
624 | mov eax, [eax + PROC.dlls_list_ptr] |
624 | mov eax, [eax + PROC.dlls_list_ptr] |
625 | test eax, eax |
625 | test eax, eax |
626 | jz .fail |
626 | jz .fail |
627 | mov esi, [eax + HDLL.fd] |
627 | mov esi, [eax + HDLL.fd] |
628 | .scan_hdll: |
628 | .scan_hdll: |
629 | cmp esi, eax |
629 | cmp esi, eax |
630 | jz .fail |
630 | jz .fail |
631 | mov edx, ebx |
631 | mov edx, ebx |
632 | sub edx, [esi + HDLL.base] |
632 | sub edx, [esi + HDLL.base] |
633 | cmp edx, [esi + HDLL.size] |
633 | cmp edx, [esi + HDLL.size] |
634 | jb .fault_in_hdll |
634 | jb .fault_in_hdll |
635 | .scan_hdll.next: |
635 | .scan_hdll.next: |
636 | mov esi, [esi + HDLL.fd] |
636 | mov esi, [esi + HDLL.fd] |
637 | jmp .scan_hdll |
637 | jmp .scan_hdll |
638 | .fault_in_hdll: |
638 | .fault_in_hdll: |
639 | ; allocate new page, map it as rw and copy data |
639 | ; allocate new page, map it as rw and copy data |
640 | call alloc_page |
640 | call alloc_page |
641 | test eax, eax |
641 | test eax, eax |
642 | jz .fail |
642 | jz .fail |
643 | stdcall map_page, ebx, eax, PG_UWR |
643 | stdcall map_page, ebx, eax, PG_UWR |
644 | mov edi, ebx |
644 | mov edi, ebx |
645 | mov ecx, 1024 |
645 | mov ecx, 1024 |
646 | sub ebx, [esi + HDLL.base] |
646 | sub ebx, [esi + HDLL.base] |
647 | mov esi, [esi + HDLL.parent] |
647 | mov esi, [esi + HDLL.parent] |
648 | mov esi, [esi + DLLDESCR.data] |
648 | mov esi, [esi + DLLDESCR.data] |
649 | add esi, ebx |
649 | add esi, ebx |
650 | rep movsd |
650 | rep movsd |
651 | jmp .exit |
651 | jmp .exit |
652 | 652 | ||
653 | .kernel_space: |
653 | .kernel_space: |
654 | test eax, PG_READ |
654 | test eax, PG_READ |
655 | jz .fail ;page does not present |
655 | jz .fail ;page does not present |
656 | 656 | ||
657 | test eax, 12 ;U/S (+below) |
657 | test eax, 12 ;U/S (+below) |
658 | jnz .fail ;application requested kernel memory |
658 | jnz .fail ;application requested kernel memory |
659 | 659 | ||
660 | ;test eax, 8 |
660 | ;test eax, 8 |
661 | ;jnz .fail ;the reserved bit is set in page tables. Added in P4/Xeon |
661 | ;jnz .fail ;the reserved bit is set in page tables. Added in P4/Xeon |
662 | 662 | ||
663 | 663 | ||
664 | ;an attempt to write to a protected kernel page |
664 | ;an attempt to write to a protected kernel page |
665 | 665 | ||
666 | cmp ebx, tss._io_map_0 |
666 | cmp ebx, tss._io_map_0 |
667 | jb .fail |
667 | jb .fail |
668 | 668 | ||
669 | cmp ebx, tss._io_map_0+8192 |
669 | cmp ebx, tss._io_map_0+8192 |
670 | jae .fail |
670 | jae .fail |
671 | 671 | ||
672 | ; io permission map |
672 | ; io permission map |
673 | ; copy-on-write protection |
673 | ; copy-on-write protection |
674 | 674 | ||
675 | call alloc_page |
675 | call alloc_page |
676 | test eax, eax |
676 | test eax, eax |
677 | jz .fail |
677 | jz .fail |
678 | 678 | ||
679 | push eax |
679 | push eax |
680 | stdcall map_page, [.err_addr], eax, dword PG_SWR |
680 | stdcall map_page, [.err_addr], eax, dword PG_SWR |
681 | pop eax |
681 | pop eax |
682 | mov edi, [.err_addr] |
682 | mov edi, [.err_addr] |
683 | and edi, -PAGE_SIZE |
683 | and edi, -PAGE_SIZE |
684 | lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 |
684 | lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 |
685 | 685 | ||
686 | mov ebx, esi |
686 | mov ebx, esi |
687 | shr ebx, 12 |
687 | shr ebx, 12 |
688 | mov edx, [current_slot] |
688 | mov edx, [current_slot] |
689 | or eax, PG_SWR |
689 | or eax, PG_SWR |
690 | mov [edx + APPDATA.io_map + ebx*4], eax |
690 | mov [edx + APPDATA.io_map + ebx*4], eax |
691 | 691 | ||
692 | add esi, [default_io_map] |
692 | add esi, [default_io_map] |
693 | mov ecx, PAGE_SIZE/4 |
693 | mov ecx, PAGE_SIZE/4 |
694 | ;cld ;caller is duty for this |
694 | ;cld ;caller is duty for this |
695 | rep movsd |
695 | rep movsd |
696 | jmp .exit |
696 | jmp .exit |
697 | endp |
697 | endp |
698 | 698 | ||
699 | ; returns number of mapped bytes |
699 | ; returns number of mapped bytes |
700 | proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\ |
700 | proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\ |
701 | ofs:dword,buf_size:dword,req_access:dword |
701 | ofs:dword,buf_size:dword,req_access:dword |
702 | locals |
702 | locals |
703 | count dd ? |
703 | count dd ? |
704 | process dd ? |
704 | process dd ? |
705 | endl |
705 | endl |
706 | 706 | ||
707 | mov [count], 0 |
707 | mov [count], 0 |
708 | cmp [buf_size], 0 |
708 | cmp [buf_size], 0 |
709 | jz .exit |
709 | jz .exit |
710 | 710 | ||
711 | mov eax, [slot] |
711 | mov eax, [slot] |
712 | shl eax, BSF sizeof.APPDATA |
712 | shl eax, BSF sizeof.APPDATA |
713 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
713 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
714 | test eax, eax |
714 | test eax, eax |
715 | jz .exit |
715 | jz .exit |
716 | 716 | ||
717 | mov [process], eax |
717 | mov [process], eax |
718 | mov ebx, [ofs] |
718 | mov ebx, [ofs] |
719 | shr ebx, 22 |
719 | shr ebx, 22 |
720 | mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table |
720 | mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table |
721 | mov esi, [ipc_ptab] |
721 | mov esi, [ipc_ptab] |
722 | and eax, -PAGE_SIZE |
722 | and eax, -PAGE_SIZE |
723 | jz .exit |
723 | jz .exit |
724 | stdcall map_page, esi, eax, PG_SWR |
724 | stdcall map_page, esi, eax, PG_SWR |
725 | @@: |
725 | @@: |
726 | mov edi, [lin_addr] |
726 | mov edi, [lin_addr] |
727 | and edi, -PAGE_SIZE |
727 | and edi, -PAGE_SIZE |
728 | mov ecx, [buf_size] |
728 | mov ecx, [buf_size] |
729 | add ecx, PAGE_SIZE-1 |
729 | add ecx, PAGE_SIZE-1 |
730 | shr ecx, 12 |
730 | shr ecx, 12 |
731 | inc ecx ; ??????????? |
731 | inc ecx ; ??????????? |
732 | 732 | ||
733 | mov edx, [ofs] |
733 | mov edx, [ofs] |
734 | shr edx, 12 |
734 | shr edx, 12 |
735 | and edx, 0x3FF |
735 | and edx, 0x3FF |
736 | .map: |
736 | .map: |
737 | stdcall safe_map_page, [slot], [req_access], [ofs] |
737 | stdcall safe_map_page, [slot], [req_access], [ofs] |
738 | jnc .exit |
738 | jnc .exit |
739 | add [count], PAGE_SIZE |
739 | add [count], PAGE_SIZE |
740 | add [ofs], PAGE_SIZE |
740 | add [ofs], PAGE_SIZE |
741 | dec ecx |
741 | dec ecx |
742 | jz .exit |
742 | jz .exit |
743 | 743 | ||
744 | add edi, PAGE_SIZE |
744 | add edi, PAGE_SIZE |
745 | inc edx |
745 | inc edx |
746 | cmp edx, 1024 |
746 | cmp edx, 1024 |
747 | jnz .map |
747 | jnz .map |
748 | 748 | ||
749 | inc ebx |
749 | inc ebx |
750 | mov eax, [process] |
750 | mov eax, [process] |
751 | mov eax, [eax + PROC.pdt_0 + ebx*4] |
751 | mov eax, [eax + PROC.pdt_0 + ebx*4] |
752 | and eax, -PAGE_SIZE |
752 | and eax, -PAGE_SIZE |
753 | jz .exit |
753 | jz .exit |
754 | 754 | ||
755 | stdcall map_page, esi, eax, PG_SWR |
755 | stdcall map_page, esi, eax, PG_SWR |
756 | xor edx, edx |
756 | xor edx, edx |
757 | jmp .map |
757 | jmp .map |
758 | .exit: |
758 | .exit: |
759 | mov eax, [count] |
759 | mov eax, [count] |
760 | ret |
760 | ret |
761 | endp |
761 | endp |
762 | 762 | ||
763 | proc map_memEx stdcall, lin_addr:dword,slot:dword,\ |
763 | proc map_memEx stdcall, lin_addr:dword,slot:dword,\ |
764 | ofs:dword,buf_size:dword,req_access:dword |
764 | ofs:dword,buf_size:dword,req_access:dword |
765 | locals |
765 | locals |
766 | count dd ? |
766 | count dd ? |
767 | process dd ? |
767 | process dd ? |
768 | endl |
768 | endl |
769 | 769 | ||
770 | mov [count], 0 |
770 | mov [count], 0 |
771 | cmp [buf_size], 0 |
771 | cmp [buf_size], 0 |
772 | jz .exit |
772 | jz .exit |
773 | 773 | ||
774 | mov eax, [slot] |
774 | mov eax, [slot] |
775 | shl eax, BSF sizeof.APPDATA |
775 | shl eax, BSF sizeof.APPDATA |
776 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
776 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
777 | test eax, eax |
777 | test eax, eax |
778 | jz .exit |
778 | jz .exit |
779 | 779 | ||
780 | mov [process], eax |
780 | mov [process], eax |
781 | mov ebx, [ofs] |
781 | mov ebx, [ofs] |
782 | shr ebx, 22 |
782 | shr ebx, 22 |
783 | mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table |
783 | mov eax, [eax + PROC.pdt_0 + ebx*4] ;get page table |
784 | mov esi, [proc_mem_tab] |
784 | mov esi, [proc_mem_tab] |
785 | and eax, -PAGE_SIZE |
785 | and eax, -PAGE_SIZE |
786 | jz .exit |
786 | jz .exit |
787 | stdcall map_page, esi, eax, PG_SWR |
787 | stdcall map_page, esi, eax, PG_SWR |
788 | @@: |
788 | @@: |
789 | mov edi, [lin_addr] |
789 | mov edi, [lin_addr] |
790 | and edi, -PAGE_SIZE |
790 | and edi, -PAGE_SIZE |
791 | mov ecx, [buf_size] |
791 | mov ecx, [buf_size] |
792 | add ecx, PAGE_SIZE-1 |
792 | add ecx, PAGE_SIZE-1 |
793 | shr ecx, 12 |
793 | shr ecx, 12 |
794 | inc ecx ; ??????????? |
794 | inc ecx ; ??????????? |
795 | 795 | ||
796 | mov edx, [ofs] |
796 | mov edx, [ofs] |
797 | shr edx, 12 |
797 | shr edx, 12 |
798 | and edx, 0x3FF |
798 | and edx, 0x3FF |
799 | .map: |
799 | .map: |
800 | stdcall safe_map_page, [slot], [req_access], [ofs] |
800 | stdcall safe_map_page, [slot], [req_access], [ofs] |
801 | jnc .exit |
801 | jnc .exit |
802 | add [count], PAGE_SIZE |
802 | add [count], PAGE_SIZE |
803 | add [ofs], PAGE_SIZE |
803 | add [ofs], PAGE_SIZE |
804 | dec ecx |
804 | dec ecx |
805 | jz .exit |
805 | jz .exit |
806 | 806 | ||
807 | add edi, PAGE_SIZE |
807 | add edi, PAGE_SIZE |
808 | inc edx |
808 | inc edx |
809 | cmp edx, 1024 |
809 | cmp edx, 1024 |
810 | jnz .map |
810 | jnz .map |
811 | 811 | ||
812 | inc ebx |
812 | inc ebx |
813 | mov eax, [process] |
813 | mov eax, [process] |
814 | mov eax, [eax + PROC.pdt_0 + ebx*4] |
814 | mov eax, [eax + PROC.pdt_0 + ebx*4] |
815 | and eax, -PAGE_SIZE |
815 | and eax, -PAGE_SIZE |
816 | jz .exit |
816 | jz .exit |
817 | 817 | ||
818 | stdcall map_page, esi, eax, PG_SWR |
818 | stdcall map_page, esi, eax, PG_SWR |
819 | xor edx, edx |
819 | xor edx, edx |
820 | jmp .map |
820 | jmp .map |
821 | .exit: |
821 | .exit: |
822 | mov eax, [count] |
822 | mov eax, [count] |
823 | ret |
823 | ret |
824 | endp |
824 | endp |
825 | 825 | ||
826 | ; in: esi+edx*4 = pointer to page table entry |
826 | ; in: esi+edx*4 = pointer to page table entry |
827 | ; in: [slot], [req_access], [ofs] on the stack |
827 | ; in: [slot], [req_access], [ofs] on the stack |
828 | ; in: edi = linear address to map |
828 | ; in: edi = linear address to map |
829 | ; out: CF cleared <=> failed |
829 | ; out: CF cleared <=> failed |
830 | ; destroys: only eax |
830 | ; destroys: only eax |
831 | proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
831 | proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
832 | mov eax, [esi + edx*4] |
832 | mov eax, [esi + edx*4] |
833 | test al, PG_READ |
833 | test al, PG_READ |
834 | jz .not_present |
834 | jz .not_present |
835 | test al, PG_WRITE |
835 | test al, PG_WRITE |
836 | jz .resolve_readonly |
836 | jz .resolve_readonly |
837 | ; normal case: writable page, just map with requested access |
837 | ; normal case: writable page, just map with requested access |
838 | .map: |
838 | .map: |
839 | stdcall map_page, edi, eax, [req_access] |
839 | stdcall map_page, edi, eax, [req_access] |
840 | stc |
840 | stc |
841 | .fail: |
841 | .fail: |
842 | ret |
842 | ret |
843 | .not_present: |
843 | .not_present: |
844 | ; check for alloc-on-demand page |
844 | ; check for alloc-on-demand page |
845 | test al, 2 |
845 | test al, 2 |
846 | jz .fail |
846 | jz .fail |
847 | ; allocate new page, save it to source page table |
847 | ; allocate new page, save it to source page table |
848 | push ecx |
848 | push ecx |
849 | call alloc_page |
849 | call alloc_page |
850 | pop ecx |
850 | pop ecx |
851 | test eax, eax |
851 | test eax, eax |
852 | jz .fail |
852 | jz .fail |
853 | or al, PG_UWR |
853 | or al, PG_UWR |
854 | mov [esi + edx*4], eax |
854 | mov [esi + edx*4], eax |
855 | jmp .map |
855 | jmp .map |
856 | .resolve_readonly: |
856 | .resolve_readonly: |
857 | ; readonly page, probably copy-on-write |
857 | ; readonly page, probably copy-on-write |
858 | ; check: readonly request of readonly page is ok |
858 | ; check: readonly request of readonly page is ok |
859 | test [req_access], PG_WRITE |
859 | test [req_access], PG_WRITE |
860 | jz .map |
860 | jz .map |
861 | ; find control structure for this page |
861 | ; find control structure for this page |
862 | pushf |
862 | pushf |
863 | cli |
863 | cli |
864 | cld |
864 | cld |
865 | push ebx ecx |
865 | push ebx ecx |
866 | mov eax, [slot] |
866 | mov eax, [slot] |
867 | shl eax, BSF sizeof.APPDATA |
867 | shl eax, BSF sizeof.APPDATA |
868 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
868 | mov eax, [SLOT_BASE + eax + APPDATA.process] |
869 | mov eax, [eax + PROC.dlls_list_ptr] |
869 | mov eax, [eax + PROC.dlls_list_ptr] |
870 | test eax, eax |
870 | test eax, eax |
871 | jz .no_hdll |
871 | jz .no_hdll |
872 | mov ecx, [eax + HDLL.fd] |
872 | mov ecx, [eax + HDLL.fd] |
873 | .scan_hdll: |
873 | .scan_hdll: |
874 | cmp ecx, eax |
874 | cmp ecx, eax |
875 | jz .no_hdll |
875 | jz .no_hdll |
876 | mov ebx, [ofs] |
876 | mov ebx, [ofs] |
877 | and ebx, -PAGE_SIZE |
877 | and ebx, -PAGE_SIZE |
878 | sub ebx, [ecx + HDLL.base] |
878 | sub ebx, [ecx + HDLL.base] |
879 | cmp ebx, [ecx + HDLL.size] |
879 | cmp ebx, [ecx + HDLL.size] |
880 | jb .hdll_found |
880 | jb .hdll_found |
881 | mov ecx, [ecx + HDLL.fd] |
881 | mov ecx, [ecx + HDLL.fd] |
882 | jmp .scan_hdll |
882 | jmp .scan_hdll |
883 | .no_hdll: |
883 | .no_hdll: |
884 | pop ecx ebx |
884 | pop ecx ebx |
885 | popf |
885 | popf |
886 | clc |
886 | clc |
887 | ret |
887 | ret |
888 | .hdll_found: |
888 | .hdll_found: |
889 | ; allocate page, save it in page table, map it, copy contents from base |
889 | ; allocate page, save it in page table, map it, copy contents from base |
890 | mov eax, [ecx + HDLL.parent] |
890 | mov eax, [ecx + HDLL.parent] |
891 | add ebx, [eax + DLLDESCR.data] |
891 | add ebx, [eax + DLLDESCR.data] |
892 | call alloc_page |
892 | call alloc_page |
893 | test eax, eax |
893 | test eax, eax |
894 | jz .no_hdll |
894 | jz .no_hdll |
895 | or al, PG_UWR |
895 | or al, PG_UWR |
896 | mov [esi + edx*4], eax |
896 | mov [esi + edx*4], eax |
897 | stdcall map_page, edi, eax, [req_access] |
897 | stdcall map_page, edi, eax, [req_access] |
898 | push esi edi |
898 | push esi edi |
899 | mov esi, ebx |
899 | mov esi, ebx |
900 | mov ecx, PAGE_SIZE/4 |
900 | mov ecx, PAGE_SIZE/4 |
901 | rep movsd |
901 | rep movsd |
902 | pop edi esi |
902 | pop edi esi |
903 | pop ecx ebx |
903 | pop ecx ebx |
904 | popf |
904 | popf |
905 | stc |
905 | stc |
906 | ret |
906 | ret |
907 | endp |
907 | endp |
908 | 908 | ||
909 | sys_IPC: |
909 | sys_IPC: |
910 | ;input: |
910 | ;input: |
911 | ; ebx=1 - set ipc buffer area |
911 | ; ebx=1 - set ipc buffer area |
912 | ; ecx=address of buffer |
912 | ; ecx=address of buffer |
913 | ; edx=size of buffer |
913 | ; edx=size of buffer |
914 | ; eax=2 - send message |
914 | ; eax=2 - send message |
915 | ; ebx=PID |
915 | ; ebx=PID |
916 | ; ecx=address of message |
916 | ; ecx=address of message |
917 | ; edx=size of message |
917 | ; edx=size of message |
918 | 918 | ||
919 | dec ebx |
919 | dec ebx |
920 | jnz @f |
920 | jnz @f |
921 | 921 | ||
922 | mov eax, [current_slot] |
922 | mov eax, [current_slot] |
923 | pushf |
923 | pushf |
924 | cli |
924 | cli |
925 | mov [eax + APPDATA.ipc_start], ecx ;set fields in extended information area |
925 | mov [eax + APPDATA.ipc_start], ecx ;set fields in extended information area |
926 | mov [eax + APPDATA.ipc_size], edx |
926 | mov [eax + APPDATA.ipc_size], edx |
927 | 927 | ||
928 | add edx, ecx |
928 | add edx, ecx |
929 | add edx, PAGE_SIZE-1 |
929 | add edx, PAGE_SIZE-1 |
930 | and edx, -PAGE_SIZE |
930 | and edx, -PAGE_SIZE |
931 | 931 | ||
932 | .touch: |
932 | .touch: |
933 | mov eax, [ecx] |
933 | mov eax, [ecx] |
934 | add ecx, PAGE_SIZE |
934 | add ecx, PAGE_SIZE |
935 | cmp ecx, edx |
935 | cmp ecx, edx |
936 | jb .touch |
936 | jb .touch |
937 | 937 | ||
938 | popf |
938 | popf |
939 | mov [esp + SYSCALL_STACK.eax], ebx ;ebx=0 |
939 | mov [esp + SYSCALL_STACK.eax], ebx ;ebx=0 |
940 | ret |
940 | ret |
941 | 941 | ||
942 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
942 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
943 | ;2 |
943 | ;2 |
944 | @@: |
944 | @@: |
945 | dec ebx |
945 | dec ebx |
946 | jnz @f |
946 | jnz @f |
947 | 947 | ||
948 | stdcall sys_ipc_send, ecx, edx, esi |
948 | stdcall sys_ipc_send, ecx, edx, esi |
949 | mov [esp + SYSCALL_STACK.eax], eax |
949 | mov [esp + SYSCALL_STACK.eax], eax |
950 | ret |
950 | ret |
951 | @@: |
951 | @@: |
952 | or eax, -1 |
952 | or eax, -1 |
953 | mov [esp + SYSCALL_STACK.eax], eax |
953 | mov [esp + SYSCALL_STACK.eax], eax |
954 | ret |
954 | ret |
955 | 955 | ||
956 | proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
956 | proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
957 | locals |
957 | locals |
958 | dst_slot dd ? |
958 | dst_slot dd ? |
959 | dst_offset dd ? |
959 | dst_offset dd ? |
960 | buf_size dd ? |
960 | buf_size dd ? |
961 | used_buf dd ? |
961 | used_buf dd ? |
962 | endl |
962 | endl |
963 | 963 | ||
964 | pushf |
964 | pushf |
965 | cli |
965 | cli |
966 | 966 | ||
967 | mov eax, [PID] |
967 | mov eax, [PID] |
968 | call pid_to_slot |
968 | call pid_to_slot |
969 | test eax, eax |
969 | test eax, eax |
970 | jz .no_pid |
970 | jz .no_pid |
971 | 971 | ||
972 | mov [dst_slot], eax |
972 | mov [dst_slot], eax |
973 | shl eax, BSF sizeof.APPDATA |
973 | shl eax, BSF sizeof.APPDATA |
974 | mov edi, [SLOT_BASE + eax + APPDATA.ipc_start] ;is ipc area defined? |
974 | mov edi, [SLOT_BASE + eax + APPDATA.ipc_start] ;is ipc area defined? |
975 | test edi, edi |
975 | test edi, edi |
976 | jz .no_ipc_area |
976 | jz .no_ipc_area |
977 | 977 | ||
978 | mov ebx, edi |
978 | mov ebx, edi |
979 | and ebx, 0xFFF |
979 | and ebx, 0xFFF |
980 | mov [dst_offset], ebx |
980 | mov [dst_offset], ebx |
981 | 981 | ||
982 | mov esi, [SLOT_BASE + eax + APPDATA.ipc_size] |
982 | mov esi, [SLOT_BASE + eax + APPDATA.ipc_size] |
983 | mov [buf_size], esi |
983 | mov [buf_size], esi |
984 | 984 | ||
985 | mov ecx, [ipc_tmp] |
985 | mov ecx, [ipc_tmp] |
986 | cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page |
986 | cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page |
987 | jbe @f |
987 | jbe @f |
988 | push esi edi |
988 | push esi edi |
989 | add esi, 0x1000 |
989 | add esi, 0x1000 |
990 | stdcall alloc_kernel_space, esi |
990 | stdcall alloc_kernel_space, esi |
991 | mov ecx, eax |
991 | mov ecx, eax |
992 | pop edi esi |
992 | pop edi esi |
993 | @@: |
993 | @@: |
994 | mov [used_buf], ecx |
994 | mov [used_buf], ecx |
995 | stdcall map_mem_ipc, ecx, [dst_slot], \ |
995 | stdcall map_mem_ipc, ecx, [dst_slot], \ |
996 | edi, esi, PG_SWR |
996 | edi, esi, PG_SWR |
997 | 997 | ||
998 | mov edi, [dst_offset] |
998 | mov edi, [dst_offset] |
999 | add edi, [used_buf] |
999 | add edi, [used_buf] |
1000 | cmp dword [edi], 0 |
1000 | cmp dword [edi], 0 |
1001 | jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
1001 | jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
1002 | 1002 | ||
1003 | mov edx, dword [edi+4] |
1003 | mov edx, dword [edi+4] |
1004 | lea ebx, [edx+8] |
1004 | lea ebx, [edx+8] |
1005 | add ebx, [msg_size] |
1005 | add ebx, [msg_size] |
1006 | cmp ebx, [buf_size] |
1006 | cmp ebx, [buf_size] |
1007 | ja .buffer_overflow ;esi<0 - not enough memory in buffer |
1007 | ja .buffer_overflow ;esi<0 - not enough memory in buffer |
1008 | 1008 | ||
1009 | mov dword [edi+4], ebx |
1009 | mov dword [edi+4], ebx |
1010 | mov eax, [current_slot] |
1010 | mov eax, [current_slot] |
1011 | mov eax, [eax + APPDATA.tid] ;eax - our PID |
1011 | mov eax, [eax + APPDATA.tid] ;eax - our PID |
1012 | add edi, edx |
1012 | add edi, edx |
1013 | mov [edi], eax |
1013 | mov [edi], eax |
1014 | mov ecx, [msg_size] |
1014 | mov ecx, [msg_size] |
1015 | 1015 | ||
1016 | mov [edi+4], ecx |
1016 | mov [edi+4], ecx |
1017 | add edi, 8 |
1017 | add edi, 8 |
1018 | mov esi, [msg_addr] |
1018 | mov esi, [msg_addr] |
1019 | ; add esi, std_application_base_address |
1019 | ; add esi, std_application_base_address |
1020 | cld |
1020 | cld |
1021 | rep movsb |
1021 | rep movsb |
1022 | 1022 | ||
1023 | mov ebx, [ipc_tmp] |
1023 | mov ebx, [ipc_tmp] |
1024 | mov edx, ebx |
1024 | mov edx, ebx |
1025 | shr ebx, 12 |
1025 | shr ebx, 12 |
1026 | xor eax, eax |
1026 | xor eax, eax |
1027 | mov [page_tabs + ebx*4], eax |
1027 | mov [page_tabs + ebx*4], eax |
1028 | invlpg [edx] |
1028 | invlpg [edx] |
1029 | 1029 | ||
1030 | mov ebx, [ipc_pdir] |
1030 | mov ebx, [ipc_pdir] |
1031 | mov edx, ebx |
1031 | mov edx, ebx |
1032 | shr ebx, 12 |
1032 | shr ebx, 12 |
1033 | xor eax, eax |
1033 | xor eax, eax |
1034 | mov [page_tabs + ebx*4], eax |
1034 | mov [page_tabs + ebx*4], eax |
1035 | invlpg [edx] |
1035 | invlpg [edx] |
1036 | 1036 | ||
1037 | mov ebx, [ipc_ptab] |
1037 | mov ebx, [ipc_ptab] |
1038 | mov edx, ebx |
1038 | mov edx, ebx |
1039 | shr ebx, 12 |
1039 | shr ebx, 12 |
1040 | xor eax, eax |
1040 | xor eax, eax |
1041 | mov [page_tabs + ebx*4], eax |
1041 | mov [page_tabs + ebx*4], eax |
1042 | invlpg [edx] |
1042 | invlpg [edx] |
1043 | 1043 | ||
1044 | mov eax, [dst_slot] |
1044 | mov eax, [dst_slot] |
1045 | shl eax, BSF sizeof.APPDATA |
1045 | shl eax, BSF sizeof.APPDATA |
1046 | or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_IPC |
1046 | or [SLOT_BASE + eax + APPDATA.occurred_events], EVENT_IPC |
1047 | push 0 |
1047 | push 0 |
1048 | jmp .ret |
1048 | jmp .ret |
1049 | .no_pid: |
1049 | .no_pid: |
1050 | popf |
1050 | popf |
1051 | mov eax, 4 |
1051 | mov eax, 4 |
1052 | ret |
1052 | ret |
1053 | .no_ipc_area: |
1053 | .no_ipc_area: |
1054 | popf |
1054 | popf |
1055 | xor eax, eax |
1055 | xor eax, eax |
1056 | inc eax |
1056 | inc eax |
1057 | ret |
1057 | ret |
1058 | .ipc_blocked: |
1058 | .ipc_blocked: |
1059 | push 2 |
1059 | push 2 |
1060 | jmp .ret |
1060 | jmp .ret |
1061 | .buffer_overflow: |
1061 | .buffer_overflow: |
1062 | push 3 |
1062 | push 3 |
1063 | .ret: |
1063 | .ret: |
1064 | mov eax, [used_buf] |
1064 | mov eax, [used_buf] |
1065 | cmp eax, [ipc_tmp] |
1065 | cmp eax, [ipc_tmp] |
1066 | je @f |
1066 | je @f |
1067 | stdcall free_kernel_space, eax |
1067 | stdcall free_kernel_space, eax |
1068 | @@: |
1068 | @@: |
1069 | pop eax |
1069 | pop eax |
1070 | popf |
1070 | popf |
1071 | ret |
1071 | ret |
1072 | endp |
1072 | endp |
1073 | 1073 | ||
1074 | align 4 |
1074 | align 4 |
1075 | sysfn_meminfo: |
1075 | sysfn_meminfo: |
1076 | cmp ecx, OS_BASE |
1076 | cmp ecx, OS_BASE |
1077 | jae .fail |
1077 | jae .fail |
1078 | 1078 | ||
1079 | mov eax, [pg_data.pages_count] |
1079 | mov eax, [pg_data.pages_count] |
1080 | mov [ecx], eax |
1080 | mov [ecx], eax |
1081 | shl eax, 12 |
1081 | shl eax, 12 |
1082 | mov [esp + SYSCALL_STACK.eax], eax |
1082 | mov [esp + SYSCALL_STACK.eax], eax |
1083 | mov eax, [pg_data.pages_free] |
1083 | mov eax, [pg_data.pages_free] |
1084 | mov [ecx + 4], eax |
1084 | mov [ecx + 4], eax |
1085 | mov eax, [pg_data.pages_faults] |
1085 | mov eax, [pg_data.pages_faults] |
1086 | mov [ecx + 8], eax |
1086 | mov [ecx + 8], eax |
1087 | mov eax, [heap_size] |
1087 | mov eax, [heap_size] |
1088 | mov [ecx + 12], eax |
1088 | mov [ecx + 12], eax |
1089 | mov eax, [heap_free] |
1089 | mov eax, [heap_free] |
1090 | mov [ecx + 16], eax |
1090 | mov [ecx + 16], eax |
1091 | mov eax, [heap_blocks] |
1091 | mov eax, [heap_blocks] |
1092 | mov [ecx + 20], eax |
1092 | mov [ecx + 20], eax |
1093 | mov eax, [free_blocks] |
1093 | mov eax, [free_blocks] |
1094 | mov [ecx + 24], eax |
1094 | mov [ecx + 24], eax |
1095 | ret |
1095 | ret |
1096 | .fail: |
1096 | .fail: |
1097 | or dword [esp + SYSCALL_STACK.eax], -1 |
1097 | or dword [esp + SYSCALL_STACK.eax], -1 |
1098 | ret |
1098 | ret |
1099 | 1099 | ||
1100 | align 4 |
1100 | align 4 |
1101 | f68: |
1101 | f68: |
1102 | cmp ebx, 4 |
1102 | cmp ebx, 4 |
1103 | jbe sys_sheduler |
1103 | jbe sys_sheduler |
1104 | cmp ebx, 11 |
1104 | cmp ebx, 11 |
1105 | jb undefined_syscall |
1105 | jb undefined_syscall |
1106 | cmp ebx, 31 |
1106 | cmp ebx, 31 |
1107 | ja undefined_syscall |
1107 | ja undefined_syscall |
1108 | xor eax, eax |
1108 | xor eax, eax |
1109 | jmp dword [f68call + ebx*4-11*4] |
1109 | jmp dword [f68call + ebx*4-11*4] |
1110 | .11: |
1110 | .11: |
1111 | call init_heap |
1111 | call init_heap |
1112 | mov [esp + SYSCALL_STACK.eax], eax |
1112 | mov [esp + SYSCALL_STACK.eax], eax |
1113 | ret |
1113 | ret |
1114 | .12: |
1114 | .12: |
1115 | stdcall user_alloc, ecx |
1115 | stdcall user_alloc, ecx |
1116 | mov [esp + SYSCALL_STACK.eax], eax |
1116 | mov [esp + SYSCALL_STACK.eax], eax |
1117 | ret |
1117 | ret |
1118 | .13: |
1118 | .13: |
1119 | stdcall user_free, ecx |
1119 | stdcall user_free, ecx |
1120 | mov [esp + SYSCALL_STACK.eax], eax |
1120 | mov [esp + SYSCALL_STACK.eax], eax |
1121 | ret |
1121 | ret |
1122 | .14: |
1122 | .14: |
1123 | cmp ecx, OS_BASE |
1123 | cmp ecx, OS_BASE |
1124 | jae .fail |
1124 | jae .fail |
1125 | mov edi, ecx |
1125 | mov edi, ecx |
1126 | call get_event_ex |
1126 | call get_event_ex |
1127 | mov [esp + SYSCALL_STACK.eax], eax |
1127 | mov [esp + SYSCALL_STACK.eax], eax |
1128 | ret |
1128 | ret |
1129 | .16: |
1129 | .16: |
1130 | test ecx, ecx |
1130 | test ecx, ecx |
1131 | jz .fail |
1131 | jz .fail |
1132 | cmp ecx, OS_BASE |
1132 | cmp ecx, OS_BASE |
1133 | jae .fail |
1133 | jae .fail |
1134 | stdcall get_service, ecx |
1134 | stdcall get_service, ecx |
1135 | mov [esp + SYSCALL_STACK.eax], eax |
1135 | mov [esp + SYSCALL_STACK.eax], eax |
1136 | ret |
1136 | ret |
1137 | .17: |
1137 | .17: |
1138 | call srv_handlerEx ;ecx |
1138 | call srv_handlerEx ;ecx |
1139 | mov [esp + SYSCALL_STACK.eax], eax |
1139 | mov [esp + SYSCALL_STACK.eax], eax |
1140 | ret |
1140 | ret |
1141 | .18: |
1141 | .18: |
1142 | mov eax, edx |
1142 | mov eax, edx |
1143 | .19: |
1143 | .19: |
1144 | stdcall is_string_userspace, ecx |
1144 | stdcall is_string_userspace, ecx |
1145 | jnz .fail |
1145 | jnz .fail |
1146 | stdcall load_library, ecx, eax |
1146 | stdcall load_library, ecx, eax |
1147 | mov [esp + SYSCALL_STACK.eax], eax |
1147 | mov [esp + SYSCALL_STACK.eax], eax |
1148 | ret |
1148 | ret |
1149 | .20: |
1149 | .20: |
1150 | mov eax, edx |
1150 | mov eax, edx |
1151 | mov ebx, ecx |
1151 | mov ebx, ecx |
1152 | call user_realloc ;in: eax = pointer, ebx = new size |
1152 | call user_realloc ;in: eax = pointer, ebx = new size |
1153 | mov [esp + SYSCALL_STACK.eax], eax |
1153 | mov [esp + SYSCALL_STACK.eax], eax |
1154 | ret |
1154 | ret |
1155 | .21: |
1155 | .21: |
1156 | cmp ecx, OS_BASE |
1156 | cmp ecx, OS_BASE |
1157 | jae .fail |
1157 | jae .fail |
1158 | cmp edx, OS_BASE |
1158 | cmp edx, OS_BASE |
1159 | jae .fail |
1159 | jae .fail |
1160 | stdcall load_pe_driver, ecx, edx |
1160 | stdcall load_pe_driver, ecx, edx |
1161 | mov [esp + SYSCALL_STACK.eax], eax |
1161 | mov [esp + SYSCALL_STACK.eax], eax |
1162 | ret |
1162 | ret |
1163 | .22: |
1163 | .22: |
1164 | cmp ecx, OS_BASE |
1164 | cmp ecx, OS_BASE |
1165 | jae .fail |
1165 | jae .fail |
1166 | stdcall shmem_open, ecx, edx, esi |
1166 | stdcall shmem_open, ecx, edx, esi |
1167 | mov [esp + SYSCALL_STACK.edx], edx |
1167 | mov [esp + SYSCALL_STACK.edx], edx |
1168 | mov [esp + SYSCALL_STACK.eax], eax |
1168 | mov [esp + SYSCALL_STACK.eax], eax |
1169 | ret |
1169 | ret |
1170 | .23: |
1170 | .23: |
1171 | cmp ecx, OS_BASE |
1171 | cmp ecx, OS_BASE |
1172 | jae .fail |
1172 | jae .fail |
1173 | stdcall shmem_close, ecx |
1173 | stdcall shmem_close, ecx |
1174 | mov [esp + SYSCALL_STACK.eax], eax |
1174 | mov [esp + SYSCALL_STACK.eax], eax |
1175 | ret |
1175 | ret |
1176 | .24: |
1176 | .24: |
1177 | mov eax, [current_slot] |
1177 | mov eax, [current_slot] |
1178 | xchg ecx, [eax + APPDATA.exc_handler] |
1178 | xchg ecx, [eax + APPDATA.exc_handler] |
1179 | xchg edx, [eax + APPDATA.except_mask] |
1179 | xchg edx, [eax + APPDATA.except_mask] |
- | 1180 | xchg esi, [eax + APPDATA.exc_reserve_stack] |
|
1180 | mov [esp + SYSCALL_STACK.ebx], edx |
1181 | mov [esp + SYSCALL_STACK.ebx], edx |
1181 | mov [esp + SYSCALL_STACK.eax], ecx |
1182 | mov [esp + SYSCALL_STACK.eax], ecx |
1182 | ret |
1183 | ret |
1183 | .25: |
1184 | .25: |
1184 | cmp ecx, 32 |
1185 | cmp ecx, 32 |
1185 | jae .fail |
1186 | jae .fail |
1186 | mov eax, [current_slot] |
1187 | mov eax, [current_slot] |
1187 | btr [eax + APPDATA.except_mask], ecx |
1188 | btr [eax + APPDATA.except_mask], ecx |
1188 | setc byte[esp + SYSCALL_STACK.eax] |
1189 | setc byte[esp + SYSCALL_STACK.eax] |
1189 | jecxz @f |
1190 | jecxz @f |
1190 | bts [eax + APPDATA.except_mask], ecx |
1191 | bts [eax + APPDATA.except_mask], ecx |
1191 | @@: |
1192 | @@: |
1192 | ret |
1193 | ret |
1193 | .26: |
1194 | .26: |
1194 | stdcall user_unmap, ecx, edx, esi |
1195 | stdcall user_unmap, ecx, edx, esi |
1195 | mov [esp + SYSCALL_STACK.eax], eax |
1196 | mov [esp + SYSCALL_STACK.eax], eax |
1196 | ret |
1197 | ret |
1197 | .27: |
1198 | .27: |
1198 | cmp ecx, OS_BASE |
1199 | cmp ecx, OS_BASE |
1199 | jae .fail |
1200 | jae .fail |
1200 | stdcall load_file_umode, ecx |
1201 | stdcall load_file_umode, ecx |
1201 | mov [esp + SYSCALL_STACK.edx], edx |
1202 | mov [esp + SYSCALL_STACK.edx], edx |
1202 | mov [esp + SYSCALL_STACK.eax], eax |
1203 | mov [esp + SYSCALL_STACK.eax], eax |
1203 | ret |
1204 | ret |
1204 | .28: |
1205 | .28: |
1205 | cmp ecx, OS_BASE |
1206 | cmp ecx, OS_BASE |
1206 | jae .fail |
1207 | jae .fail |
1207 | push ecx edx |
1208 | push ecx edx |
1208 | stdcall kernel_alloc, maxPathLength |
1209 | stdcall kernel_alloc, maxPathLength |
1209 | mov edi, eax |
1210 | mov edi, eax |
1210 | pop eax esi |
1211 | pop eax esi |
1211 | push edi |
1212 | push edi |
1212 | call getFullPath |
1213 | call getFullPath |
1213 | pop ebp |
1214 | pop ebp |
1214 | test eax, eax |
1215 | test eax, eax |
1215 | jz @f |
1216 | jz @f |
1216 | stdcall load_file_umode, ebp |
1217 | stdcall load_file_umode, ebp |
1217 | mov [esp + SYSCALL_STACK.edx], edx |
1218 | mov [esp + SYSCALL_STACK.edx], edx |
1218 | @@: |
1219 | @@: |
1219 | mov [esp + SYSCALL_STACK.eax], eax |
1220 | mov [esp + SYSCALL_STACK.eax], eax |
1220 | stdcall kernel_free, ebp |
1221 | stdcall kernel_free, ebp |
1221 | ret |
1222 | ret |
1222 | 1223 | ||
1223 | .29: |
1224 | .29: |
1224 | stdcall user_ring, ecx |
1225 | stdcall user_ring, ecx |
1225 | mov [esp + SYSCALL_STACK.eax], eax |
1226 | mov [esp + SYSCALL_STACK.eax], eax |
1226 | ret |
1227 | ret |
1227 | 1228 | ||
1228 | ; unload driver |
1229 | ; unload driver |
1229 | .30: ; ecx = handl driver edx = cmdline |
1230 | .30: ; ecx = handl driver edx = cmdline |
1230 | mov eax, -1 |
1231 | mov eax, -1 |
1231 | cmp edx, OS_BASE |
1232 | cmp edx, OS_BASE |
1232 | jae .fail |
1233 | jae .fail |
1233 | cmp ecx, OS_BASE |
1234 | cmp ecx, OS_BASE |
1234 | jbe .fail |
1235 | jbe .fail |
1235 | cmp [ecx+SRV.magic], ' SRV' |
1236 | cmp [ecx+SRV.magic], ' SRV' |
1236 | jne .fail |
1237 | jne .fail |
1237 | cmp [ecx+SRV.size], sizeof.SRV |
1238 | cmp [ecx+SRV.size], sizeof.SRV |
1238 | jne .fail |
1239 | jne .fail |
1239 | 1240 | ||
1240 | mov eax, [ecx + SRV.entry] |
1241 | mov eax, [ecx + SRV.entry] |
1241 | test eax, eax |
1242 | test eax, eax |
1242 | jz .fail |
1243 | jz .fail |
1243 | push ecx ;save handl |
1244 | push ecx ;save handl |
1244 | 1245 | ||
1245 | push edx ;cmdline |
1246 | push edx ;cmdline |
1246 | push DRV_EXIT |
1247 | push DRV_EXIT |
1247 | call eax ;the result is not checked |
1248 | call eax ;the result is not checked |
1248 | lea esp, [esp+8] |
1249 | lea esp, [esp+8] |
1249 | push ecx |
1250 | push ecx |
1250 | 1251 | ||
1251 | mov ebx, [ecx + SRV.base] |
1252 | mov ebx, [ecx + SRV.base] |
1252 | mov eax, -2 ;error free RAM |
1253 | mov eax, -2 ;error free RAM |
1253 | test ebx, ebx |
1254 | test ebx, ebx |
1254 | jz .fail |
1255 | jz .fail |
1255 | stdcall kernel_free, ebx ;del driver |
1256 | stdcall kernel_free, ebx ;del driver |
1256 | 1257 | ||
1257 | mov eax, [ecx + SRV.fd] |
1258 | mov eax, [ecx + SRV.fd] |
1258 | mov edx, [ecx + SRV.bk] |
1259 | mov edx, [ecx + SRV.bk] |
1259 | mov [edx + SRV.fd], eax |
1260 | mov [edx + SRV.fd], eax |
1260 | mov [eax + SRV.bk], edx |
1261 | mov [eax + SRV.bk], edx |
1261 | stdcall free, ecx |
1262 | stdcall free, ecx |
1262 | ;dec [count_services] |
1263 | ;dec [count_services] |
1263 | 1264 | ||
1264 | mov [esp + SYSCALL_STACK.eax], eax |
1265 | mov [esp + SYSCALL_STACK.eax], eax |
1265 | ret |
1266 | ret |
1266 | .31: ; get list service |
1267 | .31: ; get list service |
1267 | test ecx, ecx |
1268 | test ecx, ecx |
1268 | jz .fail ; get count |
1269 | jz .fail ; get count |
1269 | dec ecx |
1270 | dec ecx |
1270 | jnz @f ;1 - get pointer first and last structure |
1271 | jnz @f ;1 - get pointer first and last structure |
1271 | 1272 | ||
1272 | mov ebx, [srv.fd] |
1273 | mov ebx, [srv.fd] |
1273 | mov ecx, [srv.bk] |
1274 | mov ecx, [srv.bk] |
1274 | mov [esp + SYSCALL_STACK.ebx], ebx ;fd |
1275 | mov [esp + SYSCALL_STACK.ebx], ebx ;fd |
1275 | mov [esp + SYSCALL_STACK.ecx], ecx ;bk |
1276 | mov [esp + SYSCALL_STACK.ecx], ecx ;bk |
1276 | mov [esp + SYSCALL_STACK.eax], 0 |
1277 | mov [esp + SYSCALL_STACK.eax], 0 |
1277 | ret |
1278 | ret |
1278 | @@: |
1279 | @@: |
1279 | dec ecx |
1280 | dec ecx |
1280 | jnz .fail ; 2 - get info for SRV structure |
1281 | jnz .fail ; 2 - get info for SRV structure |
1281 | 1282 | ||
1282 | mov eax, -1 |
1283 | mov eax, -1 |
1283 | cmp edx, OS_BASE ; edx = pointer on structure |
1284 | cmp edx, OS_BASE ; edx = pointer on structure |
1284 | jbe .fail |
1285 | jbe .fail |
1285 | stdcall is_region_userspace, edi, 40 ;16+4*6=40 <-max size buffer |
1286 | stdcall is_region_userspace, edi, 40 ;16+4*6=40 <-max size buffer |
1286 | jnz .fail ; edi = pointer on buffer |
1287 | jnz .fail ; edi = pointer on buffer |
1287 | cmp [edx + SRV.magic], ' SRV' |
1288 | cmp [edx + SRV.magic], ' SRV' |
1288 | jne .fail |
1289 | jne .fail |
1289 | cmp [edx + SRV.size], sizeof.SRV |
1290 | cmp [edx + SRV.size], sizeof.SRV |
1290 | jne .fail |
1291 | jne .fail |
1291 | 1292 | ||
1292 | mov esi, edx |
1293 | mov esi, edx |
1293 | movsd ; name service 16 byte |
1294 | movsd ; name service 16 byte |
1294 | movsd |
1295 | movsd |
1295 | movsd |
1296 | movsd |
1296 | movsd |
1297 | movsd |
1297 | lea esi, [edx+SRV.fd] |
1298 | lea esi, [edx+SRV.fd] |
1298 | movsd ; SRV.fd |
1299 | movsd ; SRV.fd |
1299 | movsd ; SRV.bk |
1300 | movsd ; SRV.bk |
1300 | movsd ; SRV.base |
1301 | movsd ; SRV.base |
1301 | movsd ; SRV.entry |
1302 | movsd ; SRV.entry |
1302 | movsd ; SRV.srv_proc |
1303 | movsd ; SRV.srv_proc |
1303 | ;movsd ; SRV.srv_proc_ex |
1304 | ;movsd ; SRV.srv_proc_ex |
1304 | 1305 | ||
1305 | xor eax, eax |
1306 | xor eax, eax |
1306 | .fail: |
1307 | .fail: |
1307 | mov [esp + SYSCALL_STACK.eax], eax |
1308 | mov [esp + SYSCALL_STACK.eax], eax |
1308 | ret |
1309 | ret |
1309 | 1310 | ||
1310 | align 4 |
1311 | align 4 |
1311 | f68call: ; keep this table closer to main code |
1312 | f68call: ; keep this table closer to main code |
1312 | 1313 | ||
1313 | dd f68.11 ; init_heap |
1314 | dd f68.11 ; init_heap |
1314 | dd f68.12 ; user_alloc |
1315 | dd f68.12 ; user_alloc |
1315 | dd f68.13 ; user_free |
1316 | dd f68.13 ; user_free |
1316 | dd f68.14 ; get_event_ex |
1317 | dd f68.14 ; get_event_ex |
1317 | dd f68.fail ; moved to f68.24 |
1318 | dd f68.fail ; moved to f68.24 |
1318 | dd f68.16 ; get_service |
1319 | dd f68.16 ; get_service |
1319 | dd f68.17 ; call_service |
1320 | dd f68.17 ; call_service |
1320 | dd f68.18 ; loadLibUnicode |
1321 | dd f68.18 ; loadLibUnicode |
1321 | dd f68.19 ; load_dll |
1322 | dd f68.19 ; load_dll |
1322 | dd f68.20 ; user_realloc |
1323 | dd f68.20 ; user_realloc |
1323 | dd f68.21 ; load_driver |
1324 | dd f68.21 ; load_driver |
1324 | dd f68.22 ; shmem_open |
1325 | dd f68.22 ; shmem_open |
1325 | dd f68.23 ; shmem_close |
1326 | dd f68.23 ; shmem_close |
1326 | dd f68.24 ; set exception handler |
1327 | dd f68.24 ; set exception handler |
1327 | dd f68.25 ; unmask exception |
1328 | dd f68.25 ; unmask exception |
1328 | dd f68.26 ; user_unmap |
1329 | dd f68.26 ; user_unmap |
1329 | dd f68.27 ; load_file_umode |
1330 | dd f68.27 ; load_file_umode |
1330 | dd f68.28 ; loadFileUnicode |
1331 | dd f68.28 ; loadFileUnicode |
1331 | dd f68.29 ; user_ring |
1332 | dd f68.29 ; user_ring |
1332 | dd f68.30 ; unload_driver |
1333 | dd f68.30 ; unload_driver |
1333 | dd f68.31 ; get_driver_info |
1334 | dd f68.31 ; get_driver_info |
1334 | 1335 | ||
1335 | align 4 |
1336 | align 4 |
1336 | proc load_pe_driver stdcall, file:dword, cmdline:dword |
1337 | proc load_pe_driver stdcall, file:dword, cmdline:dword |
1337 | push esi |
1338 | push esi |
1338 | 1339 | ||
1339 | stdcall load_PE, [file] |
1340 | stdcall load_PE, [file] |
1340 | test eax, eax |
1341 | test eax, eax |
1341 | jz .fail |
1342 | jz .fail |
1342 | 1343 | ||
1343 | mov esi, eax |
1344 | mov esi, eax |
1344 | push ebx ; base addres driver |
1345 | push ebx ; base addres driver |
1345 | push [cmdline] |
1346 | push [cmdline] |
1346 | push DRV_ENTRY |
1347 | push DRV_ENTRY |
1347 | call eax |
1348 | call eax |
1348 | pop ecx |
1349 | pop ecx |
1349 | pop ecx |
1350 | pop ecx |
1350 | pop ebx |
1351 | pop ebx |
1351 | test eax, eax |
1352 | test eax, eax |
1352 | jz .fail_init |
1353 | jz .fail_init |
1353 | 1354 | ||
1354 | mov [eax + SRV.base], ebx |
1355 | mov [eax + SRV.base], ebx |
1355 | mov [eax + SRV.entry], esi |
1356 | mov [eax + SRV.entry], esi |
1356 | pop esi |
1357 | pop esi |
1357 | ret |
1358 | ret |
1358 | .fail_init: |
1359 | .fail_init: |
1359 | stdcall kernel_free, ebx ;clear memory driver |
1360 | stdcall kernel_free, ebx ;clear memory driver |
1360 | .fail: |
1361 | .fail: |
1361 | xor eax, eax |
1362 | xor eax, eax |
1362 | pop esi |
1363 | pop esi |
1363 | ret |
1364 | ret |
1364 | endp |
1365 | endp |
1365 | 1366 | ||
1366 | align 4 |
1367 | align 4 |
1367 | proc create_ring_buffer stdcall, size:dword, flags:dword |
1368 | proc create_ring_buffer stdcall, size:dword, flags:dword |
1368 | locals |
1369 | locals |
1369 | buf_ptr dd ? |
1370 | buf_ptr dd ? |
1370 | endl |
1371 | endl |
1371 | 1372 | ||
1372 | mov eax, [size] |
1373 | mov eax, [size] |
1373 | test eax, eax |
1374 | test eax, eax |
1374 | jz .fail |
1375 | jz .fail |
1375 | 1376 | ||
1376 | add eax, eax |
1377 | add eax, eax |
1377 | stdcall alloc_kernel_space, eax |
1378 | stdcall alloc_kernel_space, eax |
1378 | test eax, eax |
1379 | test eax, eax |
1379 | jz .fail |
1380 | jz .fail |
1380 | 1381 | ||
1381 | push ebx |
1382 | push ebx |
1382 | 1383 | ||
1383 | mov [buf_ptr], eax |
1384 | mov [buf_ptr], eax |
1384 | 1385 | ||
1385 | mov ebx, [size] |
1386 | mov ebx, [size] |
1386 | shr ebx, 12 |
1387 | shr ebx, 12 |
1387 | push ebx |
1388 | push ebx |
1388 | 1389 | ||
1389 | stdcall alloc_pages, ebx |
1390 | stdcall alloc_pages, ebx |
1390 | pop ecx |
1391 | pop ecx |
1391 | 1392 | ||
1392 | test eax, eax |
1393 | test eax, eax |
1393 | jz .mm_fail |
1394 | jz .mm_fail |
1394 | 1395 | ||
1395 | push edi |
1396 | push edi |
1396 | 1397 | ||
1397 | or eax, [flags] |
1398 | or eax, [flags] |
1398 | mov edi, [buf_ptr] |
1399 | mov edi, [buf_ptr] |
1399 | mov ebx, [buf_ptr] |
1400 | mov ebx, [buf_ptr] |
1400 | mov edx, ecx |
1401 | mov edx, ecx |
1401 | shl edx, 2 |
1402 | shl edx, 2 |
1402 | shr edi, 10 |
1403 | shr edi, 10 |
1403 | @@: |
1404 | @@: |
1404 | mov [page_tabs + edi], eax |
1405 | mov [page_tabs + edi], eax |
1405 | mov [page_tabs + edi + edx], eax |
1406 | mov [page_tabs + edi + edx], eax |
1406 | invlpg [ebx] |
1407 | invlpg [ebx] |
1407 | invlpg [ebx+0x10000] |
1408 | invlpg [ebx+0x10000] |
1408 | add eax, 0x1000 |
1409 | add eax, 0x1000 |
1409 | add ebx, 0x1000 |
1410 | add ebx, 0x1000 |
1410 | add edi, 4 |
1411 | add edi, 4 |
1411 | dec ecx |
1412 | dec ecx |
1412 | jnz @B |
1413 | jnz @B |
1413 | 1414 | ||
1414 | mov eax, [buf_ptr] |
1415 | mov eax, [buf_ptr] |
1415 | pop edi |
1416 | pop edi |
1416 | pop ebx |
1417 | pop ebx |
1417 | ret |
1418 | ret |
1418 | .mm_fail: |
1419 | .mm_fail: |
1419 | stdcall free_kernel_space, [buf_ptr] |
1420 | stdcall free_kernel_space, [buf_ptr] |
1420 | xor eax, eax |
1421 | xor eax, eax |
1421 | pop ebx |
1422 | pop ebx |
1422 | .fail: |
1423 | .fail: |
1423 | ret |
1424 | ret |
1424 | endp |
1425 | endp |
1425 | 1426 | ||
1426 | 1427 | ||
1427 | align 4 |
1428 | align 4 |
1428 | proc print_mem |
1429 | proc print_mem |
1429 | mov edi, BOOT.memmap_blocks |
1430 | mov edi, BOOT.memmap_blocks |
1430 | mov ecx, [edi-4] |
1431 | mov ecx, [edi-4] |
1431 | test ecx, ecx |
1432 | test ecx, ecx |
1432 | jz .done |
1433 | jz .done |
1433 | 1434 | ||
1434 | @@: |
1435 | @@: |
1435 | mov eax, [edi] |
1436 | mov eax, [edi] |
1436 | mov edx, [edi+4] |
1437 | mov edx, [edi+4] |
1437 | add eax, [edi+8] |
1438 | add eax, [edi+8] |
1438 | adc edx, [edi+12] |
1439 | adc edx, [edi+12] |
1439 | 1440 | ||
1440 | DEBUGF 1, "K : E820 %x%x - %x%x type %d\n", \ |
1441 | DEBUGF 1, "K : E820 %x%x - %x%x type %d\n", \ |
1441 | [edi+4], [edi],\ |
1442 | [edi+4], [edi],\ |
1442 | edx, eax, [edi+16] |
1443 | edx, eax, [edi+16] |
1443 | add edi, 20 |
1444 | add edi, 20 |
1444 | dec ecx |
1445 | dec ecx |
1445 | jnz @b |
1446 | jnz @b |
1446 | .done: |
1447 | .done: |
1447 | ret |
1448 | ret |
1448 | endp-max>0>>=> |
1449 | endp-max>0>>=> |