blob: 27ee37efb1b22a5d79d354f8a97f446e7e5a874b [file] [log] [blame]
Corey Tabaka84697242009-03-26 02:32:01 -04001/*
2 * Copyright (c) 2009 Corey Tabaka
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <compiler.h>
25#include <arch/x86/descriptor.h>
26
27/* not the best way to do this, but easy for now */
28typedef struct {
29 uint16_t limit_15_0;
30 uint16_t base_15_0;
31 uint8_t base_23_16;
32
33 uint8_t type : 4;
34 uint8_t s : 1;
35 uint8_t dpl : 2;
36 uint8_t p : 1;
37
38 uint8_t limit_19_16 : 4;
39 uint8_t avl : 1;
40 uint8_t reserved_0 : 1;
41 uint8_t d_b : 1;
42 uint8_t g : 1;
43
44 uint8_t base_31_24;
45} __PACKED seg_desc_t;
46
47extern seg_desc_t _gdt[];
48
49void set_global_desc(seg_sel_t sel, void *base, uint32_t limit,
50 uint8_t present, uint8_t ring, uint8_t sys, uint8_t type, uint8_t gran, uint8_t bits)
51{
52 // convert selector into index
53 uint16_t index = sel >> 3;
54
55 _gdt[index].limit_15_0 = limit & 0x0000ffff;
56 _gdt[index].limit_19_16 = (limit & 0x000f0000) >> 16;
57
58 _gdt[index].base_15_0 = ((uint32_t) base) & 0x0000ffff;
59 _gdt[index].base_23_16 = (((uint32_t) base) & 0x00ff0000) >> 16;
60 _gdt[index].base_31_24 = ((uint32_t) base) >> 24;
61
62 _gdt[index].type = type & 0x0f; // segment type
63 _gdt[index].p = present != 0; // present
64 _gdt[index].dpl = ring & 0x03; // descriptor privilege level
65 _gdt[index].g = gran != 0; // granularity
66 _gdt[index].s = sys != 0; // system / non-system
67 _gdt[index].d_b = bits != 0; // 16 / 32 bit
68}