Subversion Repositories Kolibri OS

Rev

Rev 9828 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9828 Rev 9900
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: 9828 $
8
$Revision: 9900 $
9
 
9
 
10
 
10
 
11
struct  MEM_BLOCK
11
struct  MEM_BLOCK
12
        list            LHEAD
12
        list            LHEAD
13
        next_block      dd ? ;+8
13
        next_block      dd ? ;+8
14
        prev_block      dd ? ;+4
14
        prev_block      dd ? ;+4
15
        base            dd ? ;+16
15
        base            dd ? ;+16
16
        size            dd ? ;+20
16
        size            dd ? ;+20
17
        flags           dd ? ;+24
17
        flags           dd ? ;+24
18
        handle          dd ? ;+28
18
        handle          dd ? ;+28
19
ends
19
ends
20
 
20
 
21
MEM_BLOCK_RESERVED  = 0x02      ; Will be allocated on first access (lazy allocation)
21
MEM_BLOCK_RESERVED  = 0x02      ; Will be allocated on first access (lazy allocation)
22
MEM_BLOCK_FREE      = 0x04
22
MEM_BLOCK_FREE      = 0x04
23
MEM_BLOCK_USED      = 0x08
23
MEM_BLOCK_USED      = 0x08
24
MEM_BLOCK_DONT_FREE = 0x10
24
MEM_BLOCK_DONT_FREE = 0x10
25
 
25
 
26
macro calc_index op
26
macro calc_index op
27
{          shr op, 12
27
{          shr op, 12
28
        dec     op
28
        dec     op
29
        cmp     op, 63
29
        cmp     op, 63
30
        jna     @f
30
        jna     @f
31
        mov     op, 63
31
        mov     op, 63
32
@@:
32
@@:
33
}
33
}
34
 
34
 
35
align 4
35
align 4
36
md:
36
md:
37
.add_to_used:
37
.add_to_used:
38
        mov     eax, [esi + MEM_BLOCK.base]
38
        mov     eax, [esi + MEM_BLOCK.base]
39
        mov     ebx, [esi + MEM_BLOCK.base]
39
        mov     ebx, [esi + MEM_BLOCK.base]
40
        shr     ebx, 6
40
        shr     ebx, 6
41
        add     eax, ebx
41
        add     eax, ebx
42
        shr     ebx, 6
42
        shr     ebx, 6
43
        add     eax, ebx
43
        add     eax, ebx
44
        shr     eax, 12
44
        shr     eax, 12
45
        and     eax, 63
45
        and     eax, 63
46
        inc     [mem_hash_cnt + eax*4]
46
        inc     [mem_hash_cnt + eax*4]
47
 
47
 
48
        lea     ecx, [mem_used_list + eax*8]
48
        lea     ecx, [mem_used_list + eax*8]
49
        list_add esi, ecx
49
        list_add esi, ecx
50
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
50
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
51
        mov     eax, [esi + MEM_BLOCK.size]
51
        mov     eax, [esi + MEM_BLOCK.size]
52
        sub     [heap_free], eax
52
        sub     [heap_free], eax
53
        ret
53
        ret
54
align 4
54
align 4
55
.find_used:
55
.find_used:
56
        mov     ecx, eax
56
        mov     ecx, eax
57
        mov     ebx, eax
57
        mov     ebx, eax
58
        shr     ebx, 6
58
        shr     ebx, 6
59
        add     ecx, ebx
59
        add     ecx, ebx
60
        shr     ebx, 6
60
        shr     ebx, 6
61
        add     ecx, ebx
61
        add     ecx, ebx
62
        shr     ecx, 12
62
        shr     ecx, 12
63
        and     ecx, 63
63
        and     ecx, 63
64
 
64
 
65
        lea     ebx, [mem_used_list + ecx*8]
65
        lea     ebx, [mem_used_list + ecx*8]
66
        mov     esi, ebx
66
        mov     esi, ebx
67
.next:
67
.next:
68
        mov     esi, [esi + MEM_BLOCK.list.next]
68
        mov     esi, [esi + MEM_BLOCK.list.next]
69
        cmp     esi, ebx
69
        cmp     esi, ebx
70
        je      .fail
70
        je      .fail
71
 
71
 
72
        cmp     eax, [esi + MEM_BLOCK.base]
72
        cmp     eax, [esi + MEM_BLOCK.base]
73
        jne     .next
73
        jne     .next
74
 
74
 
75
        ret
75
        ret
76
.fail:
76
.fail:
77
        xor     esi, esi
77
        xor     esi, esi
78
        ret
78
        ret
79
 
79
 
80
align 4
80
align 4
81
.del_from_used:
81
.del_from_used:
82
        call    .find_used
82
        call    .find_used
83
        test    esi, esi
83
        test    esi, esi
84
        jz      .done
84
        jz      .done
85
 
85
 
86
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
86
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
87
        jne     .fatal
87
        jne     .fatal
88
 
88
 
89
        dec     [mem_hash_cnt + ecx*4]
89
        dec     [mem_hash_cnt + ecx*4]
90
        list_del esi
90
        list_del esi
91
.done:
91
.done:
92
        ret
92
        ret
93
.fatal:                            ;FIXME panic here
93
.fatal:                            ;FIXME panic here
94
        xor     esi, esi
94
        xor     esi, esi
95
        ret
95
        ret
96
 
96
 
97
;Initial heap state
97
;Initial heap state
98
;
98
;
99
; + heap_size               terminator        MEM_BLOCK_USED
99
; + heap_size               terminator        MEM_BLOCK_USED
100
; + 4096*MEM_BLOCK.sizeof   free space        MEM_BLOCK_FREE
100
; + 4096*MEM_BLOCK.sizeof   free space        MEM_BLOCK_FREE
101
;HEAP_BASE                heap_descriptors  MEM_BLOCK_USED
101
;HEAP_BASE                heap_descriptors  MEM_BLOCK_USED
102
;
102
;
103
 
103
 
104
align 4
104
align 4
105
proc init_kernel_heap
105
proc init_kernel_heap
106
 
106
 
107
        mov     ecx, 64
107
        mov     ecx, 64
108
        mov     edi, mem_block_list
108
        mov     edi, mem_block_list
109
  @@:
109
  @@:
110
        mov     eax, edi
110
        mov     eax, edi
111
        stosd
111
        stosd
112
        stosd
112
        stosd
113
        loop    @B
113
        loop    @B
114
 
114
 
115
        mov     ecx, 64
115
        mov     ecx, 64
116
        mov     edi, mem_used_list
116
        mov     edi, mem_used_list
117
  @@:
117
  @@:
118
        mov     eax, edi
118
        mov     eax, edi
119
        stosd
119
        stosd
120
        stosd
120
        stosd
121
        loop    @B
121
        loop    @B
122
 
122
 
123
        stdcall alloc_pages, dword 32
123
        stdcall alloc_pages, dword 32
124
 
124
 
125
        or      eax, PG_SWR
125
        or      eax, PG_SWR
126
        mov     ebx, HEAP_BASE
126
        mov     ebx, HEAP_BASE
127
        mov     ecx, 32
127
        mov     ecx, 32
128
        call    commit_pages
128
        call    commit_pages
129
 
129
 
130
        mov     edi, HEAP_BASE                     ;descriptors
130
        mov     edi, HEAP_BASE                     ;descriptors
131
        mov     ebx, HEAP_BASE + sizeof.MEM_BLOCK      ;free space
131
        mov     ebx, HEAP_BASE + sizeof.MEM_BLOCK      ;free space
132
        mov     ecx, HEAP_BASE + sizeof.MEM_BLOCK*2    ;terminator
132
        mov     ecx, HEAP_BASE + sizeof.MEM_BLOCK*2    ;terminator
133
 
133
 
134
        xor     eax, eax
134
        xor     eax, eax
135
        mov     [edi + MEM_BLOCK.next_block], ebx
135
        mov     [edi + MEM_BLOCK.next_block], ebx
136
        mov     [edi + MEM_BLOCK.prev_block], eax
136
        mov     [edi + MEM_BLOCK.prev_block], eax
137
        mov     [edi + MEM_BLOCK.list.next], eax
137
        mov     [edi + MEM_BLOCK.list.next], eax
138
        mov     [edi + MEM_BLOCK.list.prev], eax
138
        mov     [edi + MEM_BLOCK.list.prev], eax
139
        mov     [edi + MEM_BLOCK.base], HEAP_BASE
139
        mov     [edi + MEM_BLOCK.base], HEAP_BASE
140
        mov     [edi + MEM_BLOCK.size], 4096*sizeof.MEM_BLOCK
140
        mov     [edi + MEM_BLOCK.size], PAGE_SIZE * sizeof.MEM_BLOCK
141
        mov     [edi + MEM_BLOCK.flags], MEM_BLOCK_USED
141
        mov     [edi + MEM_BLOCK.flags], MEM_BLOCK_USED
142
 
142
 
143
        mov     [ecx + MEM_BLOCK.next_block], eax
143
        mov     [ecx + MEM_BLOCK.next_block], eax
144
        mov     [ecx + MEM_BLOCK.prev_block], ebx
144
        mov     [ecx + MEM_BLOCK.prev_block], ebx
145
        mov     [ecx + MEM_BLOCK.list.next], eax
145
        mov     [ecx + MEM_BLOCK.list.next], eax
146
        mov     [ecx + MEM_BLOCK.list.prev], eax
146
        mov     [ecx + MEM_BLOCK.list.prev], eax
147
        mov     [ecx + MEM_BLOCK.base], eax
147
        mov     [ecx + MEM_BLOCK.base], eax
148
        mov     [ecx + MEM_BLOCK.size], eax
148
        mov     [ecx + MEM_BLOCK.size], eax
149
        mov     [ecx + MEM_BLOCK.flags], MEM_BLOCK_USED
149
        mov     [ecx + MEM_BLOCK.flags], MEM_BLOCK_USED
150
 
150
 
151
        mov     [ebx + MEM_BLOCK.next_block], ecx
151
        mov     [ebx + MEM_BLOCK.next_block], ecx
152
        mov     [ebx + MEM_BLOCK.prev_block], edi
152
        mov     [ebx + MEM_BLOCK.prev_block], edi
153
        mov     [ebx + MEM_BLOCK.base], HEAP_BASE + 4096*sizeof.MEM_BLOCK
153
        mov     [ebx + MEM_BLOCK.base], HEAP_BASE + PAGE_SIZE * sizeof.MEM_BLOCK
154
 
154
 
155
        mov     ecx, [pg_data.kernel_pages]
155
        mov     ecx, [pg_data.kernel_pages]
156
        shl     ecx, 12
156
        shl     ecx, 12
157
        sub     ecx, HEAP_BASE-OS_BASE + 4096*sizeof.MEM_BLOCK
157
        sub     ecx, HEAP_BASE-OS_BASE + PAGE_SIZE * sizeof.MEM_BLOCK
158
        mov     [heap_size], ecx
158
        mov     [heap_size], ecx
159
        mov     [heap_free], ecx
159
        mov     [heap_free], ecx
160
        mov     [ebx + MEM_BLOCK.size], ecx
160
        mov     [ebx + MEM_BLOCK.size], ecx
161
        mov     [ebx + MEM_BLOCK.flags], MEM_BLOCK_FREE
161
        mov     [ebx + MEM_BLOCK.flags], MEM_BLOCK_FREE
162
 
162
 
163
        mov     [mem_block_mask], eax
163
        mov     [mem_block_mask], eax
164
        mov     [mem_block_mask + 4], 0x80000000
164
        mov     [mem_block_mask + 4], 0x80000000
165
 
165
 
166
        mov     ecx, mem_block_list + 63*8
166
        mov     ecx, mem_block_list + 63*8
167
        list_add ebx, ecx
167
        list_add ebx, ecx
168
 
168
 
169
        mov     ecx, 4096-3-1
169
        mov     ecx, PAGE_SIZE -3-1
170
        mov     eax, HEAP_BASE + sizeof.MEM_BLOCK*4
170
        mov     eax, HEAP_BASE + sizeof.MEM_BLOCK*4
171
 
171
 
172
        mov     [next_memblock], HEAP_BASE + sizeof.MEM_BLOCK *3
172
        mov     [next_memblock], HEAP_BASE + sizeof.MEM_BLOCK *3
173
 @@:
173
 @@:
174
        mov     [eax - sizeof.MEM_BLOCK], eax
174
        mov     [eax - sizeof.MEM_BLOCK], eax
175
        add     eax, sizeof.MEM_BLOCK
175
        add     eax, sizeof.MEM_BLOCK
176
        loop    @B
176
        loop    @B
177
 
177
 
178
        mov     dword[eax - sizeof.MEM_BLOCK], 0
178
        mov     dword[eax - sizeof.MEM_BLOCK], 0
179
 
179
 
180
        mov     ecx, heap_mutex
180
        mov     ecx, heap_mutex
181
        call    mutex_init
181
        call    mutex_init
182
        mov     [heap_blocks], 4094
182
        mov     [heap_blocks], 4094
