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