Subversion Repositories Kolibri OS

Rev

Rev 40 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 1
if ~defined newprocess_inc
2
newprocess_inc_fix:
3
newprocess_inc fix newprocess_inc_fix
4
include "mem.inc"
5
include "memmanag.inc"
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
;;Working with new types of processes.
8
;;Author: Khalyavin Andrey halyavin@land.ru
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
iglobal
11
    new_process_loading db 'K : New Process - loading',13,10,0
12
    new_process_running db 'K : New Process - done',13,10,0
13
    start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
14
endg
15
;-----------------------------------------------------------------------------
16
 
17
find_new_process_place:
18
;input:
19
;  none
20
;result:
21
;  eax=[new_process_place]<>0 - ok
22
;      0 - failed.
23
;This function find least empty slot.
24
;It doesn't increase [0x3004]!
25
    mov    eax,0x3000+second_base_address
26
    push   ebx
27
    mov    ebx,[0x3004]
28
    inc    ebx
29
    shl    ebx,5
30
    add    ebx,eax               ;ebx - address of process information for (last+1) slot
31
.newprocessplace:
32
;eax = address of process information for current slot
33
    cmp    eax,ebx
34
    jz     .endnewprocessplace   ;empty slot after high boundary
35
    add    eax,0x20
36
    cmp    word [eax+0xa],9      ;check process state, 9 means that process slot is empty
37
    jnz    .newprocessplace
38
.endnewprocessplace:
39
    mov    ebx,eax
40
    sub    eax,0x3000+second_base_address
41
    shr    eax,5                 ;calculate slot index
42
    cmp    eax,256
43
    jge    .failed               ;it should be <256
44
    mov    word [ebx+0xa],9      ;set process state to 9 (for slot after hight boundary)
45
    mov    [new_process_place],eax ;save process slot
46
    pop    ebx
47
    ret
48
.failed:
49
    xor    eax,eax
50
    pop    ebx
51
    ret
52
;-----------------------------------------------------------------------------
4 poddubny 53
safe_sti:
54
    cmp    byte [0xe000], 1
55
    jne    @f
56
    sti
57
 @@:ret
58
 
1 ha 59
new_start_application_floppy:
60
;input:
61
;  eax - pointer to filename
62
;  ebx - parameters to pass
40 halyavin 63
;  edx - flags
1 ha 64
;result:
65
;  eax - pid of new process
66
;        or 0 if call fails.
5 halyavin 67
    mov    [appl_path],edi
1 ha 68
    pushad
69
    mov    esi,new_process_loading
70
    call   sys_msg_board_str     ;write to debug board
71
 
72
;wait application_table_status mutex
73
.table_status:
74
    cli
75
    cmp    [application_table_status],0
76
    jz     .stf
77
    sti
78
    call   change_task
79
    jmp    .table_status
80
.stf:
81
    call   set_application_table_status
82
;we can change system tables now
83
    push   edi
84
    push   ebx
85
    push   eax
86
    call   find_new_process_place ;find empty process slot
87
    sti
88
    test   eax,eax
89
    jz     .failed
90
 
91
    mov    edi,eax
92
    shl    edi,8
93
    add    edi,0x80000
94
    mov    ecx,256/4
95
    xor    eax,eax
96
    cld
97
    rep    stosd                 ;clean extended information about process
98
 
99
;set new process name
5 halyavin 100
    xor    eax,eax
101
    mov    [appl_path_size],eax
102
    mov    eax,[esp]  ;+8]
1 ha 103
.find_last_byte:
104
    cmp    byte [eax],0
105
    jz     .find_last_byte_end
106
    inc    eax
5 halyavin 107
    inc    [appl_path_size]
1 ha 108
    jmp    .find_last_byte
5 halyavin 109
.find_last_byte_end:
110
    add    [appl_path_size],24
1 ha 111
    sub    eax,11                ;last 11 bytes = application name
112
;    mov    eax,[esp]             ;eax - pointer to file name
113
    mov    ebx,[new_process_place]
114
    shl    ebx,8
115
    add    ebx,0x80000
116
    mov    ecx,11
117
    call   memmove
118
 
119
;read header of file
120
    mov    eax,[esp]
121
    mov    ebx,1                 ;index of first block
122
    mov    ecx,2                 ;number of blocks
123
    mov    edx,0x90000           ;temp area
124
    mov    esi,12                ;file name length
125
    mov    edi,[esp+8]
126
;    cli
127
    call   floppy_fileread       ;read file from FD
128
;    sti
129
    cmp    eax,0
130
    jne    .cleanfailed
131
;check MENUET signature
132
    cmp    [0x90000],dword 'MENU'
133
    jnz    .cleanfailed
134
    cmp    [0x90004],word 'ET'
135
    jnz    .cleanfailed
136
 
137
    call   get_app_params        ;parse header fields
138
    cmp    esi,0
139
    jz     .cleanfailed
140
 
141
    mov    eax,[new_process_place]
142
    call   create_app_cr3_table   ;create page directory for new process
143
    test   eax,eax
144
    jz     .cleanfailed_mem
145
 
146
    call   MEM_Get_Linear_Address ;calculate linear address of it
147
 
148
    mov    ebx,std_application_base_address
149
    mov    ecx,[app_mem]
150
    add    ecx,4095
151
    shr    ecx,12
152
    mov    edx,eax
153
    call   mem_alloc_specified_region ;allocate memory for application
154
    test   eax,eax
9 halyavin 155
    jz     .cleanfailed_mem1
1 ha 156
 
157
    mov    eax,[edx+(std_application_base_address shr 20)]
158
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
159
    call   MEM_Get_Linear_Address
160
    mov    edx,eax
161
 
162
;read file
163
    mov    ebx,1
164
    mov    esi,12                ;length of file name
165
.loop1:
166
;edx = linear address of current page table entry
167
;ebx = index of current block in file
168
    push   edx
169
    mov    eax,[edx]
170
    and    eax,not (4096-1)
171
    call   MEM_Get_Linear_Address
172
    mov    edx,eax               ;read file block to current page
173
    mov    eax,[esp+4]           ;restore pointer to file name
