|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1992 NeXT Computer, Inc. ! 27: * ! 28: * Locore module for NEXTSTEP/Intel Kernel. ! 29: * ! 30: * HISTORY ! 31: * ! 32: * 17 July 1994 ? at NeXT ! 33: * Major mods for user state save optimizations. ! 34: * 29 August 1992 ? at NeXT ! 35: * Created. ! 36: */ ! 37: ! 38: #import <architecture/i386/asm_help.h> ! 39: ! 40: #import <assym.h> ! 41: ! 42: TEXT ! 43: ! 44: #define EXCEPTION(name, number) \ ! 45: LEAF(_##name, 0) ; \ ! 46: pushl $0x00 ; \ ! 47: pushl $##number ; \ ! 48: jmp trap_handler ! 49: ! 50: #define EXCEPTERR(name, number) \ ! 51: LEAF(_##name, 0) ; \ ! 52: pushl $##number ; \ ! 53: jmp trap_handler ! 54: ! 55: #define INTERRUPT(name, number) \ ! 56: LEAF(_##name, 0) ; \ ! 57: pushl $0x00 ; \ ! 58: pushl $##number ; \ ! 59: jmp interrupt ! 60: ! 61: #define RETURN \ ! 62: popl %gs ; \ ! 63: popl %fs ; \ ! 64: popl %es ; \ ! 65: popl %ds ; \ ! 66: popa ; \ ! 67: addl $8, %esp ; \ ! 68: iret ! 69: ! 70: EXCEPTION(trp_divr,0x00) ! 71: EXCEPTION(trp_debg,0x01) ! 72: EXCEPTION(int__nmi,0x02) ! 73: EXCEPTION(trp_brpt,0x03) ! 74: EXCEPTION(trp_over,0x04) ! 75: EXCEPTION(flt_bnds,0x05) ! 76: EXCEPTION(flt_opcd,0x06) ! 77: EXCEPTION(flt_ncpr,0x07) ! 78: EXCEPTERR(abt_dblf,0x08) ! 79: EXCEPTION(abt_over,0x09) ! 80: EXCEPTERR(flt_btss,0x0A) ! 81: EXCEPTERR(flt_bseg,0x0B) ! 82: EXCEPTERR(flt_bstk,0x0C) ! 83: EXCEPTERR(flt_prot,0x0D) ! 84: EXCEPTERR(flt_page,0x0E) ! 85: EXCEPTION(trp_0x0F,0x0F) ! 86: EXCEPTION(flt_bcpr,0x10) ! 87: EXCEPTION(trp_0x11,0x11) ! 88: EXCEPTION(trp_0x12,0x12) ! 89: EXCEPTION(trp_0x13,0x13) ! 90: EXCEPTION(trp_0x14,0x14) ! 91: EXCEPTION(trp_0x15,0x15) ! 92: EXCEPTION(trp_0x16,0x16) ! 93: EXCEPTION(trp_0x17,0x17) ! 94: EXCEPTION(trp_0x18,0x18) ! 95: EXCEPTION(trp_0x19,0x19) ! 96: EXCEPTION(trp_0x1A,0x1A) ! 97: EXCEPTION(trp_0x1B,0x1B) ! 98: EXCEPTION(trp_0x1C,0x1C) ! 99: EXCEPTION(trp_0x1D,0x1D) ! 100: EXCEPTION(trp_0x1E,0x1E) ! 101: EXCEPTION(trp_0x1F,0x1F) ! 102: EXCEPTION(trp_0x20,0x20) ! 103: EXCEPTION(trp_0x21,0x21) ! 104: EXCEPTION(trp_0x22,0x22) ! 105: EXCEPTION(trp_0x23,0x23) ! 106: EXCEPTION(trp_0x24,0x24) ! 107: EXCEPTION(trp_0x25,0x25) ! 108: EXCEPTION(trp_0x26,0x26) ! 109: EXCEPTION(trp_0x27,0x27) ! 110: EXCEPTION(trp_0x28,0x28) ! 111: EXCEPTION(trp_0x29,0x29) ! 112: EXCEPTION(trp_0x2A,0x2A) ! 113: EXCEPTION(trp_0x2B,0x2B) ! 114: EXCEPTION(trp_0x2C,0x2C) ! 115: EXCEPTION(trp_0x2D,0x2D) ! 116: EXCEPTION(trp_0x2E,0x2E) ! 117: EXCEPTION(trp_0x2F,0x2F) ! 118: EXCEPTION(trp_0x30,0x30) ! 119: EXCEPTION(trp_0x31,0x31) ! 120: EXCEPTION(trp_0x32,0x32) ! 121: EXCEPTION(trp_0x33,0x33) ! 122: EXCEPTION(trp_0x34,0x34) ! 123: EXCEPTION(trp_0x35,0x35) ! 124: EXCEPTION(trp_0x36,0x36) ! 125: EXCEPTION(trp_0x37,0x37) ! 126: EXCEPTION(trp_0x38,0x38) ! 127: EXCEPTION(trp_0x39,0x39) ! 128: EXCEPTION(trp_0x3A,0x3A) ! 129: EXCEPTION(trp_0x3B,0x3B) ! 130: EXCEPTION(trp_0x3C,0x3C) ! 131: EXCEPTION(trp_0x3D,0x3D) ! 132: EXCEPTION(trp_0x3E,0x3E) ! 133: EXCEPTION(trp_0x3F,0x3F) ! 134: // ! 135: INTERRUPT(int_0x40,0x40) ! 136: INTERRUPT(int_0x41,0x41) ! 137: INTERRUPT(int_0x42,0x42) ! 138: INTERRUPT(int_0x43,0x43) ! 139: INTERRUPT(int_0x44,0x44) ! 140: INTERRUPT(int_0x45,0x45) ! 141: INTERRUPT(int_0x46,0x46) ! 142: INTERRUPT(int_0x47,0x47) ! 143: INTERRUPT(int_0x48,0x48) ! 144: INTERRUPT(int_0x49,0x49) ! 145: INTERRUPT(int_0x4A,0x4A) ! 146: INTERRUPT(int_0x4B,0x4B) ! 147: INTERRUPT(int_0x4C,0x4C) ! 148: INTERRUPT(int_0x4D,0x4D) ! 149: INTERRUPT(int_0x4E,0x4E) ! 150: INTERRUPT(int_0x4F,0x4F) ! 151: INTERRUPT(int_0x50,0x50) ! 152: INTERRUPT(int_0x51,0x51) ! 153: INTERRUPT(int_0x52,0x52) ! 154: INTERRUPT(int_0x53,0x53) ! 155: INTERRUPT(int_0x54,0x54) ! 156: INTERRUPT(int_0x55,0x55) ! 157: INTERRUPT(int_0x56,0x56) ! 158: INTERRUPT(int_0x57,0x57) ! 159: INTERRUPT(int_0x58,0x58) ! 160: INTERRUPT(int_0x59,0x59) ! 161: INTERRUPT(int_0x5A,0x5A) ! 162: INTERRUPT(int_0x5B,0x5B) ! 163: INTERRUPT(int_0x5C,0x5C) ! 164: INTERRUPT(int_0x5D,0x5D) ! 165: INTERRUPT(int_0x5E,0x5E) ! 166: INTERRUPT(int_0x5F,0x5F) ! 167: INTERRUPT(int_0x60,0x60) ! 168: INTERRUPT(int_0x61,0x61) ! 169: INTERRUPT(int_0x62,0x62) ! 170: INTERRUPT(int_0x63,0x63) ! 171: INTERRUPT(int_0x64,0x64) ! 172: INTERRUPT(int_0x65,0x65) ! 173: INTERRUPT(int_0x66,0x66) ! 174: INTERRUPT(int_0x67,0x67) ! 175: INTERRUPT(int_0x68,0x68) ! 176: INTERRUPT(int_0x69,0x69) ! 177: INTERRUPT(int_0x6A,0x6A) ! 178: INTERRUPT(int_0x6B,0x6B) ! 179: INTERRUPT(int_0x6C,0x6C) ! 180: INTERRUPT(int_0x6D,0x6D) ! 181: INTERRUPT(int_0x6E,0x6E) ! 182: INTERRUPT(int_0x6F,0x6F) ! 183: INTERRUPT(int_0x70,0x70) ! 184: INTERRUPT(int_0x71,0x71) ! 185: INTERRUPT(int_0x72,0x72) ! 186: INTERRUPT(int_0x73,0x73) ! 187: INTERRUPT(int_0x74,0x74) ! 188: INTERRUPT(int_0x75,0x75) ! 189: INTERRUPT(int_0x76,0x76) ! 190: INTERRUPT(int_0x77,0x77) ! 191: INTERRUPT(int_0x78,0x78) ! 192: INTERRUPT(int_0x79,0x79) ! 193: INTERRUPT(int_0x7A,0x7A) ! 194: INTERRUPT(int_0x7B,0x7B) ! 195: INTERRUPT(int_0x7C,0x7C) ! 196: INTERRUPT(int_0x7D,0x7D) ! 197: INTERRUPT(int_0x7E,0x7E) ! 198: INTERRUPT(int_0x7F,0x7F) ! 199: INTERRUPT(int_0x80,0x80) ! 200: INTERRUPT(int_0x81,0x81) ! 201: INTERRUPT(int_0x82,0x82) ! 202: INTERRUPT(int_0x83,0x83) ! 203: INTERRUPT(int_0x84,0x84) ! 204: INTERRUPT(int_0x85,0x85) ! 205: INTERRUPT(int_0x86,0x86) ! 206: INTERRUPT(int_0x87,0x87) ! 207: INTERRUPT(int_0x88,0x88) ! 208: INTERRUPT(int_0x89,0x89) ! 209: INTERRUPT(int_0x8A,0x8A) ! 210: INTERRUPT(int_0x8B,0x8B) ! 211: INTERRUPT(int_0x8C,0x8C) ! 212: INTERRUPT(int_0x8D,0x8D) ! 213: INTERRUPT(int_0x8E,0x8E) ! 214: INTERRUPT(int_0x8F,0x8F) ! 215: INTERRUPT(int_0x90,0x90) ! 216: INTERRUPT(int_0x91,0x91) ! 217: INTERRUPT(int_0x92,0x92) ! 218: INTERRUPT(int_0x93,0x93) ! 219: INTERRUPT(int_0x94,0x94) ! 220: INTERRUPT(int_0x95,0x95) ! 221: INTERRUPT(int_0x96,0x96) ! 222: INTERRUPT(int_0x97,0x97) ! 223: INTERRUPT(int_0x98,0x98) ! 224: INTERRUPT(int_0x99,0x99) ! 225: INTERRUPT(int_0x9A,0x9A) ! 226: INTERRUPT(int_0x9B,0x9B) ! 227: INTERRUPT(int_0x9C,0x9C) ! 228: INTERRUPT(int_0x9D,0x9D) ! 229: INTERRUPT(int_0x9E,0x9E) ! 230: INTERRUPT(int_0x9F,0x9F) ! 231: INTERRUPT(int_0xA0,0xA0) ! 232: INTERRUPT(int_0xA1,0xA1) ! 233: INTERRUPT(int_0xA2,0xA2) ! 234: INTERRUPT(int_0xA3,0xA3) ! 235: INTERRUPT(int_0xA4,0xA4) ! 236: INTERRUPT(int_0xA5,0xA5) ! 237: INTERRUPT(int_0xA6,0xA6) ! 238: INTERRUPT(int_0xA7,0xA7) ! 239: INTERRUPT(int_0xA8,0xA8) ! 240: INTERRUPT(int_0xA9,0xA9) ! 241: INTERRUPT(int_0xAA,0xAA) ! 242: INTERRUPT(int_0xAB,0xAB) ! 243: INTERRUPT(int_0xAC,0xAC) ! 244: INTERRUPT(int_0xAD,0xAD) ! 245: INTERRUPT(int_0xAE,0xAE) ! 246: INTERRUPT(int_0xAF,0xAF) ! 247: INTERRUPT(int_0xB0,0xB0) ! 248: INTERRUPT(int_0xB1,0xB1) ! 249: INTERRUPT(int_0xB2,0xB2) ! 250: INTERRUPT(int_0xB3,0xB3) ! 251: INTERRUPT(int_0xB4,0xB4) ! 252: INTERRUPT(int_0xB5,0xB5) ! 253: INTERRUPT(int_0xB6,0xB6) ! 254: INTERRUPT(int_0xB7,0xB7) ! 255: INTERRUPT(int_0xB8,0xB8) ! 256: INTERRUPT(int_0xB9,0xB9) ! 257: INTERRUPT(int_0xBA,0xBA) ! 258: INTERRUPT(int_0xBB,0xBB) ! 259: INTERRUPT(int_0xBC,0xBC) ! 260: INTERRUPT(int_0xBD,0xBD) ! 261: INTERRUPT(int_0xBE,0xBE) ! 262: INTERRUPT(int_0xBF,0xBF) ! 263: INTERRUPT(int_0xC0,0xC0) ! 264: INTERRUPT(int_0xC1,0xC1) ! 265: INTERRUPT(int_0xC2,0xC2) ! 266: INTERRUPT(int_0xC3,0xC3) ! 267: INTERRUPT(int_0xC4,0xC4) ! 268: INTERRUPT(int_0xC5,0xC5) ! 269: INTERRUPT(int_0xC6,0xC6) ! 270: INTERRUPT(int_0xC7,0xC7) ! 271: INTERRUPT(int_0xC8,0xC8) ! 272: INTERRUPT(int_0xC9,0xC9) ! 273: INTERRUPT(int_0xCA,0xCA) ! 274: INTERRUPT(int_0xCB,0xCB) ! 275: INTERRUPT(int_0xCC,0xCC) ! 276: INTERRUPT(int_0xCD,0xCD) ! 277: INTERRUPT(int_0xCE,0xCE) ! 278: INTERRUPT(int_0xCF,0xCF) ! 279: INTERRUPT(int_0xD0,0xD0) ! 280: INTERRUPT(int_0xD1,0xD1) ! 281: INTERRUPT(int_0xD2,0xD2) ! 282: INTERRUPT(int_0xD3,0xD3) ! 283: INTERRUPT(int_0xD4,0xD4) ! 284: INTERRUPT(int_0xD5,0xD5) ! 285: INTERRUPT(int_0xD6,0xD6) ! 286: INTERRUPT(int_0xD7,0xD7) ! 287: INTERRUPT(int_0xD8,0xD8) ! 288: INTERRUPT(int_0xD9,0xD9) ! 289: INTERRUPT(int_0xDA,0xDA) ! 290: INTERRUPT(int_0xDB,0xDB) ! 291: INTERRUPT(int_0xDC,0xDC) ! 292: INTERRUPT(int_0xDD,0xDD) ! 293: INTERRUPT(int_0xDE,0xDE) ! 294: INTERRUPT(int_0xDF,0xDF) ! 295: INTERRUPT(int_0xE0,0xE0) ! 296: INTERRUPT(int_0xE1,0xE1) ! 297: INTERRUPT(int_0xE2,0xE2) ! 298: INTERRUPT(int_0xE3,0xE3) ! 299: INTERRUPT(int_0xE4,0xE4) ! 300: INTERRUPT(int_0xE5,0xE5) ! 301: INTERRUPT(int_0xE6,0xE6) ! 302: INTERRUPT(int_0xE7,0xE7) ! 303: INTERRUPT(int_0xE8,0xE8) ! 304: INTERRUPT(int_0xE9,0xE9) ! 305: INTERRUPT(int_0xEA,0xEA) ! 306: INTERRUPT(int_0xEB,0xEB) ! 307: INTERRUPT(int_0xEC,0xEC) ! 308: INTERRUPT(int_0xED,0xED) ! 309: INTERRUPT(int_0xEE,0xEE) ! 310: INTERRUPT(int_0xEF,0xEF) ! 311: INTERRUPT(int_0xF0,0xF0) ! 312: INTERRUPT(int_0xF1,0xF1) ! 313: INTERRUPT(int_0xF2,0xF2) ! 314: INTERRUPT(int_0xF3,0xF3) ! 315: INTERRUPT(int_0xF4,0xF4) ! 316: INTERRUPT(int_0xF5,0xF5) ! 317: INTERRUPT(int_0xF6,0xF6) ! 318: INTERRUPT(int_0xF7,0xF7) ! 319: INTERRUPT(int_0xF8,0xF8) ! 320: INTERRUPT(int_0xF9,0xF9) ! 321: INTERRUPT(int_0xFA,0xFA) ! 322: INTERRUPT(int_0xFB,0xFB) ! 323: INTERRUPT(int_0xFC,0xFC) ! 324: INTERRUPT(int_0xFD,0xFD) ! 325: INTERRUPT(int_0xFE,0xFE) ! 326: INTERRUPT(int_0xFF,0xFF) ! 327: ! 328: ALIGN ! 329: trap_handler: ! 330: // save general registers ! 331: pusha ! 332: ! 333: // save segment registers ! 334: pushl %ds ! 335: pushl %es ! 336: pushl %fs ! 337: pushl %gs ! 338: ! 339: // reinitialize segment registers ! 340: movw $ KDSSEL,%ax ! 341: movw %ax,%ds ! 342: movw %ax,%es ! 343: movw $ LDATASEL,%ax ! 344: movw %ax,%fs ! 345: movw $ NULLSEL,%ax ! 346: movw %ax,%gs ! 347: ! 348: // clear direction flag ! 349: cld ! 350: ! 351: // set frame pointer ! 352: lea EBP(%esp),%ebp ! 353: ! 354: // is our stack the save area? ! 355: movl _empty_stacks,%esi ! 356: movl %esp,%ebx ! 357: andl %esi,%esi ! 358: je 0f ! 359: // yes, switch to kernel stack ! 360: // need to do this atomically ! 361: cli ! 362: movl _stack_pointers,%esp ! 363: movl $0,_empty_stacks ! 364: sti ! 365: 0: ! 366: // ptr to saved state ! 367: pushl %ebx ! 368: ! 369: call _catch_trap ! 370: // user mode trap never returns ! 371: // kernel mode trap always returns ! 372: ! 373: // restore old stack pointer ! 374: // and old value of _empty_stacks ! 375: // need to do this atomically ! 376: cli ! 377: movl %ebx,%esp ! 378: movl %esi,_empty_stacks ! 379: sti ! 380: ! 381: RETURN ! 382: ! 383: ALIGN ! 384: interrupt: ! 385: // save general registers ! 386: pusha ! 387: ! 388: // save segment registers ! 389: pushl %ds ! 390: pushl %es ! 391: pushl %fs ! 392: pushl %gs ! 393: ! 394: // reinitialize segment registers ! 395: movw $ KDSSEL,%ax ! 396: movw %ax,%ds ! 397: movw %ax,%es ! 398: movw $ LDATASEL,%ax ! 399: movw %ax,%fs ! 400: movw $ NULLSEL,%ax ! 401: movw %ax,%gs ! 402: ! 403: // clear direction flag ! 404: cld ! 405: ! 406: // set frame pointer ! 407: lea EBP(%esp),%ebp ! 408: ! 409: // is our stack the save area? ! 410: movl _empty_stacks,%esi ! 411: movl %esp,%ebx ! 412: andl %esi,%esi ! 413: je 0f ! 414: // yes, switch to kernel stack ! 415: // interrupts are already disabled ! 416: movl _stack_pointers,%esp ! 417: movl $0,_empty_stacks ! 418: 0: ! 419: // ptr to saved state ! 420: pushl %ebx ! 421: ! 422: call _catch_interrupt ! 423: // user mode interrupt may not return ! 424: // kernel mode interrupt always returns ! 425: ! 426: // restore old stack pointer ! 427: movl %ebx,%esp ! 428: ! 429: // restore old value of _empty_stacks ! 430: movl %esi,_empty_stacks ! 431: ! 432: RETURN ! 433: ! 434: LEAF(_machdep_call_, 0) ! 435: // save eflags ! 436: pushf ! 437: ! 438: // dummy trapno ! 439: pushl $0 ! 440: ! 441: // save general registers ! 442: pusha ! 443: ! 444: // save segment registers ! 445: pushl %ds ! 446: pushl %es ! 447: pushl %fs ! 448: pushl %gs ! 449: ! 450: // copy eflags to correct offset ! 451: movl ERR(%esp),%eax ! 452: movl %eax,EFL(%esp) ! 453: ! 454: // reinitialize segment registers ! 455: movw $ KDSSEL,%ax ! 456: movw %ax,%ds ! 457: movw %ax,%es ! 458: movw $ LDATASEL,%ax ! 459: movw %ax,%fs ! 460: movw $ NULLSEL,%ax ! 461: movw %ax,%gs ! 462: ! 463: // clear direction flag ! 464: cld ! 465: ! 466: // set frame pointer ! 467: lea EBP(%esp),%ebp ! 468: ! 469: // is our stack the save area? ! 470: movl _empty_stacks,%esi ! 471: movl %esp,%ebx ! 472: andl %esi,%esi ! 473: je 0f ! 474: // yes, switch to kernel stack ! 475: // need to do this atomically ! 476: cli ! 477: movl _stack_pointers,%esp ! 478: movl $0,_empty_stacks ! 479: sti ! 480: 0: ! 481: // ptr to saved state ! 482: pushl %ebx ! 483: ! 484: call _machdep_call ! 485: // call from user mode never returns ! 486: // call from kernel mode always returns (error) ! 487: ! 488: movl %ebx,%esp ! 489: ! 490: RETURN ! 491: ! 492: LEAF(_mach_kernel_trap_, 0) ! 493: // save eflags ! 494: pushf ! 495: ! 496: // dummy trapno ! 497: pushl $0 ! 498: ! 499: // save general registers ! 500: pusha ! 501: ! 502: // save segment registers ! 503: pushl %ds ! 504: pushl %es ! 505: pushl %fs ! 506: pushl %gs ! 507: ! 508: // copy eflags to correct offset ! 509: movl ERR(%esp),%eax ! 510: movl %eax,EFL(%esp) ! 511: ! 512: // reinitialize segment registers ! 513: movw $ KDSSEL,%ax ! 514: movw %ax,%ds ! 515: movw %ax,%es ! 516: movw $ LDATASEL,%ax ! 517: movw %ax,%fs ! 518: movw $ NULLSEL,%ax ! 519: movw %ax,%gs ! 520: ! 521: // clear direction flag ! 522: cld ! 523: ! 524: // set frame pointer ! 525: lea EBP(%esp),%ebp ! 526: ! 527: // is our stack the save area? ! 528: movl _empty_stacks,%esi ! 529: movl %esp,%ebx ! 530: andl %esi,%esi ! 531: je 0f ! 532: // yes, switch to kernel stack ! 533: // need to do this atomically ! 534: cli ! 535: movl _stack_pointers,%esp ! 536: movl $0,_empty_stacks ! 537: sti ! 538: 0: ! 539: // ptr to saved state ! 540: pushl %ebx ! 541: ! 542: call _mach_kernel_trap ! 543: // call from user mode never returns ! 544: // call from kernel mode always returns (error) ! 545: ! 546: movl %ebx,%esp ! 547: ! 548: RETURN ! 549: ! 550: LEAF(_unix_syscall_, 0) ! 551: // save eflags ! 552: pushf ! 553: ! 554: // dummy trapno ! 555: pushl $0 ! 556: ! 557: // save general registers ! 558: pusha ! 559: ! 560: // save segment registers ! 561: pushl %ds ! 562: pushl %es ! 563: pushl %fs ! 564: pushl %gs ! 565: ! 566: // copy eflags to correct offset ! 567: movl ERR(%esp),%eax ! 568: movl %eax,EFL(%esp) ! 569: ! 570: // reinitialize segment registers ! 571: movw $ KDSSEL,%ax ! 572: movw %ax,%ds ! 573: movw %ax,%es ! 574: movw $ LDATASEL,%ax ! 575: movw %ax,%fs ! 576: movw $ NULLSEL,%ax ! 577: movw %ax,%gs ! 578: ! 579: // clear direction flag ! 580: cld ! 581: ! 582: // set frame pointer ! 583: lea EBP(%esp),%ebp ! 584: ! 585: // is our stack the save area? ! 586: movl _empty_stacks,%esi ! 587: movl %esp,%ebx ! 588: andl %esi,%esi ! 589: je 0f ! 590: // yes, switch to kernel stack ! 591: // need to do this atomically ! 592: cli ! 593: movl _stack_pointers,%esp ! 594: movl $0,_empty_stacks ! 595: sti ! 596: 0: ! 597: // ptr to saved state ! 598: pushl %ebx ! 599: ! 600: call _unix_syscall ! 601: // call from user mode never returns ! 602: // call from kernel mode always returns (error) ! 603: ! 604: movl %ebx,%esp ! 605: ! 606: RETURN ! 607: ! 608: LEAF(_dbf_handler_, 0) ! 609: 0: call _dbf_handler ! 610: jmp 0b ! 611: ! 612: /* ! 613: * Return directly to ! 614: * a *user* context ! 615: * using a specific return ! 616: * frame. Typically, the ! 617: * frame is in the thread ! 618: * save area, but it can ! 619: * also be somewhere on the ! 620: * kernel stack. N.B. If the ! 621: * resumed context is executing ! 622: * in kernel mode, the system ! 623: * will crash and burn. ! 624: */ ! 625: LEAF(__return_with_state, 0) ! 626: // discard return address ! 627: popl %eax ! 628: ! 629: // retrieve state ptr ! 630: popl %ebx ! 631: ! 632: // switch stack back to save area ! 633: // need to do this atomically ! 634: cli ! 635: movl %ebx,%esp ! 636: movl $1,_empty_stacks ! 637: sti ! 638: ! 639: RETURN ! 640: ! 641: /* ! 642: * Perform a coroutine ! 643: * switch between threads. ! 644: */ ! 645: LEAF(__switch_tss, 0) ! 646: movl 4(%esp),%eax ! 647: andl %eax,%eax ! 648: je 0f ! 649: movl %edi,0x44(%eax) ! 650: movl %esi,0x40(%eax) ! 651: movl %ebx,0x34(%eax) ! 652: movl %ebp,0x3c(%eax) ! 653: popl %edx ! 654: movl %edx,0x20(%eax) ! 655: movl %esp,0x38(%eax) ! 656: ! 657: movl 4(%esp),%edx ! 658: movl 0x44(%edx),%edi ! 659: movl 0x40(%edx),%esi ! 660: movl 0x34(%edx),%ebx ! 661: movl 0x3c(%edx),%ebp ! 662: movl 8(%esp),%eax ! 663: movl 0x38(%edx),%esp ! 664: movl 0x20(%edx),%edx ! 665: jmp *%edx ! 666: ! 667: 0: ! 668: popl %edx ! 669: ! 670: movl 4(%esp),%edx ! 671: movl 0x44(%edx),%edi ! 672: movl 0x40(%edx),%esi ! 673: movl 0x34(%edx),%ebx ! 674: movl 0x3c(%edx),%ebp ! 675: movl 8(%esp),%eax ! 676: movl 0x38(%edx),%esp ! 677: movl 0x20(%edx),%edx ! 678: jmp *%edx ! 679: ! 680: LEAF(__stack_attach, 0) ! 681: pushl %eax ! 682: call *%ebx ! 683: 0: hlt ! 684: jmp 0b ! 685: ! 686: LEAF(__call_with_stack, 0) ! 687: movl 4(%esp),%eax ! 688: movl 8(%esp),%esp ! 689: movl %esp,%ebp ! 690: call *%eax ! 691: 0: hlt ! 692: jmp 0b ! 693: ! 694: #ifdef GPROF ! 695: LEAF(mcount, 0) ! 696: movl 0(%esp),%eax // fetch self address ! 697: pushl %eax ! 698: movl 4(%ebp),%eax // fetch parent address ! 699: pushl %eax ! 700: pushf ! 701: popl %eax ! 702: andl $0x200,%eax ! 703: je 0f ! 704: cli ! 705: call _mcount ! 706: sti ! 707: addl $8,%esp ! 708: ret ! 709: ! 710: 0: call _mcount ! 711: addl $8,%esp ! 712: ret ! 713: #endif GPROF ! 714: ! 715: #define O_EDI 0 ! 716: #define O_ESI 4 ! 717: #define O_EBX 8 ! 718: #define O_EBP 12 ! 719: #define O_ESP 16 ! 720: #define O_EIP 20 ! 721: #define O_IPL 24 ! 722: ! 723: LEAF(_setjmp, 0) ! 724: X_LEAF(_set_label, _setjmp) ! 725: call _curipl ! 726: movl 4(%esp),%edx // address of save area ! 727: movl %eax,O_IPL(%edx) // save ipl level for longjmp ! 728: movl %edi,O_EDI(%edx) ! 729: movl %esi,O_ESI(%edx) ! 730: movl %ebx,O_EBX(%edx) ! 731: movl %ebp,O_EBP(%edx) ! 732: movl %esp,O_ESP(%edx) ! 733: movl 0(%esp),%eax // %eip (return address) ! 734: movl %eax,O_EIP(%edx) ! 735: xorl %eax,%eax // retval <- 0 ! 736: ret ! 737: ! 738: LEAF(_longjmp, 0) ! 739: X_LEAF(_jump_label, _longjmp) ! 740: movl 4(%esp),%edx // address of save area ! 741: movl O_EDI(%edx),%edi ! 742: movl O_ESI(%edx),%esi ! 743: movl O_EBX(%edx),%ebx ! 744: movl O_EBP(%edx),%ebp ! 745: movl O_ESP(%edx),%esp ! 746: movl O_EIP(%edx),%eax // %eip (return address) ! 747: movl %eax,0(%esp) ! 748: pushl O_IPL(%edx) ! 749: call _splx // restore ipl level ! 750: addl $4,%esp ! 751: movl $1,%eax ! 752: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.