[BACK]Return to cpu.h CVS log [TXT][DIR] Up to [local] / prex-old / sys / arch / i386 / include

Annotation of prex-old/sys/arch/i386/include/cpu.h, Revision 1.1

1.1     ! nbrk        1: /*
        !             2:  * Copyright (c) 2005, Kohsuke Ohtani
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. Neither the name of the author nor the names of any co-contributors
        !            14:  *    may be used to endorse or promote products derived from this software
        !            15:  *    without specific prior written permission.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            27:  * SUCH DAMAGE.
        !            28:  */
        !            29:
        !            30: #ifndef _I386_CPU_H
        !            31: #define _I386_CPU_H
        !            32:
        !            33: #include <sys/cdefs.h> /* for __packed */
        !            34:
        !            35: /*
        !            36:  * GDTs
        !            37:  */
        !            38: #define KERNEL_CS      0x10
        !            39: #define KERNEL_DS      0x18
        !            40: #define USER_CS                0x20
        !            41: #define USER_DS                0x28
        !            42: #define KERNEL_TSS     0x38
        !            43:
        !            44: #define NGDTS          8
        !            45:
        !            46: /*
        !            47:  * IDTs
        !            48:  */
        !            49: #define NIDTS          0x41
        !            50: #define SYSCALL_INT    0x40
        !            51: #define INVALID_INT    0xFF
        !            52:
        !            53:
        !            54: #ifndef __ASSEMBLY__
        !            55:
        !            56: /*
        !            57:  * Segment Descriptor
        !            58:  */
        !            59: struct seg_desc {
        !            60:        int limit_lo:16;        /* segment limit (lsb) */
        !            61:        int base_lo:24;         /* segment base address (lsb) */
        !            62:        int type:8;             /* type */
        !            63:        int limit_hi:4;         /* segment limit (msb) */
        !            64:        int size:4;             /* size */
        !            65:        int base_hi:8;          /* segment base address (msb) */
        !            66: } __packed;
        !            67:
        !            68: /*
        !            69:  * Gate Descriptor
        !            70:  */
        !            71: struct gate_desc {
        !            72:        int offset_lo:16;       /* gate offset (lsb) */
        !            73:        int selector:16;        /* gate segment selector */
        !            74:        int nr_copy:8;          /* stack copy count */
        !            75:        int type:8;             /* type */
        !            76:        int offset_hi:16;       /* gate offset (msb) */
        !            77: } __packed;
        !            78:
        !            79: /*
        !            80:  * Linear memory description for lgdt and lidt instructions.
        !            81:  */
        !            82: struct desc_p {
        !            83:        u_short limit;
        !            84:        u_long base;
        !            85: } __packed;
        !            86:
        !            87: /*
        !            88:  * Segment size
        !            89:  */
        !            90: #define SIZE_32                0x4     /* 32-bit segment */
        !            91: #define SIZE_16                0x0     /* 16-bit segment */
        !            92: #define SIZE_4K                0x8     /* 4K limit field */
        !            93:
        !            94: /*
        !            95:  * Segment type
        !            96:  */
        !            97: #define ST_ACC         0x01    /* accessed */
        !            98: #define ST_LDT         0x02    /* LDT */
        !            99: #define ST_CALL_GATE_16        0x04    /* 16-bit call gate */
        !           100: #define ST_TASK_GATE   0x05    /* task gate */
        !           101: #define ST_TSS         0x09    /* task segment */
        !           102: #define ST_CALL_GATE   0x0c    /* call gate */
        !           103: #define ST_INTR_GATE   0x0e    /* interrupt gate */
        !           104: #define ST_TRAP_GATE   0x0f    /* trap gate */
        !           105:
        !           106: #define ST_TSS_BUSY    0x02    /* task busy */
        !           107:
        !           108: #define ST_DATA                0x10    /* data */
        !           109: #define ST_DATA_W      0x12    /* data, writable */
        !           110: #define ST_DATA_E      0x14    /* data, expand-down */
        !           111: #define ST_DATA_EW     0x16    /* data, expand-down, writable */
        !           112:
        !           113: #define ST_CODE                0x18    /* code */
        !           114: #define ST_CODE_R      0x1a    /* code, readable */
        !           115: #define ST_CODE_C      0x1c    /* code, conforming */
        !           116: #define ST_CODE_CR     0x1e    /* code, conforming, readable */
        !           117:
        !           118: #define ST_KERN                0x00    /* kernel access only */
        !           119: #define ST_USER                0x60    /* user access */
        !           120:
        !           121: #define ST_PRESENT     0x80    /* segment present */
        !           122:
        !           123: /*
        !           124:  * Task State Segment (TSS)
        !           125:  */
        !           126:
        !           127: #define IO_BITMAP_SIZE         (65536/8 + 1)
        !           128: #define INVALID_IO_BITMAP      0x8000
        !           129:
        !           130: struct tss {
        !           131:        u_long back_link;
        !           132:        u_long esp0, ss0;
        !           133:        u_long esp1, ss1;
        !           134:        u_long esp2, ss2;
        !           135:        u_long cr3;
        !           136:        u_long eip;
        !           137:        u_long eflags;
        !           138:        u_long eax, ecx, edx, ebx;
        !           139:        u_long esp, ebp, esi, edi;
        !           140:        u_long es, cs, ss, ds, fs, gs;
        !           141:        u_long ldt;
        !           142:        u_short dbg_trace;
        !           143:        u_short io_bitmap_offset;
        !           144: #if 0
        !           145:        u_long io_bitmap[IO_BITMAP_SIZE/4+1];
        !           146:        u_long pad[5];
        !           147: #endif
        !           148: } __packed;
        !           149:
        !           150: /*
        !           151:  * i386 flags register
        !           152:  */
        !           153: #define EFL_CF         0x00000001      /* Carry */
        !           154: #define EFL_PF         0x00000004      /* Parity */
        !           155: #define EFL_AF         0x00000010      /* Carry */
        !           156: #define EFL_ZF         0x00000040      /* Zero */
        !           157: #define EFL_SF         0x00000080      /* Sign */
        !           158: #define EFL_TF         0x00000100      /* Trap */
        !           159: #define EFL_IF         0x00000200      /* Interrupt enable */
        !           160: #define EFL_DF         0x00000400      /* Direction */
        !           161: #define EFL_OF         0x00000800      /* Overflow */
        !           162: #define EFL_IOPL       0x00003000      /* IO privilege level: */
        !           163: #define EFL_IOPL_KERN  0x00000000      /* Kernel */
        !           164: #define EFL_IOPL_USER  0x00003000      /* User */
        !           165: #define EFL_NT         0x00004000      /* Nested task */
        !           166: #define EFL_RF         0x00010000      /* Resume without tracing */
        !           167: #define EFL_VM         0x00020000      /* Virtual 8086 mode */
        !           168: #define EFL_AC         0x00040000      /* Alignment Check */
        !           169:
        !           170: /*
        !           171:  * CR0 register
        !           172:  */
        !           173: #define CR0_PG         0x80000000      /* enable paging */
        !           174: #define CR0_CD         0x40000000      /* cache disable */
        !           175: #define CR0_NW         0x20000000      /* no write-through */
        !           176: #define CR0_AM         0x00040000      /* alignment check mask */
        !           177: #define CR0_WP         0x00010000      /* write-protect kernel access */
        !           178: #define CR0_NE         0x00000020      /* handle numeric exceptions */
        !           179: #define CR0_ET         0x00000010      /* extension type is 80387 coprocessor */
        !           180: #define CR0_TS         0x00000008      /* task switch */
        !           181: #define CR0_EM         0x00000004      /* emulate coprocessor */
        !           182: #define CR0_MP         0x00000002      /* monitor coprocessor */
        !           183: #define CR0_PE         0x00000001      /* enable protected mode */
        !           184:
        !           185: /*
        !           186:  * Page table (PTE)
        !           187:  */
        !           188: typedef long *page_table_t;
        !           189:
        !           190: /*
        !           191:  * Page directory entry
        !           192:  */
        !           193: #define PDE_PRESENT    0x00000001
        !           194: #define PDE_WRITE      0x00000002
        !           195: #define PDE_USER       0x00000004
        !           196: #define PDE_WTHRU      0x00000008
        !           197: #define PDE_NCACHE     0x00000010
        !           198: #define PDE_ACCESS     0x00000020
        !           199: #define PDE_SIZE       0x00000080
        !           200: #define PDE_AVAIL      0x00000e00
        !           201: #define PDE_ADDRESS    0xfffff000
        !           202:
        !           203: /*
        !           204:  * Page table entry
        !           205:  */
        !           206: #define PTE_PRESENT    0x00000001
        !           207: #define PTE_WRITE      0x00000002
        !           208: #define PTE_USER       0x00000004
        !           209: #define PTE_WTHRU      0x00000008
        !           210: #define PTE_NCACHE     0x00000010
        !           211: #define PTE_ACCESS     0x00000020
        !           212: #define PTE_DIRTY      0x00000040
        !           213: #define PTE_AVAIL      0x00000e00
        !           214: #define PTE_ADDRESS    0xfffff000
        !           215:
        !           216: /*
        !           217:  *  Virtual and physical address translation
        !           218:  */
        !           219: #define PAGE_DIR(virt)      ((((u_long)(virt)) >> 22) & 0x3ff)
        !           220: #define PAGE_TABLE(virt)    ((((u_long)(virt)) >> 12) & 0x3ff)
        !           221:
        !           222: #define pte_present(pgd, virt)  (pgd[PAGE_DIR(virt)] & PDE_PRESENT)
        !           223:
        !           224: #define page_present(pte, virt) (pte[PAGE_TABLE(virt)] & PTE_PRESENT)
        !           225:
        !           226: #define pgd_to_pte(pgd, virt) \
        !           227:             (page_table_t)phys_to_virt((pgd)[PAGE_DIR(virt)] & PDE_ADDRESS)
        !           228:
        !           229: #define pte_to_page(pte, virt) \
        !           230:             ((pte)[PAGE_TABLE(virt)] & PTE_ADDRESS)
        !           231:
        !           232:
        !           233: /*
        !           234:  * Inline CPU functions
        !           235:  */
        !           236:
        !           237: static __inline void
        !           238: ltr(u_int sel)
        !           239: {
        !           240:        __asm__ __volatile__(
        !           241:                "ltr %%ax\n\t"
        !           242:                "jmp 1f\n\t"
        !           243:                "1:\n\t"
        !           244:                :
        !           245:                :"a" (sel));
        !           246: }
        !           247:
        !           248: static __inline void
        !           249: lgdt(void *gdt_ptr)
        !           250: {
        !           251:        __asm__ __volatile__(
        !           252:                "lgdt (%%eax)\n\t"
        !           253:                "jmp 1f\n\t"
        !           254:                "1:\n\t"
        !           255:                :
        !           256:                :"a" (gdt_ptr));
        !           257: }
        !           258:
        !           259: static __inline void
        !           260: lidt(void *idt_ptr)
        !           261: {
        !           262:        __asm__ __volatile__(
        !           263:                "lidt (%%eax)\n\t"
        !           264:                "jmp 1f\n\t"
        !           265:                "1:\n\t"
        !           266:                :
        !           267:                :"a" (idt_ptr));
        !           268: }
        !           269:
        !           270: static __inline void
        !           271: set_cs(u_short sel)
        !           272: {
        !           273:        __asm__ __volatile__(
        !           274:                "movzx %%ax, %%eax\n\t"
        !           275:                "pushl %%eax\n\t"
        !           276:                "pushl $1f\n\t"
        !           277:                "lret\n\t"
        !           278:                "1:\n\t"
        !           279:                :
        !           280:                :"a" (sel));
        !           281: }
        !           282:
        !           283: static __inline void
        !           284: set_ds(u_short sel)
        !           285: {
        !           286:        __asm__ __volatile__(
        !           287:                "movw %0, %%ds\n\t"
        !           288:                "movw %0, %%es\n\t"
        !           289:                "movw %0, %%fs\n\t"
        !           290:                "movw %0, %%gs\n\t"
        !           291:                "movw %0, %%ss\n\t"
        !           292:                :
        !           293:                :"r" (sel));
        !           294: }
        !           295:
        !           296: static __inline void
        !           297: set_esp(u_long val)
        !           298: {
        !           299:        __asm__ __volatile__(
        !           300:                "movl %0, %%esp"
        !           301:                :
        !           302:                :"r" (val));
        !           303: }
        !           304:
        !           305: static __inline u_long
        !           306: get_esp(void)
        !           307: {
        !           308:        register u_long esp;
        !           309:        __asm__ __volatile__(
        !           310:                "movl %%esp, %0"
        !           311:                :"=r" (esp));
        !           312:        return esp;
        !           313: }
        !           314:
        !           315: static __inline u_long
        !           316: get_eflags(void)
        !           317: {
        !           318:        register u_long eflags;
        !           319:        __asm__ __volatile__(
        !           320:                "pushfl\n\t"
        !           321:                "popl %0\n\t"
        !           322:                :"=r" (eflags));
        !           323:        return eflags;
        !           324: }
        !           325:
        !           326: static __inline void
        !           327: set_eflags(u_long val)
        !           328: {
        !           329:        __asm__ __volatile__(
        !           330:                "pushl %0\n\t"
        !           331:                "popfl\n\t"
        !           332:                :
        !           333:                :"r" (val));
        !           334: }
        !           335:
        !           336: static __inline u_long
        !           337: get_cr0(void)
        !           338: {
        !           339:        register u_long _cr0;
        !           340:        __asm__ __volatile__(
        !           341:                "movl %%cr0, %0"
        !           342:                :"=r" (_cr0)
        !           343:                :);
        !           344:        return _cr0;
        !           345: }
        !           346:
        !           347: static __inline void
        !           348: set_cr0(u_long _cr0)
        !           349: {
        !           350:        __asm__ __volatile__(
        !           351:                "movl %0, %%cr0"
        !           352:                :
        !           353:                :"r" (_cr0));
        !           354: }
        !           355:
        !           356: static __inline u_long
        !           357: get_cr2(void)
        !           358: {
        !           359:        register u_long _cr2;
        !           360:        __asm__ __volatile__(
        !           361:                "movl %%cr2, %0"
        !           362:                :"=r" (_cr2)
        !           363:                :);
        !           364:        return _cr2;
        !           365: }
        !           366:
        !           367: static __inline u_long
        !           368: get_cr3(void)
        !           369: {
        !           370:        register u_long _cr3;
        !           371:        __asm__ __volatile__(
        !           372:                "movl %%cr3, %0"
        !           373:                :"=r" (_cr3)
        !           374:                :);
        !           375:        return _cr3;
        !           376: }
        !           377:
        !           378: static __inline void
        !           379: set_cr3(u_long _cr3)
        !           380: {
        !           381:        __asm__ __volatile__(
        !           382:                "movl %0, %%cr3"
        !           383:                :
        !           384:                :"r" (_cr3));
        !           385: }
        !           386:
        !           387: /*
        !           388:  * Enable/disable CPU interrupt
        !           389:  */
        !           390: #define sti() __asm__ ("sti"::)
        !           391: #define cli() __asm__ ("cli"::)
        !           392:
        !           393: /*
        !           394:  * Flush translation lookaside buffer for
        !           395:  * specified page
        !           396:  */
        !           397: static __inline void
        !           398: flush_tlb_page(void *pg)
        !           399: {
        !           400:        __asm__ __volatile__(
        !           401:                "invlpg (%0)"
        !           402:                :
        !           403:                : "r" (pg)
        !           404:                : "memory");
        !           405: }
        !           406:
        !           407: /*
        !           408:  * Flush translation lookaside buffer
        !           409:  */
        !           410: static __inline void
        !           411: flush_tlb(void)
        !           412: {
        !           413:        __asm__ __volatile__(
        !           414:                "movl %%cr3, %%eax\n\t"
        !           415:                "movl %%eax, %%cr3\n\t"
        !           416:                :
        !           417:                :
        !           418:                : "ax");
        !           419: }
        !           420:
        !           421: /*
        !           422:  * Check if CPU supports "invlpg" (TLB flush per page) function.
        !           423:  * Return true if supported.
        !           424:  *
        !           425:  * TODO: I can not test this because I do not have 386 system. :-(
        !           426:  */
        !           427: static __inline int
        !           428: check_invlpg(void)
        !           429: {
        !           430:        int _i486 = 0;
        !           431:
        !           432:        __asm__ __volatile__(
        !           433:                "pushfl\n\t"
        !           434:                "popl %%eax\n\t"
        !           435:                "movl %%eax, %%ecx\n\t"
        !           436:                "xorl $0x240000, %%eax\n\t"
        !           437:                "pushl %%eax\n\t"
        !           438:                "popfl\n\t"
        !           439:                "pushfl\n\t"
        !           440:                "popl %%eax\n\t"
        !           441:                "xorl %%ecx, %%eax\n\t"
        !           442:                "pushl %%ecx\n\t"
        !           443:                "popfl\n\t"
        !           444:                "testl $0x40000, %%eax\n\t"
        !           445:                "je 1f\n\t"
        !           446:                "movl $1, %0\n\t"
        !           447:                "1:\n\t"
        !           448:                : "=r" (_i486)
        !           449:                :);
        !           450:        return _i486;
        !           451: }
        !           452:
        !           453: /*
        !           454:  * I/O instructions
        !           455:  */
        !           456: static __inline void
        !           457: outb(unsigned char value, int port)
        !           458: {
        !           459:        __asm__ __volatile__(
        !           460:                "outb %b0, %w1"
        !           461:                ::"a" (value),"Nd" (port));
        !           462: }
        !           463:
        !           464: static __inline unsigned char
        !           465: inb(int port)
        !           466: {
        !           467:        unsigned char _val;
        !           468:        __asm__ __volatile__(
        !           469:                "inb %w1, %b0"
        !           470:                :"=a" (_val)
        !           471:                :"Nd" (port));
        !           472:        return _val;
        !           473: }
        !           474:
        !           475: static __inline void
        !           476: outb_p(unsigned char value, int port)
        !           477: {
        !           478:        __asm__ __volatile__(
        !           479:                "outb %b0, %w1\n\t"
        !           480:                "outb %%al, $0x80\n\t"
        !           481:                ::"a" (value),"Nd" (port));
        !           482: }
        !           483:
        !           484: static __inline unsigned char
        !           485: inb_p(int port)
        !           486: {
        !           487:        unsigned char _val;
        !           488:        __asm__ __volatile__(
        !           489:                "inb %w1, %b0\n\t"
        !           490:                "outb %%al, $0x80\n\t"
        !           491:                :"=a" (_val)
        !           492:                :"Nd" (port));
        !           493:        return _val;
        !           494: }
        !           495:
        !           496: extern void tss_set(u_long kstack);
        !           497: extern u_long tss_get(void);
        !           498: extern void trap_set(int vector, void *handler);
        !           499:
        !           500: extern void cpu_reset(void);
        !           501: extern void cpu_init(void);
        !           502:
        !           503: #endif /* !__ASSEMBLY__ */
        !           504:
        !           505: #endif /* !_I386_CPU_H */

CVSweb