|
|
1.1 ! root 1: / /usr/src/sys/i8086/src/ldas.s ! 2: / ! 3: //////// ! 4: / ! 5: / Loadable Driver Interface Routines. ! 6: / ! 7: / Loadable drivers execute in separate code segments, and are unable ! 8: / to directly call kernel service routines. ! 9: / Loadable drivers call a kernel service stub within their code segment, ! 10: / which has has the same name as the desired service routine. ! 11: / The driver service stub performs a far call to one of these routines. ! 12: / These routines perform a near call to the desired kernel routine, ! 13: / and then perform a far return to the driver service stub routine. ! 14: / The driver service stub routine then does a near return to the driver. ! 15: / ! 16: / 90/09/11 Hal Snyder ! 17: / Add ld_call() ! 18: / ! 19: / $Log: /usr/src/sys/i8086/src/RCS/ldas.s,v $ ! 20: / Revision 1.2 91/03/01 09:23:04 root ! 21: / Part of COHERENT 3.1.0 kernel ! 22: / ! 23: / Revision 1.1 88/03/24 17:39:39 src ! 24: / Initial revision ! 25: / ! 26: / 87/12/08 Allan Cornish /usr/src/sys/i8086/src/ldas.s ! 27: / Block device interface added to loadable drivers. ! 28: / ldtimcall() function added to support timed functions in loadable drivers. ! 29: / ! 30: / 87/10/25 Allan Cornish /usr/src/sys/i8086/src/ldas.s ! 31: / Initial version - interface to/from loadable driver processes. ! 32: / ! 33: //////// ! 34: ! 35: .globl ld_xcall_ ! 36: .globl ld_call_ ! 37: .globl xcalled ! 38: .globl ldtimcall_ ! 39: .globl ld_open_ ! 40: .globl ld_close_ ! 41: .globl ld_read_ ! 42: .globl ld_write_ ! 43: .globl ld_block_ ! 44: .globl ld_ioctl_ ! 45: .globl ld_power_ ! 46: .globl ld_time_ ! 47: .globl ld_poll_ ! 48: .globl ldrvint_ / void (*ldrvint[16])(); ! 49: ! 50: //////// ! 51: / ! 52: / Constants ! 53: / ! 54: //////// ! 55: ! 56: T_LDRV = 12 / Offset(tim,t_ldrv). ! 57: B_FLAG = 6 / Offset(buf,b_flag). ! 58: B_DEV = 8 / Offset(buf,b_dev ). ! 59: BFERR = 4 / buf.b_flag bit set on I/O error. ! 60: DRV_J = 4 / offset in driver of dispatcher ! 61: ! 62: //////// ! 63: / ! 64: / External References ! 65: / ! 66: //////// ! 67: ! 68: .globl nonedev_ / extern void nonedev(); ! 69: .globl ldrvcon_ / extern CON * ldrvcon[NDRV]; ! 70: .globl ldrvsel_ / extern saddr_t ldrvsel[NDRV]; ! 71: .globl ldrvics_ / extern saddr_t ldrvics[16]; ! 72: .globl ldrvipc_ / extern void (*ldrvipc[16])(); ! 73: ! 74: //////// ! 75: / ! 76: / Shared Data ! 77: / ! 78: //////// ! 79: .shrd ! 80: ldrvint_: / Loadable Driver Interrupt Entry Points. ! 81: .word ld_intr0 ! 82: .word ld_intr1 ! 83: .word ld_intr2 ! 84: .word ld_intr3 ! 85: .word ld_intr4 ! 86: .word ld_intr5 ! 87: .word ld_intr6 ! 88: .word ld_intr7 ! 89: .word ld_intr8 ! 90: .word ld_intr9 ! 91: .word ld_intr10 ! 92: .word ld_intr11 ! 93: .word ld_intr12 ! 94: .word ld_intr13 ! 95: .word ld_intr14 ! 96: .word ld_intr15 ! 97: ! 98: //////// ! 99: / ! 100: / Private Data ! 101: / ! 102: //////// ! 103: ! 104: .prvd ! 105: .shri ! 106: ! 107: //////// ! 108: / ! 109: / Driver Configuration: Offsets to Function Pointers ! 110: / ! 111: //////// ! 112: ! 113: C_OPEN=4 ! 114: C_CLOSE=6 ! 115: C_BLOCK=8 ! 116: C_READ=10 ! 117: C_WRITE=12 ! 118: C_IOCTL=14 ! 119: C_POWER=16 ! 120: C_TIMER=18 ! 121: C_LOAD=20 ! 122: C_ULOAD=22 ! 123: C_POLL=24 ! 124: ! 125: //////// ! 126: / ! 127: / ld_xcall( fp ) - invoke far function. ! 128: / int (far *fp)(); ! 129: / ! 130: //////// ! 131: ! 132: ld_xcall_: ! 133: cli ! 134: push bp ! 135: mov bp, sp ! 136: xcall 4(bp) ! 137: pop bp ! 138: ret ! 139: ! 140: //////// ! 141: / ! 142: / call a driver function from the kernel ! 143: / sel - CS selector for the driver ! 144: / fn - offset in the driver of the function we want ! 145: / arg[1-3] - optional arguments ! 146: / ! 147: / ld_call(sel, fn, arg1, arg2, arg3) ! 148: / int sel; ! 149: / int (*fn)(void); ! 150: / int arg1, arg2, arg3; ! 151: / ! 152: //////// ! 153: ! 154: / stack when ld_call() is called: ! 155: / arg3 ! 156: / arg2 ! 157: / arg1 ! 158: / fn ! 159: / sel ! 160: / return IP ! 161: ! 162: ld_call_: / PARAMETERS (arg[1-3]) MUST BE FOUND AT 4(BP). ! 163: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 164: / lea bp, 4(sp) / this is what the next 2 instructions do ! 165: mov bp, sp ! 166: add bp, $4 ! 167: / ! 168: push 0(bp) / Push sel to allow far call ! 169: push $DRV_J / ! 170: / ! 171: mov ax, 2(bp) / Push fn ! 172: / ! 173: xcall -8(bp) / Invoke driver interface, which will ! 174: / in turn invoke driver function. ! 175: / ! 176: lea sp, -4(bp) / ! 177: pop bp / ! 178: ret / ! 179: ! 180: //////// ! 181: / ! 182: / ! 183: / ldtimcall( arg, tp ) - service timed far function. ! 184: / ! 185: //////// ! 186: ! 187: ldtimcall_: / ! 188: push bp / ! 189: mov bp, sp / ! 190: / ! 191: mov bx, 6(bp) / ! 192: mov ax, T_LDRV+2(bx) / ! 193: push ax / Loadable driver code selector. ! 194: push $DRV_J / Loadable driver invocation offset. ! 195: mov ax, T_LDRV(bx) / Desired far function. ! 196: / ! 197: xcall -4(bp) / ! 198: / ! 199: mov sp, bp / ! 200: pop bp / ! 201: ret ! 202: ! 203: //////// ! 204: / ! 205: / xcalled( f, args ) ! 206: / int (*f)(); ! 207: / ! 208: / Input: AX is pointer to kernel function to be invoked. ! 209: / ! 210: / Action: Perform a near call to the specified kernel function, ! 211: / passing 6 words as optional arguments. ! 212: / Perform a far return. ! 213: / ! 214: / Notes: Invoked by far call from loadable device driver. ! 215: / ! 216: //////// ! 217: ! 218: xcalled: / 6(bp) = grand-parent IP. ! 219: push bp / 4(bp) = parent CS ! 220: mov bp, sp / 2(bp) = parent IP ! 221: / AX = destination function. ! 222: push 20(bp) / Arg 7 / ! 223: push 18(bp) / Arg 6 / ! 224: push 16(bp) / Arg 5 / ! 225: push 14(bp) / Arg 4 / ! 226: push 12(bp) / Arg 3 / ! 227: push 10(bp) / Arg 2 / ! 228: push 8(bp) / Arg 1 / ! 229: icall ax / ! 230: / ! 231: mov sp, bp / Return to loadable driver. ! 232: pop bp / ! 233: xret / ! 234: ! 235: //////// ! 236: / ! 237: / ld_open( dev, mode ) - Open Routine. ! 238: / dev_t dev; ! 239: / int mode; ! 240: / ! 241: //////// ! 242: ! 243: ld_open_: / PARAMETERS MUST REMAIN AT 4(BP). ! 244: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 245: mov bp, sp / ! 246: / ! 247: sub bx, bx / Calculate major device number * 2. ! 248: movb bl, 5(bp) / ! 249: shl bx, $1 / ! 250: / ! 251: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 252: jcxz 0f / ! 253: push cx / ! 254: push $DRV_J / Loadable driver invocation offset. ! 255: / ! 256: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 257: or bx, bx / ! 258: je 0f / ! 259: / ! 260: mov ax, C_OPEN(bx) / Identify driver function to be invoked. ! 261: or ax, ax / ! 262: je 0f / ! 263: / ! 264: xcall -4(bp) / Invoke driver interface, which will ! 265: / in turn invoke driver function. ! 266: / ! 267: mov sp, bp / Return to caller. ! 268: pop bp / ! 269: ret / ! 270: ! 271: 0: mov sp, bp ! 272: pop bp ! 273: jmp nonedev_ ! 274: ! 275: //////// ! 276: / ! 277: / ld_close( dev ) - Close Routine. ! 278: / dev_t dev; ! 279: / ! 280: //////// ! 281: ! 282: ld_close_: / PARAMETERS MUST REMAIN AT 4(BP). ! 283: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 284: mov bp, sp / ! 285: / ! 286: sub bx, bx / Calculate major device number * 2. ! 287: movb bl, 5(bp) / ! 288: shl bx, $1 / ! 289: / ! 290: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 291: jcxz 0f / ! 292: push cx / ! 293: push $DRV_J / Loadable driver invocation offset. ! 294: / ! 295: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 296: or bx, bx / ! 297: je 0f / ! 298: / ! 299: mov ax, C_CLOSE(bx) / Identify driver function to be invoked. ! 300: or ax, ax / ! 301: je 0f / ! 302: / ! 303: xcall -4(bp) / Invoke driver interface, which will ! 304: / in turn invoke driver function. ! 305: / ! 306: mov sp, bp / Return to caller. ! 307: pop bp / ! 308: ret / ! 309: ! 310: 0: mov sp, bp ! 311: pop bp ! 312: jmp nonedev_ ! 313: ! 314: //////// ! 315: / ! 316: / ld_read( dev, iop ) - Read Routine. ! 317: / dev_t dev; ! 318: / IO * iop; ! 319: / ! 320: //////// ! 321: ! 322: ld_read_: / PARAMETERS MUST REMAIN AT 4(BP). ! 323: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 324: mov bp, sp / ! 325: / ! 326: sub bx, bx / Calculate major device number * 2. ! 327: movb bl, 5(bp) / ! 328: shl bx, $1 / ! 329: / ! 330: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 331: jcxz 0f / ! 332: push cx / ! 333: push $DRV_J / Loadable driver invocation offset. ! 334: / ! 335: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 336: or bx, bx / ! 337: je 0f / ! 338: / ! 339: mov ax, C_READ(bx) / Identify driver function to be invoked. ! 340: or ax, ax / ! 341: je 0f / ! 342: / ! 343: xcall -4(bp) / Invoke driver interface, which will ! 344: / in turn invoke driver function. ! 345: / ! 346: mov sp, bp / Return to caller. ! 347: pop bp / ! 348: ret / ! 349: ! 350: 0: mov sp, bp ! 351: pop bp ! 352: jmp nonedev_ ! 353: ! 354: /////// ! 355: / ! 356: / ld_write( dev, iop ) - Write Routine. ! 357: / dev_t dev; ! 358: / IO * iop; ! 359: / ! 360: //////// ! 361: ! 362: ld_write_: / PARAMETERS MUST REMAIN AT 4(BP). ! 363: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 364: mov bp, sp / ! 365: / ! 366: sub bx, bx / Calculate major device number * 2. ! 367: movb bl, 5(bp) / ! 368: shl bx, $1 / ! 369: / ! 370: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 371: jcxz 0f / ! 372: push cx / ! 373: push $DRV_J / Loadable driver invocation offset. ! 374: / ! 375: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 376: or bx, bx / ! 377: je 0f / ! 378: / ! 379: mov ax, C_WRITE(bx) / Identify driver function to be invoked. ! 380: or ax, ax / ! 381: je 0f / ! 382: / ! 383: xcall -4(bp) / Invoke driver interface, which will ! 384: / in turn invoke driver function. ! 385: / ! 386: mov sp, bp / Return to caller. ! 387: pop bp / ! 388: ret / ! 389: ! 390: 0: mov sp, bp ! 391: pop bp ! 392: jmp nonedev_ ! 393: ! 394: /////// ! 395: / ! 396: / ld_block( bp ) - Block Routine. ! 397: / BUF * bp; ! 398: / ! 399: //////// ! 400: ! 401: ld_block_: / PARAMETERS MUST REMAIN AT 4(BP). ! 402: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 403: mov bp, sp / ! 404: / ! 405: mov bx, 4(bp) / Calculate major device number * 2. ! 406: movb bl, B_DEV+1(bx) / ! 407: subb bh, bh / ! 408: shl bx, $1 / ! 409: / ! 410: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 411: jcxz 0f / ! 412: push cx / ! 413: push $DRV_J / Loadable driver invocation offset. ! 414: / ! 415: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 416: or bx, bx / ! 417: je 0f / ! 418: / ! 419: mov ax, C_BLOCK(bx) / Identify driver function to be invoked. ! 420: or ax, ax / ! 421: je 0f / ! 422: / ! 423: xcall -4(bp) / Invoke driver interface, which will ! 424: / in turn invoke driver function. ! 425: / ! 426: mov sp, bp / Return to caller. ! 427: pop bp / ! 428: ret / ! 429: ! 430: 0: mov bx, 4(bp) / bp->b_flag |= BFERR. ! 431: or B_FLAG(bx),$BFERR / ! 432: mov sp, bp / ! 433: pop bp / ! 434: jmp bdone_ / bdone(bp); ! 435: ! 436: //////// ! 437: / ! 438: / ld_ioctl( dev, iop ) - Ioctl Routine. ! 439: / dev_t dev; ! 440: / IO * iop; ! 441: / ! 442: //////// ! 443: ! 444: ld_ioctl_: / PARAMETERS MUST REMAIN AT 4(BP). ! 445: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 446: mov bp, sp / ! 447: / ! 448: sub bx, bx / Calculate major device number * 2. ! 449: movb bl, 5(bp) / ! 450: shl bx, $1 / ! 451: / ! 452: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 453: jcxz 0f / ! 454: push cx / ! 455: push $DRV_J / Loadable driver invocation offset. ! 456: / ! 457: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 458: or bx, bx / ! 459: je 0f / ! 460: / ! 461: mov ax, C_IOCTL(bx) / Identify driver function to be invoked. ! 462: or ax, ax / ! 463: je 0f / ! 464: / ! 465: xcall -4(bp) / Invoke driver interface, which will ! 466: / in turn invoke driver function. ! 467: / ! 468: mov sp, bp / Return to caller. ! 469: pop bp / ! 470: ret / ! 471: ! 472: 0: mov sp, bp ! 473: pop bp ! 474: jmp nonedev_ ! 475: ! 476: //////// ! 477: / ! 478: / ld_power( dev ) - Powerfail Routine. ! 479: / dev_t dev; ! 480: / ! 481: //////// ! 482: ! 483: ld_power_: / PARAMETERS MUST REMAIN AT 4(BP). ! 484: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 485: mov bp, sp / ! 486: / ! 487: sub bx, bx / Calculate major device number * 2. ! 488: movb bl, 5(bp) / ! 489: shl bx, $1 / ! 490: / ! 491: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 492: jcxz 0f / ! 493: push cx / ! 494: push $DRV_J / Loadable driver invocation offset. ! 495: / ! 496: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 497: or bx, bx / ! 498: je 0f / ! 499: / ! 500: mov ax, C_POWER(bx) / Identify driver function to be invoked. ! 501: or ax, ax / ! 502: je 0f / ! 503: / ! 504: xcall -4(bp) / Invoke driver interface, which will ! 505: / in turn invoke driver function. ! 506: / ! 507: mov sp, bp / Return to caller. ! 508: pop bp / ! 509: ret / ! 510: ! 511: 0: mov sp, bp ! 512: pop bp ! 513: jmp nonedev_ ! 514: ! 515: //////// ! 516: / ! 517: / ld_time( dev ) - Timer Routine. ! 518: / dev_t dev; ! 519: / ! 520: //////// ! 521: ! 522: ld_time_: / PARAMETERS MUST REMAIN AT 4(BP). ! 523: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 524: mov bp, sp / ! 525: / ! 526: sub bx, bx / Calculate major device number * 2. ! 527: movb bl, 5(bp) / ! 528: shl bx, $1 / ! 529: / ! 530: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 531: jcxz 0f / ! 532: push cx / ! 533: push $DRV_J / Loadable driver invocation offset. ! 534: / ! 535: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 536: or bx, bx / ! 537: je 0f / ! 538: / ! 539: mov ax, C_TIMER(bx) / Identify driver function to be invoked. ! 540: or ax, ax / ! 541: je 0f / ! 542: / ! 543: xcall -4(bp) / Invoke driver interface, which will ! 544: / in turn invoke driver function. ! 545: / ! 546: mov sp, bp / Return to caller. ! 547: pop bp / ! 548: ret / ! 549: ! 550: 0: mov sp, bp ! 551: pop bp ! 552: jmp nonedev_ ! 553: ! 554: //////// ! 555: / ! 556: / ld_poll( dev, ev, msec ) - Poll Routine. ! 557: / dev_t dev; ! 558: / int ev; ! 559: / int msec; ! 560: / ! 561: //////// ! 562: ! 563: ld_poll_: / PARAMETERS MUST REMAIN AT 4(BP). ! 564: push bp / DRIVER RESIDENT CODE RELIES ON THIS. ! 565: mov bp, sp / ! 566: / ! 567: sub bx, bx / Calculate major device number * 2. ! 568: movb bl, 5(bp) / ! 569: shl bx, $1 / ! 570: / ! 571: mov cx, ldrvsel_(bx)/ Prepare driver interface CS:IP. ! 572: jcxz 0f / ! 573: push cx / ! 574: push $DRV_J / Loadable driver invocation offset. ! 575: / ! 576: mov bx, ldrvcon_(bx)/ Identify driver configuration. ! 577: or bx, bx / ! 578: je 0f / ! 579: / ! 580: mov ax, C_POLL(bx) / Identify driver function to be invoked. ! 581: or ax, ax / ! 582: je 0f / ! 583: / ! 584: xcall -4(bp) / Invoke driver interface, which will ! 585: / in turn invoke driver function. ! 586: / ! 587: mov sp, bp / Return to caller. ! 588: pop bp / ! 589: ret / ! 590: ! 591: 0: mov sp, bp ! 592: pop bp ! 593: jmp nonedev_ ! 594: ! 595: //////// ! 596: / ! 597: / Loadable Driver Interrupt Entry Points. ! 598: / ! 599: / Invoked by Coherent to service specific interrupt. ! 600: / Identifies which loadable driver interrupt vector to be used. ! 601: / Invokes interrupt handler which will do far call to loadable driver. ! 602: / ! 603: //////// ! 604: ! 605: ld_intr0: ! 606: mov bx, $0 / ! 607: jmp ld_intr / ! 608: ! 609: ld_intr1: ! 610: mov bx, $2 / ! 611: jmp ld_intr / ! 612: ! 613: ld_intr2: ! 614: mov bx, $4 / ! 615: jmp ld_intr / ! 616: ! 617: ld_intr3: ! 618: mov bx, $6 / ! 619: jmp ld_intr / ! 620: ! 621: ld_intr4: ! 622: mov bx, $8 / ! 623: jmp ld_intr / ! 624: ! 625: ld_intr5: ! 626: mov bx, $10 / ! 627: jmp ld_intr / ! 628: ! 629: ld_intr6: ! 630: mov bx, $12 / ! 631: jmp ld_intr / ! 632: ! 633: ld_intr7: ! 634: mov bx, $14 / ! 635: jmp ld_intr / ! 636: ! 637: ld_intr8: ! 638: mov bx, $16 / ! 639: jmp ld_intr / ! 640: ! 641: ld_intr9: ! 642: mov bx, $18 / ! 643: jmp ld_intr / ! 644: ! 645: ld_intr10: ! 646: mov bx, $20 / ! 647: jmp ld_intr / ! 648: ! 649: ld_intr11: ! 650: mov bx, $22 / ! 651: jmp ld_intr / ! 652: ! 653: ld_intr12: ! 654: mov bx, $24 / ! 655: jmp ld_intr / ! 656: ! 657: ld_intr13: ! 658: mov bx, $26 / ! 659: jmp ld_intr / ! 660: ! 661: ld_intr14: ! 662: mov bx, $28 / ! 663: jmp ld_intr / ! 664: ! 665: ld_intr15: ! 666: mov bx, $30 / ! 667: jmp ld_intr / ! 668: ! 669: //////// ! 670: / ! 671: / Loadable driver interrupt handler. ! 672: / ! 673: / ! 674: / Input: bx = interrupt number * 2. ! 675: / ! 676: //////// ! 677: ! 678: ld_intr: ! 679: push bp / ! 680: mov bp, sp / ! 681: / ! 682: mov cx,ldrvics_(bx) / Prepare driver interface CS:IP. ! 683: jcxz 0f / ! 684: push cx / ! 685: push $DRV_J / Loadable driver invocation offset. ! 686: / ! 687: mov ax,ldrvipc_(bx) / Identify interrupt handler to be invoked. ! 688: or ax, ax / ! 689: je 0f / ! 690: / ! 691: xcall -4(bp) / Invoke driver interface, which will ! 692: / in turn invoke driver function. ! 693: / ! 694: 0: mov sp, bp / ! 695: pop bp / ! 696: ret /
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.