183
        mov     [free_blocks], 4093
183
        mov     [free_blocks], 4093
184
        ret
184
        ret
185
endp
185
endp
186
 
186
 
187
; param
187
; param
188
;  eax= required size
188
;  eax= required size
189
;
189
;
190
; retval
190
; retval
191
;  edi= memory block descriptor
191
;  edi= memory block descriptor
192
;  ebx= descriptor index
192
;  ebx= descriptor index
193
 
193
 
194
align 4
194
align 4
195
get_small_block:
195
get_small_block:
196
        mov     ecx, eax
196
        mov     ecx, eax
197
        shr     ecx, 12
197
        shr     ecx, 12
198
        dec     ecx
198
        dec     ecx
199
        cmp     ecx, 63
199
        cmp     ecx, 63
200
        jle     .get_index
200
        jle     .get_index
201
        mov     ecx, 63
201
        mov     ecx, 63
202
  .get_index:
202
  .get_index:
203
        lea     esi, [mem_block_mask]
203
        lea     esi, [mem_block_mask]
204
        xor     ebx, ebx
204
        xor     ebx, ebx
205
        or      edx, -1
205
        or      edx, -1
206
 
206
 
207
        cmp     ecx, 32
207
        cmp     ecx, 32
208
        jb      .bit_test
208
        jb      .bit_test
209
 
209
 
210
        sub     ecx, 32
210
        sub     ecx, 32
211
        add     ebx, 32
211
        add     ebx, 32
212
        add     esi, 4
212
        add     esi, 4
213
  .bit_test:
213
  .bit_test:
214
        shl     edx, cl
214
        shl     edx, cl
215
        and     edx, [esi]
215
        and     edx, [esi]
216
  .find:
216
  .find:
217
        bsf     edi, edx
217
        bsf     edi, edx
218
        jz      .high_mask
218
        jz      .high_mask
219
        add     ebx, edi
219
        add     ebx, edi
220
        lea     ecx, [mem_block_list + ebx*8]
220
        lea     ecx, [mem_block_list + ebx*8]
221
        mov     edi, ecx
221
        mov     edi, ecx
222
  .next:
222
  .next:
223
        mov     edi, [edi + MEM_BLOCK.list.next]
223
        mov     edi, [edi + MEM_BLOCK.list.next]
224
        cmp     edi, ecx
224
        cmp     edi, ecx
225
        je      .err
225
        je      .err
226
        cmp     eax, [edi + MEM_BLOCK.size]
226
        cmp     eax, [edi + MEM_BLOCK.size]
227
        ja      .next
227
        ja      .next
228
        ret
228
        ret
229
  .err:
229
  .err:
230
        xor     edi, edi
230
        xor     edi, edi
231
        ret
231
        ret
232
 
232
 
233
  .high_mask:
233
  .high_mask:
234
        add     esi, 4
234
        add     esi, 4
235
        cmp     esi, mem_block_mask + 8
235
        cmp     esi, mem_block_mask + 8
236
        jae     .err
236
        jae     .err
237
        add     ebx, 32
237
        add     ebx, 32
238
        mov     edx, [esi]
238
        mov     edx, [esi]
239
        jmp     .find
239
        jmp     .find
240
 
240
 
241
 
241
 
242
align 4
242
align 4
243
free_mem_block:
243
free_mem_block:
244
 
244
 
245
        mov     ebx, [next_memblock]
245
        mov     ebx, [next_memblock]
246
        mov     [eax], ebx
246
        mov     [eax], ebx
247
        mov     [next_memblock], eax
247
        mov     [next_memblock], eax
248
 
248
 
249
        xor     ebx, ebx
249
        xor     ebx, ebx
250
        mov     dword[eax + 4], ebx
250
        mov     dword[eax + 4], ebx
251
        mov     dword[eax + 8], ebx
251
        mov     dword[eax + 8], ebx
252
        mov     dword[eax + 12], ebx
252
        mov     dword[eax + 12], ebx
253
        mov     dword[eax + 16], ebx
253
        mov     dword[eax + 16], ebx
254
;           mov dword[eax + 20], 0     ;don't clear block size
254
;           mov dword[eax + 20], 0     ;don't clear block size
255
        mov     dword[eax + 24], ebx
255
        mov     dword[eax + 24], ebx
256
        mov     dword[eax + 28], ebx
256
        mov     dword[eax + 28], ebx
257
 
257
 
258
        inc     [free_blocks]
258
        inc     [free_blocks]
259
 
259
 
260
        ret
260
        ret
261
 
261
 
262
align 4
262
align 4
263
proc alloc_kernel_space stdcall, size:dword
263
proc alloc_kernel_space stdcall, size:dword
264
           local block_ind:DWORD
264
           local block_ind:DWORD
265
 
265
 
266
        push    ebx
266
        push    ebx
267
        push    esi
267
        push    esi
268
        push    edi
268
        push    edi
269
 
269
 
270
        mov     eax, [size]
270
        mov     eax, [size]
271
        add     eax, 4095
271
        add     eax, PAGE_SIZE-1
272
        and     eax, not 4095
272
        and     eax, -PAGE_SIZE
273
        mov     [size], eax
273
        mov     [size], eax
274
 
274
 
275
        cmp     eax, [heap_free]
275
        cmp     eax, [heap_free]
276
        ja      .error
276
        ja      .error
277
 
277
 
278
        spin_lock_irqsave heap_mutex
278
        spin_lock_irqsave heap_mutex
279
 
279
 
280
        mov     eax, [size]
280
        mov     eax, [size]
281
 
281
 
282
        call    get_small_block ; eax
282
        call    get_small_block ; eax
283
        test    edi, edi
283
        test    edi, edi
284
        jz      .error_unlock
284
        jz      .error_unlock
285
 
285
 
286
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
286
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
287
        jne     .error_unlock
287
        jne     .error_unlock
288
 
288
 
289
        mov     [block_ind], ebx  ;index of allocated block
289
        mov     [block_ind], ebx  ;index of allocated block
290
 
290
 
291
        mov     eax, [edi + MEM_BLOCK.size]
291
        mov     eax, [edi + MEM_BLOCK.size]
292
        cmp     eax, [size]
292
        cmp     eax, [size]
293
        je      .m_eq_size
293
        je      .m_eq_size
294
 
294
 
295
        mov     esi, [next_memblock]    ;new memory block
295
        mov     esi, [next_memblock]    ;new memory block
296
        test    esi, esi
296
        test    esi, esi
297
        jz      .error_unlock
297
        jz      .error_unlock
298
 
298
 
299
        dec     [free_blocks]
299
        dec     [free_blocks]
300
        mov     eax, [esi]
300
        mov     eax, [esi]
301
        mov     [next_memblock], eax
301
        mov     [next_memblock], eax
302
 
302
 
303
        mov     [esi + MEM_BLOCK.next_block], edi
303
        mov     [esi + MEM_BLOCK.next_block], edi
304
        mov     eax, [edi + MEM_BLOCK.prev_block]
304
        mov     eax, [edi + MEM_BLOCK.prev_block]
305
        mov     [esi + MEM_BLOCK.prev_block], eax
305
        mov     [esi + MEM_BLOCK.prev_block], eax
306
        mov     [edi + MEM_BLOCK.prev_block], esi
306
        mov     [edi + MEM_BLOCK.prev_block], esi
307
        mov     [esi + MEM_BLOCK.list.next], 0
307
        mov     [esi + MEM_BLOCK.list.next], 0
308
        mov     [esi + MEM_BLOCK.list.prev], 0
308
        mov     [esi + MEM_BLOCK.list.prev], 0
309
        mov     [eax + MEM_BLOCK.next_block], esi
309
        mov     [eax + MEM_BLOCK.next_block], esi
310
 
310
 
311
        mov     ebx, [edi + MEM_BLOCK.base]
311
        mov     ebx, [edi + MEM_BLOCK.base]
312
        mov     [esi + MEM_BLOCK.base], ebx
312
        mov     [esi + MEM_BLOCK.base], ebx
313
        mov     edx, [size]
313
        mov     edx, [size]
314
        mov     [esi + MEM_BLOCK.size], edx
314
        mov     [esi + MEM_BLOCK.size], edx
315
        add     [edi + MEM_BLOCK.base], edx
315
        add     [edi + MEM_BLOCK.base], edx
316
        sub     [edi + MEM_BLOCK.size], edx
316
        sub     [edi + MEM_BLOCK.size], edx
317
 
317
 
318
        mov     eax, [edi + MEM_BLOCK.size]
318
        mov     eax, [edi + MEM_BLOCK.size]
319
        calc_index eax
319
        calc_index eax
320
        cmp     eax, [block_ind]
320
        cmp     eax, [block_ind]
321
        je      .add_used
321
        je      .add_used
322
 
322
 
323
        list_del edi
323
        list_del edi
324
 
324
 
325
        mov     ecx, [block_ind]
325
        mov     ecx, [block_ind]
326
        lea     edx, [mem_block_list + ecx*8]
326
        lea     edx, [mem_block_list + ecx*8]
327
        cmp     edx, [edx]
327
        cmp     edx, [edx]
328
        jnz     @f
328
        jnz     @f
329
        btr     [mem_block_mask], ecx
329
        btr     [mem_block_mask], ecx
330
@@:
330
@@:
331
        bts     [mem_block_mask], eax
331
        bts     [mem_block_mask], eax
332
        lea     edx, [mem_block_list + eax*8]  ;edx= list head
332
        lea     edx, [mem_block_list + eax*8]  ;edx= list head
333
        list_add edi, edx
333
        list_add edi, edx
334
.add_used:
334
.add_used:
335
 
335
 
336
        call    md.add_to_used
336
        call    md.add_to_used
337
 
337
 
338
        spin_unlock_irqrestore heap_mutex
338
        spin_unlock_irqrestore heap_mutex
339
        mov     eax, [esi + MEM_BLOCK.base]
339
        mov     eax, [esi + MEM_BLOCK.base]
340
        pop     edi
340
        pop     edi
341
        pop     esi
341
        pop     esi
342
        pop     ebx
342
        pop     ebx
343
        ret
343
        ret
344
 
344
 
345
.m_eq_size:
345
.m_eq_size:
346
        list_del edi
346
        list_del edi
347
        lea     edx, [mem_block_list + ebx*8]
347
        lea     edx, [mem_block_list + ebx*8]
348
        cmp     edx, [edx]
348
        cmp     edx, [edx]
349
        jnz     @f
349
        jnz     @f
350
        btr     [mem_block_mask], ebx
350
        btr     [mem_block_mask], ebx
351
@@:
351
@@:
352
        mov     esi, edi
352
        mov     esi, edi
353
        jmp     .add_used
353
        jmp     .add_used
354
 
354
 
355
.error_unlock:
355
.error_unlock:
356
        spin_unlock_irqrestore heap_mutex
356
        spin_unlock_irqrestore heap_mutex
357
.error:
357
.error:
358
        xor     eax, eax
358
        xor     eax, eax
359
        pop     edi
359
        pop     edi
360
        pop     esi
360
        pop     esi
361
        pop     ebx
361
        pop     ebx
362
        ret
362
        ret
363
endp
363
endp
364
 
364
 
365
align 4
365
align 4
366
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
366
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
367
 
367
 
368
        spin_lock_irqsave heap_mutex
368
        spin_lock_irqsave heap_mutex
369
 
369
 
370
        mov     eax, [base]
370
        mov     eax, [base]
371
 
371
 
372
        call    md.del_from_used
372
        call    md.del_from_used
373
        test    esi, esi
373
        test    esi, esi
374
        jz      .fail
374
        jz      .fail
375
 
375
 
376
        mov     eax, [esi + MEM_BLOCK.size]
376
        mov     eax, [esi + MEM_BLOCK.size]
377
        add     [heap_free], eax
377
        add     [heap_free], eax
378
 
378
 
379
        mov     edi, [esi + MEM_BLOCK.next_block]
379
        mov     edi, [esi + MEM_BLOCK.next_block]
380
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
380
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
381
        jne     .prev
381
        jne     .prev
382
 
382
 
383
        list_del edi
383
        list_del edi
384
 
384
 
385
        mov     edx, [edi + MEM_BLOCK.next_block]
385
        mov     edx, [edi + MEM_BLOCK.next_block]
386
        mov     [esi + MEM_BLOCK.next_block], edx
386
        mov     [esi + MEM_BLOCK.next_block], edx
387
        mov     [edx + MEM_BLOCK.prev_block], esi
387
        mov     [edx + MEM_BLOCK.prev_block], esi
388
        mov     ecx, [edi + MEM_BLOCK.size]
388
        mov     ecx, [edi + MEM_BLOCK.size]
389
        add     [esi + MEM_BLOCK.size], ecx
389
        add     [esi + MEM_BLOCK.size], ecx
390
 
390
 
391
        calc_index ecx
391
        calc_index ecx
392
 
392
 
393
        lea     edx, [mem_block_list + ecx*8]
393
        lea     edx, [mem_block_list + ecx*8]
394
        cmp     edx, [edx]
