|
|
1.1 root 1: / $Header: /kernel/kersrc/i286/RCS/as1.s,v 1.1 92/07/17 15:21:11 bin Exp Locker: bin $
2:
3: / (lgl-
4: / The information contained herein is a trade secret of Mark Williams
5: / Company, and is confidential information. It is provided under a
6: / license agreement, and may be copied or disclosed only under the
7: / terms of that agreement. Any reproduction or disclosure of this
8: / material without the express written authorization of Mark Williams
9: / Company or persuant to the license agreement is unlawful.
10: /
11: / COHERENT Version 2.3.37
12: / Copyright (c) 1982, 1983, 1984.
13: / An unpublished work by Mark Williams Company, Chicago.
14: / All rights reserved.
15: / -lgl)
16: ////////
17: /
18: / Machine language assist for
19: / 8086/8088 Coherent. This contains the parts
20: / that are common to all machines.
21: /
22: / Note that several of the following constants can be invalidated
23: / by changing the contents of ../h/*proc.h among others,
24: / or by changing the number of automatic variables in the functions
25: / called on the paths leading to consave or conrest. Tread with caution.
26: /
27: / $Log: as1.s,v $
28: / Revision 1.1 92/07/17 15:21:11 bin
29: / Initial revision
30: /
31: / Revision 1.2 91/06/20 14:07:20 hal
32: / I'm not sure what changed here.
33:
34: / Revision 1.3 88/08/05 08:32:09 src
35: / Kludges for AMD 286 bug have been removed.
36: /
37: / Revision 1.2 88/06/24 16:02:08 src
38: / Bug: inb/outb did not work properly in split stack/data operation.
39: / Fix: inb/outb now explicitly reference the stack segment.
40: /
41: / Revision 1.1 88/03/24 17:39:08 src
42: / Initial revision
43: /
44: / 88/03/10 Allan Cornish /usr/src/sys/i8086/src/as1.s
45: / Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
46: / These partial fixes will be removed once all CPU's are replaced.
47: /
48: / 88/03/04 Allan Cornish /usr/src/sys/i8086/src/as1.s
49: / tmpcs*/tmpds* temporary variables renamed to sav_*.
50: / usave/conrest/etc now handle odd byte alignment on stack.
51: / envrest/conrest now do interrupt return as last instruction.
52: /
53: / 87/12/21 Allan Cornish /usr/src/sys/i8086/src/as1.s
54: / fclear(f,n) function added.
55: /
56: / 87/12/04 Allan Cornish /usr/src/sys/i8086/src/as1.s
57: / kfcopy(k,f,n) and fkcopy(f,k,n) routines added.
58: /
59: / 87/12/03 Allan Cornish /usr/src/sys/i8086/src/as1.s
60: / popf replaced by 'push cs; mov ax,$0f; push ax; iret; 0:' due to popf int bug.
61: /
62: / 87/11/05 Allan Cornish /usr/src/sys/i8086/src/as1.s
63: / slrcopy/srlcopy/sclear renamed plrcopy/prlcopy/pclear and moved to ibm*/as2.s
64: /
65: / 87/10/27 Allan Cornish /usr/src/sys/i8086/src/as1.s
66: / System stack/data segments now setup in ibm/ibm_at as2.s
67: /
68: / 87/02/06 Allan Cornish
69: / Functions ffword and sfword added to fetch and set far memory.
70: /
71: ////////
72:
73: UPASIZE = 1024 / Size of uproc and stack
74: USIZE = 0x114 / sizeof(UPROC)
75: USZ1 = 140 / Word count for usave, uproc size
76: UMCSP = 0x06 / offset of sp in u_syscon
77: EFAULT = 14 / Bad argument
78: PFLAGS = 0x22 / Offset into PROC.
79: PFKERN = 0x80 / Kernel process flag bit.
80: SIDEV = 0x40 / Device interrupt trap code.
81:
82: ////////
83: /
84: / After performing machine specific
85: / trap vector setup, the startup code jumps
86: / here. The DS maps the vectors.
87: /
88: ////////
89:
90: .globl start
91:
92: start:
93: / Call the machine setup code.
94: / Call Coherent main.
95: / On return, send control off to the user
96: / at its entry point.
97:
98: mov sp, $u_+UPASIZE-32 / Stack pointer for init
99: call i8086_ / Do it.
100: sti / Interrupts on, and
101: call main_ / call Coherent mainline.
102: cli / Interrupts off.
103: incb depth_ / Set stack depth to user.
104: sub ax, ax / User mode IP.
105: mov bx, uds_ / User mode DS, ES, SS
106: mov cx, ucs_ / User mode CS.
107: mov dx, $0x0200 / User mode FL.
108:
109: mov ds, bx / Map data segment
110: mov es, bx / Map extra segment
111: mov ss, bx / Map stack segment
112:
113: mov sp, $sb-aicodep_ / User's stack
114: push dx / Flags
115: push cx / CS
116: push ax / IP
117: iret / Go to user state.
118:
119: ////////
120: /
121: / Trap and interrupt save.
122: / These routines will be very familiar to any
123: / RSX-11M hackers out there; it is just the ever
124: / common co-routine call. The caller is called back,
125: / with "bx" pointing to the saved "ax" on the stack,
126: / with interrupts enabled. The called routine must
127: / set 16(bx), which was initially the call back address,
128: / to something non zero in the high byte if it does
129: / not want an EOI sent to the 8259.
130: /
131: / ttsave, tksave, tisave, and tusave could be folded into a single routine
132: / with many tests and branches, but the frequency of passage through
133: / this code warrants a minimally branched execution, and special casing
134: / the interrupted context allows minimal memory references.
135: /
136: ////////
137:
138: .globl tsave
139:
140: tsave: / What level of interrupt ?
141: push ds / Save current data base
142: mov ds, cs:cds / remap to system data space.
143: pop sav_ds /
144: decb depth_ / Adjust stack depth.
145: je tkusave / If e, stack switch may be needed.
146: ttsave: / Interrupted within interrupt
147: cmp sp,$u_+USIZE+50 / Check for stack
148: jbe tabort / overflow
149: push ss / Fake save ss
150: push sp / Fake save sp
151: push sav_ds / Save ds
152: push bx / Save bx
153:
154: sti / More interrupts ok
155:
156: push ax / Save ax
157: push dx / and remainder
158: push cx / of machine
159: push es / state
160: mov ax,ds / Map es
161: mov es,ax / to system ds
162: mov bx,sp / Load index
163: icall 16(bx) / and call the caller
164: mov bx,sp / Load index
165: mov ax,16(bx) / fetch trap type
166: cmpb ah, $SIDEV / see if eoi
167: jne ttkdone / can be skipped
168:
169: cli / don't let eoi swamp us
170: call eoi / Dismiss interrupt
171: ttkdone: / Common ttsave/tksave finish
172: pop es / Restore
173: pop cx / the
174: pop dx / machine state
175: pop ax / state
176:
177: cli / No more interrupts
178:
179: incb depth_ / Reset stack level
180: pop bx / Restore the
181: pop ds / last parts
182: add sp,$6 / forget ss, sp, and ra.
183: iret / Done.
184:
185: tabort: / Uarea stack overflowed
186: add sp,$300 / Make room for death.
187: mov ax,$oops / Load
188: push ax / message
189: call panic_ / and die.
190:
191: tkusave: / Kernel or user process interrupted
192: mov sav_bx,bx / Save bx in temp
193: mov bx,cprocp_ / Load proc pointer
194: test PFLAGS(bx),$PFKERN / Kernel process ?
195: je tusave / Sorry, go do it all.
196: tksave: / Kernel process interrupted
197: push ss / Fake save ss
198: push sp / Fake save sp
199: push sav_ds / Save ds
200: push sav_bx / Save bx
201:
202: sti / More interrupts ok.
203:
204: cmp bx,iprocp_ / Is this the idle process ?
205: je tisave / Yes, very easy
206: push ax / Save the
207: push dx / rest of
208: push cx / the machine
209: push es / state
210: mov ax,ds / And map
211: mov es,ax / extra to system data
212: mov bx,sp / Load index
213: icall 16(bx) / and call the caller back.
214: mov bx,sp / Load index
215: mov ax,16(bx) / and pull trap type.
216: cmpb ah, $SIDEV / Machine trap?
217: jne ttkdone / Yes, skip dismiss
218: call eoi / Dismiss interrupt
219: jmp ttkdone / Finish above
220:
221: tisave: / Idle process interrupted, nothing to save
222: sub sp,$8 / Push junk
223: mov bx,sp / Load index
224: icall 16(bx) / and call the caller back.
225: mov bx,sp / Load index
226: mov ax,16(bx) / and pull trap type.
227: cmpb ah, $SIDEV / Machine trap ?
228: jne 0f / Yes, skip dismiss.
229: call eoi / Dismiss interrupt
230: 0:
231: call stand_ / Clock, part 2
232: cli / No more interrupts
233:
234: add sp,$18 / Pop everything
235: incb depth_ / Reset level
236: iret / Done
237:
238: tusave: / User process interrupted
239: mov bx, $u_+UPASIZE / Get base of user area and
240: pop -8(bx) / pop the data that
241: pop -6(bx) / was pushed onto the user
242: pop -4(bx) / stack onto the new
243: pop -2(bx) / system stack.
244: mov sav_ss, ss / Save the old stack segment
245: mov sav_sp, sp / and stack pointer, then
246: mov ss, sds_ / switch onto the
247: lea sp, -8(bx) / new stack in the user area.
248: push sav_ss / Push old ss
249: push sav_sp / Push old sp
250: push sav_ds / Push old ds and
251: push sav_bx / push old bx.
252:
253: sti / Allow more interrupts.
254:
255: push ax / Save the
256: push dx / remainder of
257: push cx / the machine
258: push es / state.
259: mov ax, ds / Map extra
260: mov es, ax / segment to system data.
261: mov bx, sp / Load up an index into the stack
262: icall 16(bx) / and call the caller back.
263: mov bx, sp / Load up stack index.
264: mov ax, 16(bx) / Pull trap type.
265: cmpb ah, $SIDEV / Is this a machine trap ?
266: jne 0f / Yes, skip dismiss.
267: call eoi / Do the dismiss.
268: 0: mov bx, cprocp_ / Have we become kernel?
269: test PFLAGS(bx), $PFKERN / If so, do kernel return.
270: jne ttkdone /
271:
272: call stand_ / Clock, part 2
273: pop es / Restore the
274: pop cx / easy part of the
275: pop dx / machine
276: pop ax / state.
277:
278: cli / Interrupts off.
279:
280: incb depth_ / Adjust stack depth and
281: pop sav_bx / Pop off the old bx and
282: pop sav_ds / ds into statics, then
283: pop bx / map DS:BX over top of what
284: pop ds / was the previous stack.
285: add sp, $2 / Pop ra.
286: pop -6(bx) / Copy the IP,
287: pop -4(bx) / the CS and the old
288: pop -2(bx) / FW onto the user's stack, then
289: lea sp, -6(bx) / switch back
290: mov bx, ds / to the
291: mov ss, bx / user's stack.
292: mov ds, cs:cds /
293: mov bx, sav_bx / Reload the bx and the
294: mov ds, sav_ds / ds, then
295: iret / exit interrupt.
296:
297: ////////
298: /
299: / This dummy routine is put in vector
300: / table slots that are unused. All it does is
301: / return to the caller.
302: /
303: ////////
304:
305: .globl vret_
306:
307: vret_: ret
308:
309: ////////
310: /
311: / Fetch a word from the user's data space.
312: /
313: / getuwd(u)
314: / char *u;
315: /
316: ////////
317:
318: .globl getuwd_
319: .globl getupd_
320:
321: getuwd_:
322: getupd_:
323: mov bx,sp / Base pointer
324: mov bx,2(bx) / Argument
325: cmp bx,udl_ / In range?
326: ja kuerr / No
327:
328: push es / Save extra map and
329: mov es, uds_ / remap over the user's data.
330: mov ax,es:(bx) / Get word
331: pop es / Restore es.
332: ret / Return
333:
334: ////////
335: /
336: / Fetch a word from the user's code space.
337: /
338: / getuwi(u)
339: / char *u;
340: /
341: ////////
342:
343: .globl getuwi_
344:
345: getuwi_:
346: mov bx,sp / Base pointer
347: mov bx,2(bx) / Argument
348: cmp bx,ucl_ / In range?
349: ja kuerr / No
350:
351: push es / Save extra.
352: mov es,ucs_ / Users data segment
353: mov ax,es:(bx) / Get word
354: pop es / Restore extra.
355: ret / Return
356:
357: ////////
358: /
359: / Fetch a byte from the user's data space.
360: /
361: / getubd(u)
362: / char *u;
363: /
364: ////////
365:
366: .globl getubd_
367:
368: getubd_:
369: mov bx,sp / Base pointer
370: mov bx,2(bx) / Argument
371: cmp bx,udl_ / In range?
372: ja kuerr / No
373:
374: push es / Save es.
375: mov es,uds_ / Users data segment
376: movb al,es:(bx) / Get word
377: pop es / Restore es.
378: subb ah,ah / Clear upper half
379: ret / Return
380:
381: ////////
382: /
383: / Store a word into the user's data space.
384: /
385: / putuwd(u, w)
386: / char *u;
387: / int w;
388: /
389: ////////
390:
391: .globl putuwd_
392:
393: putuwd_:
394: mov bx,sp / Base pointer
395: mov ax,4(bx) / New value
396: mov bx,2(bx) / Argument
397: cmp bx,udl_ / In range?
398: ja kuerr / No
399:
400: push es / Save es.
401: mov es,uds_ / Users data segment
402: mov es:(bx),ax / Set value
403: pop es / Restore es.
404: sub ax,ax / Succesful
405: ret / Return
406:
407: ////////
408: /
409: / Store a word into the user's code space.
410: /
411: / putuwi(u, w)
412: / char *u;
413: / int w;
414: /
415: ////////
416:
417: .globl putuwi_
418:
419: putuwi_:
420: mov bx,sp / Base pointer
421: mov ax,4(bx) / New value
422: mov bx,2(bx) / Argument
423: cmp bx,ucl_ / In range?
424: ja kuerr / No
425:
426: push ucs_ / Get physical address.
427: sub ax, ax / DX:AX = phy = vtop( ucs:0 );
428: push ax /
429: call vtop_ /
430: add sp, $4 /
431: /
432: sub bx, bx / Get writable virtual address.
433: push bx / DX:AX = fp = ptov( phy, ucl );
434: push ucl_ /
435: push dx /
436: push ax /
437: call ptov_ /
438: add sp, $8 /
439: /
440: mov bx, sp /
441: mov ax, 4(bx) / New value
442: mov bx, 2(bx) / Argument
443: push es / Save ES
444: mov es, dx / Users (writable) code segment
445: mov es:(bx), ax / Set value
446: pop es / Restore es
447: /
448: push dx / Release writable virtual address.
449: sub ax, ax / vrelse( fp );
450: push ax /
451: call vrelse_ /
452: add sp, $4 /
453: /
454: sub ax,ax / Succesful
455: ret / Return
456:
457: ////////
458: /
459: / Store a byte into the user's data space.
460: /
461: / putubd(u, w)
462: / char *u;
463: / int w;
464: /
465: ////////
466:
467: .globl putubd_
468:
469: putubd_:
470: mov bx,sp / Base pointer
471: mov ax,4(bx) / New value
472: mov bx,2(bx) / Argument
473: cmp bx,udl_ / In range?
474: ja kuerr / No
475:
476: push es / Save es.
477: mov es,uds_ / Users data segment
478: movb es:(bx),al / Set value
479: pop es / Restore es.
480: sub ax,ax / Succesful
481: ret / Return
482:
483: ////////
484: /
485: / Block transfer "n" bytes from location
486: / "k" in the system map to location "u" in the
487: / user's data space. Return the number of bytes
488: / transferred.
489: /
490: / kucopy(k, u, n)
491: / char *k;
492: / char *u;
493: / int n;
494: /
495: ////////
496:
497: .globl kucopy_
498:
499: kucopy_:
500: mov bx,sp / Base pointer
501: mov ax,4(bx) / User address
502: dec ax / Don't wrap too soon
503: add ax,6(bx) / Add count
504: jc kuerr / Out of bounds
505: cmp ax,udl_ / In range?
506: ja kuerr / No
507:
508: push si / Save si
509: push di / Save di
510: push es / Save es.
511:
512: mov si,2(bx) / Kernel address
513: mov di,4(bx) / User address
514: mov cx,6(bx) / Count
515: mov ax,cx / Move here to return
516: mov es,uds_ / Map extra segment to user
517:
518: cld / Auto increment
519: clc /
520: rcr cx, $1 / Calculate Word count
521: rep /
522: movsw / Move words.
523: rcl cx, $1
524: rep
525: movsb / Move odd byte.
526:
527: pop es / Restore es.
528: pop di / Restore di
529: pop si / Restore si
530: ret / Return
531:
532: ////////
533: /
534: / Block copy "n" bytes from location "u" in
535: / the user data space to location "k" in the system
536: / data space. Return the actual number of bytes
537: / moved.
538: /
539: / ukcopy(u, k, n)
540: / char *u;
541: / char *k;
542: / int n;
543: /
544: ////////
545:
546: .globl ukcopy_
547:
548: ukcopy_:
549: mov bx,sp / Base pointer
550: mov ax,2(bx) / User address
551: dec ax / Don't wrap too soon
552: add ax,6(bx) / Count
553: jc kuerr / Out of bounds
554: cmp ax,udl_ / In range?
555: ja kuerr / No
556:
557: push si / Save si
558: push di / Save di
559: push ds / Save ds
560:
561: mov si,2(bx) / User address
562: mov di,4(bx) / Kernel address
563: mov cx,6(bx) / Count
564: mov ax,cx / Move here to return
565: mov bx, uds_ / Map data segment
566: mov ds, bx / avoiding bug in 8088.
567:
568: cld / Auto increment
569: clc /
570: rcr cx, $1 / Word count, odd byte in carry.
571: rep /
572: movsw / Move words.
573: rcl cx, $1
574: rep / Move odd byte.
575: movsb
576:
577: pop ds / Restore ds
578: pop di / Restore di
579: pop si / Restore si
580: ret / Return
581:
582: ////////
583: /
584: / All of the above copy routines jump to
585: / "kuerr", with the stack untouched, if they detect
586: / a bounds error on a user address.
587: /
588: ////////
589:
590: kuerr:
591: mov bx,$u_ / Pointer to user area
592: movb (bx),$EFAULT / Bad parameter error
593: sub ax,ax / Didn't copy anything
594: ret / Return
595:
596: ////////
597: /
598: / sfbyte( fp, b ) -- set far byte
599: / int far * fp;
600: / int b;
601: /
602: ////////
603:
604: .globl sfbyte_
605:
606: sfbyte_:push es / sfbyte( fp, b )
607: push di / register int far * fp; /* ES:DI */
608: push bp / register int b; /* AX */
609: mov bp, sp / {
610: les di, 8(bp) /
611: mov ax, 12(bp) /
612: /
613: movb es:(di), al / *fp = b;
614: /
615: pop bp / }
616: pop di
617: pop es
618: ret
619:
620: ////////
621: /
622: / sfword( fp, w ) -- set far word
623: / int far * fp;
624: / int w;
625: /
626: ////////
627:
628: .globl sfword_
629:
630: sfword_:push es / sfword( fp, w )
631: push di / register int far * fp; /* ES:DI */
632: push bp / register int w; /* AX */
633: mov bp, sp / {
634: les di, 8(bp) /
635: mov ax, 12(bp) /
636: /
637: mov es:(di), ax / *fp = w;
638: /
639: pop bp / }
640: pop di
641: pop es
642: ret
643:
644: ////////
645: /
646: / ffbyte( fp ) -- fetch far byte
647: / int far * fp;
648: /
649: ////////
650:
651: .globl ffbyte_
652:
653: ffbyte_:push es / ffbyte( fp )
654: push di / register int far * fp; /* ES:DI */
655: push bp / {
656: mov bp, sp /
657: les di, 8(bp) /
658: /
659: sub ax, ax /
660: movb al, es:(di) / return *fp;
661: /
662: pop bp / }
663: pop di
664: pop es
665: ret
666:
667: ////////
668: /
669: / ffword( fp ) -- fetch far word
670: / int far * fp;
671: /
672: ////////
673:
674: .globl ffword_
675:
676: ffword_:push es / ffword( fp )
677: push di / register int far * fp; /* ES:DI */
678: push bp / {
679: mov bp, sp /
680: les di, 8(bp) /
681: /
682: mov ax, es:(di) / return *fp;
683: /
684: pop bp / }
685: pop di
686: pop es
687: ret
688:
689: ////////
690: /
691: / Block transfer "n" bytes from location
692: / "k" in the system map to location "f"
693: / in the virtual address space.
694: / Return the number of bytes / transferred.
695: /
696: / kfcopy(k, f, n)
697: / char *k;
698: / faddr_t f;
699: / int n;
700: /
701: ////////
702:
703: .globl kfcopy_
704:
705: kfcopy_:
706: push si / Save si
707: push di / Save di
708: push bp / Save bp
709: mov bp, sp / Base pointer
710: push es / Save es.
711:
712: mov si, 8(bp) / Kernel address
713: les di, 10(bp) / Far address
714: mov cx, 14(bp) / Count
715: mov ax, cx / Move here to return
716:
717: cld / Auto increment
718: clc /
719: rcr cx, $1 / Calculate Word count.
720: rep /
721: movsw / Move words.
722: rcl cx, $1 /
723: rep /
724: movsb / Move odd byte.
725: /
726: pop es / Restore es.
727: pop bp / Restore bp.
728: pop di / Restore di
729: pop si / Restore si
730: ret / Return
731:
732: ////////
733: /
734: / Block transfer "n" bytes from location
735: / "f" in the virtual addres sspace to
736: / location "f" in the system map.
737: / Return the number of bytes / transferred.
738: /
739: / fkcopy(f, k, n)
740: / faddr_t f;
741: / char *k;
742: / int n;
743: /
744: ////////
745:
746: .globl fkcopy_
747:
748: fkcopy_:
749: push si / Save si
750: push di / Save di
751: push bp / Save bp
752: mov bp, sp / Base pointer
753: push ds / Save ds.
754:
755: lds si, 8(bp) / Far address
756: mov di, 12(bp) / Kernel address
757: mov cx, 14(bp) / Count
758: mov ax, cx / Move here to return
759:
760: cld / Auto increment
761: clc /
762: rcr cx, $1 / Calculate Word count.
763: rep /
764: movsw / Move words.
765: rcl cx, $1 /
766: rep /
767: movsb / Move odd byte.
768: /
769: pop ds / Restore ds.
770: pop bp / Restore bp.
771: pop di / Restore di
772: pop si / Restore si
773: ret / Return
774:
775: ////////
776: /
777: / fclear( fp, n ) - Erase far memory.
778: / faddr_t fp;
779: / unsigned n;
780: /
781: ////////
782:
783: .globl fclear_
784:
785: fclear_:
786: push es / Save es
787: push di / Save di
788: push bp / Save bp
789: mov bp, sp / Base pointer
790:
791: les di, 8(bp) / Far address
792: mov cx, 12(bp) / Count
793: sub ax, ax /
794:
795: cld / Auto increment
796: clc /
797: rcr cx, $1 / Calculate Word count.
798: rep /
799: stosw / Clear words.
800: rcl cx, $1 /
801: rep /
802: stosb / Clear odd byte.
803: /
804: pop bp / Restore bp.
805: pop di / Restore di.
806: pop es / Restore es.
807: ret / Return
808:
809: ////////
810: /
811: / Profile scaling.
812: /
813: ////////
814:
815: .globl pscale_
816:
817: pscale_:
818: mov bx,sp / Base pointer
819: mov ax,2(bx) / Multiply
820: mul 4(bx) /
821: mov ax,dx / Get high half
822: ret / And return
823:
824: ////////
825: /
826: / Save the environment of a process
827: / envsave(p)
828: / MENV *p;
829: /
830: / Save the context of a process
831: / consave(p)
832: / MCON *p;
833: /
834: ////////
835:
836: .globl consave_
837: .globl envsave_
838:
839: envsave_:
840: consave_:
841: mov cx, di / Hide di.
842: mov bx, sp / Point bx at the stack and
843: mov di, 2(bx) / di at the MCON block.
844: cld / Ensure increment.
845: mov ax, cx / Save di
846: stosw
847: mov ax, si / Save si
848: stosw
849: mov ax, bp / Save bp
850: stosw
851: mov ax, sp / Save sp
852: stosw
853: mov ax, (bx) / Save ra as pc
854: stosw
855: pushf / Save fw
856: pop ax
857: stosw
858: movb al, depth_ / Save stack depth
859: cbw
860: stosw
861: mov di, cx / Put di back,
862: sub ax, ax / indicate a state save and
863: ret / return to caller.
864:
865: ////////
866: /
867: / Restore the environment of a process.
868: / envrest(p)
869: / MENV *p;
870: /
871: ////////
872:
873: .globl envrest_
874:
875: envrest_:
876: cli
877: cld
878: mov bx,sp / Base pointer
879: mov si,2(bx) / Pointer to context
880: lodsw / Restore di
881: mov di,ax /
882: lodsw / Restore si
883: mov cx,ax / Save for later
884: lodsw / Restore bp
885: mov bp,ax /
886: lodsw / Restore sp
887: mov sp,ax /
888: mov bx,ax / Our frame
889: push cs / Push current CS
890: lodsw / Restore pc
891: push ax /
892: lodsw / Restore flags
893: mov (bx),ax / Stack now in form PSW,CS,IP.
894: lodsw / Restore stack depth
895: cli / No more interrupts
896: movb depth_, al
897: mov si,cx / Restore si
898: mov ax,$1 / We are restoring
899: iret / Return through PSW,CS,IP.
900:
901: ////////
902: /
903: / Restore the context of a process.
904: / Called with interrupts disabled from dispatch.
905: / conrest(u, o)
906: / saddr_t u;
907: /
908: ////////
909:
910: .globl conrest_
911:
912: conrest_:
913: decb depth_ / Falsify user/system state
914: sti / Interrupts ok here
915: / Save current uarea
916: call usave_ / Save the uarea in its segment.
917: / Copy in new uarea
918: mov bx,sp / Base pointer
919: mov ax, 2(bx) / Fetch uarea saddr_t
920: mov bx, 4(bx) / Fetch syscon offset
921: mov uasa_, ax / Save uarea saddr_t
922: mov cx,$USZ1 / uproc size
923: / mov es,sds_ / system data segment
924: mov di,$u_ / system data uarea offset
925: mov ds,ax / uarea segment
926: sub si,si / uarea offset
927: mov sp,UMCSP(bx) / new stack
928: cld / increment
929: rep / repeat
930: movsw / copy uproc
931: mov di,sp / stack offset in system data
932: and di,$~1 / ensure word alignment
933: mov cx,$u_+UPASIZE / compute byte
934: sub cx,di / count
935: mov si,$UPASIZE / compute offset
936: sub si,cx / in segment
937: shr cx,$1 / make word count
938: rep / repeat
939: movsw / copy stack
940: / Clean up
941: mov ax, es / Restore data
942: mov ds, ax / segment
943: / Now restore context
944: add bx, $u_ / convert to address
945: mov si, bx / Get source index for restore
946: lodsw / Restore di
947: mov di,ax /
948: lodsw / Restore si
949: mov cx,ax / Save for later
950: lodsw / Restore bp
951: mov bp,ax /
952: lodsw / Restore sp
953: mov sp,ax /
954: mov bx,ax / Our frame
955: push cs / Push current CS
956: lodsw / Restore pc
957: push ax /
958: lodsw / Restore flags
959: mov (bx),ax / Stack now in form PSW,CS,IP.
960: lodsw / Restore stack depth
961: cli / No more interrupts
962: movb depth_, al
963: mov si,cx / Restore si
964: mov ax,$1 / We are restoring
965: iret / Return through PSW,CS,IP.
966:
967: ////////
968: / usave()
969: / Save uarea in segment.
970: / Knowing that ds points to the system data segment
971: / and that es should map there also.
972: / And guaranteed not to step on ax or bx for conrest
973: /
974: .globl usave_
975: 0: ret
976: usave_:
977: cmp uasa_, $0 /
978: je 0b
979: push es / Save es
980: push si / Save si
981: push di / Save di
982: mov cx,$USZ1 / count
983: sub di,di / uarea segment offset
984: mov es,uasa_ / uarea segment
985: mov si,$u_ / system data offset
986: / mov ds,sds_ / system data segment
987: cld / increment
988: rep / repeat
989: movsw / copy uproc
990: mov si,sp / stack offset in system data
991: and si,$~1 / ensure word alignment
992: mov cx,$u_+UPASIZE / compute byte
993: sub cx,si / count
994: mov di,$UPASIZE / compute offset
995: sub di,cx / in segment
996: shr cx,$1 / make word count
997: rep / repeat
998: movsw / copy stack
999: pop di / Restore di
1000: pop si / Restore si
1001: pop es / Restore extra
1002: ret
1003:
1004: / Save useful registers.
1005: /
1006: .globl msysgen_
1007: /
1008: / msysgen(p)
1009: / MGEN *p;
1010: /
1011: msysgen_:
1012: ret / Nothing useful to save
1013:
1014: / Disable interrupts. Previous value is returned.
1015: /
1016: .globl sphi_
1017:
1018: sphi_:
1019: pushf / Save flags
1020: pop ax / Return current value
1021: cli / Disable interrupts
1022: ret / And return
1023:
1024: / Enable interrupts. Previous value is returned.
1025: /
1026: .globl splo_
1027:
1028: splo_:
1029: pushf
1030: pop ax
1031: sti
1032: ret
1033:
1034: / Change interrupt flag. Previous value is returned.
1035: /
1036: .globl spl_
1037:
1038: spl_:
1039: pop ax / ip
1040: pop bx / psw
1041: push bx
1042: push bx / push psw, cs, ip for iret
1043: push cs
1044: push ax
1045: pushf / old psw
1046: pop ax
1047: iret
1048:
1049: ////////
1050: /
1051: / Idle routine.
1052: / Enable interupts, and wait for something to
1053: / happen. Does not do anything to the 8259, bacause
1054: / this will be set up correctly.
1055: /
1056: ////////
1057:
1058: .globl _idle_
1059:
1060: _idle_: sti / Interupts on.
1061: hlt / Wait for an interrupt
1062: ret / and return.
1063:
1064: ////////
1065: /
1066: / The world is indeed grim.
1067: / Halt. Keep the interrupts on so that the
1068: / keyboard can get int.
1069: /
1070: ////////
1071:
1072: .globl halt_
1073:
1074: halt_: sti / Be safe,
1075: 0:
1076: hlt / and halt.
1077: jmp 0b / Paranoid, yes sir.
1078:
1079: ////////
1080: /
1081: / Basic port level I/O.
1082: /
1083: / int inb(port);
1084: / int outb(port, data);
1085: /
1086: ////////
1087:
1088: .globl inb_
1089: .globl outb_
1090:
1091: inb_: mov bx, sp
1092: mov dx, ss:2(bx)
1093: sub ax, ax
1094: inb al, dx
1095: ret
1096:
1097: outb_: mov bx, sp
1098: mov dx, ss:2(bx)
1099: mov ax, ss:4(bx)
1100: outb dx, al
1101: ret
1102:
1103: ////////
1104: /
1105: / Routines to move data to and from
1106: / the system auxiliary segment.
1107: /
1108: ////////
1109:
1110: .globl ageti_
1111:
1112: ageti_:
1113: mov bx,sp / Base pointer
1114: mov bx,2(bx) / Pointer
1115: push es / Save extra mapping and
1116: mov es, sas_ / remap.
1117: mov ax,es:(bx) / Get value
1118: pop es / Restore es and
1119: ret / Return
1120:
1121: .globl aputp_
1122: .globl aputi_
1123:
1124: aputp_:
1125: aputi_:
1126: mov bx,sp / Base pointer
1127: mov ax,4(bx) / Value
1128: mov bx,2(bx) / Pointer
1129: push es / Save extra base and
1130: mov es, sas_ / remap.
1131: mov es:(bx),ax / Set value
1132: pop es / Restore extra base
1133: ret / Return
1134:
1135: .globl aputc_
1136:
1137: aputc_:
1138: mov bx,sp / Base pointer
1139: mov ax,4(bx) / Value
1140: mov bx,2(bx) / Pointer
1141: push es / Save es and
1142: mov es, sas_ / remap.
1143: movb es:(bx),al / Set value
1144: pop es / Restore es and
1145: ret / Return
1146:
1147: ////////
1148: /
1149: / Data.
1150: / A small number of variables must be
1151: / in the code segment. All of these variables have
1152: / something to do with the interrupt linkage; when you
1153: / get an interrupt the only thing that is valid is
1154: / the code segment.
1155: /
1156: ////////
1157:
1158: .globl cds
1159:
1160: .shri
1161: cds: .blkw 1 / Copy of "sds_".
1162:
1163: .globl u_
1164: .globl depth_, sas_, scs_, sds_, ucs_
1165: .globl ucl_, uds_, udl_
1166:
1167: .bssd
1168: .even
1169: u_: .blkb UPASIZE
1170:
1171: .prvd
1172: oops: .ascii "stack overflow"
1173: .byte 0
1174:
1175: depth_: .byte 0 / System state.
1176:
1177: .even
1178: sas_: .blkw 1 / System auxiliary segment.
1179: scs_: .blkw 1 / System code segment.
1180: sds_: .blkw 1 / System data segment.
1181: ucs_: .blkw 1 / User code segment.
1182: ucl_: .blkw 1 / User code limit.
1183: uds_: .blkw 1 / User data segment.
1184: udl_: .blkw 1 / User data limit.
1185: sav_ds: .blkw 1 / Four scratch words
1186: sav_bx: .blkw 1
1187: sav_ss: .blkw 1
1188: sav_sp: .blkw 1
1189:
1190: ////////
1191: /
1192: / This is the image of the init process.
1193: / It gets copied into a user segment when the system
1194: / is first brought up. It must be in the data segment, because
1195: / that is how it is used, and it must be dephased in a funny
1196: / way because it is executed at location 0.
1197: /
1198: ////////
1199:
1200: .globl aicodep_ / Position of code.
1201: .globl aicodes_ / Size of code.
1202: .globl aidatap_ / Position of data.
1203: .globl aidatas_ / Size of data.
1204:
1205: .shrd
1206: aicodep_:
1207: sub ax,ax / No environment
1208: push ax
1209: mov ax,$argl-aidatap_ / Argument list
1210: push ax
1211: mov ax,$fn-aidatap_ / File name
1212: push ax
1213: sub sp,$2 / Dummy word for exec
1214: sys 11 / Sys exec
1215: jmp . / This should not return
1216: aicodes_ = .-aicodep_
1217:
1218: aidatap_:
1219: .word 0 /
1220: .word 0 / Errno
1221: .word 0 /
1222: .word 0 /
1223: .word 0 /
1224: .word 0 /
1225: .word 0 /
1226: .word 0 /
1227: argl: .word fn-aidatap_ / argv[0] = "/etc/init";
1228: .word a1-aidatap_ / argv[1] = "";
1229: .word 0 / argv[2] = NULL;
1230:
1231: fn: .ascii "/etc/init\000"
1232: a1: .byte 0
1233:
1234: .even
1235: .blkb 64
1236: sb:
1237: aidatas_ = .-aidatap_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.