174
    mov    ecx,8                 ;number of blocks read
175
    push   ebx
176
    mov    edi,[esp+16]
177
;    cli
178
    call   floppy_fileread
179
;ebx=file size
180
;    sti
181
    pop    ecx
182
    shr    ebx,9
183
    cmp    ecx,ebx
184
    jg     .endloop1             ;if end of file?
185
    mov    ebx,ecx
186
    test   eax,eax
187
    jnz    .endloop1             ;check io errors
188
    pop    edx
189
    add    ebx,8                 ;go to next page
190
    add    edx,4
191
    jmp    .loop1
192
 
193
.endloop1:
194
    add    esp,8+4                 ;pop linear address of page table entry and pointer to file name
195
    call   new_start_application_fl.add_app_parameters
196
    mov    [esp+28],eax
197
    popad
198
    ret
9 halyavin 199
 
200
.cleanfailed_mem1:
201
;there is mem for directory entry, but there is no mem for pages
202
;so free directory entry
203
    mov    eax,[new_process_place]
204
    shl    eax,8
205
    mov    eax,[0x80000+eax+0xB8]
206
    call   MEM_Free_Page
1 ha 207
.cleanfailed_mem:
9 halyavin 208
;there is no mem for directory entry, display message.
1 ha 209
    mov    esi,start_not_enough_memory
210
    call   sys_msg_board_str
211
.cleanfailed:                    ;clean process name
9 halyavin 212
;can't read file, clean process name.
213
;this avoid problems with panel application.
1 ha 214
    mov    edi,[new_process_place]
215
    shl    edi,8
216
    add    edi,0x80000
217
    mov    ecx,11
218
    mov    eax,' '
219
    cld
220
    rep    stosb
221
.failed:
9 halyavin 222
;no more slots
1 ha 223
    add    esp,8+4
224
    mov    [application_table_status],0
225
    popad
226
    sti
227
    mov    eax,-1
228
    ret
229
 
230
;-----------------------------------------------------------------------------
231
new_start_application_fl:
232
;input:
233
;  eax - pointer to filename
234
;  ebx - parameters to pass
40 halyavin 235
;  edx - flags
1 ha 236
;result:
237
;  eax - pid of new process
238
;        or 0 if call fails.
5 halyavin 239
    mov    [appl_path],edi
240
    mov    [appl_path_size],36
1 ha 241
    pushad
242
    mov    esi,new_process_loading
243
    call   sys_msg_board_str     ;write to debug board
244
 
245
;wait application_table_status mutex
246
.table_status:
247
    cli
248
    cmp    [application_table_status],0
249
    jz     .stf
250
    sti
251
    call   change_task
252
    jmp    .table_status
253
.stf:
254
    call   set_application_table_status
255
;we can change system tables now
256
    push   ebx
257
    push   eax
258
    call   find_new_process_place ;find empty process slot
4 poddubny 259
    call   safe_sti
1 ha 260
    test   eax,eax
261
    jz     .failed
262
 
263
    mov    edi,eax
264
    shl    edi,8
265
    add    edi,0x80000
266
    mov    ecx,256/4
267
    xor    eax,eax
268
    cld
269
    rep    stosd                 ;clean extended information about process
270
 
271
;set new process name
272
    mov    eax,[esp]             ;eax - pointer to file name
273
    mov    ebx,[new_process_place]
274
    shl    ebx,8
275
    add    ebx,0x80000
276
    mov    ecx,11
277
    call   memmove
278
 
279
;read header of file
280
    mov    ebx,1                 ;index of first block
281
    mov    ecx,2                 ;number of blocks
282
    mov    edx,0x90000           ;temp area
283
    mov    esi,12                ;file name length
284
    cli
285
    call   fileread              ;read file from RD
4 poddubny 286
    call   safe_sti
1 ha 287
    cmp    eax,0
288
    jne    .cleanfailed
289
;check MENUET signature
290
    cmp    [0x90000],dword 'MENU'
291
    jnz    .cleanfailed
292
    cmp    [0x90004],word 'ET'
293
    jnz    .cleanfailed
294
 
295
    call   get_app_params        ;parse header fields
296
    cmp    esi,0
21 poddubny 297
    jz     .cleanfailed
1 ha 298
 
299
    mov    eax,[new_process_place]
300
    call   create_app_cr3_table   ;create page directory for new process
301
    test   eax,eax
302
    jz     .cleanfailed_mem
303
 
304
    call   MEM_Get_Linear_Address ;calculate linear address of it
305
 
306
    mov    ebx,std_application_base_address
307
    mov    ecx,[app_mem]
308
    add    ecx,4095
309
    shr    ecx,12
310
    mov    edx,eax
311
    call   mem_alloc_specified_region ;allocate memory for application
312
    test   eax,eax
9 halyavin 313
    jz     .cleanfailed_mem1
1 ha 314
 
315
    mov    eax,[edx+(std_application_base_address shr 20)]
316
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
317
    call   MEM_Get_Linear_Address
318
    mov    edx,eax
319
 
320
;read file
321
    mov    ebx,1
322
    mov    esi,12                ;length of file name
323
.loop1:
324
;edx = linear address of current page table entry
325
;ebx = index of current block in file
326
    push   edx
327
    mov    eax,[edx]
328
    and    eax,not (4096-1)
329
    call   MEM_Get_Linear_Address
330
    mov    edx,eax               ;read file block to current page
331
    mov    eax,[esp+4]           ;restore pointer to file name
332
    mov    ecx,8                 ;number of blocks read
333
    push   ebx
334
    cli
335
    call   fileread
336
;ebx=file size
4 poddubny 337
    call   safe_sti
1 ha 338
    pop    ecx
339
    shr    ebx,9
340
    cmp    ecx,ebx
341
    jg     .endloop1             ;if end of file?
342
    mov    ebx,ecx
343
    test   eax,eax
344
    jnz    .endloop1             ;check io errors
345
    pop    edx
346
    add    ebx,8                 ;go to next page
347
    add    edx,4
348
    jmp    .loop1
349
 
350
.endloop1:
351
    add    esp,8                 ;pop linear address of page table entry and pointer to file name