394
        cmp     edx, [edx]
395
        jne     @F
395
        jne     @F
396
        btr     [mem_block_mask], ecx
396
        btr     [mem_block_mask], ecx
397
@@:
397
@@:
398
        mov     eax, edi
398
        mov     eax, edi
399
        call    free_mem_block
399
        call    free_mem_block
400
.prev:
400
.prev:
401
        mov     edi, [esi + MEM_BLOCK.prev_block]
401
        mov     edi, [esi + MEM_BLOCK.prev_block]
402
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
402
        cmp     [edi + MEM_BLOCK.flags], MEM_BLOCK_FREE
403
        jne     .insert
403
        jne     .insert
404
 
404
 
405
        mov     edx, [esi + MEM_BLOCK.next_block]
405
        mov     edx, [esi + MEM_BLOCK.next_block]
406
        mov     [edi + MEM_BLOCK.next_block], edx
406
        mov     [edi + MEM_BLOCK.next_block], edx
407
        mov     [edx + MEM_BLOCK.prev_block], edi
407
        mov     [edx + MEM_BLOCK.prev_block], edi
408
 
408
 
409
        mov     eax, esi
409
        mov     eax, esi
410
        call    free_mem_block
410
        call    free_mem_block
411
 
411
 
412
        mov     ecx, [edi + MEM_BLOCK.size]
412
        mov     ecx, [edi + MEM_BLOCK.size]
413
        mov     eax, [esi + MEM_BLOCK.size]
413
        mov     eax, [esi + MEM_BLOCK.size]
414
        add     eax, ecx
414
        add     eax, ecx
415
        mov     [edi + MEM_BLOCK.size], eax
415
        mov     [edi + MEM_BLOCK.size], eax
416
 
416
 
417
        calc_index eax                     ;new index
417
        calc_index eax                     ;new index
418
        calc_index ecx                     ;old index
418
        calc_index ecx                     ;old index
419
        cmp     eax, ecx
419
        cmp     eax, ecx
420
        je      .m_eq
420
        je      .m_eq
421
 
421
 
422
        push    ecx
422
        push    ecx
423
        list_del edi
423
        list_del edi
424
        pop     ecx
424
        pop     ecx
425
 
425
 
426
        lea     edx, [mem_block_list + ecx*8]
426
        lea     edx, [mem_block_list + ecx*8]
427
        cmp     edx, [edx]
427
        cmp     edx, [edx]
428
        jne     .add_block
428
        jne     .add_block
429
        btr     [mem_block_mask], ecx
429
        btr     [mem_block_mask], ecx
430
 
430
 
431
.add_block:
431
.add_block:
432
        bts     [mem_block_mask], eax
432
        bts     [mem_block_mask], eax
433
        lea     edx, [mem_block_list + eax*8]
433
        lea     edx, [mem_block_list + eax*8]
434
        list_add edi, edx
434
        list_add edi, edx
435
.m_eq:
435
.m_eq:
436
        spin_unlock_irqrestore heap_mutex
436
        spin_unlock_irqrestore heap_mutex
437
        xor     eax, eax
437
        xor     eax, eax
438
        not     eax
438
        not     eax
439
        ret
439
        ret
440
.insert:
440
.insert:
441
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_FREE
441
        mov     [esi + MEM_BLOCK.flags], MEM_BLOCK_FREE
442
        mov     eax, [esi + MEM_BLOCK.size]
442
        mov     eax, [esi + MEM_BLOCK.size]
443
        calc_index eax
443
        calc_index eax
444
        mov     edi, esi
444
        mov     edi, esi
445
        jmp     .add_block
445
        jmp     .add_block
446
 
446
 
447
.fail:
447
.fail:
448
        spin_unlock_irqrestore heap_mutex
448
        spin_unlock_irqrestore heap_mutex
449
        xor     eax, eax
449
        xor     eax, eax
450
        ret
450
        ret
451
endp
451
endp
452
 
452
 
453
align 4
453
align 4
454
proc kernel_alloc stdcall, size:dword
454
proc kernel_alloc stdcall, size:dword
455
        locals
455
        locals
456
          lin_addr    dd ?
456
          lin_addr    dd ?
457
          pages_count dd ?
457
          pages_count dd ?
458
        endl
458
        endl
459
 
459
 
460
        push    ebx
460
        push    ebx
461
        push    edi
461
        push    edi
462
 
462
 
463
        mov     eax, [size]
463
        mov     eax, [size]
464
        add     eax, 4095
464
        add     eax, PAGE_SIZE-1
465
        and     eax, not 4095;
465
        and     eax, -PAGE_SIZE;
466
        mov     [size], eax
466
        mov     [size], eax
467
        and     eax, eax
467
        and     eax, eax
468
        jz      .err
468
        jz      .err
469
        mov     ebx, eax
469
        mov     ebx, eax
470
        shr     ebx, 12
470
        shr     ebx, 12
471
        mov     [pages_count], ebx
471
        mov     [pages_count], ebx
472
 
472
 
473
        stdcall alloc_kernel_space, eax
473
        stdcall alloc_kernel_space, eax
474
        mov     [lin_addr], eax
474
        mov     [lin_addr], eax
475
        mov     ebx, [pages_count]
475
        mov     ebx, [pages_count]
476
        test    eax, eax
476
        test    eax, eax
477
        jz      .err
477
        jz      .err
478
 
478
 
479
        mov     edx, eax
479
        mov     edx, eax
480
 
480
 
481
        shr     ebx, 3
481
        shr     ebx, 3
482
        jz      .tail
482
        jz      .tail
483
 
483
 
484
        shl     ebx, 3
484
        shl     ebx, 3
485
        stdcall alloc_pages, ebx
485
        stdcall alloc_pages, ebx
486
        test    eax, eax
486
        test    eax, eax
487
        jz      .err
487
        jz      .err
488
 
488
 
489
        mov     ecx, ebx
489
        mov     ecx, ebx
490
        or      eax, PG_GLOBAL + PG_SWR
490
        or      eax, PG_GLOBAL + PG_SWR
491
        mov     ebx, [lin_addr]
491
        mov     ebx, [lin_addr]
492
        call    commit_pages
492
        call    commit_pages
493
 
493
 
494
        mov     edx, ebx                    ; this dirty hack
494
        mov     edx, ebx                    ; this dirty hack
495
.tail:
495
.tail:
496
        mov     ebx, [pages_count]
496
        mov     ebx, [pages_count]
497
        and     ebx, 7
497
        and     ebx, 7
498
        jz      .end
498
        jz      .end
499
@@:
499
@@:
500
        call    alloc_page
500
        call    alloc_page
501
        test    eax, eax
501
        test    eax, eax
502
        jz      .err
502
        jz      .err
503
 
503
 
504
        stdcall map_page, edx, eax, dword (PG_GLOBAL + PG_SWR)
504
        stdcall map_page, edx, eax, dword (PG_GLOBAL + PG_SWR)
505
        add     edx, 0x1000
505
        add     edx, PAGE_SIZE
506
        dec     ebx
506
        dec     ebx
507
        jnz     @B
507
        jnz     @B
508
.end:
508
.end:
509
        mov     eax, [lin_addr]
509
        mov     eax, [lin_addr]
510
        pop     edi
510
        pop     edi
511
        pop     ebx
511
        pop     ebx
512
        ret
512
        ret
513
.err:
513
.err:
514
        xor     eax, eax
514
        xor     eax, eax
515
        pop     edi
515
        pop     edi
516
        pop     ebx
516
        pop     ebx
517
        ret
517
        ret
518
endp
518
endp
519
 
519
 
520
align 4
520
align 4
521
proc kernel_free stdcall, base:dword
521
proc kernel_free stdcall, base:dword
522
 
522
 
523
        push    ebx esi
523
        push    ebx esi
524
 
524
 
525
        spin_lock_irqsave heap_mutex
525
        spin_lock_irqsave heap_mutex
526
 
526
 
527
        mov     eax, [base]
527
        mov     eax, [base]
528
        call    md.find_used
528
        call    md.find_used
529
 
529
 
530
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
530
        cmp     [esi + MEM_BLOCK.flags], MEM_BLOCK_USED
531
        jne     .fail
531
        jne     .fail
532
 
532
 
533
        spin_unlock_irqrestore heap_mutex
533
        spin_unlock_irqrestore heap_mutex
534
 
534
 
535
        mov     eax, [esi + MEM_BLOCK.base]
535
        mov     eax, [esi + MEM_BLOCK.base]
536
        mov     ecx, [esi + MEM_BLOCK.size]
536
        mov     ecx, [esi + MEM_BLOCK.size]
537
        shr     ecx, 12
537
        shr     ecx, 12
538
        call    release_pages   ;eax, ecx
538
        call    release_pages   ;eax, ecx
539
        stdcall free_kernel_space, [base]
539
        stdcall free_kernel_space, [base]
540
        pop     esi ebx
540
        pop     esi ebx
541
        ret
541
        ret
542
.fail:
542
.fail:
543
        spin_unlock_irqrestore heap_mutex
543
        spin_unlock_irqrestore heap_mutex
544
        xor     eax, eax
544
        xor     eax, eax
545
        pop     esi ebx
545
        pop     esi ebx
546
        ret
546
        ret
547
endp
547
endp
548
 
548
 
549
;;;;;;;;;;;;;;      USER HEAP     ;;;;;;;;;;;;;;;;;
549
;;;;;;;;;;;;;;      USER HEAP     ;;;;;;;;;;;;;;;;;
550
 
550
 
551
HEAP_TOP  = 0x80000000
551
HEAP_TOP  = 0x80000000
552
 
552
 
553
align 4
553
align 4
554
proc init_heap
554
proc init_heap
555
 
555
 
556
        mov     ebx, [current_process]
556
        mov     ebx, [current_process]
557
        mov     eax, [ebx + PROC.heap_top]
557
        mov     eax, [ebx + PROC.heap_top]
558
        test    eax, eax
558
        test    eax, eax
559
        jz      @F
559
        jz      @F
560
        sub     eax, [ebx + PROC.heap_base]
560
        sub     eax, [ebx + PROC.heap_base]
561
        sub     eax, PAGE_SIZE
561
        sub     eax, PAGE_SIZE
562
        ret
562
        ret
563
@@:
563
@@:
564
        lea     ecx, [ebx + PROC.heap_lock]
564
        lea     ecx, [ebx + PROC.heap_lock]
565
        call    mutex_init
565
        call    mutex_init
566
 
566
 
567
        mov     esi, [ebx + PROC.mem_used]
567
        mov     esi, [ebx + PROC.mem_used]
568
        add     esi, 4095
568
        add     esi, PAGE_SIZE-1
569
        and     esi, not 4095
569
        and     esi, -PAGE_SIZE
570
        mov     [ebx + PROC.mem_used], esi
570
        mov     [ebx + PROC.mem_used], esi
571
        mov     eax, HEAP_TOP
571
        mov     eax, HEAP_TOP
572
        mov     [ebx + PROC.heap_base], esi
572
        mov     [ebx + PROC.heap_base], esi
573
        mov     [ebx + PROC.heap_top], eax
573
        mov     [ebx + PROC.heap_top], eax
574
 
574
 
575
        sub     eax, esi
575
        sub     eax, esi
576
        shr     esi, 10
576
        shr     esi, 10
577
        mov     ecx, eax
577
        mov     ecx, eax
578
        sub     eax, PAGE_SIZE
578
        sub     eax, PAGE_SIZE
579
        or      ecx, MEM_BLOCK_FREE
579
        or      ecx, MEM_BLOCK_FREE
580
        mov     [page_tabs + esi], ecx
580
        mov     [page_tabs + esi], ecx
581
        ret
581
        ret
582
endp
582
endp
583
 
583
 
584
align 4
584
align 4
585
proc user_alloc stdcall, alloc_size:dword
585
proc user_alloc stdcall, alloc_size:dword
586
 
586
 
587
        push    ebx esi edi
587
        push    ebx esi edi
588
 
588
 
589
        mov     ebx, [current_process]
589
        mov     ebx, [current_process]
590
        lea     ecx, [ebx + PROC.heap_lock]
590
        lea     ecx, [ebx + PROC.heap_lock]
591
        call    mutex_lock
591
        call    mutex_lock
592
 
592
 
593
        mov     ecx, [alloc_size]
593
        mov     ecx, [alloc_size]
594
        add     ecx, (4095 + PAGE_SIZE)
594
        add     ecx, (4095 + PAGE_SIZE)
595
        and     ecx, not 4095
595
        and     ecx, -PAGE_SIZE
596
        mov     esi, [ebx + PROC.heap_base]
596
        mov     esi, [ebx + PROC.heap_base]
597
        mov     edi, [ebx + PROC.heap_top]
597
        mov     edi, [ebx + PROC.heap_top]
598
  .scan:
598
  .scan:
599
        cmp     esi, edi
599
        cmp     esi, edi
600
        jae     .m_exit
600
        jae     .m_exit
601
 
601
 
602
        mov     ebx, esi
602
        mov     ebx, esi
603
        shr     ebx, 12
