Subversion Repositories Kolibri OS

Rev

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

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