|
|
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.