352
    call   .add_app_parameters
353
    mov    [esp+28],eax
354
    popad
355
    ret
356
 
9 halyavin 357
.cleanfailed_mem1:
358
;there is mem for directory entry, but there is no mem for pages
359
;so free directory entry
360
    mov    eax,[new_process_place]
361
    shl    eax,8
362
    mov    eax,[0x80000+eax+0xB8]
363
    call   MEM_Free_Page
1 ha 364
.cleanfailed_mem:
9 halyavin 365
;there is no mem for directory entry, display message.
1 ha 366
    mov    esi,start_not_enough_memory
367
    call   sys_msg_board_str
368
.cleanfailed:                    ;clean process name
9 halyavin 369
;can't read file, clean process name.
370
;this avoid problems with panel application.
1 ha 371
    mov    edi,[new_process_place]
372
    shl    edi,8
373
    add    edi,0x80000
374
    mov    ecx,11
375
    mov    eax,' '
376
    cld
377
    rep    stosb
378
.failed:
9 halyavin 379
;no more slots
1 ha 380
    add    esp,8
381
    mov    [application_table_status],0
382
    popad
4 poddubny 383
    call   safe_sti
1 ha 384
    mov    eax,-1
385
    ret
386
 
387
.add_app_parameters:
388
;input:
389
;  [esp] - pointer to parameters
390
;  [esp+4]-[esp+36] pushad registers.
391
;result
392
;  eax - pid of new process
393
;        or zero if failed
394
    cli
395
    mov    ebx,[new_process_place]
396
    cmp    ebx,[0x3004]
397
    jle    .noinc
398
    inc    dword [0x3004]        ;update number of processes
399
.noinc:
400
 
401
;   mov    ebx,[new_process_place]
402
;set 0x8c field of extended information about process
403
;(size of application memory)
404
    shl    ebx,8
405
    mov    eax,[app_mem]
406
    mov    [second_base_address+0x80000+0x8c+ebx],eax
407
;set 0x10 field of information about process
408
;(application base address)
409
;    mov    ebx,[new_process_place]
410
;    shl    ebx,5
411
    shr    ebx,3
412
    mov    dword [second_base_address+0x3000+ebx+0x10],std_application_base_address
413
 
414
;add command line parameters
415
.add_command_line:
416
    mov    edx,[app_i_param]
417
    test   edx,edx
418
    jz     .no_command_line      ;application don't need parameters
419
    mov    eax,[esp+4]
420
    test   eax,eax
421
    jz     .no_command_line      ;no parameters specified
422
;calculate parameter length
423
    mov    esi,eax
424
    xor    ecx,ecx
425
.command_line_len:
426
    cmp    byte [esi],0
427
    jz     .command_line_len_end
428
    inc    esi
429
    inc    ecx
430
    cmp    ecx,256
431
    jl     .command_line_len
432
 
433
.command_line_len_end:
434
;ecx - parameter length
435
;edx - address of parameters in new process address space
436
    mov    ebx,eax               ;ebx - address of parameters in our address space
437
    mov    eax,[new_process_place]
438
    call   write_process_memory  ;copy parameters to new process address space
439
 
440
.no_command_line:
5 halyavin 441
;******************************************************************
442
    mov    edx,[app_i_icon]
443
    test   edx,edx
444
    jz     .no_command_line_1      ;application don't need path of file
445
    mov    ebx,[appl_path]
446
    mov    ecx,[appl_path_size]
447
    mov    eax,[new_process_place]
448
    call   write_process_memory  ;copy path of file to new process address space
449
.no_command_line_1:
450
;******************************************************************
1 ha 451
    mov    ebx,[new_process_place]
452
    mov    eax,ebx
453
    shl    ebx,5
454
    add    ebx,0x3000            ;ebx - pointer to information about process
455
    mov    [ebx+0xe],al          ;set window number on screen = process slot
456
 
457
    mov    [ebx],dword 1+2+4     ;set default event flags (see 40 function)
458
 
459
    inc    dword [process_number]
460
    mov    eax,[process_number]
461
    mov    [ebx+4],eax           ;set PID
462
 
463
    mov    ecx,ebx
464
    add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
465
;set draw data to full screen
466
    mov    [ecx+0],dword 0
467
    mov    [ecx+4],dword 0
468
    mov    eax,[0xfe00]
469
    mov    [ecx+8],eax
470
    mov    eax,[0xfe04]
471
    mov    [ecx+12],eax
41 mikedld 472
;set window state to 'normal' (non-minimized/maximized/rolled-up) state
473
    mov    [ecx+WDATA.fl_wstate],WSTATE_NORMAL
1 ha 474
;set cr3 register in TSS of application
475
    mov    ecx,[new_process_place]
476
    shl    ecx,8
477
    mov    eax,[0x800B8+ecx]
478
    add    eax,8+16              ;add flags
479
    mov    [l.cr3],eax
480
 
481
    mov    eax,[app_start]
482
    mov    [l.eip],eax           ;set eip in TSS
483
    mov    eax,[app_esp]
484
    mov    [l.esp],eax           ;set stack in TSS
485
 
486
;gdt
4 poddubny 487
    ;mov    ebx,[new_process_place]
488
    ;shl    ebx,3
1 ha 489
    mov    ax,app_code           ;ax - selector of code segment
4 poddubny 490
    ;add    ax,bx
1 ha 491
    mov    [l.cs],ax
492
    mov    ax,app_data
4 poddubny 493
    ;add    ax,bx                 ;ax - selector of data segment
1 ha 494
    mov    [l.ss],ax
495
    mov    [l.ds],ax
496
    mov    [l.es],ax
497
    mov    [l.fs],ax
498
    mov    ax,graph_data         ;ax - selector of graphic segment
499
    mov    [l.gs],ax
500
    mov    [l.io],word 128
501
    mov    [l.eflags],dword 0x11202
502
    mov    [l.ss0],os_data
4 poddubny 503
    mov    ebx,[new_process_place]
504
    shl    ebx,12
14 poddubny 505
    add    ebx,sysint_stack_data+4096
