[BACK]Return to gidt.S CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / stand / libsa

Annotation of sys/arch/i386/stand/libsa/gidt.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: gidt.S,v 1.32 2006/12/26 19:30:44 tom Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 1997 Michael Shalayeff
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     19:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     26:  * SUCH DAMAGE.
                     27:  *
                     28:  */
                     29:
                     30:        .file "gidt.S"
                     31:
                     32: #include <machine/asm.h>
                     33: #define _LOCORE
                     34: #include <machine/trap.h>
                     35: #include <debug_md.h>
                     36: #undef _LOCORE
                     37: #include <assym.h>
                     38:
                     39: #include "gidt.h"
                     40:
                     41: #ifdef GIDT_DEBUG
                     42: #define        gidt_debug0             ; \
                     43:        mov     $0xb8000, %eax  ; \
                     44:        mov     $0x47314730, (%eax)
                     45: #define        gidt_debug1             ; \
                     46:        mov     $(0xb8000 - LINKADDR), %eax     ; \
                     47:        mov     $0x4f314f30, (%eax)
                     48: #define        gidt_debug2             ; \
                     49:        mov     $0xb8004, %eax  ; \
                     50:        mov     $0x47334732, (%eax)
                     51: #define        gidt_debug3             ; \
                     52:        mov     $0xb8004, %eax  ; \
                     53:        mov     $0x4f334f32, (%eax)
                     54: #define gidt_debug4            ; \
                     55:        movl    $0xb8008, %eax  ; \
                     56:        movl    $0x47344733, (%eax)
                     57: #else
                     58: #define gidt_debug0 /* gidt_debug0 */
                     59: #define gidt_debug1 /* gidt_debug1 */
                     60: #define gidt_debug2 /* gidt_debug2 */
                     61: #define gidt_debug3 /* gidt_debug3 */
                     62: #define gidt_debug4 /* gidt_debug4 */
                     63: #endif
                     64:
                     65: #define prot2real                                              \
                     66:        gidt_debug0;                                            \
                     67:                                                                \
                     68:        ljmp    $S16TEXT, $1f - LINKADDR;                       \
                     69: 1:                                                             \
                     70:        .code16;                                                \
                     71:        movw    $S16DATA, %ax;                                  \
                     72:        movw    %ax, %ds;                                       \
                     73:        movw    %ax, %es;                                       \
                     74:        gidt_debug1;                                            \
                     75:                                                                \
                     76:        movl    %cr0, %eax;     /* disable pmmm */              \
                     77:        andl    $~CR0_PE, %eax;                                 \
                     78:        movl    %eax, %cr0;                                     \
                     79:                                                                \
                     80:        /* reload real cs:ip */                                 \
                     81:        data32 ljmp     $(LINKADDR >> 4), $1f - LINKADDR;       \
                     82: 1:                                                             \
                     83:        movw    %cs, %ax;       /* setup: %ds, %es, %ss = %cs */ \
                     84:        movw    %ax, %ds;                                       \
                     85:        movw    %ax, %es;                                       \
                     86:        xorw    %ax, %ax;                                       \
                     87:        movw    %ax, %ss;                                       \
                     88:                                                                \
                     89:        gidt_debug2;                                            \
                     90:                                                                \
                     91:        data32 addr32 lidt (Idtr_real - LINKADDR); /* load idtr for real mode */
                     92:
                     93: #define real2prot                                              \
                     94:        gidt_debug3;                                            \
                     95:                                                                \
                     96:        movw    $LINKADDR >> 4, %ax;                            \
                     97:        movw    %ax, %ds;                                       \
                     98:        data32 addr32 lgdt (Gdtr - LINKADDR);   /* load the gdtr */     \
                     99:                                                                \
                    100:        movl    %cr0, %eax;     /* enable pmmm */               \
                    101:        orl     $CR0_PE, %eax;                                  \
                    102:        movl    %eax, %cr0;                                     \
                    103:                                                                \
                    104:        data32 ljmp     $S32TEXT, $1f;   /* reload %cs,flush pipeline */\
                    105: 1:                                                             \
                    106:        .code32;                                                \
                    107:        /* reload 32bit %ds, %ss, %es */                        \
                    108:        mov     $S32DATA, %eax;                                 \
                    109:        mov     %ax, %ds;                                       \
                    110:        mov     %ax, %ss;                                       \
                    111:        mov     %ax, %es;                                       \
                    112:                                                                \
                    113:        gidt_debug4;                                            \
                    114:                                                                \
                    115:        /* load idtr for debugger and DOS/BIOS iface */         \
                    116:        lidt    Idtr;
                    117:
                    118:
                    119:        .globl  _C_LABEL(BIOS_regs)
                    120:
                    121:        .text
                    122:        .code32
                    123:        .globl  _ASM_LABEL(pmm_init)
                    124:        .globl  _C_LABEL(_rtt)
                    125:
                    126: ENTRY(_rtt)
                    127: #ifdef GIDT_DEBUG
                    128:        movl    $0xb8000, %ebx
                    129:        movl    $0x4f514f51, (%ebx)
                    130: #endif
                    131:        movw    $0x1234, %ax
                    132:        movw    %ax, 0x472      /* warm boot */
                    133:
                    134:        /* Try to use the KBD to reboot system */
                    135:        movb    $0xfe, %al
                    136:        outb    %al, $0x64
                    137:
                    138:        movl    $0x5000, %ecx
                    139: 1:     inb     $0x84, %al
                    140:        loop    1b
                    141:
                    142:        movb    $0xfe, %al
                    143:        outb    %al, $0x64
                    144:
                    145: #ifdef GIDT_DEBUG
                    146:        movl    $0xb8000, %ebx
                    147:        movl    $0x07310731, (%ebx)
                    148: #endif
                    149:
                    150:        /* Try to cause a triple fault... */
                    151:        lidt    Idtr_reset
                    152:        xorl    %eax, %eax
                    153:        divl    %eax, %eax
                    154:
                    155:        /* Again... */
                    156:        int $0x8
                    157:
                    158:        /* Again... */
                    159:        movl    $0, %esp        /* segment violation */
                    160:        ret
                    161:
                    162:        .align  8, 0x90
                    163: pmm_init:
                    164:        /* load idtr for interrupts */
                    165:        lidt    Idtr
                    166:        ret
                    167:
                    168:
                    169: #ifdef __STDC__
                    170: #define IPROC(n)       X##n
                    171: #define IEMU(n)                IPROC(emu##n)
                    172: #else
                    173: #define IPROC(n)       X/**/n
                    174: #define IEMU(n)                IPROC(emu/**/n)
                    175: #endif
                    176:        .align 8, 0x90
                    177: idt:
                    178: #define idte(e)        \
                    179:        .short  IPROC(e); .short (S32TEXT); \
                    180:        .short  ((0x80|SDT_SYS386TGT) << 8); .short (LINKADDR >> 16)
                    181: /* internal (0-31) */
                    182:        idte(de); idte(db); idte(nmi); idte(bp); idte(of); idte(br)
                    183:        idte(ud); idte(nm); idte(df);  idte(fo); idte(ts); idte(np)
                    184:        idte(ss); idte(gp); idte(pf);  idte(xx); idte(mf); idte(ac)
                    185:        idte(mc)
                    186:        idte(xx); idte(xx); idte(xx);  idte(xx); idte(xx); idte(xx)
                    187:        idte(xx); idte(xx); idte(xx);  idte(xx); idte(xx); idte(xx)
                    188:        idte(xx)
                    189:                /* Maskable interrupts (32-255) */
                    190:                /* BIOS entry points (32-63) */
                    191:                /* DOS entry points (64-80) */
                    192: #ifdef __STDC__
                    193: #define idtb(b)        idte(emu##b)
                    194: #else
                    195: #define idtb(b)        idte(emu/**/b)
                    196: #endif
                    197:        idtb(0);  idtb(1);  idtb(2);  idtb(3);  idtb(4);  idtb(5)
                    198:        idtb(6);  idtb(7);  idtb(8);  idtb(9);  idtb(10); idtb(11)
                    199:        idtb(12); idtb(13); idtb(14); idtb(15); idtb(16); idtb(17)
                    200:        idtb(18); idtb(19); idtb(20); idtb(21); idtb(22); idtb(23)
                    201:        idtb(24); idtb(25); idtb(26); idtb(27); idtb(28); idtb(29)
                    202:        idtb(30); idtb(31); idtb(32); idtb(33); idtb(34); idtb(35)
                    203:        idtb(36); idtb(37); idtb(38); idtb(39); idtb(40); idtb(41)
                    204:        idtb(42); idtb(43); idtb(44); idtb(45); idtb(46); idtb(47)
                    205: #undef idte
                    206:        .globl  Idtr
                    207: Idtr:  .word   . - idt - 1
                    208:        .long   idt
                    209:        .word   0
                    210:
                    211:        .align  8
                    212:        .globl  Idtr_real
                    213: Idtr_real:     .word   1023
                    214:                .long   0
                    215:                .word   0
                    216:
                    217:        .align  8
                    218: Idtr_reset:    .long   0, 0
                    219:
                    220:        .align  8
                    221: gdt:
                    222:                /* 0x00 : null */
                    223:        .space  8
                    224:                /* 0x08 : flat code */
                    225:        .word   0xFFFF                  # lolimit
                    226:        .word   0                       # lobase
                    227:        .byte   0                       # midbase
                    228:        .byte   SDT_MEMERAC | 0 | 0x80  # RXAC, dpl = 0, present
                    229:        .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
                    230:        .byte   0                       # hibase
                    231:                /* 0x10 : flat data */
                    232:        .word   0xFFFF                  # lolimit
                    233:        .word   0                       # lobase
                    234:        .byte   0                       # midbase
                    235:        .byte   SDT_MEMRWA | 0 | 0x80   # RWA, dpl = 0, present
                    236:        .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
                    237:        .byte   0                       # hibase
                    238:                /* 0x18 : 16 bit code */
                    239:        .word   0xFFFF                  # lolimit
                    240:        .word   (LINKADDR & 0xffff)     # lobase
                    241:        .byte   (LINKADDR >> 16) & 0xff # midbase
                    242:        .byte   SDT_MEMERAC | 0 | 0x80  # RXAC, dpl = 0, present
                    243:        .byte   0x0 | 0 | 0 | 0         # hilimit, xx, 16bit, byte granularity
                    244:        .byte   (LINKADDR >> 20) & 0xff # hibase
                    245:                /* 0x20 : 16 bit data */
                    246:        .word   0xFFFF                  # lolimit
                    247:        .word   (LINKADDR & 0xffff)     # lobase
                    248:        .byte   (LINKADDR >> 16) & 0xff # midbase
                    249:        .byte   SDT_MEMRWA | 0 | 0x80   # RWA, dpl = 0, present
                    250:        .byte   0x0 | 0 | 0 | 0         # hilimit, xx, 16bit, byte granularity
                    251:        .byte   (LINKADDR >> 20) & 0xff # hibase
                    252:
                    253: .globl Gdtr
                    254: Gdtr:  .word   . - gdt - 1
                    255:        .long   gdt
                    256:        .word   0
                    257:
                    258: #define IENTRY(name,type) \
                    259: IPROC(name): \
                    260:        pushl   $type ; \
                    261:        jmp     1f
                    262: #define IENTRY_ERR(name,err,type) \
                    263: IPROC(name): \
                    264:        pushl   $err ; \
                    265:        pushl   $type ; \
                    266:        jmp     1f
                    267:
                    268: IPROC(xx):
                    269:        pushl   $1
                    270:        pushl   $T_RESERVED
                    271:        jmp     1f
                    272:
                    273: IENTRY_ERR(de,0,T_DIVIDE)      /* #DE divide by zero */
                    274: IENTRY_ERR(db,0,T_TRCTRAP)     /* #DB debug */
                    275: IENTRY_ERR(nmi,0,T_NMI)                /* NMI */
                    276: IENTRY_ERR(bp,0,T_BPTFLT)      /* #BP breakpoint */
                    277: IENTRY_ERR(of,0,T_OFLOW)       /* #OF overflow */
                    278: IENTRY_ERR(br,0,T_BOUND)       /* #BR BOUND range exceeded */
                    279: IENTRY_ERR(ud,0,T_PRIVINFLT)   /* #UD invalid opcode */
                    280: IENTRY_ERR(nm,0,T_DNA)         /* #NM device not available */
                    281: IENTRY(df,T_DOUBLEFLT)         /* #DF double fault */
                    282: IENTRY_ERR(fo,0,T_FPOPFLT)     /* #FO coprocessor segment overrun */
                    283: IENTRY(ts,T_TSSFLT)            /* #TS invalid TSS */
                    284: IENTRY(np,T_SEGNPFLT)          /* #NP segment not present */
                    285: IENTRY(ss,T_STKFLT)            /* #SS stack fault */
                    286: IENTRY(gp,T_PROTFLT)           /* #GP general protection */
                    287: IENTRY(pf,T_PAGEFLT)           /* #PF page fault */
                    288: IENTRY_ERR(mf,0,T_ARITHTRAP)   /* #MF floating point error */
                    289: IENTRY(ac,T_ALIGNFLT)          /* #AC alignment check */
                    290: IENTRY(mc,T_MACHK)             /* #MC machine check */
                    291:
                    292:        .globl  alltraps
                    293: 1:     /* save on jumps */
                    294:        jmp     alltraps
                    295:
                    296: #define        IEMUENT(n)      IEMU(n): pushl $n; jmp 1f
                    297:
                    298: IEMUENT(0);  IEMUENT(1);  IEMUENT(2);  IEMUENT(3)
                    299: IEMUENT(4);  IEMUENT(5);  IEMUENT(6);  IEMUENT(7)
                    300: IEMUENT(8);  IEMUENT(9);  IEMUENT(10); IEMUENT(11)
                    301: IEMUENT(12); IEMUENT(13); IEMUENT(14); IEMUENT(15)
                    302: IEMUENT(16); IEMUENT(17); IEMUENT(18); IEMUENT(19)
                    303: IEMUENT(20); IEMUENT(21); IEMUENT(22); IEMUENT(23)
                    304: IEMUENT(24); IEMUENT(25); IEMUENT(26); IEMUENT(27)
                    305: IEMUENT(28); IEMUENT(29); IEMUENT(30); IEMUENT(31)
                    306: 1:     jmp     EMUh    /* redirect for short jumps */
                    307: IEMUENT(32); IEMUENT(33); IEMUENT(34); IEMUENT(35)
                    308: IEMUENT(36); IEMUENT(37); IEMUENT(38); IEMUENT(39)
                    309: IEMUENT(40); IEMUENT(41); IEMUENT(42); IEMUENT(43)
                    310: IEMUENT(44); IEMUENT(45); IEMUENT(46); IEMUENT(47)
                    311: 1:     jmp     EMUh
                    312:
                    313: /*
                    314:  * entry point for BIOS real-mode interface
                    315:  * all the magic for real-prot mode switching is here
                    316:  *
                    317:  * Call:       %eax, %ecx, %edx, %ebx, %ebp, %esi, %edi, %es, %ds
                    318:  * Return:     %eax, %edx, %ecx, %eflags (as returned from BIOS)
                    319:  *
                    320:  */
                    321:        .globl  EMUh
                    322:        .align  8, 0x90
                    323: EMUh:
                    324:        /* save %eax */
                    325:        mov     %eax, 3f
                    326:        pop     %eax
                    327:
                    328:        pusha
                    329:        push    %ds
                    330:        push    %es
                    331:        push    %fs
                    332:        push    %gs
                    333:
                    334:        /* save BIOS int vector */
                    335:        mov     %al, intno
                    336:
                    337:        prot2real
                    338:
                    339:        push    %ds
                    340:
                    341:        addr32  movw (_C_LABEL(BIOS_regs)+(BIOSR_ES) - LINKADDR), %ax
                    342:        movw    %ax, %es
                    343:        addr32  movw (_C_LABEL(BIOS_regs)+(BIOSR_DS) - LINKADDR), %ax
                    344:        movw    %ax, %ds
                    345:
                    346:        # data32 movl $Leax, %eax
                    347:        .byte   0x66, 0xb8
                    348: 3:     .long   0x90909090
                    349:
                    350:        ;sti
                    351:        int     $0
                    352: intno  = . - 1
                    353:        ;cli
                    354:
                    355:        pop     %ds
                    356:
                    357:        addr32 movl %ebx, (_C_LABEL(BIOS_regs)+(BIOSR_BX) - LINKADDR)
                    358:        movw    %es, %bx
                    359:        addr32 movw %bx, (_C_LABEL(BIOS_regs)+(BIOSR_ES) - LINKADDR)
                    360:        movb    %ah, %bh
                    361:        lahf
                    362:        xchgb   %ah, %bh
                    363:
                    364:        addr32 movl %eax, (2f - LINKADDR)
                    365:
                    366:        real2prot
                    367:
                    368:        # movl $Leax, %eax
                    369:        .byte 0xb8
                    370: 2:     .long 0x90909090
                    371:
                    372:        /* pass BIOS return values back to caller */
                    373:        movl    %eax, 0xb*4(%esp)
                    374:        movl    %ecx, 0xa*4(%esp)
                    375:        movl    %edx, 0x9*4(%esp)
                    376:        movb    %bh , 0xe*4(%esp)
                    377:
                    378:        /* clear NT flag in eflags */
                    379:        /* Martin Fredriksson <martin@gbg.netman.se> */
                    380:        pushf
                    381:        pop     %eax
                    382:        and     $0xffffbfff, %eax
                    383:        push    %eax
                    384:        popf
                    385:
                    386:        /* save registers into save area */
                    387:        movl    %eax, _C_LABEL(BIOS_regs)+BIOSR_AX
                    388:        movl    %ecx, _C_LABEL(BIOS_regs)+BIOSR_CX
                    389:        movl    %edx, _C_LABEL(BIOS_regs)+BIOSR_DX
                    390:        movl    %ebp, _C_LABEL(BIOS_regs)+BIOSR_BP
                    391:        movl    %esi, _C_LABEL(BIOS_regs)+BIOSR_SI
                    392:        movl    %edi, _C_LABEL(BIOS_regs)+BIOSR_DI
                    393:
                    394:        pop     %gs
                    395:        pop     %fs
                    396:        pop     %es
                    397:        pop     %ds
                    398:        popa
                    399:        iret
                    400:
                    401: /* Call buffer at 07c0:0000 in real mode to simulate a BIOS boot */
                    402: ENTRY(bootbuf)
                    403:        pop     %eax            /* Don't need return address */
                    404:        pop     %esi            /* Buffer */
                    405:        pop     %edx            /* Device */
                    406:        prot2real               /* Switch */
                    407:
                    408:        /* Set up stack */
                    409:        cli
                    410:        xor     %ax, %ax
                    411:        mov     %ax, %ss
                    412:        mov     $0xfffc, %esp
                    413:        sti
                    414:
                    415:        /* Jump to buffer */
                    416:        ljmp $0x0, $0x7c00
                    417:
                    418:        .end

CVSweb