]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8a/l.s
fix typo
[plan9front.git] / sys / src / cmd / 8a / l.s
1 /*
2  * Memory and machine-specific definitions.  Used in C and assembler.
3  */
4
5 /*
6  * Sizes
7  */
8 #define BI2BY           8                       /* bits per byte */
9 #define BI2WD           32                      /* bits per word */
10 #define BY2WD           4                       /* bytes per word */
11 #define BY2PG           4096                    /* bytes per page */
12 #define WD2PG           (BY2PG/BY2WD)           /* words per page */
13 #define PGSHIFT         12                      /* log(BY2PG) */
14 #define PGROUND(s)      (((s)+(BY2PG-1))&~(BY2PG-1))
15
16 #define MAXMACH         1                       /* max # cpus system can run */
17
18 /*
19  * Time
20  */
21 #define HZ              (20)                    /* clock frequency */
22 #define MS2HZ           (1000/HZ)               /* millisec per clock tick */
23 #define TK2SEC(t)       ((t)/HZ)                /* ticks to seconds */
24 #define TK2MS(t)        ((((ulong)(t))*1000)/HZ)        /* ticks to milliseconds */
25 #define MS2TK(t)        ((((ulong)(t))*HZ)/1000)        /* milliseconds to ticks */
26
27 /*
28  * Fundamental addresses
29  */
30
31 /*
32  *  Address spaces
33  *
34  *  User is at 0-2GB
35  *  Kernel is at 2GB-4GB
36  *
37  *  To avoid an extra page map, both the user stack (USTKTOP) and
38  *  the temporary user stack (TSTKTOP) should be in the the same
39  *  4 meg.
40  */
41 #define UZERO           0                       /* base of user address space */
42 #define UTZERO          (UZERO+BY2PG)           /* first address in user text */
43 #define KZERO           0x80000000              /* base of kernel address space */
44 #define KTZERO          KZERO                   /* first address in kernel text */
45 #define USERADDR        0xC0000000              /* struct User */
46 #define UREGADDR        (USERADDR+BY2PG-4*19)   
47 #define TSTKTOP         USERADDR                /* end of new stack in sysexec */
48 #define TSTKSIZ 10
49 #define USTKTOP         (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
50 #define USTKSIZE        (16*1024*1024 - TSTKSIZ*BY2PG)  /* size of user stack */
51 #define ROMBIOS         (KZERO|0xF0000)
52
53 #define MACHSIZE        4096
54
55 #define isphys(x) (((ulong)x)&KZERO)
56
57 /*
58  *  known 80386 segments (in GDT) and their selectors
59  */
60 #define NULLSEG 0       /* null segment */
61 #define KDSEG   1       /* kernel data/stack */
62 #define KESEG   2       /* kernel executable */ 
63 #define UDSEG   3       /* user data/stack */
64 #define UESEG   4       /* user executable */
65 #define TSSSEG  5       /* task segment */
66
67 #define SELGDT  (0<<3)  /* selector is in gdt */
68 #define SELLDT  (1<<3)  /* selector is in ldt */
69
70 #define SELECTOR(i, t, p)       (((i)<<3) | (t) | (p))
71
72 #define NULLSEL SELECTOR(NULLSEG, SELGDT, 0)
73 #define KESEL   SELECTOR(KESEG, SELGDT, 0)
74 #define KDSEL   SELECTOR(KDSEG, SELGDT, 0)
75 #define UESEL   SELECTOR(UESEG, SELGDT, 3)
76 #define UDSEL   SELECTOR(UDSEG, SELGDT, 3)
77 #define TSSSEL  SELECTOR(TSSSEG, SELGDT, 0)
78
79 /*
80  *  fields in segment descriptors
81  */
82 #define SEGDATA (0x10<<8)       /* data/stack segment */
83 #define SEGEXEC (0x18<<8)       /* executable segment */
84 #define SEGTSS  (0x9<<8)        /* TSS segment */
85 #define SEGCG   (0x0C<<8)       /* call gate */
86 #define SEGIG   (0x0E<<8)       /* interrupt gate */
87 #define SEGTG   (0x0F<<8)       /* task gate */
88 #define SEGTYPE (0x1F<<8)
89
90 #define SEGP    (1<<15)         /* segment present */
91 #define SEGPL(x) ((x)<<13)      /* priority level */
92 #define SEGB    (1<<22)         /* granularity 1==4k (for expand-down) */
93 #define SEGG    (1<<23)         /* granularity 1==4k (for other) */
94 #define SEGE    (1<<10)         /* expand down */
95 #define SEGW    (1<<9)          /* writable (for data/stack) */
96 #define SEGR    (1<<9)          /* readable (for code) */
97 #define SEGD    (1<<22)         /* default 1==32bit (for code) */
98
99 /*
100  *  virtual MMU
101  */
102 #define PTEMAPMEM       (1024*1024)     /* ??? */       
103 #define SEGMAPSIZE      16              /* ??? */
104 #define PTEPERTAB       (PTEMAPMEM/BY2PG)       /* ??? */
105 #define PPN(x)          ((x)&~(BY2PG-1))
106
107 /*
108  *  physical MMU
109  */
110 #define PTEVALID        (1<<0)
111 #define PTEUNCACHED     0               /* everything is uncached */
112 #define PTEWRITE        (1<<1)
113 #define PTERONLY        (0<<1)
114 #define PTEKERNEL       (0<<2)
115 #define PTEUSER         (1<<2)
116
117 /*
118  *  flag register bits that we care about
119  */
120 #define IFLAG   0x200
121
122 #define OP16    BYTE    $0x66
123
124 /*
125  *      about to walk all over ms/dos - turn off interrupts
126  */
127 TEXT    origin(SB),$0
128
129         CLI
130
131 #ifdef BOOT
132 /*
133  *      This part of l.s is used only in the boot kernel.
134  *      It assumes that we are in real address mode, i.e.,
135  *      that we look like an 8086.
136  */
137 /*
138  *      relocate everything to a half meg and jump there
139  *      - looks wierd because it is being assembled by a 32 bit
140  *        assembler for a 16 bit world
141  */
142         MOVL    $0,BX
143         INCL    BX
144         SHLL    $15,BX
145         MOVL    BX,CX
146         MOVW    BX,ES
147         MOVL    $0,SI
148         MOVL    SI,DI
149         CLD; REP; MOVSL
150 /*      JMPFAR  0X8000:$lowcore(SB) /**/
151          BYTE   $0xEA
152          WORD   $lowcore(SB)
153          WORD   $0X8000
154
155 TEXT    lowcore(SB),$0
156
157 /*
158  *      now that we're in low core, update the DS
159  */
160
161         MOVW    BX,DS
162
163 /*
164  *      goto protected mode
165  */
166 /*      MOVL    tgdtptr(SB),GDTR /**/
167          BYTE   $0x0f
168          BYTE   $0x01
169          BYTE   $0x16
170          WORD   $tgdtptr(SB)
171         MOVL    CR0,AX
172         ORL     $1,AX
173         MOVL    AX,CR0
174
175 /*
176  *      clear prefetch queue (wierd code to avoid optimizations)
177  */
178         CLC
179         JCC     flush
180         MOVL    AX,AX
181 flush:
182
183 /*
184  *      set all segs
185  */
186 /*      MOVW    $SELECTOR(1, SELGDT, 0),AX      /**/
187          BYTE   $0xc7
188          BYTE   $0xc0
189          WORD   $SELECTOR(1, SELGDT, 0)
190         MOVW    AX,DS
191         MOVW    AX,SS
192         MOVW    AX,ES
193         MOVW    AX,FS
194         MOVW    AX,GS
195
196 /*      JMPFAR  SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/
197          BYTE   $0x66
198          BYTE   $0xEA
199          LONG   $mode32bit-KZERO(SB)
200          WORD   $SELECTOR(2, SELGDT, 0)
201
202 TEXT    mode32bit(SB),$0
203
204 #endif BOOT
205
206         /*
207          * Clear BSS
208          */
209         LEAL    edata-KZERO(SB),SI
210         MOVL    SI,DI
211         ADDL    $4,DI
212         MOVL    $0,AX
213         MOVL    AX,(SI)
214         LEAL    end-KZERO(SB),CX
215         SUBL    DI,CX
216         SHRL    $2,CX
217         CLD; REP; MOVSL
218
219         /*
220          *  make a bottom level page table page that maps the first
221          *  16 meg of physical memory
222          */
223         LEAL    tpt-KZERO(SB),AX        /* get phys addr of temporary page table */
224         ADDL    $(BY2PG-1),AX           /* must be page aligned */
225         ANDL    $(~(BY2PG-1)),AX        /* ... */
226         MOVL    $(4*1024),CX            /* pte's per page */
227         MOVL    $((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX
228 setpte:
229         MOVL    BX,-4(AX)(CX*4)
230         SUBL    $(1<<PGSHIFT),BX
231         LOOP    setpte
232
233         /*
234          *  make a top level page table page that maps the first
235          *  16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg
236          */
237         MOVL    AX,BX
238         ADDL    $(4*BY2PG),AX
239         ADDL    $(PTEVALID|PTEKERNEL|PTEWRITE),BX
240         MOVL    BX,0(AX)
241         MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)
242         ADDL    $BY2PG,BX
243         MOVL    BX,4(AX)
244         MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)
245         ADDL    $BY2PG,BX
246         MOVL    BX,8(AX)
247         MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)
248         ADDL    $BY2PG,BX
249         MOVL    BX,12(AX)
250         MOVL    BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX)
251
252         /*
253          *  point processor to top level page & turn on paging
254          */
255         MOVL    AX,CR3
256         MOVL    CR0,AX
257         ORL     $0X80000000,AX
258         ANDL    $~(0x8|0x2),AX  /* TS=0, MP=0 */
259         MOVL    AX,CR0
260
261         /*
262          *  use a jump to an absolute location to get the PC into
263          *  KZERO.
264          */
265         LEAL    tokzero(SB),AX
266         JMP*    AX
267
268 TEXT    tokzero(SB),$0
269
270         /*
271          *  stack and mach
272          */
273         MOVL    $mach0(SB),SP
274         MOVL    SP,m(SB)
275         MOVL    $0,0(SP)
276         ADDL    $(MACHSIZE-4),SP        /* start stack under machine struct */
277         MOVL    $0, u(SB)
278
279         /*
280          *  clear flags
281          */
282         MOVL    $0,AX
283         PUSHL   AX
284         POPFL
285
286         CALL    main(SB)
287
288 loop:
289         JMP     loop
290
291 GLOBL   mach0+0(SB), $MACHSIZE
292 GLOBL   u(SB), $4
293 GLOBL   m(SB), $4
294 GLOBL   tpt(SB), $(BY2PG*6)
295
296 /*
297  *  gdt to get us to 32-bit/segmented/unpaged mode
298  */
299 TEXT    tgdt(SB),$0
300
301         /* null descriptor */
302         LONG    $0
303         LONG    $0
304
305         /* data segment descriptor for 4 gigabytes (PL 0) */
306         LONG    $(0xFFFF)
307         LONG    $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
308
309         /* exec segment descriptor for 4 gigabytes (PL 0) */
310         LONG    $(0xFFFF)
311         LONG    $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
312
313 /*
314  *  pointer to initial gdt
315  */
316 TEXT    tgdtptr(SB),$0
317
318         WORD    $(3*8)
319         LONG    $tgdt-KZERO(SB)
320
321 /*
322  *  input a byte
323  */
324 TEXT    inb(SB),$0
325
326         MOVL    p+0(FP),DX
327         XORL    AX,AX
328         INB
329         RET
330
331 /*
332  *  output a byte
333  */
334 TEXT    outb(SB),$0
335
336         MOVL    p+0(FP),DX
337         MOVL    b+4(FP),AX
338         OUTB
339         RET
340
341 /*
342  *  input a string of shorts from a port
343  */
344 TEXT    inss(SB),$0
345         MOVL    p+0(FP),DX
346         MOVL    a+4(FP),DI
347         MOVL    c+8(FP),CX
348         CLD; REP; OP16; INSL
349         RET
350
351 /*
352  *  output a string of shorts to a port
353  */
354 TEXT    outss(SB),$0
355         MOVL    p+0(FP),DX
356         MOVL    a+4(FP),SI
357         MOVL    c+8(FP),CX
358         CLD; REP; OP16; OUTSL
359         RET
360
361 /*
362  *  test and set
363  */
364 TEXT    tas(SB),$0
365         MOVL    $0xdeadead,AX
366         MOVL    l+0(FP),BX
367         XCHGL   AX,(BX)
368         RET
369
370 /*
371  *  routines to load/read various system registers
372  */
373 GLOBL   idtptr(SB),$6
374 TEXT    putidt(SB),$0           /* interrupt descriptor table */
375         MOVL    t+0(FP),AX
376         MOVL    AX,idtptr+2(SB)
377         MOVL    l+4(FP),AX
378         MOVW    AX,idtptr(SB)
379         MOVL    idtptr(SB),IDTR
380         RET
381
382 GLOBL   gdtptr(SB),$6
383 TEXT    putgdt(SB),$0           /* global descriptor table */
384         MOVL    t+0(FP),AX
385         MOVL    AX,gdtptr+2(SB)
386         MOVL    l+4(FP),AX
387         MOVW    AX,gdtptr(SB)
388         MOVL    gdtptr(SB),GDTR
389         RET
390
391 TEXT    putcr3(SB),$0           /* top level page table pointer */
392         MOVL    t+0(FP),AX
393         MOVL    AX,CR3
394         RET
395
396 TEXT    puttr(SB),$0            /* task register */
397         MOVL    t+0(FP),AX
398         MOVW    AX,TASK
399         RET
400
401 TEXT    getcr0(SB),$0           /* coprocessor bits */
402         MOVL    CR0,AX
403         RET
404
405 TEXT    getcr2(SB),$0           /* fault address */
406         MOVL    CR2,AX
407         RET
408
409 #define FPOFF\
410         WAIT;\
411         MOVL    CR0,AX;\
412         ORL     $0x4,AX         /* EM=1 */;\
413         MOVL    AX,CR0
414
415 #define FPON\
416         MOVL    CR0,AX;\
417         ANDL    $~0x4,AX        /* EM=0 */;\
418         MOVL    AX,CR0
419         
420 TEXT    fpoff(SB),$0            /* turn off floating point */
421         FPOFF
422         RET
423
424 TEXT    fpinit(SB),$0           /* turn on & init the floating point */
425         FPON
426         FINIT
427         WAIT
428         PUSHW   $0x0330
429         FLDCW   0(SP)           /* ignore underflow/precision, signal others */
430         POPW    AX
431         WAIT
432         RET
433
434 TEXT    fpsave(SB),$0           /* save floating point state and turn off */
435         MOVL    p+0(FP),AX
436         WAIT
437         FSAVE   0(AX)
438         FPOFF
439         RET
440
441 TEXT    fprestore(SB),$0        /* turn on floating point and restore regs */
442         FPON
443         MOVL    p+0(FP),AX
444         FRSTOR  0(AX)
445         WAIT
446         RET
447
448 TEXT    fpstatus(SB),$0         /* get floating point status */
449         FSTSW   AX
450         RET
451
452 /*
453  *  special traps
454  */
455 TEXT    intr0(SB),$0
456         PUSHL   $0
457         PUSHL   $0
458         JMP     intrcommon
459 TEXT    intr1(SB),$0
460         PUSHL   $0
461         PUSHL   $1
462         JMP     intrcommon
463 TEXT    intr2(SB),$0
464         PUSHL   $0
465         PUSHL   $2
466         JMP     intrcommon
467 TEXT    intr3(SB),$0
468         PUSHL   $0
469         PUSHL   $3
470         JMP     intrcommon
471 TEXT    intr4(SB),$0
472         PUSHL   $0
473         PUSHL   $4
474         JMP     intrcommon
475 TEXT    intr5(SB),$0
476         PUSHL   $0
477         PUSHL   $5
478         JMP     intrcommon
479 TEXT    intr6(SB),$0
480         PUSHL   $0
481         PUSHL   $6
482         JMP     intrcommon
483 TEXT    intr7(SB),$0
484         PUSHL   $0
485         PUSHL   $7
486         JMP     intrcommon
487 TEXT    intr8(SB),$0
488         PUSHL   $8
489         JMP     intrscommon
490 TEXT    intr9(SB),$0
491         PUSHL   $0
492         PUSHL   $9
493         JMP     intrcommon
494 TEXT    intr10(SB),$0
495         PUSHL   $10
496         JMP     intrscommon
497 TEXT    intr11(SB),$0
498         PUSHL   $11
499         JMP     intrscommon
500 TEXT    intr12(SB),$0
501         PUSHL   $12
502         JMP     intrscommon
503 TEXT    intr13(SB),$0
504         PUSHL   $13
505         JMP     intrscommon
506 TEXT    intr14(SB),$0
507         PUSHL   $14
508         JMP     intrscommon
509 TEXT    intr15(SB),$0
510         PUSHL   $0
511         PUSHL   $15
512         JMP     intrcommon
513 TEXT    intr16(SB),$0
514         PUSHL   $0
515         PUSHL   $16
516         JMP     intrcommon
517 TEXT    intr24(SB),$0
518         PUSHL   $0
519         PUSHL   $24
520         JMP     intrcommon
521 TEXT    intr25(SB),$0
522         PUSHL   $0
523         PUSHL   $25
524         JMP     intrcommon
525 TEXT    intr26(SB),$0
526         PUSHL   $0
527         PUSHL   $26
528         JMP     intrcommon
529 TEXT    intr27(SB),$0
530         PUSHL   $0
531         PUSHL   $27
532         JMP     intrcommon
533 TEXT    intr28(SB),$0
534         PUSHL   $0
535         PUSHL   $28
536         JMP     intrcommon
537 TEXT    intr29(SB),$0
538         PUSHL   $0
539         PUSHL   $29
540         JMP     intrcommon
541 TEXT    intr30(SB),$0
542         PUSHL   $0
543         PUSHL   $30
544         JMP     intrcommon
545 TEXT    intr31(SB),$0
546         PUSHL   $0
547         PUSHL   $31
548         JMP     intrcommon
549 TEXT    intr32(SB),$0
550         PUSHL   $0
551         PUSHL   $16
552         JMP     intrcommon
553 TEXT    intr33(SB),$0
554         PUSHL   $0
555         PUSHL   $33
556         JMP     intrcommon
557 TEXT    intr34(SB),$0
558         PUSHL   $0
559         PUSHL   $34
560         JMP     intrcommon
561 TEXT    intr35(SB),$0
562         PUSHL   $0
563         PUSHL   $35
564         JMP     intrcommon
565 TEXT    intr36(SB),$0
566         PUSHL   $0
567         PUSHL   $36
568         JMP     intrcommon
569 TEXT    intr37(SB),$0
570         PUSHL   $0
571         PUSHL   $37
572         JMP     intrcommon
573 TEXT    intr38(SB),$0
574         PUSHL   $0
575         PUSHL   $38
576         JMP     intrcommon
577 TEXT    intr39(SB),$0
578         PUSHL   $0
579         PUSHL   $39
580         JMP     intrcommon
581 TEXT    intr64(SB),$0
582         PUSHL   $0
583         PUSHL   $64
584         JMP     intrcommon
585 TEXT    intrbad(SB),$0
586         PUSHL   $0
587         PUSHL   $0x1ff
588         JMP     intrcommon
589
590 intrcommon:
591         PUSHL   DS
592         PUSHL   ES
593         PUSHL   FS
594         PUSHL   GS
595         PUSHAL
596         MOVL    $(KDSEL),AX
597         MOVW    AX,DS
598         MOVW    AX,ES
599         LEAL    0(SP),AX
600         PUSHL   AX
601         CALL    trap(SB)
602         POPL    AX
603         POPAL
604         POPL    GS
605         POPL    FS
606         POPL    ES
607         POPL    DS
608         ADDL    $8,SP   /* error code and trap type */
609         IRETL
610
611 intrscommon:
612         PUSHL   DS
613         PUSHL   ES
614         PUSHL   FS
615         PUSHL   GS
616         PUSHAL
617         MOVL    $(KDSEL),AX
618         MOVW    AX,DS
619         MOVW    AX,ES
620         LEAL    0(SP),AX
621         PUSHL   AX
622         CALL    trap(SB)
623         POPL    AX
624         POPAL
625         POPL    GS
626         POPL    FS
627         POPL    ES
628         POPL    DS
629         ADDL    $8,SP   /* error code and trap type */
630         IRETL
631
632 /*
633  *  interrupt level is interrupts on or off
634  */
635 TEXT    spllo(SB),$0
636         PUSHFL
637         POPL    AX
638         STI
639         RET
640
641 TEXT    splhi(SB),$0
642         PUSHFL
643         POPL    AX
644         CLI
645         RET
646
647 TEXT    splx(SB),$0
648         MOVL    s+0(FP),AX
649         PUSHL   AX
650         POPFL
651         RET
652
653 /*
654  *  do nothing whatsoever till interrupt happens
655  */
656 TEXT    idle(SB),$0
657         HLT
658         RET
659
660 /*
661  *  label consists of a stack pointer and a PC
662  */
663 TEXT    gotolabel(SB),$0
664         MOVL    l+0(FP),AX
665         MOVL    0(AX),SP        /* restore sp */
666         MOVL    4(AX),AX        /* put return pc on the stack */
667         MOVL    AX,0(SP)
668         MOVL    $1,AX           /* return 1 */
669         RET
670
671 TEXT    setlabel(SB),$0
672         MOVL    l+0(FP),AX
673         MOVL    SP,0(AX)        /* store sp */
674         MOVL    0(SP),BX        /* store return pc */
675         MOVL    BX,4(AX)
676         MOVL    $0,AX           /* return 0 */
677         RET
678
679 /*
680  *  Used to get to the first process.
681  *  Set up an interrupt return frame and IRET to user level.
682  */
683 TEXT    touser(SB),$0
684         PUSHL   $(UDSEL)                /* old ss */
685         PUSHL   $(USTKTOP)              /* old sp */
686         PUSHFL                          /* old flags */
687         PUSHL   $(UESEL)                /* old cs */
688         PUSHL   $(UTZERO+32)            /* old pc */
689         MOVL    $(UDSEL),AX
690         MOVW    AX,DS
691         MOVW    AX,ES
692         MOVW    AX,GS
693         MOVW    AX,FS
694         IRETL
695
696 /*
697  *  set configuration register
698  */
699 TEXT    config(SB),$0
700         MOVL    l+0(FP),AX
701         MOVL    $0x3F3,DX
702         OUTB
703         OUTB
704         RET