3 halyavin 506
    mov    [l.esp0],ebx
1 ha 507
 
508
;copy tss to it place
509
    mov    eax,tss_sceleton
510
    mov    ebx,[new_process_place]
511
    imul   ebx,tss_step
512
    add    ebx,tss_data          ;ebx - address of application TSS
513
    mov    ecx,120
514
    call   memmove
515
 
516
;Add IO access table - bit array of permitted ports
517
    or     eax,-1
518
    mov    edi,[new_process_place]
519
    imul   edi,tss_step
520
    add    edi,tss_data+128
521
    mov    ecx,2048
522
    cld
523
    rep    stosd                 ;full access to 2048*8=16384 ports
524
 
525
    mov    ecx,ebx               ;ecx - address of application TSS
526
    mov    edi,[new_process_place]
527
    shl    edi,3
528
;set TSS descriptor
529
    mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
530
    mov    [edi+gdts+tss0+2],cx  ;part of offset
531
    mov    eax,ecx
532
    shr    eax,16
533
    mov    [edi+gdts+tss0+4],al  ;part of offset
534
    mov    [edi+gdts+tss0+7],ah  ;part of offset
535
    mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
536
 
537
 
538
;flush keyboard and buttons queue
539
    mov    [0xf400],byte 0
540
    mov    [0xf500],byte 0
541
 
542
    mov    edi,[new_process_place]
543
    shl    edi,5
544
    add    edi,window_data
545
    mov    ebx,[new_process_place]
546
    movzx  esi,word [0xC000+ebx*2]
547
    lea    esi,[0xC400+esi*2]
548
    call   windowactivate        ;gui initialization
549
 
550
    mov    ebx,[new_process_place]
551
    shl    ebx,5
552
    mov    [0x3000+ebx+0xa],byte 0 ;set process state - running
40 halyavin 553
; set if debuggee
554
    test   byte [esp+28], 1
555
    jz     .no_debug
556
    mov    [0x3000+ebx+0xa],byte 1 ;set process state - suspended
557
    mov    eax,[0x3000]
558
    mov    [0x80000+ebx*8+0xac],eax ;set debugger PID - current
559
.no_debug:
1 ha 560
 
561
    mov    esi,new_process_running
562
    call   sys_msg_board_str     ;output information about succefull startup
563
 
564
;    add    esp,4                 ;pop pointer to parameters
565
;    popad
566
    mov    eax,[process_number]  ;set result
567
    mov    [application_table_status],0 ;unlock application_table_status mutex
4 poddubny 568
    call   safe_sti
1 ha 569
    ret    4
570
;-----------------------------------------------------------------------------
571
new_sys_threads:
572
;eax=1 - create thread
573
;   ebx=thread start
574
;   ecx=thread stack value
575
;result:
576
;   eax=pid
40 halyavin 577
    xor    edx,edx	; flags=0
1 ha 578
    pushad
579
 
580
    cmp    eax,1
581
    jnz    .ret                  ;other subfunctions
582
    mov    esi,new_process_loading
583
    call   sys_msg_board_str
584
;lock application_table_status mutex
585
.table_status:
586
    cli
587
    cmp    [application_table_status],0
588
    je     .stf
589
    sti
590
    call   change_task
591
    jmp    .table_status
592
.stf:
593
    call   set_application_table_status
594
;find free process slot
595
 
596
    call   find_new_process_place
597
    test   eax,eax
598
    jz     .failed
599
 
600
;set parameters for thread
601
    xor    eax,eax
602
    mov    [app_i_param],eax
603
    mov    [app_i_icon],eax
604
    mov    [app_start],ebx
605
    mov    [app_esp],ecx
606
 
607
    mov    esi,[0x3000]
608
    shl    esi,8
609
    add    esi,0x80000
610
    mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
611
 
612
    mov    edi,[new_process_place]
613
    shl    edi,8
614
    add    edi,0x80000
615
    mov    edx,edi               ;edx=edi - pointer to extended infomation about new thread
616
    mov    ecx,256/4
617
    rep    stosd                 ;clean extended information about new thread
618
    mov    edi,edx
619
    mov    ecx,11
620
    rep    movsb                 ;copy process name
621
    mov    eax,[ebx+0x8c]
622
    mov    [app_mem],eax         ;set memory size
623
    mov    eax,[ebx+0xb8]
624
    mov    [edx+0xb8],eax        ;copy page directory
625
;    mov    eax,[new_process_place]
626
;    mov    ebx,[0x3000]
627
;    call   addreference_app_cr3_table
628
 
629
    push   0                     ;no parameters
630
    call    new_start_application_fl.add_app_parameters ;start thread
631
    mov    [esp+28],eax
632
    popad
633
    ret
634
 
635
.failed:
636
    sti
637
    popad
638
    mov    eax,-1
639
    ret
640
.ret:
641
    popad
642
    ret
643
;-----------------------------------------------------------------------------
644
new_mem_resize:
645
;input:
646
;  ebx - new size
647
;result:
648
;  [esp+36]:=0 - normal
649
;  [esp+36]:=1 - error
650
;This function set new application memory size.
651
    mov    esi,ebx               ;save new size
652
    add    ebx,4095
653
    and    ebx,not (4096-1)      ;round up size
654
    mov    ecx,[0x3000]
655
    shl    ecx,8
656
    mov    edx,[0x8008C+ecx]
657
    add    edx,4095
658
    and    edx,not (4096-1)      ;old size
659
    mov    eax,[0x800B8+ecx]
660
    call   MEM_Get_Linear_Address
661
;eax - linear address of page directory
662
    call   MEM_Heap_Lock         ;guarantee that two threads willn't
663
                                 ;change memory size simultaneously
664
    cmp    ebx,edx
665
;    mov    esi,ebx               ;save new size
666
    jg     .expand
667
 
668
.free:
669
    sub    edx,ebx
670
    jz     .unlock               ;do nothing
671
    mov    ecx,edx
672
    shr    ecx,12
673
    add    ebx,std_application_base_address
674
    call   mem_free_specified_region  ;free unnecessary pages
675
    jmp    .unlock
676
 