603
        shr     ebx, 12
604
        mov     eax, [page_tabs + ebx*4]
604
        mov     eax, [page_tabs + ebx*4]
605
        test    al, MEM_BLOCK_FREE
605
        test    al, MEM_BLOCK_FREE
606
        jz      .test_used
606
        jz      .test_used
607
        and     eax, 0xFFFFF000
607
        and     eax, -PAGE_SIZE
608
        cmp     eax, ecx   ;alloc_size
608
        cmp     eax, ecx   ;alloc_size
609
        jb      .m_next
609
        jb      .m_next
610
        jz      @f
610
        jz      @f
611
 
611
 
612
        lea     edx, [esi + ecx]
612
        lea     edx, [esi + ecx]
613
        sub     eax, ecx
613
        sub     eax, ecx
614
        or      al, MEM_BLOCK_FREE
614
        or      al, MEM_BLOCK_FREE
615
        shr     edx, 12
615
        shr     edx, 12
616
        mov     [page_tabs + edx*4], eax
616
        mov     [page_tabs + edx*4], eax
617
  @@:
617
  @@:
618
        or      ecx, MEM_BLOCK_USED
618
        or      ecx, MEM_BLOCK_USED
619
        mov     [page_tabs + ebx*4], ecx
619
        mov     [page_tabs + ebx*4], ecx
620
        shr     ecx, 12
620
        shr     ecx, 12
621
        inc     ebx
621
        inc     ebx
622
        dec     ecx
622
        dec     ecx
623
        jz      .no
623
        jz      .no
624
  @@:
624
  @@:
625
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
625
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
626
        inc     ebx
626
        inc     ebx
627
        dec     ecx
627
        dec     ecx
628
        jnz     @B
628
        jnz     @B
629
  .no:
629
  .no:
630
 
630
 
631
        mov     edx, [current_process]
631
        mov     edx, [current_process]
632
        mov     ebx, [alloc_size]
632
        mov     ebx, [alloc_size]
633
        add     ebx, 0xFFF
633
        add     ebx, PAGE_SIZE-1
634
        and     ebx, not 0xFFF
634
        and     ebx, -PAGE_SIZE
635
        add     [edx + PROC.mem_used], ebx
635
        add     [edx + PROC.mem_used], ebx
636
 
636
 
637
        lea     ecx, [edx + PROC.heap_lock]
637
        lea     ecx, [edx + PROC.heap_lock]
638
        call    mutex_unlock
638
        call    mutex_unlock
639
 
639
 
640
        lea     eax, [esi + 4096]
640
        lea     eax, [esi + PAGE_SIZE]
641
 
641
 
642
        pop     edi
642
        pop     edi
643
        pop     esi
643
        pop     esi
644
        pop     ebx
644
        pop     ebx
645
        ret
645
        ret
646
.test_used:
646
.test_used:
647
        test    al, MEM_BLOCK_USED
647
        test    al, MEM_BLOCK_USED
648
        jz      .m_exit
648
        jz      .m_exit
649
 
649
 
650
        and     eax, 0xFFFFF000 ; not PAGESIZE
650
        and     eax, -PAGE_SIZE
651
.m_next:
651
.m_next:
652
        add     esi, eax
652
        add     esi, eax
653
        jmp     .scan
653
        jmp     .scan
654
.m_exit:
654
.m_exit:
655
        mov     ecx, [current_process]
655
        mov     ecx, [current_process]
656
        lea     ecx, [ecx + PROC.heap_lock]
656
        lea     ecx, [ecx + PROC.heap_lock]
657
        call    mutex_unlock
657
        call    mutex_unlock
658
 
658
 
659
        xor     eax, eax
659
        xor     eax, eax
660
        pop     edi
660
        pop     edi
661
        pop     esi
661
        pop     esi
662
        pop     ebx
662
        pop     ebx
663
        ret
663
        ret
664
endp
664
endp
665
 
665
 
666
align 4
666
align 4
667
proc user_alloc_at stdcall, address:dword, alloc_size:dword
667
proc user_alloc_at stdcall, address:dword, alloc_size:dword
668
 
668
 
669
        push    ebx
669
        push    ebx
670
        push    esi
670
        push    esi
671
        push    edi
671
        push    edi
672
 
672
 
673
        mov     ebx, [current_process]
673
        mov     ebx, [current_process]
674
        lea     ecx, [ebx + PROC.heap_lock]
674
        lea     ecx, [ebx + PROC.heap_lock]
675
        call    mutex_lock
675
        call    mutex_lock
676
 
676
 
677
        mov     edx, [address]
677
        mov     edx, [address]
678
        and     edx, not 0xFFF
678
        and     edx, -PAGE_SIZE
679
        mov     [address], edx
679
        mov     [address], edx
680
        sub     edx, 0x1000
680
        sub     edx, PAGE_SIZE
681
        jb      .error
681
        jb      .error
682
        mov     esi, [ebx + PROC.heap_base]
682
        mov     esi, [ebx + PROC.heap_base]
683
        mov     edi, [ebx + PROC.heap_top]
683
        mov     edi, [ebx + PROC.heap_top]
684
        cmp     edx, esi
684
        cmp     edx, esi
685
        jb      .error
685
        jb      .error
686
.scan:
686
.scan:
687
        cmp     esi, edi
687
        cmp     esi, edi
688
        jae     .error
688
        jae     .error
689
        mov     ebx, esi
689
        mov     ebx, esi
690
        shr     ebx, 12
690
        shr     ebx, 12
691
        mov     eax, [page_tabs + ebx*4]
691
        mov     eax, [page_tabs + ebx*4]
692
        mov     ecx, eax
692
        mov     ecx, eax
693
        and     ecx, 0xFFFFF000
693
        and     ecx, -PAGE_SIZE
694
        add     ecx, esi
694
        add     ecx, esi
695
        cmp     edx, ecx
695
        cmp     edx, ecx
696
        jb      .found
696
        jb      .found
697
        mov     esi, ecx
697
        mov     esi, ecx
698
        jmp     .scan
698
        jmp     .scan
699
.error:
699
.error:
700
        mov     ecx, [current_process]
700
        mov     ecx, [current_process]
701
        lea     ecx, [ecx + PROC.heap_lock]
701
        lea     ecx, [ecx + PROC.heap_lock]
702
        call    mutex_unlock
702
        call    mutex_unlock
703
 
703
 
704
        xor     eax, eax
704
        xor     eax, eax
705
        pop     edi
705
        pop     edi
706
        pop     esi
706
        pop     esi
707
        pop     ebx
707
        pop     ebx
708
        ret
708
        ret
709
.found:
709
.found:
710
        test    al, MEM_BLOCK_FREE
710
        test    al, MEM_BLOCK_FREE
711
        jz      .error
711
        jz      .error
712
        mov     eax, ecx
712
        mov     eax, ecx
713
        sub     eax, edx
713
        sub     eax, edx
714
        sub     eax, 0x1000
714
        sub     eax, PAGE_SIZE
715
        cmp     eax, [alloc_size]
715
        cmp     eax, [alloc_size]
716
        jb      .error
716
        jb      .error
717
 
717
 
718
; Here we have 1 big free block which includes requested area.
718
; Here we have 1 big free block which includes requested area.
719
; In general, 3 other blocks must be created instead:
719
; In general, 3 other blocks must be created instead:
720
; free at [esi, edx);
720
; free at [esi, edx);
721
; busy at [edx, edx + 0x1000 + ALIGN_UP(alloc_size,0x1000));
721
; busy at [edx, edx + 0x1000 + ALIGN_UP(alloc_size,0x1000));
722
; free at [edx + 0x1000 + ALIGN_UP(alloc_size,0x1000), ecx)
722
; free at [edx + 0x1000 + ALIGN_UP(alloc_size,0x1000), ecx)
723
; First or third block (or both) may be absent.
723
; First or third block (or both) may be absent.
724
        mov     eax, edx
724
        mov     eax, edx
725
        sub     eax, esi
725
        sub     eax, esi
726
        jz      .nofirst
726
        jz      .nofirst
727
        or      al, MEM_BLOCK_FREE
727
        or      al, MEM_BLOCK_FREE
728
        mov     [page_tabs + ebx*4], eax
728
        mov     [page_tabs + ebx*4], eax
729
  .nofirst:
729
  .nofirst:
730
        mov     eax, [alloc_size]
730
        mov     eax, [alloc_size]
731
        add     eax, 0x1FFF
731
        add     eax, 0x1FFF
732
        and     eax, not 0xFFF
732
        and     eax, -PAGE_SIZE
733
        mov     ebx, edx
733
        mov     ebx, edx
734
        add     edx, eax
734
        add     edx, eax
735
        shr     ebx, 12
735
        shr     ebx, 12
736
        or      al, MEM_BLOCK_USED
736
        or      al, MEM_BLOCK_USED
737
        mov     [page_tabs + ebx*4], eax
737
        mov     [page_tabs + ebx*4], eax
738
        shr     eax, 12
738
        shr     eax, 12
739
        dec     eax
739
        dec     eax
740
        jz      .second_nofill
740
        jz      .second_nofill
741
        inc     ebx
741
        inc     ebx
742
  .fill:
742
  .fill:
743
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
743
        mov     dword [page_tabs + ebx*4], MEM_BLOCK_RESERVED
744
        inc     ebx
744
        inc     ebx
745
        dec     eax
745
        dec     eax
746
        jnz     .fill
746
        jnz     .fill
747
 
747
 
748
  .second_nofill:
748
  .second_nofill:
749
        sub     ecx, edx
749
        sub     ecx, edx
750
        jz      .nothird
750
        jz      .nothird
751
        or      cl, MEM_BLOCK_FREE
751
        or      cl, MEM_BLOCK_FREE
752
        mov     [page_tabs + ebx*4], ecx
752
        mov     [page_tabs + ebx*4], ecx
753
 
753
 
754
  .nothird:
754
  .nothird:
755
        mov     edx, [current_process]
755
        mov     edx, [current_process]
756
        mov     ebx, [alloc_size]
756
        mov     ebx, [alloc_size]
757
        add     ebx, 0xFFF
757
        add     ebx, PAGE_SIZE-1
758
        and     ebx, not 0xFFF
758
        and     ebx, -PAGE_SIZE
759
        add     [edx + PROC.mem_used], ebx
759
        add     [edx + PROC.mem_used], ebx
760
 
760
 
761
        lea     ecx, [edx + PROC.heap_lock]
761
        lea     ecx, [edx + PROC.heap_lock]
762
        call    mutex_unlock
762
        call    mutex_unlock
763
 
763
 
764
        mov     eax, [address]
764
        mov     eax, [address]
765
 
765
 
766
        pop     edi
766
        pop     edi
767
        pop     esi
767
        pop     esi
768
        pop     ebx
768
        pop     ebx
769
        ret
769
        ret
770
endp
770
endp
771
 
771
 
772
align 4
772
align 4
773
proc user_free stdcall, base:dword
773
proc user_free stdcall, base:dword
774
 
774
 
775
        push    esi
775
        push    esi
776
 
776
 
777
        mov     esi, [base]
777
        mov     esi, [base]
778
        test    esi, esi
778
        test    esi, esi
779
        jz      .fail
779
        jz      .fail
780
 
780
 
781
        push    ebx
781
        push    ebx
782
 
782
 
783
        mov     ebx, [current_process]
783
        mov     ebx, [current_process]
784
        lea     ecx, [ebx + PROC.heap_lock]
784
        lea     ecx, [ebx + PROC.heap_lock]
785
        call    mutex_lock
785
        call    mutex_lock
786
 
786
 
787
        xor     ebx, ebx
787
        xor     ebx, ebx
788
        shr     esi, 12
788
        shr     esi, 12
789
        mov     eax, [page_tabs + (esi-1)*4]
789
        mov     eax, [page_tabs + (esi-1)*4]
790
        test    al, MEM_BLOCK_USED
790
        test    al, MEM_BLOCK_USED
791
        jz      .cantfree
791
        jz      .cantfree
792
        test    al, MEM_BLOCK_DONT_FREE
792
        test    al, MEM_BLOCK_DONT_FREE
793
        jnz     .cantfree
793
        jnz     .cantfree
794
 
794
 
795
        and     eax, not 4095
795
        and     eax, -PAGE_SIZE
796
        mov     ecx, eax
796
        mov     ecx, eax
797
        or      al, MEM_BLOCK_FREE
797
        or      al, MEM_BLOCK_FREE
798
        mov     [page_tabs + (esi-1)*4], eax
798
        mov     [page_tabs + (esi-1)*4], eax
799
        sub     ecx, 4096
799
        sub     ecx, PAGE_SIZE
800
        mov     ebx, ecx
800
        mov     ebx, ecx
801
        shr     ecx, 12
801
        shr     ecx, 12
802
        jz      .released
802
        jz      .released
803
  .release:
803
  .release:
804
        xor     eax, eax
804
        xor     eax, eax
805
        xchg    eax, [page_tabs + esi*4]
805
        xchg    eax, [page_tabs + esi*4]
