Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/include/arch/i386.h need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #ifndef __I386_H__
0019 #define __I386_H__
0020 #include"types.h"
0021 
0022 /* EFLAGS bits */
0023 #define F_CF 0x01               /* carry */
0024 #define F_1 0x02
0025 #define F_PF 0x04               /* parity */
0026 #define F_AF 0x10               /* auxiliary carry */
0027 #define F_ZF 0x40               /* zero */
0028 #define F_SF 0x80               /* sign */
0029 #define F_TF 0x100              /* trap */
0030 #define F_IF 0x200              /* interrupt enable */
0031 #define F_DF 0x400              /* direction */
0032 #define F_OF 0x800              /* overflow */
0033 #define F_IOPL0 0x1000
0034 #define F_IOPL1 0x2000
0035 #define F_IOPL 0x3000           /* I/O privilege level */
0036 #define F_NT 0x4000             /* nested task */
0037 #define F_RF 0x10000            /* resume */
0038 #define F_VM 0x20000            /* virtual 8086 mode */
0039 #define F_AC 0x40000            /* alignment check */
0040 #define F_VIF 0x80000           /* virtual interrupt flag */
0041 #define F_VIP 0x100000          /* virtual interrupt pending */
0042 #define F_ID 0x200000           /* identification flag */
0043 
0044 /* Page table entry bits */
0045 #define PTE_P 0x01              /* present */
0046 #define PTE_RW 0x02             /* read/write */
0047 #define PTE_US 0x04             /* user/supervisor */
0048 #define PTE_A 0x20              /* accessed */
0049 #define PTE_D 0x40              /* dirty */
0050 #define PTE_AVAIL0 0x200
0051 #define PTE_AVAIL1 0x400
0052 #define PTE_AVAIL2 0x800
0053 #define PTE_FRAME 0xFFFFF000    /* page frame address */
0054 
0055 #define PIC1_BASE_IRQ 0x20
0056 #define PIC2_BASE_IRQ 0x28
0057 
0058 extern uint16 serial_port1;
0059 
0060 typedef struct _tss
0061 {
0062   /* 80386 hardware data */
0063   uint16 usPrevious;            /* previous task selector */
0064   uint16 usReserved0;
0065   uint32 ulESP0;                /* ring 0 stack pointer */
0066   uint16 usSS0;                 /* ring 0 stack selector */
0067   uint16 usReserved1;
0068   uint32 ulESP1;                /* ring 1 stack pointer */
0069   uint16 usSS1;                 /* ring 1 stack selector */
0070   uint16 usReserved2;
0071   uint32 ulESP2;                /* ring 2 stack pointer */
0072   uint16 usSS2;                 /* ring 2 stack selector */
0073   uint16 usReserved3;
0074   void *pCR3;                   /* page directory */
0075   uint32 ulEIP;                 /* instruction pointer */
0076   uint32 ulEFlags;
0077   uint32 ulEAX, ulECX, ulEDX, ulEBX, ulESP, ulEBP, ulESI, ulEDI;
0078   uint16 usES, usReserved4, usCS, usReserved5, usSS, usReserved6,
0079     usDS, usReserved7, usFS, usReserved8, usGS, usReserved9;
0080   uint16 usLDT, usReserved10;
0081   uint32 fTrap:1;
0082   uint32 uReserved11:15;
0083   uint16 usIOMap;
0084 } tss;
0085 
0086 /* Bit-field definitions for a segment descriptor */
0087 typedef struct _descriptor
0088 {
0089   uint32 uLimit0:16;      /* limit (bits 0-15) */
0090   uint32 pBase0:16;       /* base (bits 0-15) */
0091   uint32 pBase1:8;        /* base (bits 16-23) */
0092   uint32 uType:5;         /* type */
0093   uint32 uDPL:2;          /* privilege level */
0094   uint32 fPresent:1;      /* present */
0095   uint32 uLimit1:4;       /* limit (bits 16-19) */
0096   uint32 f:1;             /* available */
0097   uint32 f0:1;            /* reserved */
0098   uint32 fX:1;            /* varies (32-bit) */
0099   uint32 fGranularity:1;  /* granularity */
0100   uint32 pBase2:8;        /* base (bits 24-31) */
0101 } descriptor;
0102 
0103 typedef struct _idt_descriptor
0104 {
0105   uint32 pBase0:16;       /* Offset (bits 0-15) */
0106   uint32 pSeg:16;         /* Segment */
0107   uint32 fReserved:5;     /* reserved */
0108   uint32 fZero0:3;        /* zeroed */
0109   uint32 fType:3;         /* 0x6 = interrupt, 0x7 = trap */
0110   uint32 f32bit:1;        /* 1 = 32 bit size of gate, 0 = 16 bit */
0111   uint32 fZero1:1;        /* zeroed */
0112   uint32 uDPL:2;          /* Descriptor privilege level */
0113   uint32 fPresent:1;      /* present bit */
0114   uint32 pBase1:16;       /* Offset (bits 16-31) */
0115 } idt_descriptor;
0116 
0117 static inline void
0118 cli (void)
0119 {
0120 
0121   asm volatile ("cli");
0122 }
0123 
0124 static inline void
0125 sti (void)
0126 {
0127 
0128   asm volatile ("sti");
0129 }
0130 
0131 static inline void hlt (void) __attribute__ ((noreturn));
0132 static inline void
0133 hlt (void)
0134 {
0135 
0136   for (;;)
0137     asm volatile ("hlt");
0138 }
0139 
0140 /* Get physical address of the page directory in CR3 */
0141 static inline void *
0142 get_pdbr (void)
0143 {
0144 
0145   void *p;
0146 
0147   asm volatile ("movl %%cr3,%0":"=r" (p):);
0148   return p;
0149 }
0150 
0151 #if 0
0152 static inline void
0153 jmp_gate (uint16 us)
0154 {
0155   uint16 gate[3];
0156 
0157   asm volatile ("movw %1,0x4(%0)\n" /* Set segment selector -- ignore 4-byte offset */
0158                 "ljmp *(%0)"::"r" (gate),"r"(us));
0159 }
0160 
0161 static inline void
0162 call_gate (uint16 us)
0163 {
0164   uint16 gate[3];
0165 
0166   gate[2] = us;                 /* Set segment selector -- ignore 4-byte offset */
0167 
0168   asm volatile ("lcall *(%0)"::"r" (gate));
0169 }
0170 #endif
0171 
0172 static inline void
0173 bochs_instr_trace (void)
0174 {
0175 
0176 
0177   asm volatile ("outw %%ax, (%%dx)"::"a" (0x8AE3), "d" (0x8A00));
0178 
0179 }
0180 
0181 
0182 static inline void
0183 bochs_regs_trace (void)
0184 {
0185 
0186 
0187   asm volatile ("outw %%ax, (%%dx)"::"a" (0x8AE5), "d" (0x8A00));
0188 
0189 }
0190 
0191 
0192 static inline void
0193 invalidate_page (void *va)
0194 {
0195 
0196 
0197   asm volatile ("invlpg %0"::"m" (*(char *) va));
0198 
0199 }
0200 
0201 
0202 static inline void
0203 flush_tlb_all ()
0204 {
0205 
0206   uint32 tmpreg;
0207 
0208   asm volatile ("movl %%cr3, %0\n" "movl %0, %%cr3":"=&r" (tmpreg):);
0209 
0210 }
0211 
0212 
0213 static inline uint8
0214 inb (uint16 usPort)
0215 {
0216 
0217   uint8 uch;
0218 
0219   asm volatile ("inb %1,%0":"=a" (uch):"Nd" (usPort));
0220   return uch;
0221 }
0222 
0223 
0224 static inline uint16
0225 inw (uint16 usPort)
0226 {
0227 
0228   uint16 us;
0229 
0230   asm volatile ("inw %1,%0":"=a" (us):"Nd" (usPort));
0231   return us;
0232 }
0233 
0234 static inline uint32
0235 inl (uint16 usPort)
0236 {
0237 
0238   uint32 ul;
0239 
0240   asm volatile ("inl %1,%0":"=a" (ul):"Nd" (usPort));
0241   return ul;
0242 }
0243 
0244 static inline void
0245 insb (uint16 usPort, void *buf, int count)
0246 {
0247 
0248   asm volatile ("cld; rep insb"
0249                 :"=c" (count), "=D" (buf)
0250                 :"0" (count), "1" (buf), "d" (usPort)
0251                 :"memory","flags");
0252 }
0253 
0254 static inline void
0255 insw (uint16 usPort, void *buf, int count)
0256 {
0257 
0258   asm volatile ("cld; rep insw"
0259                 :"=c" (count), "=D" (buf)
0260                 :"0" (count), "1" (buf), "d" (usPort)
0261                 :"memory","flags");
0262 }
0263 
0264 static inline void
0265 insl (uint16 usPort, void *buf, int count)
0266 {
0267 
0268   asm volatile ("cld; rep insl"
0269                 :"=c" (count), "=D" (buf)
0270                 :"0" (count), "1" (buf), "d" (usPort)
0271                 :"memory","flags");
0272 }
0273 
0274 static inline void
0275 insb_rev (uint16 usPort, void *buf, int count)
0276 {
0277 
0278   asm volatile ("std; rep insb"
0279                 :"=c" (count), "=D" (buf)
0280                 :"0" (count), "1" (buf), "d" (usPort)
0281                 :"memory","flags");
0282 }
0283 
0284 static inline void
0285 insw_rev (uint16 usPort, void *buf, int count)
0286 {
0287 
0288   asm volatile ("std; rep insw"
0289                 :"=c" (count), "=D" (buf)
0290                 :"0" (count), "1" (buf), "d" (usPort)
0291                 :"memory","flags");
0292 }
0293 
0294 static inline void
0295 insl_rev (uint16 usPort, void *buf, int count)
0296 {
0297 
0298   asm volatile ("std; rep insl"
0299                 :"=c" (count), "=D" (buf)
0300                 :"0" (count), "1" (buf), "d" (usPort)
0301                 :"memory","flags");
0302 }
0303 
0304 static inline void
0305 outsb (uint16 usPort, void *buf, int count)
0306 {
0307   asm volatile ("cld; rep outsb"
0308                 :"=S" (buf), "=c" (count)
0309                 :"0" (buf), "1" (count), "d" (usPort)
0310                 :"flags");
0311 }
0312 
0313 static inline void
0314 outsw (uint16 usPort, void *buf, int count)
0315 {
0316   asm volatile ("cld; rep outsw"
0317                 :"=S" (buf), "=c" (count)
0318                 :"0" (buf), "1" (count), "d" (usPort)
0319                 :"flags");
0320 }
0321 
0322 static inline void
0323 outsl (uint16 usPort, void *buf, int count)
0324 {
0325   asm volatile ("cld; rep outsl"
0326                 :"=S" (buf), "=c" (count)
0327                 :"0" (buf), "1" (count), "d" (usPort)
0328                 :"flags");
0329 }
0330 
0331 
0332 static inline void
0333 outsb_rev (uint16 usPort, void *buf, int count)
0334 {
0335   asm volatile ("std; rep outsb"
0336                 :"=S" (buf), "=c" (count)
0337                 :"0" (buf), "1" (count), "d" (usPort)
0338                 :"flags");
0339 }
0340 
0341 static inline void
0342 outsw_rev (uint16 usPort, void *buf, int count)
0343 {
0344   asm volatile ("std; rep outsw"
0345                 :"=S" (buf), "=c" (count)
0346                 :"0" (buf), "1" (count), "d" (usPort)
0347                 :"flags");
0348 }
0349 
0350 static inline void
0351 outsl_rev (uint16 usPort, void *buf, int count)
0352 {
0353   asm volatile ("std; rep outsl"
0354                 :"=S" (buf), "=c" (count)
0355                 :"0" (buf), "1" (count), "d" (usPort)
0356                 :"flags");
0357 }
0358 
0359 static inline void
0360 outb (uint8 uch, uint16 usPort)
0361 {
0362 
0363   asm volatile ("outb %0,%1"::"a" (uch), "Nd" (usPort));
0364 }
0365 
0366 
0367 static inline void
0368 outw (uint16 us, uint16 usPort)
0369 {
0370 
0371   asm volatile ("outw %0,%1"::"a" (us), "Nd" (usPort));
0372 }
0373 
0374 static inline void
0375 outl (uint32 ul, uint16 usPort)
0376 {
0377 
0378   asm volatile ("outl %0,%1"::"a" (ul), "Nd" (usPort));
0379 }
0380 
0381 static inline void *
0382 sgdtr (void)
0383 {
0384   uint8 buf[6];
0385   asm volatile ("sgdt %0":"=m" (buf));
0386   return (void *) *((uint32 *) (buf + 2));
0387 }
0388 
0389 static inline void *
0390 sidtr (void)
0391 {
0392   uint8 buf[6];
0393   asm volatile ("sidt %0":"=m" (buf));
0394   return (void *) *((uint32 *) (buf + 2));
0395 }
0396 
0397 static inline uint16
0398 sgdtr_limit (void)
0399 {
0400   uint8 buf[6];
0401   asm volatile ("sgdt %0":"=m" (buf));
0402   return *((uint16 *) buf);
0403 }
0404 
0405 static inline uint16
0406 sidtr_limit (void)
0407 {
0408   uint8 buf[6];
0409   asm volatile ("sidt %0":"=m" (buf));
0410   return *((uint16 *) buf);
0411 }
0412 
0413 #define GET_ESP(esp) asm volatile ("movl %%esp, %0":"=r" (esp):);
0414 
0415 static inline uint16
0416 hw_str (void)
0417 {
0418 
0419   uint16 us;
0420 
0421   asm volatile ("str %0":"=r" (us):);
0422   return us;
0423 }
0424 
0425 
0426 static inline void
0427 hw_ltr (uint16 us)
0428 {
0429 
0430   asm volatile ("ltr %0"::"r" (us));
0431 
0432 }
0433 
0434 
0435 static inline uint32
0436 ffs (uint32 word)
0437 {
0438   asm volatile ("bsfl %1,%0":"=r" (word):"rm" (word));
0439   return word;
0440 }
0441 
0442 static inline int
0443 fls(uint32 x)
0444 {
0445   int r;
0446   asm("bsrl %1,%0\n\t"
0447       "jnz 1f\n\t"
0448       "movl $-1,%0\n"
0449       "1:" : "=r" (r) : "rm" (x));
0450   return r + 1;
0451 }
0452 
0453 
0454 #define RDTSC(var)                                              \
0455   {                                                             \
0456     uint32 var##_lo, var##_hi;                                  \
0457     asm volatile("rdtsc" : "=a"(var##_lo), "=d"(var##_hi));     \
0458     var = var##_hi;                                             \
0459     var <<= 32;                                                 \
0460     var |= var##_lo;                                            \
0461   }
0462 
0463 /* serializing instruction, ring0 */
0464 #define SERIALIZE0 asm volatile ("lldt %%ax"::"a" (0));
0465 
0466 static inline void *
0467 memset (void *p, int ch, uint32 cb)
0468 {
0469 
0470   asm volatile ("cld; rep stosb"
0471                 :"=D" (p), "=a" (ch), "=c" (cb)
0472                 :"0" (p), "1" (ch), "2" (cb)
0473                 :"memory","flags");
0474   return p;
0475 }
0476 
0477 static inline void *
0478 memcpy (void *pDest, const void *pSrc, uint32 cb)
0479 {
0480   asm volatile ("cld; rep movsb"
0481                 :"=c" (cb), "=D" (pDest), "=S" (pSrc)
0482                 :"0" (cb), "1" (pDest), "2" (pSrc)
0483                 :"memory","flags");
0484   return pDest;
0485 }
0486 
0487 static inline uint32
0488 strlen (const char *s)
0489 {
0490   uint32 i=0;
0491   while (*(s++)) i++;
0492   return i;
0493 }
0494 
0495 static inline void *
0496 strcpy (char *dest, const char *src)
0497 {
0498   return memcpy (dest, src, strlen (src) + 1);
0499 }
0500 
0501 static inline int
0502 strcmp (const char *a, const char *b)
0503 {
0504   int i = 0;
0505   while (*a && *b) {
0506     i = *(a++) - *(b++);
0507     if (i != 0) return i;
0508   }
0509   i += *a - *b;
0510   return i;
0511 }
0512 
0513 static inline int
0514 strncmp (const char *a, const char *b, int n)
0515 {
0516   int i = 0;
0517   while (*a && *b && n-- > 0) {
0518     i = *(a++) - *(b++);
0519     if (i != 0) return i;
0520   }
0521   return i;
0522 }
0523 
0524 static inline uint64
0525 rdmsr (uint32 ecx)
0526 {
0527   uint32 edx, eax;
0528 
0529   asm volatile ("rdmsr":"=d" (edx), "=a" (eax):"c" (ecx));
0530   return (((uint64) edx) << 32) | ((uint64) eax);
0531 }
0532 
0533 static inline void
0534 wrmsr (uint32 ecx, uint64 val)
0535 {
0536   uint32 edx, eax;
0537 
0538   edx = (uint32) (val >> 32);
0539   eax = (uint32) val;
0540 
0541   asm volatile ("wrmsr"::"d" (edx), "a" (eax), "c" (ecx));
0542 }
0543 
0544 static inline u32
0545 div_u64_u32_u32 (u64 a, u32 b)
0546 {
0547   uint32 c, a_hi, a_lo, r;
0548 
0549   a_hi = (u32) (a >> 32);
0550   a_lo = (u32) (a & 0xFFFFFFFF);
0551   asm volatile ("div %2"
0552                 :"=a" (c), "=d" (r)
0553                 :"r" (b), "a" (a_lo), "d" (a_hi));
0554 
0555   return c;
0556 }
0557 
0558 
0559 /* from Linux */
0560 
0561 #define __constant_cpu_to_be32(x) (___constant_swab32((x)))
0562 #define ___constant_swab32(x)                   \
0563   ((u32)                                        \
0564    ((((u32)(x) & (u32)0x000000ffUL) << 24) |    \
0565     (((u32)(x) & (u32)0x0000ff00UL) <<  8) |    \
0566     (((u32)(x) & (u32)0x00ff0000UL) >>  8) |    \
0567     (((u32)(x) & (u32)0xff000000UL) >> 24)))
0568 #define __constant_cpu_to_le32(x) (x)
0569 #define cpu_to_le16(x) (x)
0570 #define __cpu_to_le16(x) (x)
0571 #define __cpu_to_le32(x) (x)
0572 #define __cpu_to_le64(x) (x)
0573 #define __cpu_to_be32(x) (___constant_swab32(x))
0574 #define __be32_to_cpu(x) (___constant_swab32(x))
0575 #define __le32_to_cpu(x) (x)
0576 #define __le64_to_cpu(x) (x)
0577 
0578 
0579 #define unlikely(x) (x)
0580 #define likely(x) (x)
0581 
0582 
0583 #endif
0584 
0585 /* 
0586  * Local Variables:
0587  * indent-tabs-mode: nil
0588  * mode: C
0589  * c-file-style: "gnu"
0590  * c-basic-offset: 2
0591  * End: 
0592  */
0593 
0594 /* vi: set et sw=2 sts=2: */