Advertisement
Guest User

Untitled

a guest
Jul 3rd, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. //GDT Entry
  2. class EntryGDT {
  3.     private:
  4.         uint32_t        limit_low : 16; //The lower 16 bits of the limit
  5.         uint32_t         base_low : 24; //The lower 24 bits of base
  6.     public:
  7.         //Access byte used in GDT entries
  8.         //    See http://files.osdev.org/mirrors/geezer/os/pm.htm:
  9.         //        discr_type bit: 1 is code/data selector, 0 is TSS, LDT, or Gate (but also says earlier the same as the below):
  10.         //    See http://wiki.osdev.org/Global_Descriptor_Table:
  11.         //        discr_type bit: 1 is code selector, 0 is data selector
  12.         //    See http://wiki.osdev.org/Segmentation
  13.         //        discr_type bit: 1 is code/data selector, 0 is system
  14.         union Access {
  15.             class AccessByte { public:
  16.                 bool     accessed :  1; //Initialized to 0; CPU sets when segment is accessed
  17.                 bool           rw :  1; //Writable bit for data selectors / Readable bit for code selectors
  18.                 bool     dir_conf :  1; //For data selectors, 0 the segment grows up, 1 the segment grows down.  For code selectors, 0 only executable by processes with exactly privilege, 1 lower is okay too
  19.                 bool   discr_type :  1; //See above
  20.                 bool       unused :  1; //Initialized to 1
  21.                 uint8_t privilege :  2; //Ring
  22.                 bool      present :  1; //Must be 1 for all valid selectors
  23.  
  24.                 static AccessByte get_null(void);
  25.                 static AccessByte get_selector_datacode(uint8_t ring);
  26.             } flags; //Will be packed since EntryGDT is packed
  27.             uint8_t          byte :  8;
  28.         } access;
  29.     private:
  30.         uint32_t       limit_high :  4; //The upper 4 bits of the limit
  31.     public:
  32.         //Flags.  Can't be in a struct because it is not byte-aligned and it would screw up the packing.
  33.         int          flags_unused :  2; //(at least on x86)
  34.         bool           flags_size :  1; //0 is 16-bit protected mode, 1 is 32-bit protected mode
  35.         bool    flags_granularity :  1; //If 0 the limit is in 1B blocks (byte granularity), if 1 the limit is in 4KiB blocks (page granularity).
  36.     private:
  37.         uint32_t        base_high :  8; //The upper 8 bits of the base.
  38.  
  39.     public:
  40.         void set_limit(uint32_t limit);
  41.         uint32_t get_limit(void) const;
  42.  
  43.         void set_base(uint32_t base);
  44.         uint32_t get_base(void) const;
  45.  
  46.         static void construct(EntryGDT* entry, uint32_t base, uint32_t limit, Access::AccessByte access);
  47. } __attribute__((packed));
  48.  
  49.  
  50. EntryGDT::Access::AccessByte EntryGDT::Access::AccessByte::get_null(void) {
  51.     EntryGDT::Access::AccessByte result;
  52.     result.  accessed = 0;
  53.     result.        rw = 0;
  54.     result.  dir_conf = 0;
  55.     result.discr_type = 0;
  56.     result.    unused = 0;
  57.     result. privilege = 0;
  58.     result.   present = 0;
  59.     return result;
  60. }
  61. EntryGDT::Access::AccessByte EntryGDT::Access::AccessByte::get_selector_datacode(uint8_t ring) {
  62.     EntryGDT::Access::AccessByte result;
  63.     result.  accessed =    0;
  64.     result.        rw =    1;
  65.     result.  dir_conf =    0;
  66.     result.discr_type =    1;
  67.     result.    unused =    1;
  68.     result. privilege = ring;
  69.     result.   present =    1;
  70.     return result;
  71. }
  72.  
  73. void EntryGDT::set_limit(uint32_t limit) {
  74.     limit_low  =  limit & 0x0FFFF     ;
  75.     limit_high = (limit & 0xF0000)>>16;
  76. }
  77. uint32_t EntryGDT::get_limit(void) const {
  78.     return (limit_high<<16) | limit_low;
  79. }
  80.  
  81. void EntryGDT::set_base(uint32_t base) {
  82.     base_low  =  base & 0x00FFFFFF     ;
  83.     base_high = (base & 0xFF000000)>>24;
  84. }
  85. uint32_t EntryGDT::get_base(void) const {
  86.     return (base_high<<24) | base_low;
  87. }
  88.  
  89. void EntryGDT::construct(EntryGDT* entry, uint32_t base, uint32_t limit, Access::AccessByte access) {
  90.     entry->set_base(base);
  91.     entry->set_limit(limit);
  92.  
  93.     entry->access.flags = access;
  94.  
  95.     entry->     flags_unused = 0;
  96.     entry->       flags_size = 1; //32-bit mode segment
  97.     entry->flags_granularity = 0; //The limit is a 32-bit number and represents the number of bytes, NOT the number of 4KiB blocks
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement