aboutsummaryrefslogtreecommitdiff
path: root/src/gdt/segmentdescriptor.cc
blob: 94205c8ae5d5f26e947015c06fd1bb859162b4d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "../gdt.h"

GDT::SegmentDescriptor::SegmentDescriptor(uint32_t base, uint32_t limit, GDT::SegmentDescriptor::Access a) : access(a) {
  // store base
  base_15_0 = base & 0xffff;
  base_23_16 = (base >> 16) & 0xff;
  base_31_24 = (base >> 24) & 0xff;

  // store limit
  if (limit <= 0xffffu) {  // 16-bit address space
    limit_15_0 = limit & 0xffff;
    limit_19_16 = 0;
  } else {
    db = 1;
    // limit is uint32_t, which we need to store in limit_19_16 and limit_15_0, a total of 20 bits
    limit = limit >> 12;
    limit_15_0 = limit & 0xffff;
    limit_19_16 = (limit >> 16) & 0xf;
  }

  granularity = 1;
}

uint32_t GDT::SegmentDescriptor::base() const {
  uint32_t base = base_31_24;
  base = (base << 8) + base_23_16;
  base = (base << 16) + base_15_0;
  return base;
}

uint32_t GDT::SegmentDescriptor::limit() const {
  uint32_t limit = 0;
  if (db == 1) {
    limit = limit_19_16;
    limit = limit << 16;
  }
  limit += limit_15_0;
  return 0;
}