806
        test    al, 1
806
        test    al, 1
807
        jz      @F
807
        jz      @F
808
        test    eax, PG_SHARED
808
        test    eax, PG_SHARED
809
        jnz     @F
809
        jnz     @F
810
        call    free_page
810
        call    free_page
811
        mov     eax, esi
811
        mov     eax, esi
812
        shl     eax, 12
812
        shl     eax, 12
813
        invlpg  [eax]
813
        invlpg  [eax]
814
  @@:
814
  @@:
815
        inc     esi
815
        inc     esi
816
        dec     ecx
816
        dec     ecx
817
        jnz     .release
817
        jnz     .release
818
 
818
 
819
 .released:
819
 .released:
820
        push    edi
820
        push    edi
821
 
821
 
822
        mov     edx, [current_process]
822
        mov     edx, [current_process]
823
        lea     ecx, [edx + PROC.heap_lock]
823
        lea     ecx, [edx + PROC.heap_lock]
824
        mov     esi, dword [edx + PROC.heap_base]
824
        mov     esi, dword [edx + PROC.heap_base]
825
        mov     edi, dword [edx + PROC.heap_top]
825
        mov     edi, dword [edx + PROC.heap_top]
826
        sub     ebx, [edx + PROC.mem_used]
826
        sub     ebx, [edx + PROC.mem_used]
827
        neg     ebx
827
        neg     ebx
828
        mov     [edx + PROC.mem_used], ebx
828
        mov     [edx + PROC.mem_used], ebx
829
        call    user_normalize
829
        call    user_normalize
830
        pop     edi
830
        pop     edi
831
 .exit:
831
 .exit:
832
        call    mutex_unlock
832
        call    mutex_unlock
833
 
833
 
834
        xor     eax, eax
834
        xor     eax, eax
835
        inc     eax
835
        inc     eax
836
        pop     ebx
836
        pop     ebx
837
        pop     esi
837
        pop     esi
838
        ret
838
        ret
839
 
839
 
840
  .cantfree:
840
  .cantfree:
841
        mov     ecx, [current_process]
841
        mov     ecx, [current_process]
842
        lea     ecx, [ecx + PROC.heap_lock]
842
        lea     ecx, [ecx + PROC.heap_lock]
843
        jmp     .exit
843
        jmp     .exit
844
  .fail:
844
  .fail:
845
        xor     eax, eax
845
        xor     eax, eax
846
        pop     esi
846
        pop     esi
847
        ret
847
        ret
848
endp
848
endp
849
 
849
 
850
 
850
 
851
align 4
851
align 4
852
proc user_unmap stdcall, base:dword, offset:dword, size:dword
852
proc user_unmap stdcall, base:dword, offset:dword, size:dword
853
 
853
 
854
        push    ebx
854
        push    ebx
855
 
855
 
856
        mov     ebx, [base]             ; must be valid pointer
856
        mov     ebx, [base]             ; must be valid pointer
857
        test    ebx, ebx
857
        test    ebx, ebx
858
        jz      .error
858
        jz      .error
859
 
859
 
860
        mov     edx, [offset]           ; check offset
860
        mov     edx, [offset]           ; check offset
861
        add     edx, ebx                ; must be below 2Gb app limit
861
        add     edx, ebx                ; must be below 2Gb app limit
862
        js      .error
862
        js      .error
863
 
863
 
864
        shr     ebx, 12                 ; chek block attributes
864
        shr     ebx, 12                 ; chek block attributes
865
        lea     ebx, [page_tabs + ebx*4]
865
        lea     ebx, [page_tabs + ebx*4]
866
        mov     eax, [ebx - 4]          ; block attributes
866
        mov     eax, [ebx - 4]          ; block attributes
867
        test    al, MEM_BLOCK_USED
867
        test    al, MEM_BLOCK_USED
868
        jz      .error
868
        jz      .error
869
        test    al, MEM_BLOCK_DONT_FREE
869
        test    al, MEM_BLOCK_DONT_FREE
870
        jnz     .error
870
        jnz     .error
871
 
871
 
872
        shr     edx, 12
872
        shr     edx, 12
873
        lea     edx, [page_tabs + edx*4]  ; unmap offset
873
        lea     edx, [page_tabs + edx*4]  ; unmap offset
874
 
874
 
875
        mov     ecx, [size]
875
        mov     ecx, [size]
876
        add     ecx, 4095
876
        add     ecx, PAGE_SIZE-1
877
        shr     ecx, 12                 ; unmap size in pages
877
        shr     ecx, 12                 ; unmap size in pages
878
 
878
 
879
        shr     eax, 12                 ; block size  +  1 page
879
        shr     eax, 12                 ; block size  +  1 page
880
        lea     ebx, [ebx + eax*4-4]      ; block end ptr
880
        lea     ebx, [ebx + eax*4-4]      ; block end ptr
881
        lea     eax, [edx + ecx*4]        ; unmap end ptr
881
        lea     eax, [edx + ecx*4]        ; unmap end ptr
882
 
882
 
883
        cmp     eax, ebx                ; check for overflow
883
        cmp     eax, ebx                ; check for overflow
884
        ja      .error
884
        ja      .error
885
 
885
 
886
        mov     ebx, [offset]
886
        mov     ebx, [offset]
887
        and     ebx, not 4095           ; is it required ?
887
        and     ebx, -PAGE_SIZE         ; is it required ?
888
        add     ebx, [base]
888
        add     ebx, [base]
889
 
889
 
890
  .unmap:
890
  .unmap:
891
        mov     eax, [edx]              ; get page addres
891
        mov     eax, [edx]              ; get page addres
892
        test    al, 1                   ; page mapped ?
892
        test    al, 1                   ; page mapped ?
893
        jz      @F
893
        jz      @F
894
        test    eax, PG_SHARED          ; page shared ?
894
        test    eax, PG_SHARED          ; page shared ?
895
        jnz     @F
895
        jnz     @F
896
        mov     dword[edx], MEM_BLOCK_RESERVED
896
        mov     dword[edx], MEM_BLOCK_RESERVED
897
                                        ; mark page as reserved
897
                                        ; mark page as reserved
898
        invlpg  [ebx]                   ; when we start using
898
        invlpg  [ebx]                   ; when we start using
899
        call    free_page               ; empty c-o-w page instead this ?
899
        call    free_page               ; empty c-o-w page instead this ?
900
  @@:
900
  @@:
901
        add     ebx, 4096       ; PAGESIZE?
901
        add     ebx, PAGE_SIZE
902
        add     edx, 4
902
        add     edx, 4
903
        dec     ecx
903
        dec     ecx
904
        jnz     .unmap
904
        jnz     .unmap
905
 
905
 
906
        pop     ebx
906
        pop     ebx
907
        or      al, 1                   ; return non zero on success
907
        or      al, 1                   ; return non zero on success
908
        ret
908
        ret
909
.error:
909
.error:
910
        pop     ebx
910
        pop     ebx
911
        xor     eax, eax                ; something wrong
911
        xor     eax, eax                ; something wrong
912
        ret
912
        ret
913
endp
913
endp
914
 
914
 
915
align 4
915
align 4
916
user_normalize:
916
user_normalize:
917
; in: esi=heap_base, edi=heap_top
917
; in: esi=heap_base, edi=heap_top
918
; out: eax=0 <=> OK
918
; out: eax=0 <=> OK
919
; destroys: ebx,edx,esi,edi
919
; destroys: ebx,edx,esi,edi
920
        shr     esi, 12
920
        shr     esi, 12
921
        shr     edi, 12
921
        shr     edi, 12
922
@@:
922
@@:
923
        mov     eax, [page_tabs + esi*4]
923
        mov     eax, [page_tabs + esi*4]
924
        test    al, MEM_BLOCK_USED
924
        test    al, MEM_BLOCK_USED
925
        jz      .test_free
925
        jz      .test_free
926
        shr     eax, 12
926
        shr     eax, 12
927
        add     esi, eax
927
        add     esi, eax
928
        jmp     @B
928
        jmp     @B
929
.test_free:
929
.test_free:
930
        test    al, MEM_BLOCK_FREE
930
        test    al, MEM_BLOCK_FREE
931
        jz      .err
931
        jz      .err
932
        mov     edx, eax
932
        mov     edx, eax
933
        shr     edx, 12
933
        shr     edx, 12
934
        add     edx, esi
934
        add     edx, esi
935
        cmp     edx, edi
935
        cmp     edx, edi
936
        jae     .exit
936
        jae     .exit
937
 
937
 
938
        mov     ebx, [page_tabs + edx*4]
938
        mov     ebx, [page_tabs + edx*4]
939
        test    bl, MEM_BLOCK_USED
939
        test    bl, MEM_BLOCK_USED
940
        jz      .next_free
940
        jz      .next_free
941
 
941
 
942
        shr     ebx, 12
942
        shr     ebx, 12
943
        add     edx, ebx
943
        add     edx, ebx
944
        mov     esi, edx
944
        mov     esi, edx
945
        jmp     @B
945
        jmp     @B
946
.next_free:
946
.next_free:
947
        test    bl, MEM_BLOCK_FREE
947
        test    bl, MEM_BLOCK_FREE
948
        jz      .err
948
        jz      .err
949
        and     dword[page_tabs + edx*4], 0
949
        and     dword[page_tabs + edx*4], 0
950
        add     eax, ebx
950
        add     eax, ebx
951
        and     eax, not 4095           ; not (PAGESIZE - 1)    ?
951
        and     eax, -PAGE_SIZE
952
        or      eax, MEM_BLOCK_FREE
952
        or      eax, MEM_BLOCK_FREE
953
        mov     [page_tabs + esi*4], eax
953
        mov     [page_tabs + esi*4], eax
954
        jmp     @B
954
        jmp     @B
955
.exit:
955
.exit:
956
        xor     eax, eax
956
        xor     eax, eax
957
        inc     eax
957
        inc     eax
958
        ret
958
        ret
959
.err:
959
.err:
960
        xor     eax, eax
960
        xor     eax, eax
961
        ret
961
        ret
962
 
962
 
963
user_realloc:
963
user_realloc:
964
; in: eax = pointer, ebx = new size
964
; in: eax = pointer, ebx = new size
965
; out: eax = new pointer or NULL
965
; out: eax = new pointer or NULL
966
        test    eax, eax
966
        test    eax, eax
967
        jnz     @f
967
        jnz     @f
968
; realloc(NULL,sz) - same as malloc(sz)
968
; realloc(NULL,sz) - same as malloc(sz)
969
        push    ebx
969
        push    ebx
970
        call    user_alloc
970
        call    user_alloc
971
        ret
971
        ret
972
@@:
972
@@:
973
        push    ecx edx
973
        push    ecx edx
974
 
974
 
975
        push    eax
975
        push    eax
976
        mov     ecx, [current_process]
976
        mov     ecx, [current_process]
977
        lea     ecx, [ecx + PROC.heap_lock]
977
        lea     ecx, [ecx + PROC.heap_lock]
978
        call    mutex_lock
978
        call    mutex_lock
979
        pop     eax
979
        pop     eax
980
 
980
 
981
        lea     ecx, [eax - 0x1000]
981
        lea     ecx, [eax - PAGE_SIZE]
982
        shr     ecx, 12
982
        shr     ecx, 12
983
        mov     edx, [page_tabs + ecx*4]
983
        mov     edx, [page_tabs + ecx*4]
984
        test    dl, MEM_BLOCK_USED
984
        test    dl, MEM_BLOCK_USED
985
        jnz     @f
985
        jnz     @f
986
; attempt to realloc invalid pointer
986
; attempt to realloc invalid pointer
987
.ret0:
987
.ret0:
988
        mov     ecx, [current_process]
988
        mov     ecx, [current_process]
989
        lea     ecx, [ecx + PROC.heap_lock]
989
        lea     ecx, [ecx + PROC.heap_lock]
990
        call    mutex_unlock
990
        call    mutex_unlock
991
 
991
 
992
        pop     edx ecx
992
        pop     edx ecx
993
        xor     eax, eax
993
        xor     eax, eax
994
        ret
994
        ret
995
@@:
995
@@:
996
        test    dl, MEM_BLOCK_DONT_FREE
996
        test    dl, MEM_BLOCK_DONT_FREE
997
        jnz     .ret0
997
        jnz     .ret0
998
        add     ebx, 0x1FFF
998
        add     ebx, 0x1FFF
999
        shr     edx, 12
999
        shr     edx, 12
1000
        shr     ebx, 12
1000
        shr     ebx, 12
1001
; edx = allocated size, ebx = new size
1001
; edx = allocated size, ebx = new size
1002
        add     edx, ecx
1002
        add     edx, ecx
1003
        add     ebx, ecx
1003
        add     ebx, ecx
1004
        cmp     edx, ebx
1004
        cmp     edx, ebx
1005
        jb      .realloc_add
1005
        jb      .realloc_add
1006
; release part of allocated memory
1006
; release part of allocated memory
1007
.loop:
1007
.loop:
1008
        cmp     edx, ebx
1008
        cmp     edx, ebx
