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