source: trunk/hal/x86_64/core/hal_segmentation.h @ 359

Last change on this file since 359 was 359, checked in by max@…, 4 years ago

Synchronize tls_intr between context switches.

File size: 7.6 KB
Line 
1/*
2 * hal_segmentation.h - Segmentation-related values and structures
3 *
4 * Copyright (c) 2017 Maxime Villard
5 *
6 * This file is part of ALMOS-MKH.
7 *
8 * ALMOS-MKH is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2.0 of the License.
11 *
12 * ALMOS-MKH is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/*
23 * The GDT has NGDT_MEM entries of 8-byte-sized, static memory entries. Then
24 * there is a certain number of 16-byte-sized TSS entries, one for each CPU.
25 */
26#define GDT_NULL_SEL    0       /* Null descriptor */
27#define GDT_KCODE_SEL   1       /* Kernel code descriptor */
28#define GDT_KDATA_SEL   2       /* Kernel data descriptor */
29#define GDT_UCODE32_SEL 3       /* User code descriptor - 32bit */
30#define GDT_UCODE_SEL   4       /* User code descriptor */
31#define GDT_UDATA_SEL   5       /* User data descriptor */
32#define NGDT_MEM        6       /* aligned */
33
34#define GDT_CPUTSS_SEL  0       /* cpu TSS base index */
35#define NGDT_DYN        CONFIG_MAX_LOCAL_CORES  /* one TSS per core */
36
37/*
38 * GDT Selectors Privileges
39 */
40#define ISPL(s)         ((s) & SEL_RPL)
41#define USERMODE(c, f)          (ISPL(c) == SEL_UPL)
42#define KERNELMODE(c, f)        (ISPL(c) == SEL_KPL)
43#define SEL_KPL         0               /* kernel privilege level */
44#define SEL_UPL         3               /* user privilege level */
45#define SEL_RPL         3               /* requester's privilege level mask */
46#define SEL_LDT         4               /* local descriptor table */
47
48#define SYSSEL_START    (NGDT_MEM * 8)
49
50/* Create a selector, with an index and a privilege */
51#define GDT_FIXED_SEL(s,r)      (((s) << 3) | r)
52#define GDT_DYNAM_SEL(s,r)      ((SYSSEL_START + ((s) << 4)) | r)
53
54#ifndef x86_ASM
55
56/*
57 * Offsets.
58 */
59#define GDT_ADDR_MEM(s,i)       \
60        ((struct gdt_memseg *)((s) + ((i) << 3)))
61#define GDT_ADDR_SYS(s,i)       \
62        ((struct gdt_sysseg *)((s) + (SYSSEL_START + ((i) << 4))))
63
64/*
65 * System segment descriptor (16 bytes): used for TSS and LDT.
66 */
67struct gdt_sysseg {
68        uint64_t sd_lolimit:16; /* segment extent (lsb) */
69        uint64_t sd_lobase:24;  /* segment base address (lsb) */
70        uint64_t sd_type:5;     /* segment type */
71        uint64_t sd_dpl:2;      /* segment descriptor priority level */
72        uint64_t sd_p:1;        /* segment descriptor present */
73        uint64_t sd_hilimit:4;  /* segment extent (msb) */
74        uint64_t sd_xx1:3;      /* avl, long and def32 (not used) */
75        uint64_t sd_gran:1;     /* limit granularity (byte/page) */
76        uint64_t sd_hibase:40;  /* segment base address (msb) */
77        uint64_t sd_xx2:8;      /* reserved */
78        uint64_t sd_zero:5;     /* must be zero */
79        uint64_t sd_xx3:19;     /* reserved */
80} __packed;
81
82/*
83 * Memory segment descriptor (8 bytes): used for cs, ds, etc.
84 */
85struct gdt_memseg {
86        unsigned sd_lolimit:16; /* segment extent (lsb) */
87        unsigned sd_lobase:24;  /* segment base address (lsb) */
88        unsigned sd_type:5;     /* segment type */
89        unsigned sd_dpl:2;      /* segment descriptor priority level */
90        unsigned sd_p:1;        /* segment descriptor present */
91        unsigned sd_hilimit:4;  /* segment extent (msb) */
92        unsigned sd_avl:1;      /* available */
93        unsigned sd_long:1;     /* long mode */
94        unsigned sd_def32:1;    /* default 32 vs 16 bit size */
95        unsigned sd_gran:1;     /* limit granularity (byte/page) */
96        unsigned sd_hibase:8;   /* segment base address (msb) */
97} __packed;
98
99/*
100 * Common part of the above structures. Used to walk descriptor tables.
101 */
102struct common_segment_descriptor {
103        unsigned sdc_lolimit:16;
104        unsigned sdc_lobase:24;
105        unsigned sdc_type:5;
106        unsigned sdc_other:19;
107} __packed;
108
109/*
110 * IDT descriptors (16 bytes).
111 */
112struct idt_seg {
113        uint64_t gd_looffset:16;/* gate offset (lsb) */
114        uint64_t gd_selector:16;/* gate segment selector */
115        uint64_t gd_ist:3;      /* IST select */
116        uint64_t gd_xx1:5;      /* reserved */
117        uint64_t gd_type:5;     /* segment type */
118        uint64_t gd_dpl:2;      /* segment descriptor priority level */
119        uint64_t gd_p:1;        /* segment descriptor present */
120        uint64_t gd_hioffset:48;/* gate offset (msb) */
121        uint64_t gd_xx2:8;      /* reserved */
122        uint64_t gd_zero:5;     /* must be zero */
123        uint64_t gd_xx3:19;     /* reserved */
124} __packed;
125
126/*
127 * Region descriptors, used to load gdt/idt tables before segments yet exist.
128 */
129struct region_descriptor {
130        uint16_t rd_limit;      /* segment extent */
131        uint64_t rd_base;       /* base address  */
132} __packed;
133
134struct tss {
135        uint32_t tss_reserved1;
136        uint64_t tss_rsp0;      /* kernel stack pointer ring 0 */
137        uint64_t tss_rsp1;      /* kernel stack pointer ring 1 */
138        uint64_t tss_rsp2;      /* kernel stack pointer ring 2 */
139        uint32_t tss_reserved2;
140        uint32_t tss_reserved3;
141        uint64_t tss_ist[7];    /* Interrupt stack table */
142        uint32_t tss_reserved4;
143        uint32_t tss_reserved5;
144        uint32_t tss_iobase;
145} __packed;
146
147#define IOMAP_INVALOFF  0xffff
148
149/*
150 * Our definition of Thread-Local Storage.
151 */
152struct tls {
153        void *tls_self;
154        uint32_t tls_gid;
155        uint32_t tls_lid;
156        uint64_t tls_rsp0; /* pointer for fast access */
157        reg_t tls_intr;
158        void *tls_thr;
159} __packed;
160typedef struct tls tls_t;
161
162void lgdt(struct region_descriptor *);
163void lidt(struct region_descriptor *);
164void ltr(uint16_t);
165tls_t *curtls();
166
167#define INTRS_ENABLED   0xFFEFAAAA
168#define INTRS_DISABLED  0xD0CCCCC0
169
170#endif /* !x86_ASM */
171
172/* TLS offsets */
173#define TLS_SELF        0
174#define TLS_GID         8
175#define TLS_LID         12
176#define TLS_RSP0        16
177#define TLS_INTR        24
178
179/* system segments and gate types */
180#define SDT_SYSNULL      0      /* system null */
181#define SDT_SYS286TSS    1      /* system 286 TSS available */
182#define SDT_SYSLDT       2      /* system local descriptor table */
183#define SDT_SYS286BSY    3      /* system 286 TSS busy */
184#define SDT_SYS286CGT    4      /* system 286 call gate */
185#define SDT_SYSTASKGT    5      /* system task gate */
186#define SDT_SYS286IGT    6      /* system 286 interrupt gate */
187#define SDT_SYS286TGT    7      /* system 286 trap gate */
188#define SDT_SYSNULL2     8      /* system null again */
189#define SDT_SYS386TSS    9      /* system 386 TSS available */
190#define SDT_SYSNULL3    10      /* system null again */
191#define SDT_SYS386BSY   11      /* system 386 TSS busy */
192#define SDT_SYS386CGT   12      /* system 386 call gate */
193#define SDT_SYSNULL4    13      /* system null again */
194#define SDT_SYS386IGT   14      /* system 386 interrupt gate */
195#define SDT_SYS386TGT   15      /* system 386 trap gate */
196
197/* memory segment types */
198#define SDT_MEMRO       16      /* memory read only */
199#define SDT_MEMROA      17      /* memory read only accessed */
200#define SDT_MEMRW       18      /* memory read write */
201#define SDT_MEMRWA      19      /* memory read write accessed */
202#define SDT_MEMROD      20      /* memory read only expand dwn limit */
203#define SDT_MEMRODA     21      /* memory read only expand dwn limit accessed */
204#define SDT_MEMRWD      22      /* memory read write expand dwn limit */
205#define SDT_MEMRWDA     23      /* memory read write expand dwn limit accessed */
206#define SDT_MEME        24      /* memory execute only */
207#define SDT_MEMEA       25      /* memory execute only accessed */
208#define SDT_MEMER       26      /* memory execute read */
209#define SDT_MEMERA      27      /* memory execute read accessed */
210#define SDT_MEMEC       28      /* memory execute only conforming */
211#define SDT_MEMEAC      29      /* memory execute only accessed conforming */
212#define SDT_MEMERC      30      /* memory execute read conforming */
213#define SDT_MEMERAC     31      /* memory execute read accessed conforming */
214
215/*
216 * Entries in the Interrupt Descriptor Table (IDT)
217 */
218#define CPUVEC_MIN      0
219#define CPUVEC_MAX      32      /* reserved entries for CPU exceptions */
220
221#define DYNVEC_MIN      (CPUVEC_MAX + 0)
222#define DYNVEC_MAX      (CPUVEC_MAX + 4)
223
224#define VECTOR_APIC_SPURIOU     (DYNVEC_MIN + 0)
225
226/* debug only, will be moved soon */
227#define LAPIC_TIMER_VECTOR      (DYNVEC_MIN + 1)
228#define IOAPIC_COM1_VECTOR      (DYNVEC_MIN + 2)
229#define IOAPIC_KEYBOARD_VECTOR  (DYNVEC_MIN + 3)
230
231#define NIDT    256     /* total number of IDT entries */
232
Note: See TracBrowser for help on using the repository browser.