1009
        jz      .release_done
1009
        jz      .release_done
1010
        dec     edx
1010
        dec     edx
1011
        xor     eax, eax
1011
        xor     eax, eax
1012
        xchg    eax, [page_tabs + edx*4]
1012
        xchg    eax, [page_tabs + edx*4]
1013
        test    al, 1
1013
        test    al, 1
1014
        jz      .loop
1014
        jz      .loop
1015
        call    free_page
1015
        call    free_page
1016
        mov     eax, edx
1016
        mov     eax, edx
1017
        shl     eax, 12
1017
        shl     eax, 12
1018
        invlpg  [eax]
1018
        invlpg  [eax]
1019
        jmp     .loop
1019
        jmp     .loop
1020
.release_done:
1020
.release_done:
1021
        sub     ebx, ecx
1021
        sub     ebx, ecx
1022
        cmp     ebx, 1
1022
        cmp     ebx, 1
1023
        jnz     .nofreeall
1023
        jnz     .nofreeall
1024
        mov     eax, [page_tabs + ecx*4]
1024
        mov     eax, [page_tabs + ecx*4]
1025
        and     eax, not 0xFFF
1025
        and     eax, -PAGE_SIZE
1026
        mov     edx, [current_process]
1026
        mov     edx, [current_process]
1027
        mov     ebx, [edx + PROC.mem_used]
1027
        mov     ebx, [edx + PROC.mem_used]
1028
        sub     ebx, eax
1028
        sub     ebx, eax
1029
        add     ebx, 0x1000
1029
        add     ebx, PAGE_SIZE
1030
        or      al, MEM_BLOCK_FREE
1030
        or      al, MEM_BLOCK_FREE
1031
        mov     [page_tabs + ecx*4], eax
1031
        mov     [page_tabs + ecx*4], eax
1032
        push    esi edi
1032
        push    esi edi
1033
        mov     esi, [edx + PROC.heap_base]
1033
        mov     esi, [edx + PROC.heap_base]
1034
        mov     edi, [edx + PROC.heap_top]
1034
        mov     edi, [edx + PROC.heap_top]
1035
        mov     [edx + PROC.mem_used], ebx
1035
        mov     [edx + PROC.mem_used], ebx
1036
        call    user_normalize
1036
        call    user_normalize
1037
        pop     edi esi
1037
        pop     edi esi
1038
        jmp     .ret0   ; all freed
1038
        jmp     .ret0   ; all freed
1039
.nofreeall:
1039
.nofreeall:
1040
        sub     edx, ecx
1040
        sub     edx, ecx
1041
        shl     ebx, 12
1041
        shl     ebx, 12
1042
        or      ebx, MEM_BLOCK_USED
1042
        or      ebx, MEM_BLOCK_USED
1043
        xchg    [page_tabs + ecx*4], ebx
1043
        xchg    [page_tabs + ecx*4], ebx
1044
        shr     ebx, 12
1044
        shr     ebx, 12
1045
        sub     ebx, edx
1045
        sub     ebx, edx
1046
        push    ebx ecx edx
1046
        push    ebx ecx edx
1047
        mov     edx, [current_process]
1047
        mov     edx, [current_process]
1048
        shl     ebx, 12
1048
        shl     ebx, 12
1049
        sub     ebx, [edx + PROC.mem_used]
1049
        sub     ebx, [edx + PROC.mem_used]
1050
        neg     ebx
1050
        neg     ebx
1051
        mov     [edx + PROC.mem_used], ebx
1051
        mov     [edx + PROC.mem_used], ebx
1052
        pop     edx ecx ebx
1052
        pop     edx ecx ebx
1053
        lea     eax, [ecx + 1]
1053
        lea     eax, [ecx + 1]
1054
        shl     eax, 12
1054
        shl     eax, 12
1055
        push    eax
1055
        push    eax
1056
        add     ecx, edx
1056
        add     ecx, edx
1057
        lea     edx, [ecx + ebx]
1057
        lea     edx, [ecx + ebx]
1058
        shl     ebx, 12
1058
        shl     ebx, 12
1059
        jz      .ret
1059
        jz      .ret
1060
        push    esi
1060
        push    esi
1061
        mov     esi, [current_process]
1061
        mov     esi, [current_process]
1062
        mov     esi, [esi + PROC.heap_top]
1062
        mov     esi, [esi + PROC.heap_top]
1063
        shr     esi, 12
1063
        shr     esi, 12
1064
@@:
1064
@@:
1065
        cmp     edx, esi
1065
        cmp     edx, esi
1066
        jae     .merge_done
1066
        jae     .merge_done
1067
        mov     eax, [page_tabs + edx*4]
1067
        mov     eax, [page_tabs + edx*4]
1068
        test    al, MEM_BLOCK_USED
1068
        test    al, MEM_BLOCK_USED
1069
        jnz     .merge_done
1069
        jnz     .merge_done
1070
        and     dword [page_tabs + edx*4], 0
1070
        and     dword [page_tabs + edx*4], 0
1071
        shr     eax, 12
1071
        shr     eax, 12
1072
        add     edx, eax
1072
        add     edx, eax
1073
        shl     eax, 12
1073
        shl     eax, 12
1074
        add     ebx, eax
1074
        add     ebx, eax
1075
        jmp     @b
1075
        jmp     @b
1076
.merge_done:
1076
.merge_done:
1077
        pop     esi
1077
        pop     esi
1078
        or      ebx, MEM_BLOCK_FREE
1078
        or      ebx, MEM_BLOCK_FREE
1079
        mov     [page_tabs + ecx*4], ebx
1079
        mov     [page_tabs + ecx*4], ebx
1080
.ret:
1080
.ret:
1081
        mov     ecx, [current_process]
1081
        mov     ecx, [current_process]
1082
        lea     ecx, [ecx + PROC.heap_lock]
1082
        lea     ecx, [ecx + PROC.heap_lock]
1083
        call    mutex_unlock
1083
        call    mutex_unlock
1084
        pop     eax edx ecx
1084
        pop     eax edx ecx
1085
        ret
1085
        ret
1086
 
1086
 
1087
.realloc_add:
1087
.realloc_add:
1088
; get some additional memory
1088
; get some additional memory
1089
        mov     eax, [current_process]
1089
        mov     eax, [current_process]
1090
        mov     eax, [eax + PROC.heap_top]
1090
        mov     eax, [eax + PROC.heap_top]
1091
        shr     eax, 12
1091
        shr     eax, 12
1092
        cmp     edx, eax
1092
        cmp     edx, eax
1093
        jae     .cant_inplace
1093
        jae     .cant_inplace
1094
        mov     eax, [page_tabs + edx*4]
1094
        mov     eax, [page_tabs + edx*4]
1095
        test    al, MEM_BLOCK_FREE
1095
        test    al, MEM_BLOCK_FREE
1096
        jz      .cant_inplace
1096
        jz      .cant_inplace
1097
        shr     eax, 12
1097
        shr     eax, 12
1098
        add     eax, edx
1098
        add     eax, edx
1099
        sub     eax, ebx
1099
        sub     eax, ebx
1100
        jb      .cant_inplace
1100
        jb      .cant_inplace
1101
        jz      @f
1101
        jz      @f
1102
        shl     eax, 12
1102
        shl     eax, 12
1103
        or      al, MEM_BLOCK_FREE
1103
        or      al, MEM_BLOCK_FREE
1104
        mov     [page_tabs + ebx*4], eax
1104
        mov     [page_tabs + ebx*4], eax
1105
@@:
1105
@@:
1106
        mov     eax, ebx
1106
        mov     eax, ebx
1107
        sub     eax, ecx
1107
        sub     eax, ecx
1108
        shl     eax, 12
1108
        shl     eax, 12
1109
        or      al, MEM_BLOCK_USED
1109
        or      al, MEM_BLOCK_USED
1110
        mov     [page_tabs + ecx*4], eax
1110
        mov     [page_tabs + ecx*4], eax
1111
        lea     eax, [ecx + 1]
1111
        lea     eax, [ecx + 1]
1112
        shl     eax, 12
1112
        shl     eax, 12
1113
        push    eax
1113
        push    eax
1114
        push    edi
1114
        push    edi
1115
        lea     edi, [page_tabs + edx*4]
1115
        lea     edi, [page_tabs + edx*4]
1116
        mov     eax, 2
1116
        mov     eax, 2
1117
        sub     ebx, edx
1117
        sub     ebx, edx
1118
        mov     ecx, ebx
1118
        mov     ecx, ebx
1119
        cld
1119
        cld
1120
        rep stosd
1120
        rep stosd
1121
        pop     edi
1121
        pop     edi
1122
        mov     edx, [current_process]
1122
        mov     edx, [current_process]
1123
        shl     ebx, 12
1123
        shl     ebx, 12
1124
        add     [edx + PROC.mem_used], ebx
1124
        add     [edx + PROC.mem_used], ebx
1125
 
1125
 
1126
        mov     ecx, [current_process]
1126
        mov     ecx, [current_process]
1127
        lea     ecx, [ecx + PROC.heap_lock]
1127
        lea     ecx, [ecx + PROC.heap_lock]
1128
        call    mutex_unlock
1128
        call    mutex_unlock
1129
        pop     eax edx ecx
1129
        pop     eax edx ecx
1130
        ret
1130
        ret
1131
 
1131
 
1132
.cant_inplace:
1132
.cant_inplace:
1133
        push    esi edi
1133
        push    esi edi
1134
        mov     eax, [current_process]
1134
        mov     eax, [current_process]
1135
        mov     esi, [eax + PROC.heap_base]
1135
        mov     esi, [eax + PROC.heap_base]
1136
        mov     edi, [eax + PROC.heap_top]
1136
        mov     edi, [eax + PROC.heap_top]
1137
        shr     esi, 12
1137
        shr     esi, 12
1138
        shr     edi, 12
1138
        shr     edi, 12
1139
        sub     ebx, ecx
1139
        sub     ebx, ecx
1140
.find_place:
1140
.find_place:
1141
        cmp     esi, edi
1141
        cmp     esi, edi
1142
        jae     .place_not_found
1142
        jae     .place_not_found
1143
        mov     eax, [page_tabs + esi*4]
1143
        mov     eax, [page_tabs + esi*4]
1144
        test    al, MEM_BLOCK_FREE
1144
        test    al, MEM_BLOCK_FREE
1145
        jz      .next_place
1145
        jz      .next_place
1146
        shr     eax, 12
1146
        shr     eax, 12
1147
        cmp     eax, ebx
1147
        cmp     eax, ebx
1148
        jae     .place_found
1148
        jae     .place_found
1149
        add     esi, eax
1149
        add     esi, eax
1150
        jmp     .find_place
1150
        jmp     .find_place
1151
.next_place:
1151
.next_place:
1152
        shr     eax, 12
1152
        shr     eax, 12
1153
        add     esi, eax
1153
        add     esi, eax
1154
        jmp     .find_place
1154
        jmp     .find_place
1155
.place_not_found:
1155
.place_not_found:
1156
        pop     edi esi
1156
        pop     edi esi
1157
        jmp     .ret0
1157
        jmp     .ret0
1158
.place_found:
1158
.place_found:
1159
        sub     eax, ebx
1159
        sub     eax, ebx
1160
        jz      @f
1160
        jz      @f
1161
        push    esi
1161
        push    esi
1162
        add     esi, ebx
1162
        add     esi, ebx
1163
        shl     eax, 12
1163
        shl     eax, 12
1164
        or      al, MEM_BLOCK_FREE
1164
        or      al, MEM_BLOCK_FREE
1165
        mov     [page_tabs + esi*4], eax
1165
        mov     [page_tabs + esi*4], eax
1166
        pop     esi
1166
        pop     esi
1167
@@:
1167
@@:
1168
        mov     eax, ebx
1168
        mov     eax, ebx
1169
        shl     eax, 12
1169
        shl     eax, 12
1170
        or      al, MEM_BLOCK_USED
1170
        or      al, MEM_BLOCK_USED
1171
        mov     [page_tabs + esi*4], eax
1171
        mov     [page_tabs + esi*4], eax
1172
        inc     esi
1172
        inc     esi
1173
        mov     eax, esi
1173
        mov     eax, esi
1174
        shl     eax, 12
1174
        shl     eax, 12
1175
        push    eax
1175
        push    eax
1176
        mov     eax, [page_tabs + ecx*4]
1176
        mov     eax, [page_tabs + ecx*4]
1177
        and     eax, not 0xFFF
1177
        and     eax, -PAGE_SIZE
1178
        or      al, MEM_BLOCK_FREE
1178
        or      al, MEM_BLOCK_FREE
1179
        sub     edx, ecx
1179
        sub     edx, ecx
1180
        mov     [page_tabs + ecx*4], eax
1180
        mov     [page_tabs + ecx*4], eax
1181
        inc     ecx
1181
        inc     ecx
1182
        dec     ebx
1182
        dec     ebx
1183
        dec     edx
1183
        dec     edx
1184
        jz      .no
1184
        jz      .no