677
.expand:
678
    sub    ebx,edx
679
    mov    ecx,ebx
680
    shr    ecx,12
681
    mov    ebx,edx
682
    add    ebx,std_application_base_address
683
    call   mem_alloc_specified_region ;alloc necessary pages
684
    test   eax,eax
685
    jz     .failed               ;not enough memory
686
 
687
.unlock:
688
    mov    ebx,esi
689
    mov    eax,[0x3000]
690
    shl    eax,8
691
    mov    [eax+0x8008c],ebx     ;write new memory size
692
;search threads and update
693
;application memory size infomation
694
    mov    ecx,[eax+0x800b8]
695
    mov    eax,2
696
 
697
.search_threads:
698
;eax = current slot
699
;ebx = new memory size
700
;ecx = page directory
701
    cmp    eax,[0x3004]
702
    jg     .search_threads_end
703
    mov    edx,eax
704
    shl    edx,5
705
    cmp    word [0x3000+edx+0xa],9 ;if slot empty?
706
    jz     .search_threads_next
707
    shl    edx,3
708
    cmp    [edx+0x800b8],ecx     ;if it is our thread?
709
    jnz    .search_threads_next
710
    mov    [edx+0x8008c],ebx     ;update memory size
711
.search_threads_next:
712
    inc    eax
713
    jmp    .search_threads
714
.search_threads_end:
715
 
716
    call   MEM_Heap_UnLock
717
    mov    dword [esp+36],0
718
    ret
719
 
720
.failed:
721
    call   MEM_Heap_UnLock
722
    mov    dword [esp+36],1
723
    ret
724
;-----------------------------------------------------------------------------
725
pid_to_slot:
726
;Input:
727
;  eax - pid of process
728
;Output:
729
;  eax - slot of process or 0 if process don't exists
730
;Search process by PID.
731
    push   ebx
732
    push   ecx
733
    mov    ebx,[0x3004]
734
    shl    ebx,5
735
    mov    ecx,2*32
736
 
737
.loop:
738
;ecx=offset of current process info entry
739
;ebx=maximum permitted offset
740
    cmp    byte [second_base_address+0x3000+ecx+0xa],9
741
    jz     .endloop              ;skip empty slots
742
    cmp    [second_base_address+0x3000+ecx+0x4],eax ;check PID
743
    jz     .pid_found
744
.endloop:
745
    add    ecx,32
746
    cmp    ecx,ebx
747
    jle    .loop
748
 
749
    pop    ecx
750
    pop    ebx
751
    xor    eax,eax
752
    ret
753
 
754
.pid_found:
755
    shr    ecx,5
756
    mov    eax,ecx               ;convert offset to index of slot
757
    pop    ecx
758
    pop    ebx
759
    ret
760
;-----------------------------------------------------------------------------
761
is_new_process:
762
;Input:
763
;  eax - process slot
764
;Output:
765
;  eax=1 - it is new process
766
;  eax=0 - it is old process
767
;    shl   eax,5
768
;    mov   eax,[second_base_address+0x3000+eax+0x10]
769
;    cmp   eax,std_application_base_address  ;check base address of application
770
;    jz    .new_process
771
;    xor   eax,eax
772
;    ret
773
 
774
;.new_process:
775
    mov   eax,1
776
    ret
777
;-----------------------------------------------------------------------------
778
write_process_memory:
779
;Input:
780
;  eax - process slot
781
;  ebx - buffer address
782
;  ecx - buffer size
783
;  edx - start address in other process
784
;Output:
785
;  eax - number of bytes written
786
    pushad
787
    shl  eax,8
788
    mov  eax,[0x80000+eax+0xB8]
789
    call MEM_Get_Linear_Address
790
    mov  ebp,eax
791
;ebp=linear address of page directory of other process.
792
    add  edx,std_application_base_address  ;convert to linear address
793
    test ecx,ecx
794
    jle  .ret
795
 
796
.write_loop:
797
;ebx = current buffer address
798
;ecx>0 = current size
799
;edx = current address in other process
800
;ebp = linear address of page directory
801
 
802
    call MEM_Heap_Lock           ;cli
803
    mov  esi,edx
804
    shr  esi,22
805
    mov  eax,[ebp+4*esi]         ;find page directory entry
806
    and  eax,not (4096-1)        ;clear flags
807
    test eax,eax
808
    jz   .page_not_found
809
    call MEM_Get_Linear_Address  ;calculate linear address of page table
810
    test eax,eax
811
    jz   .page_not_found
812
    mov  esi,edx
813
    shr  esi,12
814
    and  esi,1023
815
    mov  eax,[eax+4*esi]         ;find page table entry
816
    and  eax,not (4096-1)
817
    test eax,eax
818
    jz   .page_not_found
819
    call MEM_Get_Linear_Address  ;calculate linear address of page
820
    test eax,eax
821
    jz   .page_not_found
822
    mov  edi,eax
823
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
824
    call MEM_Heap_UnLock         ;sti
825
 
826
    mov  esi,edx
827
    and  esi,4095
828
    add  edi,esi                 ;add offset in page
829
;edi = linear address corresponding edx in other process
830
    sub  esi,4096
831
    neg  esi                     ;esi - number of remaining bytes in page
832
    cmp  esi,ecx
833
    jl   .min_ecx
834
    mov  esi,ecx
835
.min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
836
    sub  ecx,esi
837
    push ecx
838
    mov  ecx,esi                 ;ecx - number of bytes to write
839
    mov  esi,ebx                 ;esi - source, edi - destination
840
    add  edx,ecx                 ;move pointer in address space of other process
841
    push edi
842
 
843
;move ecx bytes
844
    test ecx,3
845
    jnz  .not_aligned
846
    shr  ecx,2
847
    rep  movsd
848
    jmp  .next_iter
849
.not_aligned:
850
    rep  movsb
851
.next_iter:
852
 
853
    pop  eax
854
    and  eax,not (4096-1)        ;eax - linear address of current page
855
    call MEM_Free_Page_Linear    ;free reference
856
    mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
857
    pop  ecx                     ;restore number of remaining bytes
858
    test ecx,ecx
