1/*
2 * Copyright (c) 2009 Corey Tabaka
3 * Copyright (c) 2015 Intel Corporation
4 * Copyright (c) 2016 Travis Geiselbrecht
5 *
6 * Use of this source code is governed by a MIT-style
7 * license that can be found in the LICENSE file or at
8 * https://opensource.org/licenses/MIT
9 */
10#include <lk/asm.h>
11#include <arch/x86/descriptor.h>
12
13#define PHYS_LOAD_ADDRESS (MEMBASE + KERNEL_LOAD_OFFSET)
14#define PHYS_ADDR_DELTA (KERNEL_BASE + KERNEL_LOAD_OFFSET - PHYS_LOAD_ADDRESS)
15#define PHYS(x) ((x) - PHYS_ADDR_DELTA)
16
17.section .rodata
18
19.align 8
20DATA(_gdtr_phys)
21    .short _gdt_end - _gdt - 1
22    .int PHYS(_gdt)
23
24.align 8
25DATA(_gdtr)
26    .short _gdt_end - _gdt - 1
27#if ARCH_X86_32
28    .int _gdt
29#elif ARCH_X86_64
30    .quad _gdt
31#endif
32
33.data
34.align 8
35DATA(_gdt)
36    .int 0
37    .int 0
38
39/* ring 0 descriptors */
40.set codesel_32, . - _gdt
41_code_32_gde:
42    .short 0xffff           /* limit 15:00 */
43    .short 0x0000           /* base 15:00 */
44    .byte  0x00             /* base 23:16 */
45    .byte  0b10011010       /* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
46    .byte  0b11001111       /* G(1) D(1) 0 0 limit 19:16 */
47    .byte  0x0              /* base 31:24 */
48
49.set datasel, . - _gdt
50_data_gde:
51    .short 0xffff           /* limit 15:00 */
52    .short 0x0000           /* base 15:00 */
53    .byte  0x00             /* base 23:16 */
54    .byte  0b10010010       /* P(1) DPL(00) S(1) 0 E(0) W(1) A(0) */
55    .byte  0b11001111       /* G(1) B(1) 0 0 limit 19:16 */
56    .byte  0x0              /* base 31:24 */
57
58.set user_codesel_32, . - _gdt
59_user_code_32_gde:
60    .short 0xffff           /* limit 15:00 */
61    .short 0x0000           /* base 15:00 */
62    .byte  0x00             /* base 23:16 */
63    .byte  0b11111010       /* P(1) DPL(11) S(1) 1 C(0) R(1) A(0) */
64    .byte  0b11001111       /* G(1) D(1) 0 0 limit 19:16 */
65    .byte  0x0              /* base 31:24 */
66
67
68.set user_datasel, . - _gdt
69_user_data_32_gde:
70    .short 0xffff           /* limit 15:00 */
71    .short 0x0000           /* base 15:00 */
72    .byte  0x00             /* base 23:16 */
73    .byte  0b11110010       /* P(1) DPL(11) S(1) 0 E(0) W(1) A(0) */
74    .byte  0b11001111       /* G(1) B(1) 0 0 limit 19:16 */
75    .byte  0x0              /* base 31:24 */
76
77.set codesel_64, . - _gdt
78_code_64_gde:
79    .short 0xffff           /* limit 15:00 */
80    .short 0x0000           /* base 15:00 */
81    .byte  0x00             /* base 23:16 */
82    .byte  0b10011010       /* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
83    .byte  0b10101111       /* G(1) D(0) L(1) AVL(0) limit 19:16 */
84    .byte  0x0              /* base 31:24 */
85
86.set datasel_64, . - _gdt
87_data_64_gde:
88    .short 0xffff           /* limit 15:00 */
89    .short 0x0000           /* base 15:00 */
90    .byte  0x00             /* base 23:16 */
91    .byte  0b10010010       /* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
92    .byte  0b11001111       /* G(1) B(1) 0 AVL(0) limit 19:16 */
93    .byte  0x0              /* base 31:24 */
94
95.set user_codesel_64, . - _gdt
96_user_code_64_gde:
97    .short 0xffff           /* limit 15:00 */
98    .short 0x0000           /* base 15:00 */
99    .byte  0x00             /* base 23:16 */
100    .byte  0b11111010       /* P(1) DPL(11) S(1) 1 C(0) R(1) A(0) */
101    .byte  0b10101111       /* G(1) D(1) L(0) AVL(0) limit 19:16 */
102    .byte  0x0              /* base 31:24 */
103
104.set user_datasel_64, . - _gdt
105_user_data_64_gde:
106    .short 0xffff           /* limit 15:00 */
107    .short 0x0000           /* base 15:00 */
108    .byte  0x00             /* base 23:16 */
109    .byte  0b11110010       /* P(1) DPL(11) S(1) 0 E(0) W(1) A(0) */
110    .byte  0b11001111       /* G(1) B(1) 0 0 limit 19:16 */
111    .byte  0x0              /* base 31:24 */
112
113/* TSS descriptor */
114.set tsssel, . - _gdt
115_tss_gde:
116.set i, 1
117.rept SMP_MAX_CPUS
118    .short 0                /* limit 15:00 */
119    .short 0                /* base 15:00 */
120    .byte  0                /* base 23:16 */
121    .byte  0x89             /* P(1) DPL(00) S(0) TYPE(9) */
122    .byte  0x80             /* G(1) D/B(0) L(0) AVL(0) limit 19:16 */
123    .byte  0                /* base 31:24 */
124    .quad  0x0000000000000000
125.set i, i+1
126.endr
127
128DATA(_gdt_end)
129
130