1185
@@:
1185
@@:
1186
        xor     eax, eax
1186
        xor     eax, eax
1187
        xchg    eax, [page_tabs + ecx*4]
1187
        xchg    eax, [page_tabs + ecx*4]
1188
        mov     [page_tabs + esi*4], eax
1188
        mov     [page_tabs + esi*4], eax
1189
        mov     eax, ecx
1189
        mov     eax, ecx
1190
        shl     eax, 12
1190
        shl     eax, 12
1191
        invlpg  [eax]
1191
        invlpg  [eax]
1192
        inc     esi
1192
        inc     esi
1193
        inc     ecx
1193
        inc     ecx
1194
        dec     ebx
1194
        dec     ebx
1195
        dec     edx
1195
        dec     edx
1196
        jnz     @b
1196
        jnz     @b
1197
.no:
1197
.no:
1198
        push    ebx
1198
        push    ebx
1199
        mov     edx, [current_process]
1199
        mov     edx, [current_process]
1200
        shl     ebx, 12
1200
        shl     ebx, 12
1201
        add     [edx + PROC.mem_used], ebx
1201
        add     [edx + PROC.mem_used], ebx
1202
        pop     ebx
1202
        pop     ebx
1203
@@:
1203
@@:
1204
        mov     dword [page_tabs + esi*4], MEM_BLOCK_RESERVED
1204
        mov     dword [page_tabs + esi*4], MEM_BLOCK_RESERVED
1205
        inc     esi
1205
        inc     esi
1206
        dec     ebx
1206
        dec     ebx
1207
        jnz     @b
1207
        jnz     @b
1208
 
1208
 
1209
        mov     ecx, [current_process]
1209
        mov     ecx, [current_process]
1210
        lea     ecx, [ecx + PROC.heap_lock]
1210
        lea     ecx, [ecx + PROC.heap_lock]
1211
        call    mutex_unlock
1211
        call    mutex_unlock
1212
        pop     eax edi esi edx ecx
1212
        pop     eax edi esi edx ecx
1213
        ret
1213
        ret
1214
 
1214
 
1215
 
1215
 
1216
 
1216
 
1217
;;;;;;;;;;;;;;      SHARED MEMORY     ;;;;;;;;;;;;;;;;;
1217
;;;;;;;;;;;;;;      SHARED MEMORY     ;;;;;;;;;;;;;;;;;
1218
 
1218
 
1219
 
1219
 
1220
; param
1220
; param
1221
;  eax= shm_map object
1221
;  eax= shm_map object
1222
 
1222
 
1223
align 4
1223
align 4
1224
destroy_smap:
1224
destroy_smap:
1225
 
1225
 
1226
        pushfd
1226
        pushfd
1227
        cli
1227
        cli
1228
 
1228
 
1229
        push    esi
1229
        push    esi
1230
        push    edi
1230
        push    edi
1231
 
1231
 
1232
        mov     edi, eax
1232
        mov     edi, eax
1233
        mov     esi, [eax + SMAP.parent]
1233
        mov     esi, [eax + SMAP.parent]
1234
        test    esi, esi
1234
        test    esi, esi
1235
        jz      .done
1235
        jz      .done
1236
 
1236
 
1237
        lock dec [esi + SMEM.refcount]
1237
        lock dec [esi + SMEM.refcount]
1238
        jnz     .done
1238
        jnz     .done
1239
 
1239
 
1240
        mov     ecx, [esi + SMEM.bk]
1240
        mov     ecx, [esi + SMEM.bk]
1241
        mov     edx, [esi + SMEM.fd]
1241
        mov     edx, [esi + SMEM.fd]
1242
 
1242
 
1243
        mov     [ecx + SMEM.fd], edx
1243
        mov     [ecx + SMEM.fd], edx
1244
        mov     [edx + SMEM.bk], ecx
1244
        mov     [edx + SMEM.bk], ecx
1245
 
1245
 
1246
        stdcall kernel_free, [esi + SMEM.base]
1246
        stdcall kernel_free, [esi + SMEM.base]
1247
        mov     eax, esi
1247
        mov     eax, esi
1248
        call    free
1248
        call    free
1249
.done:
1249
.done:
1250
        mov     eax, edi
1250
        mov     eax, edi
1251
        call    destroy_kernel_object
1251
        call    destroy_kernel_object
1252
 
1252
 
1253
        pop     edi
1253
        pop     edi
1254
        pop     esi
1254
        pop     esi
1255
        popfd
1255
        popfd
1256
 
1256
 
1257
        ret
1257
        ret
1258
 
1258
 
1259
E_NOTFOUND      =  5
1259
E_NOTFOUND      =  5
1260
E_ACCESS        = 10
1260
E_ACCESS        = 10
1261
E_NOMEM         = 30
1261
E_NOMEM         = 30
1262
E_PARAM         = 33
1262
E_PARAM         = 33
1263
 
1263
 
1264
SHM_READ        = 0
1264
SHM_READ        = 0
1265
SHM_WRITE       = 1
1265
SHM_WRITE       = 1
1266
 
1266
 
1267
SHM_ACCESS_MASK = 3
1267
SHM_ACCESS_MASK = 3
1268
 
1268
 
1269
SHM_OPEN        = 0 shl 2
1269
SHM_OPEN        = 0 shl 2
1270
SHM_OPEN_ALWAYS = 1 shl 2
1270
SHM_OPEN_ALWAYS = 1 shl 2
1271
SHM_CREATE      = 2 shl 2
1271
SHM_CREATE      = 2 shl 2
1272
 
1272
 
1273
SHM_OPEN_MASK   = 3 shl 2
1273
SHM_OPEN_MASK   = 3 shl 2
1274
 
1274
 
1275
align 4
1275
align 4
1276
proc shmem_open stdcall name:dword, size:dword, access:dword
1276
proc shmem_open stdcall name:dword, size:dword, access:dword
1277
        locals
1277
        locals
1278
           action         dd ?
1278
           action         dd ?
1279
           owner_access   dd ?
1279
           owner_access   dd ?
1280
           mapped         dd ?
1280
           mapped         dd ?
1281
        endl
1281
        endl
1282
 
1282
 
1283
        push    ebx
1283
        push    ebx
1284
        push    esi
1284
        push    esi
1285
        push    edi
1285
        push    edi
1286
 
1286
 
1287
        mov     [mapped], 0
1287
        mov     [mapped], 0
1288
        mov     [owner_access], 0
1288
        mov     [owner_access], 0
1289
 
1289
 
1290
        pushfd                         ;mutex required
1290
        pushfd                         ;mutex required
1291
        cli
1291
        cli
1292
 
1292
 
1293
        mov     eax, [access]
1293
        mov     eax, [access]
1294
        and     eax, SHM_OPEN_MASK
1294
        and     eax, SHM_OPEN_MASK
1295
        mov     [action], eax
1295
        mov     [action], eax
1296
 
1296
 
1297
        mov     ebx, [name]
1297
        mov     ebx, [name]
1298
        test    ebx, ebx
1298
        test    ebx, ebx
1299
        mov     edx, E_PARAM
1299
        mov     edx, E_PARAM
1300
        jz      .fail
1300
        jz      .fail
1301
 
1301
 
1302
        mov     esi, [shmem_list.fd]
1302
        mov     esi, [shmem_list.fd]
1303
align 4
1303
align 4
1304
@@:
1304
@@:
1305
        cmp     esi, shmem_list
1305
        cmp     esi, shmem_list
1306
        je      .not_found
1306
        je      .not_found
1307
 
1307
 
1308
        lea     edx, [esi + SMEM.name]; link , base, size
1308
        lea     edx, [esi + SMEM.name]; link , base, size
1309
        stdcall strncmp, edx, ebx, 32
1309
        stdcall strncmp, edx, ebx, 32
1310
        test    eax, eax
1310
        test    eax, eax
1311
        je      .found
1311
        je      .found
1312
 
1312
 
1313
        mov     esi, [esi + SMEM.fd]
1313
        mov     esi, [esi + SMEM.fd]
1314
        jmp     @B
1314
        jmp     @B
1315
 
1315
 
1316
.not_found:
1316
.not_found:
1317
        mov     eax, [action]
1317
        mov     eax, [action]
1318
 
1318
 
1319
        cmp     eax, SHM_OPEN
1319
        cmp     eax, SHM_OPEN
1320
        mov     edx, E_NOTFOUND
1320
        mov     edx, E_NOTFOUND
1321
        je      .fail
1321
        je      .fail
1322
 
1322
 
1323
        cmp     eax, SHM_CREATE
1323
        cmp     eax, SHM_CREATE
1324
        mov     edx, E_PARAM
1324
        mov     edx, E_PARAM
1325
        je      .create_shm
1325
        je      .create_shm
1326
 
1326
 
1327
        cmp     eax, SHM_OPEN_ALWAYS
1327
        cmp     eax, SHM_OPEN_ALWAYS
1328
        jne     .fail
1328
        jne     .fail
1329
 
1329
 
1330
.create_shm:
1330
.create_shm:
1331
 
1331
 
1332
        mov     ecx, [size]
1332
        mov     ecx, [size]
1333
        test    ecx, ecx
1333
        test    ecx, ecx
1334
        jz      .fail
1334
        jz      .fail
1335
 
1335
 
1336
        add     ecx, 4095
1336
        add     ecx, PAGE_SIZE-1
1337
        and     ecx, -4096
1337
        and     ecx, -PAGE_SIZE
1338
        mov     [size], ecx
1338
        mov     [size], ecx
1339
 
1339
 
1340
        mov     eax, sizeof.SMEM
1340
        mov     eax, sizeof.SMEM
1341
        call    malloc
1341
        call    malloc
1342
        test    eax, eax
1342
        test    eax, eax
1343
        mov     esi, eax
1343
        mov     esi, eax
1344
        mov     edx, E_NOMEM
1344
        mov     edx, E_NOMEM
1345
        jz      .fail
1345
        jz      .fail
1346
 
1346
 
1347
        stdcall kernel_alloc, [size]
1347
        stdcall kernel_alloc, [size]
1348
        test    eax, eax
1348
        test    eax, eax
1349
        mov     [mapped], eax
1349
        mov     [mapped], eax
1350
        mov     edx, E_NOMEM
1350
        mov     edx, E_NOMEM
1351
        jz      .cleanup
1351
        jz      .cleanup
1352
 
1352
 
1353
        mov     ecx, [size]
1353
        mov     ecx, [size]
1354
        mov     edx, [access]
1354
        mov     edx, [access]
1355
        and     edx, SHM_ACCESS_MASK
1355
        and     edx, SHM_ACCESS_MASK
1356
 
1356
 
1357
        mov     [esi + SMEM.base], eax
1357
        mov     [esi + SMEM.base], eax
1358
        mov     [esi + SMEM.size], ecx
1358
        mov     [esi + SMEM.size], ecx
1359
        mov     [esi + SMEM.access], edx
1359
        mov     [esi + SMEM.access], edx
1360
        mov     [esi + SMEM.refcount], 0
1360
        mov     [esi + SMEM.refcount], 0
1361
        mov     [esi + SMEM.name + 28], 0
1361
        mov     [esi + SMEM.name + 28], 0
1362
 
1362
 
1363
        lea     eax, [esi + SMEM.name]
1363
        lea     eax, [esi + SMEM.name]
1364
        stdcall strncpy, eax, [name], 31
1364
        stdcall strncpy, eax, [name], 31
1365
 
1365
 
1366
        mov     eax, [shmem_list.fd]
1366
        mov     eax, [shmem_list.fd]
1367
        mov     [esi + SMEM.bk], shmem_list
1367
        mov     [esi + SMEM.bk], shmem_list
1368
        mov     [esi + SMEM.fd], eax
1368
        mov     [esi + SMEM.fd], eax
1369
 
1369
 
1370
        mov     [eax + SMEM.bk], esi
1370
        mov     [eax + SMEM.bk], esi
1371
        mov     [shmem_list.fd], esi
1371
        mov     [shmem_list.fd], esi
1372
 
1372
 
1373
        mov     [action], SHM_OPEN
1373
        mov     [action], SHM_OPEN
1374
        mov     [owner_access], SHM_WRITE
1374
        mov     [owner_access], SHM_WRITE
1375
 
1375
 
1376
.found:
1376
.found:
1377
        mov     eax, [action]
1377
        mov     eax, [action]
1378
 
1378
 
1379
        cmp     eax, SHM_CREATE
1379
        cmp     eax, SHM_CREATE
1380
        mov     edx, E_ACCESS
1380
        mov     edx, E_ACCESS
1381
        je      .exit
1381
        je      .exit
1382
 
1382
 
1383
        cmp     eax, SHM_OPEN
1383
        cmp     eax, SHM_OPEN
1384
        mov     edx, E_PARAM
1384
        mov     edx, E_PARAM
1385
        je      .create_map
1385
        je      .create_map
1386
 
1386
 
1387
        cmp     eax, SHM_OPEN_ALWAYS
1387
        cmp     eax, SHM_OPEN_ALWAYS
1388
        jne     .fail