859
    jnz  .write_loop
860
.ret:
861
    popad
862
    mov  eax,ecx
863
    ret
864
 
865
.page_not_found:
866
    call MEM_Heap_UnLock         ;error has appeared in critical region
867
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
868
    neg  ecx                     ;ecx=number_of_written_bytes
869
    mov  [esp+28],ecx            ;[esp+28]<-->eax
870
    popad
871
    ret
872
;-----------------------------------------------------------------------------
873
syscall_test:
874
;for testing memory manager from applications.
875
    mov  edx,ecx
876
    mov  ecx,ebx
877
    call trans_address
878
    mov  ebx,eax
879
    mov  eax,[0x3000]
880
    call read_process_memory
881
    ret
882
;-----------------------------------------------------------------------------
883
read_process_memory:
884
;Input:
885
;  eax - process slot
886
;  ebx - buffer address
887
;  ecx - buffer size
888
;  edx - start address in other process
889
;Output:
890
;  eax - number of bytes read.
891
    pushad
892
    shl  eax,8
893
    mov  eax,[0x80000+eax+0xB8]
894
    call MEM_Get_Linear_Address
895
    mov  ebp,eax
896
    add  edx,std_application_base_address
897
.read_loop:
898
;ebx = current buffer address
899
;ecx>0 = current size
900
;edx = current address in other process
901
;ebp = linear address of page directory
902
 
903
    call MEM_Heap_Lock           ;cli
904
    mov  esi,edx
905
    shr  esi,22
906
    mov  eax,[ebp+4*esi]         ;find page directory entry
907
    and  eax,not (4096-1)
908
    test eax,eax
909
    jz   .page_not_found
910
    call MEM_Get_Linear_Address
911
    test eax,eax
912
    jz   .page_not_found
913
    mov  esi,edx
914
    shr  esi,12
915
    and  esi,1023
916
    mov  eax,[eax+4*esi]         ;find page table entry
917
    and  eax,not (4096-1)
918
    test eax,eax
919
    jz   .page_not_found
920
    call MEM_Get_Linear_Address  ;calculate linear address of page
921
    test eax,eax
922
    jz   .page_not_found
923
    mov  esi,eax
924
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
925
    call MEM_Heap_UnLock         ;sti
926
 
927
    mov  edi,edx
928
    and  edi,4095
929
    add  esi,edi                 ;add offset in page
930
;esi = linear address corresponding edx in other process
931
    sub  edi,4096
932
    neg  edi
933
 
934
;edi=min(edi,ecx) - number of bytes to copy
935
    cmp  edi,ecx
936
    jl   .min_ecx
937
    mov  edi,ecx
938
.min_ecx:
939
 
940
    sub  ecx,edi                 ;update size of remaining bytes
941
    add  edx,edi                 ;update current pointer in other address space.
942
    push ecx
943
    mov  ecx,edi                 ;ecx - number of bytes to read
944
    mov  edi,ebx                 ;esi - source, edi - destination
945
    push esi
946
;move ecx bytes
947
    test ecx,3
948
    jnz  .not_aligned
949
    shr  ecx,2
950
    rep  movsd
951
    jmp  .next_iter
952
.not_aligned:
953
    rep  movsb
954
.next_iter:
955
    pop  eax
956
    and  eax,not (4096-1)        ;eax - linear address of current page
957
    call MEM_Free_Page_Linear    ;free reference
958
    mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
959
    pop  ecx                     ;restore number of remaining bytes
960
    test ecx,ecx
961
    jnz  .read_loop
962
 
963
    popad
964
    mov  eax,ecx
965
    ret
966
 
967
.page_not_found:
968
    call MEM_Heap_UnLock         ;error has appeared in critical region
969
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
970
    neg  ecx                     ;ecx=number_of_read_bytes
971
    mov  [esp+28],ecx            ;[esp+28]<-->eax
972
    popad
973
    ret
974
;-----------------------------------------------------------------------------
975
check_region:
976
;input:
977
;  ebx - start of buffer
978
;  ecx - size of buffer
979
;result:
980
;  eax = 1 region lays in app memory
981
;  eax = 0 region don't lays in app memory
982
    mov  eax,[0x3000]
983
    jmp  check_process_region
984
;-----------------------------------------------------------------------------
985
check_process_region:
986
;input:
987
;  eax - slot
988
;  ebx - start of buffer
989
;  ecx - size of buffer
990
;result:
991
;  eax = 1 region lays in app memory
992
;  eax = 0 region don't lays in app memory
993
    test ecx,ecx
994
    jle  .ok
995
    shl  eax,5
996
    cmp  word [0x3000+eax+0xa],0
997
    jnz  .failed
998
    shl  eax,3
999
    mov  eax,[0x80000+eax+0xb8]
1000
    test eax,eax
1001
    jz   .failed
1002
    call MEM_Get_Linear_Address
1003
    push ebx
1004
    push ecx
1005
    push edx
1006
    mov  edx,ebx
1007
    and  edx,not (4096-1)
1008
    sub  ebx,edx
1009
    add  ecx,ebx
1010
    mov  ebx,edx
1011
    add  ecx,(4096-1)
1012
    and  ecx,not (4096-1)
1013
.loop:
1014
;eax - linear address of page directory
1015
;ebx - current page
1016
;ecx - current size
1017
    mov  edx,ebx
1018
    shr  edx,22
1019
    mov  edx,[eax+4*edx]
1020
    and  edx,not (4096-1)
1021
    test edx,edx
1022
    jz   .failed1
1023
    push eax
1024
    mov  eax,edx
1025
    call MEM_Get_Linear_Address
1026
    mov  edx,ebx
1027
    shr  edx,12
1028
    and  edx,(1024-1)
1029
    mov  eax,[eax+4*edx]
1030
    and  eax,not (4096-1)
1031
    test eax,eax
1032
    pop  eax
1033
    jz   .failed1
1034
    add  ebx,4096
1035
    sub  ecx,4096
1036
    jg   .loop
1037
    pop  edx
1038
    pop  ecx
1039
    pop  ebx
1040
.ok:
1041
    mov  eax,1
