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