1388
        jne     .fail
1389
 
1389
 
1390
.create_map:
1390
.create_map:
1391
 
1391
 
1392
        mov     eax, [access]
1392
        mov     eax, [access]
1393
        and     eax, SHM_ACCESS_MASK
1393
        and     eax, SHM_ACCESS_MASK
1394
        cmp     eax, [esi + SMEM.access]
1394
        cmp     eax, [esi + SMEM.access]
1395
        mov     [access], eax
1395
        mov     [access], eax
1396
        mov     edx, E_ACCESS
1396
        mov     edx, E_ACCESS
1397
        ja      .fail
1397
        ja      .fail
1398
 
1398
 
1399
        mov     ebx, [current_slot]
1399
        mov     ebx, [current_slot]
1400
        mov     ebx, [ebx + APPDATA.tid]
1400
        mov     ebx, [ebx + APPDATA.tid]
1401
        mov     eax, sizeof.SMAP
1401
        mov     eax, sizeof.SMAP
1402
 
1402
 
1403
        call    create_kernel_object
1403
        call    create_kernel_object
1404
        test    eax, eax
1404
        test    eax, eax
1405
        mov     edi, eax
1405
        mov     edi, eax
1406
        mov     edx, E_NOMEM
1406
        mov     edx, E_NOMEM
1407
        jz      .fail
1407
        jz      .fail
1408
 
1408
 
1409
        inc     [esi + SMEM.refcount]
1409
        inc     [esi + SMEM.refcount]
1410
 
1410
 
1411
        mov     [edi + SMAP.magic], 'SMAP'
1411
        mov     [edi + SMAP.magic], 'SMAP'
1412
        mov     [edi + SMAP.destroy], destroy_smap
1412
        mov     [edi + SMAP.destroy], destroy_smap
1413
        mov     [edi + SMAP.parent], esi
1413
        mov     [edi + SMAP.parent], esi
1414
        mov     [edi + SMAP.base], 0
1414
        mov     [edi + SMAP.base], 0
1415
 
1415
 
1416
        stdcall user_alloc, [esi + SMEM.size]
1416
        stdcall user_alloc, [esi + SMEM.size]
1417
        test    eax, eax
1417
        test    eax, eax
1418
        mov     [mapped], eax
1418
        mov     [mapped], eax
1419
        mov     edx, E_NOMEM
1419
        mov     edx, E_NOMEM
1420
        jz      .cleanup2
1420
        jz      .cleanup2
1421
 
1421
 
1422
        mov     [edi + SMAP.base], eax
1422
        mov     [edi + SMAP.base], eax
1423
 
1423
 
1424
        mov     ecx, [esi + SMEM.size]
1424
        mov     ecx, [esi + SMEM.size]
1425
        mov     [size], ecx
1425
        mov     [size], ecx
1426
 
1426
 
1427
        shr     ecx, 12
1427
        shr     ecx, 12
1428
        shr     eax, 10
1428
        shr     eax, 10
1429
 
1429
 
1430
        mov     esi, [esi + SMEM.base]
1430
        mov     esi, [esi + SMEM.base]
1431
        shr     esi, 10
1431
        shr     esi, 10
1432
        lea     edi, [page_tabs + eax]
1432
        lea     edi, [page_tabs + eax]
1433
        add     esi, page_tabs
1433
        add     esi, page_tabs
1434
 
1434
 
1435
        mov     edx, [access]
1435
        mov     edx, [access]
1436
        or      edx, [owner_access]
1436
        or      edx, [owner_access]
1437
        shl     edx, 1
1437
        shl     edx, 1
1438
        or      edx, PG_SHARED + PG_UR
1438
        or      edx, PG_SHARED + PG_UR
1439
@@:
1439
@@:
1440
        lodsd
1440
        lodsd
1441
        and     eax, 0xFFFFF000
1441
        and     eax, -PAGE_SIZE
1442
        or      eax, edx
1442
        or      eax, edx
1443
        stosd
1443
        stosd
1444
        loop    @B
1444
        loop    @B
1445
 
1445
 
1446
        xor     edx, edx
1446
        xor     edx, edx
1447
 
1447
 
1448
        cmp     [owner_access], 0
1448
        cmp     [owner_access], 0
1449
        jne     .fail
1449
        jne     .fail
1450
.exit:
1450
.exit:
1451
        mov     edx, [size]
1451
        mov     edx, [size]
1452
.fail:
1452
.fail:
1453
        mov     eax, [mapped]
1453
        mov     eax, [mapped]
1454
 
1454
 
1455
        popfd
1455
        popfd
1456
        pop     edi
1456
        pop     edi
1457
        pop     esi
1457
        pop     esi
1458
        pop     ebx
1458
        pop     ebx
1459
        ret
1459
        ret
1460
.cleanup:
1460
.cleanup:
1461
        mov     [size], edx
1461
        mov     [size], edx
1462
        mov     eax, esi
1462
        mov     eax, esi
1463
        call    free
1463
        call    free
1464
        jmp     .exit
1464
        jmp     .exit
1465
 
1465
 
1466
.cleanup2:
1466
.cleanup2:
1467
        mov     [size], edx
1467
        mov     [size], edx
1468
        mov     eax, edi
1468
        mov     eax, edi
1469
        call    destroy_smap
1469
        call    destroy_smap
1470
        jmp     .exit
1470
        jmp     .exit
1471
endp
1471
endp
1472
 
1472
 
1473
align 4
1473
align 4
1474
proc shmem_close stdcall, name:dword
1474
proc shmem_close stdcall, name:dword
1475
 
1475
 
1476
        mov     eax, [name]
1476
        mov     eax, [name]
1477
        test    eax, eax
1477
        test    eax, eax
1478
        jz      .fail
1478
        jz      .fail
1479
 
1479
 
1480
        push    ebx ; Added
1480
        push    ebx ; Added
1481
        push    esi
1481
        push    esi
1482
        push    edi
1482
        push    edi
1483
        pushfd
1483
        pushfd
1484
        cli
1484
        cli
1485
 
1485
 
1486
        mov     esi, [current_slot]
1486
        mov     esi, [current_slot]
1487
        add     esi, APP_OBJ_OFFSET
1487
        add     esi, APP_OBJ_OFFSET
1488
        mov     ebx, esi ; Fixed endless loop bug with not existing name (part 1)
1488
        mov     ebx, esi ; Fixed endless loop bug with not existing name (part 1)
1489
.next:
1489
.next:
1490
        mov     eax, [esi + APPOBJ.fd]
1490
        mov     eax, [esi + APPOBJ.fd]
1491
        test    eax, eax
1491
        test    eax, eax
1492
        jz      @F
1492
        jz      @F
1493
 
1493
 
1494
        cmp     eax, ebx ;esi ; Fixed endless loop bug with not existing name (part 2)
1494
        cmp     eax, ebx ;esi ; Fixed endless loop bug with not existing name (part 2)
1495
        je      @F            ; Small optimization
1495
        je      @F            ; Small optimization
1496
        mov     esi, eax
1496
        mov     esi, eax
1497
        ;je      @F
1497
        ;je      @F
1498
 
1498
 
1499
        cmp     [eax + SMAP.magic], 'SMAP'
1499
        cmp     [eax + SMAP.magic], 'SMAP'
1500
        jne     .next
1500
        jne     .next
1501
 
1501
 
1502
        mov     edi, [eax + SMAP.parent]
1502
        mov     edi, [eax + SMAP.parent]
1503
        test    edi, edi
1503
        test    edi, edi
1504
        jz      .next
1504
        jz      .next
1505
 
1505
 
1506
        lea     edi, [edi + SMEM.name]
1506
        lea     edi, [edi + SMEM.name]
1507
        stdcall strncmp, [name], edi, 32
1507
        stdcall strncmp, [name], edi, 32
1508
        test    eax, eax
1508
        test    eax, eax
1509
        jne     .next
1509
        jne     .next
1510
 
1510
 
1511
        stdcall user_free, [esi + SMAP.base]
1511
        stdcall user_free, [esi + SMAP.base]
1512
 
1512
 
1513
        mov     eax, esi
1513
        mov     eax, esi
1514
        call    [esi + APPOBJ.destroy]
1514
        call    [esi + APPOBJ.destroy]
1515
@@:
1515
@@:
1516
        popfd
1516
        popfd
1517
        pop     edi
1517
        pop     edi
1518
        pop     esi
1518
        pop     esi
1519
        pop     ebx ; Added
1519
        pop     ebx ; Added
1520
.fail:
1520
.fail:
1521
        ret
1521
        ret
1522
endp
1522
endp
1523
 
1523
 
1524
 
1524
 
1525
 
1525
 
1526
proc    user_ring stdcall, size:dword
1526
proc    user_ring stdcall, size:dword
1527
 
1527
 
1528
locals
1528
locals
1529
        virt_ptr        dd ?
1529
        virt_ptr        dd ?
1530
        phys_ptr        dd ?
1530
        phys_ptr        dd ?
1531
        num_pages       dd ?
1531
        num_pages       dd ?
1532
endl
1532
endl
1533
 
1533
 
1534
; Size must be an exact multiple of pagesize
1534
; Size must be an exact multiple of pagesize
1535
        mov     eax, [size]
1535
        mov     eax, [size]
1536
        test    eax, PAGE_SIZE-1
1536
        test    eax, PAGE_SIZE-1
1537
        jnz     .exit
1537
        jnz     .exit
1538
 
1538
 
1539
; We must have at least one complete page
1539
; We must have at least one complete page
1540
        shr     eax, 12
1540
        shr     eax, 12
1541
        jz      .exit
1541
        jz      .exit
1542
        mov     [num_pages], eax
1542
        mov     [num_pages], eax
1543
 
1543
 
1544
; Allocate double the virtual memory
1544
; Allocate double the virtual memory
1545
        mov     eax, [size]
1545
        mov     eax, [size]
1546
        shl     eax, 1
1546
        shl     eax, 1
1547
        jz      .exit
1547
        jz      .exit
1548
        stdcall user_alloc, eax
1548
        stdcall user_alloc, eax
1549
        test    eax, eax
1549
        test    eax, eax
1550
        jz      .exit
1550
        jz      .exit
1551
        mov     [virt_ptr], eax
1551
        mov     [virt_ptr], eax
1552
 
1552
 
1553
; Now allocate physical memory
1553
; Now allocate physical memory
1554
        stdcall alloc_pages, [num_pages]
1554
        stdcall alloc_pages, [num_pages]
1555
        test    eax, eax
1555
        test    eax, eax
1556
        jz      .exit_free_virt
1556
        jz      .exit_free_virt
1557
        mov     [phys_ptr], eax
1557
        mov     [phys_ptr], eax
1558
 
1558
 
1559
; Map first half of virtual memory to physical memory
1559
; Map first half of virtual memory to physical memory
1560
        push    ecx esi edi
1560
        push    ecx esi edi
1561
        mov     ecx, [num_pages]
1561
        mov     ecx, [num_pages]
1562
        mov     esi, [virt_ptr]
1562
        mov     esi, [virt_ptr]
1563
        mov     edi, [phys_ptr]
1563
        mov     edi, [phys_ptr]
1564
  .loop1:
1564
  .loop1:
1565
        stdcall map_page, esi, edi, PG_UWR
1565
        stdcall map_page, esi, edi, PG_UWR
1566
        add     esi, PAGE_SIZE
1566
        add     esi, PAGE_SIZE
1567
        add     edi, PAGE_SIZE
1567
        add     edi, PAGE_SIZE
1568
        dec     ecx
1568
        dec     ecx
1569
        jnz     .loop1
1569
        jnz     .loop1
1570
 
1570
 
1571
; Map second half of virtual memory to same physical memory
1571
; Map second half of virtual memory to same physical memory
1572
        mov     ecx, [num_pages]
1572
        mov     ecx, [num_pages]
1573
        mov     edi, [phys_ptr]
1573
        mov     edi, [phys_ptr]
1574
  .loop2:
1574
  .loop2:
1575
        stdcall map_page, esi, edi, PG_UWR
1575
        stdcall map_page, esi, edi, PG_UWR
1576
        add     esi, PAGE_SIZE
1576
        add     esi, PAGE_SIZE
1577
        add     edi, PAGE_SIZE
1577
        add     edi, PAGE_SIZE
1578
        dec     ecx
1578
        dec     ecx
1579
        jnz     .loop2
1579
        jnz     .loop2
1580
        pop     edi esi ecx
1580
        pop     edi esi ecx
1581
 
1581
 
1582
        mov     eax, [virt_ptr]
1582
        mov     eax, [virt_ptr]
1583
        ret
1583
        ret
1584
 
1584
 
1585
  .exit_free_virt:
1585
  .exit_free_virt:
1586
        stdcall user_free, [virt_ptr]
1586
        stdcall user_free, [virt_ptr]
1587
 
1587
 
1588
  .exit:
1588
  .exit:
1589
        xor     eax, eax
1589
        xor     eax, eax
1590
        ret
1590
        ret
1591
 
1591
 
1592
endp
1592
endp