i386.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #ifndef __I386_H_
  2. #define __I386_H_
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. static __inline unsigned char inb(int port)
  7. {
  8. unsigned char data;
  9. __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
  10. return data;
  11. }
  12. static __inline unsigned short inw(int port)
  13. {
  14. unsigned short data;
  15. __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
  16. return data;
  17. }
  18. static __inline unsigned int inl(int port)
  19. {
  20. unsigned int data;
  21. __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
  22. return data;
  23. }
  24. static __inline void insl(int port, void *addr, int cnt)
  25. {
  26. __asm __volatile("cld\n\trepne\n\tinsl" :
  27. "=D" (addr), "=c" (cnt) :
  28. "d" (port), "0" (addr), "1" (cnt) :
  29. "memory", "cc");
  30. }
  31. static __inline void outb(int port, unsigned char data)
  32. {
  33. __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
  34. }
  35. static __inline void outw(int port, unsigned short data)
  36. {
  37. __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
  38. }
  39. /* Gate descriptors are slightly different*/
  40. struct Gatedesc {
  41. unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment
  42. unsigned gd_ss : 16; // segment selector
  43. unsigned gd_args : 5; // # args, 0 for interrupt/trap gates
  44. unsigned gd_rsv1 : 3; // reserved(should be zero I guess)
  45. unsigned gd_type :4; // type(STS_{TG,IG32,TG32})
  46. unsigned gd_s : 1; // must be 0 (system)
  47. unsigned gd_dpl : 2; // descriptor(meaning new) privilege level
  48. unsigned gd_p : 1; // Present
  49. unsigned gd_off_31_16 : 16; // high bits of offset in segment
  50. };
  51. /* Pseudo-descriptors used for LGDT, LLDT and LIDT instructions*/
  52. struct Pseudodesc {
  53. rt_uint16_t pd__garbage; // LGDT supposed to be from address 4N+2
  54. rt_uint16_t pd_lim; // Limit
  55. rt_uint32_t pd_base __attribute__ ((packed)); // Base address
  56. };
  57. #define SETGATE(gate, istrap, sel, off, dpl) \
  58. { \
  59. (gate).gd_off_15_0 = (rt_uint32_t) (off) & 0xffff; \
  60. (gate).gd_ss = (sel); \
  61. (gate).gd_args = 0; \
  62. (gate).gd_rsv1 = 0; \
  63. (gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; \
  64. (gate).gd_s = 0; \
  65. (gate).gd_dpl = dpl; \
  66. (gate).gd_p = 1; \
  67. (gate).gd_off_31_16 = (rt_uint32_t) (off) >> 16; \
  68. }
  69. /* Global descriptor numbers*/
  70. #define GD_KT 0x08 // kernel text
  71. #define GD_KD 0x10 // kernel data
  72. #define GD_UT 0x18 // user text
  73. #define GD_UD 0x20 // user data
  74. /* Application segment type bits*/
  75. #define STA_X 0x8 // Executable segment
  76. #define STA_E 0x4 // Expand down(non-executable segments)
  77. #define STA_C 0x4 // Conforming code segment(executable only)
  78. #define STA_W 0x2 // Writeable(non-executable segments)
  79. #define STA_R 0x2 // Readable(executable segments)
  80. #define STA_A 0x1 // Accessed
  81. /* System segment type bits*/
  82. #define STS_T16A 0x1 // Available 16-bit TSS
  83. #define STS_LDT 0x2 // Local Descriptor Table
  84. #define STS_T16B 0x3 // Busy 16-bit TSS
  85. #define STS_CG16 0x4 // 16-bit Call Gate
  86. #define STS_TG 0x5 // Task Gate / Coum Transmitions
  87. #define STS_IG16 0x6 // 16-bit Interrupt Gate
  88. #define STS_TG16 0x7 // 16-bit Trap Gate
  89. #define STS_T32A 0x9 // Available 32-bit TSS
  90. #define STS_T32B 0xb // Busy 32-bit TSS
  91. #define STS_CG32 0xc // 32-bit Call Gate
  92. #define STS_IG32 0xe // 32-bit Interrupt Gate
  93. #define STS_TG32 0xf // 32-bit Trap Gate
  94. #endif