Subversion Repositories Kolibri OS

Rev

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