1042
    ret
1043
 
1044
.failed1:
1045
    pop  edx
1046
    pop  ecx
1047
    pop  ebx
1048
.failed:
1049
    xor  eax,eax
1050
    ret
1051
;-----------------------------------------------------------------------------
1052
new_sys_ipc:
1053
;input:
1054
;  eax=1 - set ipc buffer area
1055
;    ebx=address of buffer
1056
;    ecx=size of buffer
1057
;  eax=2 - send message
1058
;    ebx=PID
1059
;    ecx=address of message
1060
;    edx=size of message
1061
    cmp  eax,1
1062
    jnz  .no_ipc_def
1063
;set ipc buffer area
1064
    mov  edi,[0x3000]
1065
    shl  edi,8
1066
    add  edi,0x80000
1067
    cli
1068
    mov  [edi+0xA0],ebx          ;set fields in extended information area
1069
    mov  [edi+0xA4],ecx
1070
    sti
1071
    mov  [esp+36],dword 0        ;success
1072
    ret
1073
 
1074
.no_ipc_def:
1075
    cmp  eax,2
1076
    jnz  .no_ipc_send
1077
;send message
1078
    cli
1079
;obtain slot from PID
1080
    mov  eax,ebx
1081
    call pid_to_slot
1082
    test eax,eax
1083
    jz   .no_pid
1084
    mov  ebp,eax
1085
;ebp = slot of other process
1086
    shl  eax,8
1087
    mov  edi,[eax+0x80000+0xa0]  ;is ipc area defined?
1088
    test edi,edi
1089
    jz   .no_ipc_area
1090
    mov  esi,[eax+0x80000+0xa4]  ;esi - size of buffer
1091
    push dword -1                ;temp variable for read_process_memory
1092
    mov  ebx,esp
1093
    push ecx
1094
    push edx
1095
    mov  ecx,4                   ;read 4 bytes
1096
    mov  eax,ebp
1097
    mov  edx,edi                 ;from beginning of buffer.
1098
    call read_process_memory
1099
    mov  eax,[esp+8]
1100
    test eax,eax
1101
    jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
1102
    add  edx,4                   ;move to next 4 bytes
1103
    mov  eax,ebp
1104
    call read_process_memory     ;read size of occupied space in buffer
1105
    sub  esi,8
1106
    sub  esi,[esp]
1107
    sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
1108
    js   .buffer_overflow        ;esi<0 - not enough memory in buffer
1109
    mov  esi,[esp+8]             ;previous offset
1110
    add  dword [esp+8],8
1111
    mov  edi,[esp]
1112
    add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
1113
    mov  eax,ebp
1114
    call write_process_memory
1115
    add  edx,esi
1116
    sub  edx,4                   ;move to beginning of place for our message
1117
    mov  eax,[second_base_address+0x3010]
1118
    mov  eax,[eax+0x4]           ;eax - our PID
1119
    mov  [esp+8],eax
1120
    mov  eax,ebp
1121
    call write_process_memory    ;write PID
1122
    mov  ebx,esp                 ;address of size of message
1123
    mov  eax,ebp
1124
    add  edx,4
1125
    call write_process_memory    ;write size of message
1126
    add  edx,4
1127
    pop  ecx                     ;ecx - size of message
1128
    pop  eax
1129
    call trans_address
1130
    mov  ebx,eax                 ;ebx - linear address of message
1131
    add  esp,4                   ;pop temporary variable
1132
    mov  eax,ebp
1133
    call write_process_memory    ;write message
1134
    sti
1135
;awake other process
1136
    shl  ebp,8
1137
    mov  eax,ebp
1138
    or   [eax+0x800A8],dword 0x40
1139
 
1140
    cmp  dword [check_idle_semaphore],20
1141
    jge  .ipc_no_cis
1142
    mov  dword [check_idle_semaphore],5
1143
.ipc_no_cis:
1144
    mov  dword [esp+36],0
1145
    ret
1146
.no_ipc_send:
1147
    mov  dword [esp+36],-1
1148
    ret
1149
.no_pid:
1150
    sti
1151
    mov  dword [esp+36],4
1152
    ret
1153
.no_ipc_area:
1154
    sti
1155
    mov  dword [esp+36],1
1156
    ret
1157
.ipc_blocked:
1158
    sti
1159
    add  esp,12
1160
    mov  dword [esp+36],2
1161
    ret
1162
.buffer_overflow:
1163
    sti
1164
    add  esp,12
1165
    mov  dword [esp+36],3
1166
    ret
1167
;-----------------------------------------------------------------------------
1168
trans_address:
1169
;Input
1170
;  eax - application address
1171
;Output
1172
;  eax - linear address for kernel
1173
    add   eax,std_application_base_address
1174
    ret
1175
;-----------------------------------------------------------------------------
1176
new_start_application_hd:
1177
;eax - file name (kernel address)
1178
;ebx - file name length
1179
;ecx - work area (kernel address)
40 halyavin 1180
;edx - flags
1 ha 1181
;ebp - parameters
5 halyavin 1182
    mov    [appl_path],edi
1 ha 1183
    pushad
1184
 
1185
    mov    esi,new_process_loading
1186
    call   sys_msg_board_str     ;write message to message board
1187
 
1188
;lock application_table_status mutex
1189
.table_status:
1190
    cli
1191
    cmp    [application_table_status],0
1192
    jz     .stf
1193
    sti
1194
    call   change_task
1195
    jmp    .table_status
1196
.stf:
1197
    call   set_application_table_status
1198
 
1199
    push   ebp
1200
    push   ebx
1201
    push   eax
1202
    push   ecx
1203
    call   find_new_process_place ;find new process slot
1204
    sti
1205
    test   eax,eax
1206
    jz     .failed
1207
 
5 halyavin 1208
;write application name
1209
    xor    eax,eax
1210
    mov    [appl_path_size],eax
1 ha 1211
    mov    eax,[esp+4]
1212
.find_last_byte:
1213
    cmp    byte [eax],0
1214
    jz     .find_last_byte_end
1215
    inc    eax
5 halyavin 1216
    inc    [appl_path_size]
