]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc64/l.s
pc64: fix kmap()
[plan9front.git] / sys / src / 9 / pc64 / l.s
1 #include "mem.h"
2
3 MODE $32
4
5 #define DELAY           BYTE $0xEB; BYTE $0x00  /* JMP .+2 */
6
7 #define pFARJMP32(s, o) BYTE $0xea;             /* far jump to ptr32:16 */\
8                         LONG $o; WORD $s
9
10 /*
11  * Enter here in 32-bit protected mode. Welcome to 1982.
12  * Make sure the GDT is set as it should be:
13  *      disable interrupts;
14  *      load the GDT with the table in _gdt32p;
15  *      load all the data segments
16  *      load the code segment via a far jump.
17  */
18 TEXT _protected<>(SB), 1, $-4
19         CLI
20
21         MOVL    $_gdtptr32p<>-KZERO(SB), AX
22         MOVL    (AX), GDTR
23
24         MOVL    $SELECTOR(2, SELGDT, 0), AX
25         MOVW    AX, DS
26         MOVW    AX, ES
27         MOVW    AX, FS
28         MOVW    AX, GS
29         MOVW    AX, SS
30
31         pFARJMP32(SELECTOR(3, SELGDT, 0), _warp64<>-KZERO(SB))
32
33 TEXT _gdt<>(SB), 1, $-4
34         /* null descriptor */
35         LONG    $0
36         LONG    $0
37
38         /* (KESEG) 64 bit long mode exec segment */
39         LONG    $(0xFFFF)
40         LONG    $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR)
41
42         /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */
43         LONG    $(0xFFFF)
44         LONG    $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
45
46         /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */
47         LONG    $(0xFFFF)
48         LONG    $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
49
50
51 TEXT _gdtptr32p<>(SB), 1, $-4
52         WORD    $(4*8-1)
53         LONG    $_gdt<>-KZERO(SB)
54
55 TEXT _gdtptr64p<>(SB), 1, $-4
56         WORD    $(4*8-1)
57         QUAD    $_gdt<>-KZERO(SB)
58
59 TEXT _gdtptr64v<>(SB), 1, $-4
60         WORD    $(4*8-1)
61         QUAD    $_gdt<>(SB)
62
63 /*
64  * Macros for accessing page table entries; change the
65  * C-style array-index macros into a page table byte offset
66  */
67 #define PML4O(v)        ((PTLX((v), 3))<<3)
68 #define PDPO(v)         ((PTLX((v), 2))<<3)
69 #define PDO(v)          ((PTLX((v), 1))<<3)
70 #define PTO(v)          ((PTLX((v), 0))<<3)
71
72 TEXT _warp64<>(SB), 1, $-4
73
74         /* clear mach and page tables */
75         MOVL    $((CPU0END-CPU0PML4)>>2), CX
76         MOVL    $(CPU0PML4-KZERO), SI
77         MOVL    SI, DI
78         XORL    AX, AX
79         CLD
80         REP;    STOSL
81
82         MOVL    SI, AX                          /* PML4 */
83         MOVL    AX, DX
84         ADDL    $(PTSZ|PTEWRITE|PTEVALID), DX   /* PDP at PML4 + PTSZ */
85         MOVL    DX, PML4O(0)(AX)                /* PML4E for double-map */
86         MOVL    DX, PML4O(KZERO)(AX)            /* PML4E for KZERO */
87
88         ADDL    $PTSZ, AX                       /* PDP at PML4 + PTSZ */
89         ADDL    $PTSZ, DX                       /* PD at PML4 + 2*PTSZ */
90         MOVL    DX, PDPO(0)(AX)                 /* PDPE for double-map */
91         MOVL    DX, PDPO(KZERO)(AX)             /* PDPE for KZERO */
92
93         ADDL    $PTSZ, AX                       /* PD at PML4 + 2*PTSZ */
94         MOVL    $(PTESIZE|PTEGLOBAL|PTEWRITE|PTEVALID), DX
95         MOVL    DX, PDO(0)(AX)                  /* PDE for double-map */
96
97         ADDL    $PDO(KZERO), AX
98 memloop:
99         MOVL    DX, 0(AX)
100         ADDL    $PGLSZ(1), DX
101         ADDL    $8, AX
102         CMPL    DX, $INIMAP
103         JLT     memloop
104
105 /*
106  * Enable and activate Long Mode. From the manual:
107  *      make sure Page Size Extentions are off, and Page Global
108  *      Extensions and Physical Address Extensions are on in CR4;
109  *      set Long Mode Enable in the Extended Feature Enable MSR;
110  *      set Paging Enable in CR0;
111  *      make an inter-segment jump to the Long Mode code.
112  * It's all in 32-bit mode until the jump is made.
113  */
114 TEXT _lme<>(SB), 1, $-4
115         MOVL    SI, CR3                         /* load the mmu */
116         DELAY
117
118         MOVL    CR4, AX
119         ANDL    $~0x00000010, AX                        /* Page Size */
120         ORL     $0x000000A0, AX                 /* Page Global, Phys. Address */
121         MOVL    AX, CR4
122
123         MOVL    $0xc0000080, CX                 /* Extended Feature Enable */
124         RDMSR
125         ORL     $0x00000100, AX                 /* Long Mode Enable */
126         WRMSR
127
128         MOVL    CR0, DX
129         ANDL    $~0x6000000a, DX
130         ORL     $0x80010000, DX                 /* Paging Enable, Write Protect */
131         MOVL    DX, CR0
132
133         pFARJMP32(SELECTOR(KESEG, SELGDT, 0), _identity<>-KZERO(SB))
134
135 /*
136  * Long mode. Welcome to 2003.
137  * Jump out of the identity map space;
138  * load a proper long mode GDT.
139  */
140 MODE $64
141
142 TEXT _identity<>(SB), 1, $-4
143         MOVQ    $_start64v<>(SB), AX
144         JMP*    AX
145
146 TEXT _start64v<>(SB), 1, $-4
147         MOVQ    $_gdtptr64v<>(SB), AX
148         MOVL    (AX), GDTR
149
150         XORQ    AX, AX
151         MOVW    AX, DS                          /* not used in long mode */
152         MOVW    AX, ES                          /* not used in long mode */
153         MOVW    AX, FS
154         MOVW    AX, GS
155         MOVW    AX, SS                          /* not used in long mode */
156
157         MOVW    AX, LDTR
158
159         MOVQ    $(CPU0MACH+MACHSIZE), SP
160         MOVQ    $(CPU0MACH), RMACH
161         MOVQ    AX, RUSER                       /* up = 0; */
162
163 _clearbss:
164         MOVQ    $edata(SB), DI
165         MOVQ    $end(SB), CX
166         SUBQ    DI, CX                          /* end-edata bytes */
167         SHRQ    $2, CX                          /* end-edata doublewords */
168
169         CLD
170         REP;    STOSL                           /* clear BSS */
171
172         PUSHQ   AX                              /* clear flags */
173         POPFQ
174
175         CALL    main(SB)
176
177 /*
178  * The CPUID instruction is always supported on the amd64.
179  */
180 TEXT cpuid(SB), $-4
181         MOVL    RARG, AX                        /* function in AX */
182         CPUID
183
184         MOVQ    info+8(FP), BP
185         MOVL    AX, 0(BP)
186         MOVL    BX, 4(BP)
187         MOVL    CX, 8(BP)
188         MOVL    DX, 12(BP)
189         RET
190
191 /*
192  * Port I/O.
193  */
194 TEXT inb(SB), 1, $-4
195         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
196         XORL    AX, AX
197         INB
198         RET
199
200 TEXT insb(SB), 1, $-4
201         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
202         MOVQ    address+8(FP), DI
203         MOVL    count+16(FP), CX
204         CLD
205         REP;    INSB
206         RET
207
208 TEXT ins(SB), 1, $-4
209         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
210         XORL    AX, AX
211         INW
212         RET
213
214 TEXT inss(SB), 1, $-4
215         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
216         MOVQ    address+8(FP), DI
217         MOVL    count+16(FP), CX
218         CLD
219         REP;    INSW
220         RET
221
222 TEXT inl(SB), 1, $-4
223         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
224         INL
225         RET
226
227 TEXT insl(SB), 1, $-4
228         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
229         MOVQ    address+8(FP), DI
230         MOVL    count+16(FP), CX
231         CLD
232         REP; INSL
233         RET
234
235 TEXT outb(SB), 1, $-1
236         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
237         MOVL    byte+8(FP), AX
238         OUTB
239         RET
240
241 TEXT outsb(SB), 1, $-4
242         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
243         MOVQ    address+8(FP), SI
244         MOVL    count+16(FP), CX
245         CLD
246         REP; OUTSB
247         RET
248
249 TEXT outs(SB), 1, $-4
250         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
251         MOVL    short+8(FP), AX
252         OUTW
253         RET
254
255 TEXT outss(SB), 1, $-4
256         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
257         MOVQ    address+8(FP), SI
258         MOVL    count+16(FP), CX
259         CLD
260         REP; OUTSW
261         RET
262
263 TEXT outl(SB), 1, $-4
264         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
265         MOVL    long+8(FP), AX
266         OUTL
267         RET
268
269 TEXT outsl(SB), 1, $-4
270         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
271         MOVQ    address+8(FP), SI
272         MOVL    count+16(FP), CX
273         CLD
274         REP; OUTSL
275         RET
276
277 TEXT getgdt(SB), 1, $-4
278         MOVQ    RARG, AX
279         MOVL    GDTR, (AX)                      /* Note: 10 bytes returned */
280         RET
281
282 TEXT lgdt(SB), $0                               /* GDTR - global descriptor table */
283         MOVQ    RARG, AX
284         MOVL    (AX), GDTR
285         RET
286
287 TEXT lidt(SB), $0                               /* IDTR - interrupt descriptor table */
288         MOVQ    RARG, AX
289         MOVL    (AX), IDTR
290         RET
291
292 TEXT ltr(SB), 1, $-4
293         MOVW    RARG, AX
294         MOVW    AX, TASK
295         RET
296
297 /*
298  * Read/write various system registers.
299  */
300 TEXT getcr0(SB), 1, $-4                         /* Processor Control */
301         MOVQ    CR0, AX
302         RET
303
304 TEXT putcr0(SB), 1, $-4
305         MOVQ    RARG, CR0
306         RET
307
308 TEXT getcr2(SB), 1, $-4                         /* #PF Linear Address */
309         MOVQ    CR2, AX
310         RET
311
312 TEXT getcr3(SB), 1, $-4                         /* PML4 Base */
313         MOVQ    CR3, AX
314         RET
315
316 TEXT putcr3(SB), 1, $-4
317         MOVQ    RARG, CR3
318         RET
319
320 TEXT getcr4(SB), 1, $-4                         /* Extensions */
321         MOVQ    CR4, AX
322         RET
323
324 TEXT putcr4(SB), 1, $-4
325         MOVQ    RARG, CR4
326         RET
327
328 TEXT mb386(SB), 1, $-4                          /* hack */
329 TEXT mb586(SB), 1, $-4
330         XORL    AX, AX
331         CPUID
332         RET
333
334 /*
335  * Park a processor. Should never fall through a return from main to here,
336  * should only be called by application processors when shutting down.
337  */
338 TEXT idle(SB), 1, $-4
339 _idle:
340         STI
341         HLT
342         JMP     _idle
343
344 /*
345  * BIOS32.
346  */
347 TEXT bios32call(SB), 1, $-4
348         XORL    AX, AX
349         INCL    AX
350         RET
351
352 /*
353  * Basic timing loop to determine CPU frequency.
354  */
355 TEXT aamloop(SB), 1, $-4
356         MOVL    RARG, CX
357 _aamloop:
358         LOOP    _aamloop
359         RET
360
361 TEXT _cycles(SB), 1, $-4                        /* time stamp counter */
362         RDTSC
363         MOVL    AX, 0(RARG)                     /* lo */
364         MOVL    DX, 4(RARG)                     /* hi */
365         RET
366
367 TEXT rdmsr(SB), 1, $-4                          /* Model-Specific Register */
368         MOVL    RARG, CX
369         MOVQ    $0, BP
370 TEXT _rdmsrinst(SB), $0
371         RDMSR
372         MOVQ    vlong+8(FP), CX                 /* &vlong */
373         MOVL    AX, 0(CX)                       /* lo */
374         MOVL    DX, 4(CX)                       /* hi */
375         MOVQ    BP, AX                          /* BP set to -1 if traped */
376         RET
377         
378 TEXT wrmsr(SB), 1, $-4
379         MOVL    RARG, CX
380         MOVL    lo+8(FP), AX
381         MOVL    hi+12(FP), DX
382         MOVQ    $0, BP
383 TEXT _wrmsrinst(SB), $0
384         WRMSR
385         MOVQ    BP, AX                          /* BP set to -1 if traped */
386         RET
387
388 TEXT invlpg(SB), 1, $-4                         /* INVLPG va+0(FP) */
389         MOVQ    RARG, va+0(FP)
390
391         INVLPG  va+0(FP)
392
393         RET
394
395 TEXT wbinvd(SB), 1, $-4
396         WBINVD
397         RET
398
399 /*
400  * Serialisation.
401  */
402 TEXT lfence(SB), 1, $-4
403         LFENCE
404         RET
405
406 TEXT mfence(SB), 1, $-4
407         MFENCE
408         RET
409
410 TEXT sfence(SB), 1, $-4
411         SFENCE
412         RET
413
414 /*
415  * Note: CLI and STI are not serialising instructions.
416  * Is that assumed anywhere?
417  */
418 TEXT splhi(SB), 1, $-4
419 _splhi:
420         PUSHFQ
421         POPQ    AX
422         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
423         JZ      _alreadyhi                      /* use CMOVLEQ etc. here? */
424
425         MOVQ    (SP), BX
426         MOVQ    BX, 8(RMACH)                    /* save PC in m->splpc */
427
428 _alreadyhi:
429         CLI
430         RET
431
432 TEXT spllo(SB), 1, $-4
433 _spllo:
434         PUSHFQ
435         POPQ    AX
436         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
437         JNZ     _alreadylo                      /* use CMOVLEQ etc. here? */
438
439         MOVQ    $0, 8(RMACH)                    /* clear m->splpc */
440
441 _alreadylo:
442         STI
443         RET
444
445 TEXT splx(SB), 1, $-4
446         TESTQ   $0x200, RARG                    /* 0x200 - Interrupt Flag */
447         JNZ     _spllo
448         JMP     _splhi
449
450 TEXT spldone(SB), 1, $-4
451         RET
452
453 TEXT islo(SB), 1, $-4
454         PUSHFQ
455         POPQ    AX
456         ANDQ    $0x200, AX                      /* 0x200 - Interrupt Flag */
457         RET
458
459 /*
460  * Synchronisation
461  */
462 TEXT ainc8(SB), 1, $-4
463         XORL    AX, AX
464         INCL    AX
465         LOCK;   XADDB AX, (RARG)
466 /* BOTCH        INCL    AX */
467         RET
468
469 TEXT _xinc(SB), 1, $-4                          /* int _inc(long*); */
470         MOVL    $1, AX
471         LOCK; XADDL AX, (RARG)
472         ADDL    $1, AX                          /* overflow if -ve or 0 */
473         JGT     _return
474 _trap:
475         XORQ    BX, BX
476         MOVQ    (BX), BX                        /* over under sideways down */
477 _return:
478         RET
479
480 TEXT _xdec(SB), 1, $-4                          /* int _dec(long*); */
481         MOVL    $-1, AX
482         LOCK; XADDL AX, (RARG)
483         SUBL    $1, AX                          /* underflow if -ve */
484         JLT     _trap
485         RET
486
487 TEXT tas(SB), 1, $-4
488         MOVL    $0xdeaddead, AX
489         XCHGL   AX, (RARG)                      /*  */
490         RET
491
492 TEXT fas64(SB), 1, $-4
493         MOVQ    p+8(FP), AX
494         LOCK; XCHGQ     AX, (RARG)                      /*  */
495         RET
496
497 TEXT cmpswap486(SB), 1, $-4
498 TEXT cas(SB), 1, $-4
499         MOVL    exp+8(FP), AX
500         MOVL    new+16(FP), BX
501         LOCK; CMPXCHGL BX, (RARG)
502         MOVL    $1, AX                          /* use CMOVLEQ etc. here? */
503         JNZ     _cas32r0
504 _cas32r1:
505         RET
506 _cas32r0:
507         DECL    AX
508         RET
509
510 TEXT cas64(SB), 1, $-4
511         MOVQ    exp+8(FP), AX
512         MOVQ    new+16(FP), BX
513         LOCK; CMPXCHGQ BX, (RARG)
514         MOVL    $1, AX                          /* use CMOVLEQ etc. here? */
515         JNZ     _cas64r0
516 _cas64r1:
517         RET
518 _cas64r0:
519         DECL    AX
520         RET
521
522 /*
523  * Label consists of a stack pointer and a programme counter
524  */
525 TEXT gotolabel(SB), 1, $-4
526         MOVQ    0(RARG), SP                     /* restore SP */
527         MOVQ    8(RARG), AX                     /* put return PC on the stack */
528         MOVQ    AX, 0(SP)
529         MOVL    $1, AX                          /* return 1 */
530         RET
531
532 TEXT setlabel(SB), 1, $-4
533         MOVQ    SP, 0(RARG)                     /* store SP */
534         MOVQ    0(SP), BX                       /* store return PC */
535         MOVQ    BX, 8(RARG)
536         MOVL    $0, AX                          /* return 0 */
537         RET
538
539 TEXT halt(SB), 1, $-4
540         CLI
541         CMPL    nrdy(SB), $0
542         JEQ     _nothingready
543         STI
544         RET
545 _nothingready:
546         STI
547         HLT
548         RET
549
550 TEXT mwait(SB), 1, $-4
551         MOVQ    RARG, AX
552         MOVL    (AX), CX
553         ORL     CX, CX
554         JNZ     _mwaitdone
555         XORL    DX, DX
556         BYTE $0x0f; BYTE $0x01; BYTE $0xc8      /* MONITOR */
557         MOVL    (AX), CX
558         ORL     CX, CX
559         JNZ     _mwaitdone
560         XORL    AX, AX
561         BYTE $0x0f; BYTE $0x01; BYTE $0xc9      /* MWAIT */
562 _mwaitdone:
563         RET
564
565 /*
566  * SIMD Floating Point.
567  * Note: for x87 instructions which have both a 'wait' and 'nowait' version,
568  * 8a only knows the 'wait' mnemonic but does NOT insertthe WAIT prefix byte
569  * (i.e. they act like their FNxxx variations) so WAIT instructions must be
570  * explicitly placed in the code if necessary.
571  */
572 TEXT _clts(SB), 1, $-4
573         CLTS
574         RET
575
576 TEXT _fldcw(SB), 1, $-4                         /* Load x87 FPU Control Word */
577         MOVQ    RARG, cw+0(FP)
578         FLDCW   cw+0(FP)
579         RET
580
581 TEXT _fnclex(SB), 1, $-4
582         FCLEX
583         RET
584
585 TEXT _fninit(SB), 1, $-4
586         FINIT                                   /* no WAIT */
587         RET
588
589 TEXT _fxrstor(SB), 1, $-4
590         FXRSTOR64 (RARG)
591         RET
592
593 TEXT _fxsave(SB), 1, $-4
594         FXSAVE64 (RARG)
595         RET
596
597 TEXT _fwait(SB), 1, $-4
598         WAIT
599         RET
600
601 TEXT _ldmxcsr(SB), 1, $-4                       /* Load MXCSR */
602         MOVQ    RARG, mxcsr+0(FP)
603         LDMXCSR mxcsr+0(FP)
604         RET
605
606 TEXT _stts(SB), 1, $-4
607         MOVQ    CR0, AX
608         ORQ     $8, AX                          /* Ts */
609         MOVQ    AX, CR0
610         RET
611
612 TEXT mul64fract(SB), 1, $-4
613         MOVQ    a+8(FP), AX
614         MULQ    b+16(FP)                        /* a*b */
615         SHRQ    $32, AX:DX
616         MOVQ    AX, (RARG)
617         RET
618
619 #define RDRANDAX        BYTE $0x0f; BYTE $0xc7; BYTE $0xf0
620 #define RDRAND64AX      BYTE $0x48; BYTE $0x0f; BYTE $0xc7;  BYTE $0xf0
621
622 TEXT rdrand32(SB), $-4
623 loop32:
624         RDRANDAX
625         JCC             loop32
626         RET
627
628 TEXT rdrand64(SB), $-4
629 loop64:
630         RDRAND64AX
631         JCC             loop64
632         RET
633
634 TEXT rdrandbuf(SB), $0
635         MOVQ    RARG, DX
636
637         MOVLQZX cnt+8(FP), CX
638         SHRQ    $3, CX
639 eights:
640         CMPL    CX, $0
641         JLE     f1
642         CALL    rdrand64(SB)
643         MOVQ    AX, 0(DX)
644         ADDQ    $8, DX
645         SUBL    $1, CX
646         JMP     eights
647
648 f1:
649         MOVLQZX cnt+8(FP), CX
650         ANDL    $7, CX
651         SHRQ    $2, CX
652 fours:
653         CMPL    CX, $0
654         JLE     f2
655         CALL    rdrand32(SB)
656         MOVL    AX, 0(DX)
657         ADDQ    $4, DX
658         SUBL    $1, CX
659         JMP     fours
660
661 f2:
662         MOVLQZX cnt+8(FP), CX
663         ANDL    $3, CX
664 ones:
665         CMPL    CX, $0
666         JLE     f3
667         CALL    rdrand32(SB)
668         MOVB    AX, 0(DX)
669         ADDQ    $1, DX
670         SUBL    $1, CX
671         JMP     ones
672
673 f3:
674         RET
675
676 /*
677  */
678 TEXT touser(SB), 1, $-4
679         CLI
680         SWAPGS
681         MOVQ    $UDSEL, AX
682         MOVW    AX, DS
683         MOVW    AX, ES
684         MOVW    AX, FS
685         MOVW    AX, GS
686
687         MOVQ    $(UTZERO+0x28), CX              /* ip */
688         MOVQ    $0x200, R11                     /* flags */
689
690         MOVQ    RARG, SP                        /* sp */
691
692         BYTE $0x48; SYSRET                      /* SYSRETQ */
693
694 /*
695  */
696 TEXT syscallentry(SB), 1, $-4
697         SWAPGS
698         BYTE $0x65; MOVQ 0, RMACH               /* m-> (MOVQ GS:0x0, R15) */
699         MOVQ    16(RMACH), RUSER                /* m->proc */
700         MOVQ    SP, R13
701         MOVQ    16(RUSER), SP                   /* m->proc->kstack */
702         ADDQ    $KSTACK, SP
703         PUSHQ   $UDSEL                          /* old stack segment */
704         PUSHQ   R13                             /* old sp */
705         PUSHQ   R11                             /* old flags */
706         PUSHQ   $UESEL                          /* old code segment */
707         PUSHQ   CX                              /* old ip */
708
709         SUBQ    $(17*8), SP                     /* unsaved registers */
710         PUSHQ   RARG                            /* system call number */
711
712         MOVW    $UDSEL, (15*8+0)(SP)
713         MOVW    ES, (15*8+2)(SP)
714         MOVW    FS, (15*8+4)(SP)
715         MOVW    GS, (15*8+6)(SP)
716
717         MOVQ    SP, RARG
718         PUSHQ   SP                              /* Ureg* */
719         CALL    syscall(SB)
720
721 TEXT forkret(SB), 1, $-4
722         MOVQ    8(SP), AX                       /* Ureg.ax */
723         MOVQ    (8+6*8)(SP), BP                 /* Ureg.bp */
724         ADDQ    $(16*8), SP                     /* registers + arguments */
725
726         CLI
727         SWAPGS
728         MOVW    0(SP), DS
729         MOVW    2(SP), ES
730         MOVW    4(SP), FS
731         MOVW    6(SP), GS
732
733         MOVQ    24(SP), CX                      /* ip */
734         MOVQ    40(SP), R11                     /* flags */
735
736         MOVQ    48(SP), SP                      /* sp */
737
738         BYTE $0x48; SYSRET                      /* SYSRETQ */
739
740 /*
741  * Interrupt/exception handling.
742  */
743
744 TEXT _strayintr(SB), 1, $-4                     /* no error code pushed */
745         PUSHQ   AX                              /* save AX */
746         MOVQ    8(SP), AX                       /* vectortable(SB) PC */
747         JMP     _intrcommon
748
749 TEXT _strayintrx(SB), 1, $-4                    /* error code pushed */
750         XCHGQ   AX, (SP)
751 _intrcommon:
752         MOVBQZX (AX), AX
753         XCHGQ   AX, (SP)
754
755         SUBQ    $24, SP                         /* R1[45], [DEFG]S */
756         CMPW    48(SP), $KESEL                  /* old CS */
757         JEQ     _intrnested
758
759         MOVQ    RUSER, 0(SP)
760         MOVQ    RMACH, 8(SP)
761         MOVW    DS, 16(SP)
762         MOVW    ES, 18(SP)
763         MOVW    FS, 20(SP)
764         MOVW    GS, 22(SP)
765
766         SWAPGS
767         BYTE $0x65; MOVQ 0, RMACH               /* m-> (MOVQ GS:0x0, R15) */
768         MOVQ    16(RMACH), RUSER                /* up */
769
770 _intrnested:
771         PUSHQ   R13
772         PUSHQ   R12
773         PUSHQ   R11
774         PUSHQ   R10
775         PUSHQ   R9
776         PUSHQ   R8
777         PUSHQ   BP
778         PUSHQ   DI
779         PUSHQ   SI
780         PUSHQ   DX
781         PUSHQ   CX
782         PUSHQ   BX
783         PUSHQ   AX
784
785         MOVQ    SP, RARG
786         PUSHQ   SP
787         CALL    trap(SB)
788
789         POPQ    AX
790
791         POPQ    AX
792         POPQ    BX
793         POPQ    CX
794         POPQ    DX
795         POPQ    SI
796         POPQ    DI
797         POPQ    BP
798         POPQ    R8
799         POPQ    R9
800         POPQ    R10
801         POPQ    R11
802         POPQ    R12
803         POPQ    R13
804
805         CMPQ    48(SP), $KESEL
806         JEQ     _iretnested
807
808         SWAPGS
809         MOVW    22(SP), GS
810         MOVW    20(SP), FS
811         MOVW    18(SP), ES
812         MOVW    16(SP), DS
813         MOVQ    8(SP), RMACH
814         MOVQ    0(SP), RUSER
815
816 _iretnested:
817         ADDQ    $40, SP
818         IRETQ
819
820 TEXT vectortable(SB), $0
821         CALL _strayintr(SB); BYTE $0x00         /* divide error */
822         CALL _strayintr(SB); BYTE $0x01         /* debug exception */
823         CALL _strayintr(SB); BYTE $0x02         /* NMI interrupt */
824         CALL _strayintr(SB); BYTE $0x03         /* breakpoint */
825         CALL _strayintr(SB); BYTE $0x04         /* overflow */
826         CALL _strayintr(SB); BYTE $0x05         /* bound */
827         CALL _strayintr(SB); BYTE $0x06         /* invalid opcode */
828         CALL _strayintr(SB); BYTE $0x07         /* no coprocessor available */
829         CALL _strayintrx(SB); BYTE $0x08        /* double fault */
830         CALL _strayintr(SB); BYTE $0x09         /* coprocessor segment overflow */
831         CALL _strayintrx(SB); BYTE $0x0A        /* invalid TSS */
832         CALL _strayintrx(SB); BYTE $0x0B        /* segment not available */
833         CALL _strayintrx(SB); BYTE $0x0C        /* stack exception */
834         CALL _strayintrx(SB); BYTE $0x0D        /* general protection error */
835         CALL _strayintrx(SB); BYTE $0x0E        /* page fault */
836         CALL _strayintr(SB); BYTE $0x0F         /*  */
837         CALL _strayintr(SB); BYTE $0x10         /* coprocessor error */
838         CALL _strayintrx(SB); BYTE $0x11        /* alignment check */
839         CALL _strayintr(SB); BYTE $0x12         /* machine check */
840         CALL _strayintr(SB); BYTE $0x13
841         CALL _strayintr(SB); BYTE $0x14
842         CALL _strayintr(SB); BYTE $0x15
843         CALL _strayintr(SB); BYTE $0x16
844         CALL _strayintr(SB); BYTE $0x17
845         CALL _strayintr(SB); BYTE $0x18
846         CALL _strayintr(SB); BYTE $0x19
847         CALL _strayintr(SB); BYTE $0x1A
848         CALL _strayintr(SB); BYTE $0x1B
849         CALL _strayintr(SB); BYTE $0x1C
850         CALL _strayintr(SB); BYTE $0x1D
851         CALL _strayintr(SB); BYTE $0x1E
852         CALL _strayintr(SB); BYTE $0x1F
853         CALL _strayintr(SB); BYTE $0x20         /* VectorLAPIC */
854         CALL _strayintr(SB); BYTE $0x21
855         CALL _strayintr(SB); BYTE $0x22
856         CALL _strayintr(SB); BYTE $0x23
857         CALL _strayintr(SB); BYTE $0x24
858         CALL _strayintr(SB); BYTE $0x25
859         CALL _strayintr(SB); BYTE $0x26
860         CALL _strayintr(SB); BYTE $0x27
861         CALL _strayintr(SB); BYTE $0x28
862         CALL _strayintr(SB); BYTE $0x29
863         CALL _strayintr(SB); BYTE $0x2A
864         CALL _strayintr(SB); BYTE $0x2B
865         CALL _strayintr(SB); BYTE $0x2C
866         CALL _strayintr(SB); BYTE $0x2D
867         CALL _strayintr(SB); BYTE $0x2E
868         CALL _strayintr(SB); BYTE $0x2F
869         CALL _strayintr(SB); BYTE $0x30
870         CALL _strayintr(SB); BYTE $0x31
871         CALL _strayintr(SB); BYTE $0x32
872         CALL _strayintr(SB); BYTE $0x33
873         CALL _strayintr(SB); BYTE $0x34
874         CALL _strayintr(SB); BYTE $0x35
875         CALL _strayintr(SB); BYTE $0x36
876         CALL _strayintr(SB); BYTE $0x37
877         CALL _strayintr(SB); BYTE $0x38
878         CALL _strayintr(SB); BYTE $0x39
879         CALL _strayintr(SB); BYTE $0x3A
880         CALL _strayintr(SB); BYTE $0x3B
881         CALL _strayintr(SB); BYTE $0x3C
882         CALL _strayintr(SB); BYTE $0x3D
883         CALL _strayintr(SB); BYTE $0x3E
884         CALL _strayintr(SB); BYTE $0x3F
885         CALL _strayintr(SB); BYTE $0x40         /* was VectorSYSCALL */
886         CALL _strayintr(SB); BYTE $0x41
887         CALL _strayintr(SB); BYTE $0x42
888         CALL _strayintr(SB); BYTE $0x43
889         CALL _strayintr(SB); BYTE $0x44
890         CALL _strayintr(SB); BYTE $0x45
891         CALL _strayintr(SB); BYTE $0x46
892         CALL _strayintr(SB); BYTE $0x47
893         CALL _strayintr(SB); BYTE $0x48
894         CALL _strayintr(SB); BYTE $0x49
895         CALL _strayintr(SB); BYTE $0x4A
896         CALL _strayintr(SB); BYTE $0x4B
897         CALL _strayintr(SB); BYTE $0x4C
898         CALL _strayintr(SB); BYTE $0x4D
899         CALL _strayintr(SB); BYTE $0x4E
900         CALL _strayintr(SB); BYTE $0x4F
901         CALL _strayintr(SB); BYTE $0x50
902         CALL _strayintr(SB); BYTE $0x51
903         CALL _strayintr(SB); BYTE $0x52
904         CALL _strayintr(SB); BYTE $0x53
905         CALL _strayintr(SB); BYTE $0x54
906         CALL _strayintr(SB); BYTE $0x55
907         CALL _strayintr(SB); BYTE $0x56
908         CALL _strayintr(SB); BYTE $0x57
909         CALL _strayintr(SB); BYTE $0x58
910         CALL _strayintr(SB); BYTE $0x59
911         CALL _strayintr(SB); BYTE $0x5A
912         CALL _strayintr(SB); BYTE $0x5B
913         CALL _strayintr(SB); BYTE $0x5C
914         CALL _strayintr(SB); BYTE $0x5D
915         CALL _strayintr(SB); BYTE $0x5E
916         CALL _strayintr(SB); BYTE $0x5F
917         CALL _strayintr(SB); BYTE $0x60
918         CALL _strayintr(SB); BYTE $0x61
919         CALL _strayintr(SB); BYTE $0x62
920         CALL _strayintr(SB); BYTE $0x63
921         CALL _strayintr(SB); BYTE $0x64
922         CALL _strayintr(SB); BYTE $0x65
923         CALL _strayintr(SB); BYTE $0x66
924         CALL _strayintr(SB); BYTE $0x67
925         CALL _strayintr(SB); BYTE $0x68
926         CALL _strayintr(SB); BYTE $0x69
927         CALL _strayintr(SB); BYTE $0x6A
928         CALL _strayintr(SB); BYTE $0x6B
929         CALL _strayintr(SB); BYTE $0x6C
930         CALL _strayintr(SB); BYTE $0x6D
931         CALL _strayintr(SB); BYTE $0x6E
932         CALL _strayintr(SB); BYTE $0x6F
933         CALL _strayintr(SB); BYTE $0x70
934         CALL _strayintr(SB); BYTE $0x71
935         CALL _strayintr(SB); BYTE $0x72
936         CALL _strayintr(SB); BYTE $0x73
937         CALL _strayintr(SB); BYTE $0x74
938         CALL _strayintr(SB); BYTE $0x75
939         CALL _strayintr(SB); BYTE $0x76
940         CALL _strayintr(SB); BYTE $0x77
941         CALL _strayintr(SB); BYTE $0x78
942         CALL _strayintr(SB); BYTE $0x79
943         CALL _strayintr(SB); BYTE $0x7A
944         CALL _strayintr(SB); BYTE $0x7B
945         CALL _strayintr(SB); BYTE $0x7C
946         CALL _strayintr(SB); BYTE $0x7D
947         CALL _strayintr(SB); BYTE $0x7E
948         CALL _strayintr(SB); BYTE $0x7F
949         CALL _strayintr(SB); BYTE $0x80         /* Vector[A]PIC */
950         CALL _strayintr(SB); BYTE $0x81
951         CALL _strayintr(SB); BYTE $0x82
952         CALL _strayintr(SB); BYTE $0x83
953         CALL _strayintr(SB); BYTE $0x84
954         CALL _strayintr(SB); BYTE $0x85
955         CALL _strayintr(SB); BYTE $0x86
956         CALL _strayintr(SB); BYTE $0x87
957         CALL _strayintr(SB); BYTE $0x88
958         CALL _strayintr(SB); BYTE $0x89
959         CALL _strayintr(SB); BYTE $0x8A
960         CALL _strayintr(SB); BYTE $0x8B
961         CALL _strayintr(SB); BYTE $0x8C
962         CALL _strayintr(SB); BYTE $0x8D
963         CALL _strayintr(SB); BYTE $0x8E
964         CALL _strayintr(SB); BYTE $0x8F
965         CALL _strayintr(SB); BYTE $0x90
966         CALL _strayintr(SB); BYTE $0x91
967         CALL _strayintr(SB); BYTE $0x92
968         CALL _strayintr(SB); BYTE $0x93
969         CALL _strayintr(SB); BYTE $0x94
970         CALL _strayintr(SB); BYTE $0x95
971         CALL _strayintr(SB); BYTE $0x96
972         CALL _strayintr(SB); BYTE $0x97
973         CALL _strayintr(SB); BYTE $0x98
974         CALL _strayintr(SB); BYTE $0x99
975         CALL _strayintr(SB); BYTE $0x9A
976         CALL _strayintr(SB); BYTE $0x9B
977         CALL _strayintr(SB); BYTE $0x9C
978         CALL _strayintr(SB); BYTE $0x9D
979         CALL _strayintr(SB); BYTE $0x9E
980         CALL _strayintr(SB); BYTE $0x9F
981         CALL _strayintr(SB); BYTE $0xA0
982         CALL _strayintr(SB); BYTE $0xA1
983         CALL _strayintr(SB); BYTE $0xA2
984         CALL _strayintr(SB); BYTE $0xA3
985         CALL _strayintr(SB); BYTE $0xA4
986         CALL _strayintr(SB); BYTE $0xA5
987         CALL _strayintr(SB); BYTE $0xA6
988         CALL _strayintr(SB); BYTE $0xA7
989         CALL _strayintr(SB); BYTE $0xA8
990         CALL _strayintr(SB); BYTE $0xA9
991         CALL _strayintr(SB); BYTE $0xAA
992         CALL _strayintr(SB); BYTE $0xAB
993         CALL _strayintr(SB); BYTE $0xAC
994         CALL _strayintr(SB); BYTE $0xAD
995         CALL _strayintr(SB); BYTE $0xAE
996         CALL _strayintr(SB); BYTE $0xAF
997         CALL _strayintr(SB); BYTE $0xB0
998         CALL _strayintr(SB); BYTE $0xB1
999         CALL _strayintr(SB); BYTE $0xB2
1000         CALL _strayintr(SB); BYTE $0xB3
1001         CALL _strayintr(SB); BYTE $0xB4
1002         CALL _strayintr(SB); BYTE $0xB5
1003         CALL _strayintr(SB); BYTE $0xB6
1004         CALL _strayintr(SB); BYTE $0xB7
1005         CALL _strayintr(SB); BYTE $0xB8
1006         CALL _strayintr(SB); BYTE $0xB9
1007         CALL _strayintr(SB); BYTE $0xBA
1008         CALL _strayintr(SB); BYTE $0xBB
1009         CALL _strayintr(SB); BYTE $0xBC
1010         CALL _strayintr(SB); BYTE $0xBD
1011         CALL _strayintr(SB); BYTE $0xBE
1012         CALL _strayintr(SB); BYTE $0xBF
1013         CALL _strayintr(SB); BYTE $0xC0
1014         CALL _strayintr(SB); BYTE $0xC1
1015         CALL _strayintr(SB); BYTE $0xC2
1016         CALL _strayintr(SB); BYTE $0xC3
1017         CALL _strayintr(SB); BYTE $0xC4
1018         CALL _strayintr(SB); BYTE $0xC5
1019         CALL _strayintr(SB); BYTE $0xC6
1020         CALL _strayintr(SB); BYTE $0xC7
1021         CALL _strayintr(SB); BYTE $0xC8
1022         CALL _strayintr(SB); BYTE $0xC9
1023         CALL _strayintr(SB); BYTE $0xCA
1024         CALL _strayintr(SB); BYTE $0xCB
1025         CALL _strayintr(SB); BYTE $0xCC
1026         CALL _strayintr(SB); BYTE $0xCD
1027         CALL _strayintr(SB); BYTE $0xCE
1028         CALL _strayintr(SB); BYTE $0xCF
1029         CALL _strayintr(SB); BYTE $0xD0
1030         CALL _strayintr(SB); BYTE $0xD1
1031         CALL _strayintr(SB); BYTE $0xD2
1032         CALL _strayintr(SB); BYTE $0xD3
1033         CALL _strayintr(SB); BYTE $0xD4
1034         CALL _strayintr(SB); BYTE $0xD5
1035         CALL _strayintr(SB); BYTE $0xD6
1036         CALL _strayintr(SB); BYTE $0xD7
1037         CALL _strayintr(SB); BYTE $0xD8
1038         CALL _strayintr(SB); BYTE $0xD9
1039         CALL _strayintr(SB); BYTE $0xDA
1040         CALL _strayintr(SB); BYTE $0xDB
1041         CALL _strayintr(SB); BYTE $0xDC
1042         CALL _strayintr(SB); BYTE $0xDD
1043         CALL _strayintr(SB); BYTE $0xDE
1044         CALL _strayintr(SB); BYTE $0xDF
1045         CALL _strayintr(SB); BYTE $0xE0
1046         CALL _strayintr(SB); BYTE $0xE1
1047         CALL _strayintr(SB); BYTE $0xE2
1048         CALL _strayintr(SB); BYTE $0xE3
1049         CALL _strayintr(SB); BYTE $0xE4
1050         CALL _strayintr(SB); BYTE $0xE5
1051         CALL _strayintr(SB); BYTE $0xE6
1052         CALL _strayintr(SB); BYTE $0xE7
1053         CALL _strayintr(SB); BYTE $0xE8
1054         CALL _strayintr(SB); BYTE $0xE9
1055         CALL _strayintr(SB); BYTE $0xEA
1056         CALL _strayintr(SB); BYTE $0xEB
1057         CALL _strayintr(SB); BYTE $0xEC
1058         CALL _strayintr(SB); BYTE $0xED
1059         CALL _strayintr(SB); BYTE $0xEE
1060         CALL _strayintr(SB); BYTE $0xEF
1061         CALL _strayintr(SB); BYTE $0xF0
1062         CALL _strayintr(SB); BYTE $0xF1
1063         CALL _strayintr(SB); BYTE $0xF2
1064         CALL _strayintr(SB); BYTE $0xF3
1065         CALL _strayintr(SB); BYTE $0xF4
1066         CALL _strayintr(SB); BYTE $0xF5
1067         CALL _strayintr(SB); BYTE $0xF6
1068         CALL _strayintr(SB); BYTE $0xF7
1069         CALL _strayintr(SB); BYTE $0xF8
1070         CALL _strayintr(SB); BYTE $0xF9
1071         CALL _strayintr(SB); BYTE $0xFA
1072         CALL _strayintr(SB); BYTE $0xFB
1073         CALL _strayintr(SB); BYTE $0xFC
1074         CALL _strayintr(SB); BYTE $0xFD
1075         CALL _strayintr(SB); BYTE $0xFE
1076         CALL _strayintr(SB); BYTE $0xFF