1 ha 1217
    jmp    .find_last_byte
5 halyavin 1218
.find_last_byte_end:
1219
    add    [appl_path_size],24
1 ha 1220
    lea    esi,[eax-11]          ;last 11 bytes = application name
1221
    mov    edi,[new_process_place]
1222
    shl    edi,8
1223
    add    edi,0x80000
1224
    mov    ecx,11
1225
    cld
1226
    rep    movsb                 ;copy name to extended information about process
1227
 
1228
;read header
1229
    mov    eax,[esp+4]           ;file name
1230
    mov    esi,[esp]             ;work area
1231
    mov    ecx,1                 ;read from first block
1232
    mov    edx,1                 ;read 1 block
1233
    call   read_hd_file
1234
    test   eax,eax
1235
    jnz    .cleanfailed
1236
 
1237
    mov    esi,[esp]
1238
;check menuet signature
1239
    cmp    [esi+1024+0],dword 'MENU'  ;read_hd_file function write file to +1024 offset
1240
    jnz    .cleanfailed
1241
    cmp    [esi+1024+4],word 'ET'
1242
    jnz    .cleanfailed
1243
    add    esi,1024
1244
    mov    edi,0x90000
1245
    mov    ecx,512/4
1246
    cld
1247
    rep    movsd                 ;copy first block to 0x90000 address for get_app_params function
1248
    call   get_app_params
1249
    test   esi,esi
1250
    jz     .cleanfailed
1251
 
1252
    mov    eax,[new_process_place]
1253
    call   create_app_cr3_table  ;create page directory
1254
    test   eax,eax
1255
    jz     .cleanfailed_mem
1256
 
1257
    call   MEM_Get_Linear_Address
1258
 
1259
    mov    ebx,std_application_base_address
1260
    mov    ecx,[app_mem]
1261
    add    ecx,4096-1
1262
    shr    ecx,12
1263
    mov    edx,eax               ;edx - linear address of page directory
1264
    call   mem_alloc_specified_region ;allocate memory for application
1265
    test   eax,eax
9 halyavin 1266
    jz     .cleanfailed_mem1
1 ha 1267
 
1268
    add    edx,(std_application_base_address shr 20)
1269
    mov    eax,[edx]
1270
    and    eax,not (4096-1)
1271
    call   MEM_Get_Linear_Address
1272
    push   edx                   ;save pointer to first page table
1273
    mov    edx,eax
1274
;read file
1275
    mov    ecx,1
1276
    xor    ebp,ebp
1277
.loop1:
1278
;[esp] - pointer to current page directory entry
1279
;edx - pointer to current page table
1280
;ebp - offset in page
1281
;ecx - current cluster
1282
    push   edx
1283
    mov    eax,[esp+12]          ;file name
1284
    mov    ebx,[esp+16]          ;file name length
1285
    mov    esi,[esp+8]           ;work area
1286
    mov    edx,1                 ;number of blocks to read
1287
    push   ecx
1288
    push   ebp
1289
    cli
1290
    call   read_hd_file
1291
    sti
1292
    pop    ebp
1293
    test   eax,eax
1294
    jnz    .endloop1             ;check io errors
1295
 
1296
    mov    esi,[esp+8+4]         ;work area
1297
    add    esi,1024
1298
    mov    eax,[esp+4]           ;current page table
1299
    mov    eax,[eax]
1300
    and    eax,not (4096-1)
1301
    call   MEM_Get_Linear_Address;calculate linear page address
1302
    lea    edi,[eax+ebp]         ;add page offset
1303
    mov    ecx,512/4
1304
    cld
1305
    rep    movsd                 ;copy data
1306
 
1307
    pop    ecx
1308
    inc    ecx                   ;next block
1309
    mov    eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
1310
    add    eax,512-1
1311
    shr    eax,9                 ;calculate application image size
1312
    cmp    ecx,eax
1313
    jg     .endloop11
1314
    pop    edx
1315
    add    ebp,512               ;new offset
1316
    test   ebp,4096
1317
    jz     .loop1
1318
    xor    ebp,ebp
1319
    add    edx,4                 ;go to next page
1320
    test   edx,(4096-1)
1321
    jnz    .loop1
1322
    add    dword [esp],4         ;go to next directory entry
1323
    mov    eax,[esp]
1324
    mov    eax,[eax]
1325
    and    eax,not (4096-1)
1326
    call   MEM_Get_Linear_Address
1327
    mov    edx,eax
1328
    jmp    .loop1
1329
.endloop1:
1330
    add    esp,4                 ;pop ecx
1331
.endloop11:
1332
    add    esp,4+4               ;pop edx, pop edx
1333
 
1334
;add_app_parameters
1335
    add    esp,12                ;now pointer to parameters is on the top of the stack
1336
    call   new_start_application_fl.add_app_parameters ;start process
1337
    mov    [esp+28],eax
1338
    popad
1339
    ret
1340
 
9 halyavin 1341
.cleanfailed_mem1:
1342
;there is mem for directory entry, but there is no mem for pages
1343
;so free directory entry
1344
    mov    eax,[new_process_place]
1345
    shl    eax,8
1346
    mov    eax,[0x80000+eax+0xB8]
1347
    call   MEM_Free_Page
1 ha 1348
.cleanfailed_mem:
9 halyavin 1349
;there is no mem for directory entry, display message.
1 ha 1350
    mov    esi,start_not_enough_memory
1351
    call   sys_msg_board_str
1352
.cleanfailed:                    ;clean process name
9 halyavin 1353
;can't read file, clean process name.
1354
;this avoid problems with panel application.
1 ha 1355
    mov    edi,[new_process_place]
1356
    shl    edi,8
1357
    add    edi,0x80000
1358
    mov    ecx,11
1359
    mov    eax,' '
1360
    cld
1361
    rep    stosb
1362
.failed:
9 halyavin 1363
;no more slots
1 ha 1364
    add    esp,16
1365
    popad
1366
    mov    eax,-1
1367
    mov    [application_table_status],0
1368
    sti
1369
    ret
1370
end if
40 halyavin 1371
 
1372
	include 'debug.inc'