source: trunk/hal/x86_64/hal_segmentation.h @ 50

Last change on this file since 50 was 45, checked in by max@…, 7 years ago

Add some code for LAPIC; far from complete, but a good start.

File size: 6.8 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_UCODE_SEL   3       /* User code descriptor */
30#define GDT_UDATA_SEL   4       /* User data descriptor */
31#define NGDT_MEM        6               /* aligned */
32
33#define GDT_CPU0TSS_SEL 0       /* cpu0's tss */
34#define NGDT_DYN        (256 - (NGDT_MEM / 2) * 16)
35
36/*
37 * GDT Selectors Privileges
38 */
39#define ISPL(s)         ((s) & SEL_RPL)
40#define USERMODE(c, f)          (ISPL(c) == SEL_UPL)
41#define KERNELMODE(c, f)        (ISPL(c) == SEL_KPL)
42#define SEL_KPL         0               /* kernel privilege level */
43#define SEL_UPL         3               /* user privilege level */
44#define SEL_RPL         3               /* requester's privilege level mask */
45#define SEL_LDT         4               /* local descriptor table */
46
47#define SYSSEL_START    (NGDT_MEM * 8)
48
49/* Create a selector, with an index and a privilege */
50#define GDT_FIXED_SEL(s,r)      (((s) << 3) | r)
51#define GDT_DYNAM_SEL(s,r)      ((SYSSEL_START + ((s) << 4)) | r)
52
53#ifndef x86_ASM
54
55/*
56 * Offsets.
57 */
58#define GDT_ADDR_MEM(s,i)       \
59        ((struct gdt_memseg *)((s) + ((i) << 3)))
60#define GDT_ADDR_SYS(s,i)       \
61        ((struct gdt_sysseg *)((s) + (SYSSEL_START + ((i) << 4))))
62
63/*
64 * System segment descriptor (16 bytes): used for TSS and LDT.
65 */
66struct gdt_sysseg {
67        uint64_t sd_lolimit:16; /* segment extent (lsb) */
68        uint64_t sd_lobase:24;  /* segment base address (lsb) */
69        uint64_t sd_type:5;     /* segment type */
70        uint64_t sd_dpl:2;      /* segment descriptor priority level */
71        uint64_t sd_p:1;        /* segment descriptor present */
72        uint64_t sd_hilimit:4;  /* segment extent (msb) */
73        uint64_t sd_xx1:3;      /* avl, long and def32 (not used) */
74        uint64_t sd_gran:1;     /* limit granularity (byte/page) */
75        uint64_t sd_hibase:40;  /* segment base address (msb) */
76        uint64_t sd_xx2:8;      /* reserved */
77        uint64_t sd_zero:5;     /* must be zero */
78        uint64_t sd_xx3:19;     /* reserved */
79} __packed;
80
81/*
82 * Memory segment descriptor (8 bytes): used for cs, ds, etc.
83 */
84struct gdt_memseg {
85        unsigned sd_lolimit:16; /* segment extent (lsb) */
86        unsigned sd_lobase:24;  /* segment base address (lsb) */
87        unsigned sd_type:5;     /* segment type */
88        unsigned sd_dpl:2;      /* segment descriptor priority level */
89        unsigned sd_p:1;        /* segment descriptor present */
90        unsigned sd_hilimit:4;  /* segment extent (msb) */
91        unsigned sd_avl:1;      /* available */
92        unsigned sd_long:1;     /* long mode */
93        unsigned sd_def32:1;    /* default 32 vs 16 bit size */
94        unsigned sd_gran:1;     /* limit granularity (byte/page) */
95        unsigned sd_hibase:8;   /* segment base address (msb) */
96} __packed;
97
98/*
99 * Common part of the above structures. Used to walk descriptor tables.
100 */
101struct common_segment_descriptor {
102        unsigned sdc_lolimit:16;
103        unsigned sdc_lobase:24;
104        unsigned sdc_type:5;
105        unsigned sdc_other:19;
106} __packed;
107
108/*
109 * IDT descriptors (16 bytes).
110 */
111struct idt_seg {
112        uint64_t gd_looffset:16;/* gate offset (lsb) */
113        uint64_t gd_selector:16;/* gate segment selector */
114        uint64_t gd_ist:3;      /* IST select */
115        uint64_t gd_xx1:5;      /* reserved */
116        uint64_t gd_type:5;     /* segment type */
117        uint64_t gd_dpl:2;      /* segment descriptor priority level */
118        uint64_t gd_p:1;        /* segment descriptor present */
119        uint64_t gd_hioffset:48;/* gate offset (msb) */
120        uint64_t gd_xx2:8;      /* reserved */
121        uint64_t gd_zero:5;     /* must be zero */
122        uint64_t gd_xx3:19;     /* reserved */
123} __packed;
124
125/*
126 * Region descriptors, used to load gdt/idt tables before segments yet exist.
127 */
128struct region_descriptor {
129        uint16_t rd_limit;      /* segment extent */
130        uint64_t rd_base;       /* base address  */
131} __packed;
132
133struct tss {
134        uint32_t tss_reserved1;
135        uint64_t tss_rsp0;
136        uint64_t tss_rsp1;
137        uint64_t tss_rsp3;
138        uint32_t tss_reserved2;
139        uint32_t tss_reserved3;
140        uint64_t tss_ist[7];
141        uint32_t tss_reserved4;
142        uint32_t tss_reserved5;
143        uint32_t tss_iobase;
144} __packed;
145
146#define IOMAP_INVALOFF  0xffff
147
148void lgdt(struct region_descriptor *);
149void lidt(struct region_descriptor *);
150void ltr(uint16_t);
151
152#endif /* !x86_ASM */
153
154/* system segments and gate types */
155#define SDT_SYSNULL      0      /* system null */
156#define SDT_SYS286TSS    1      /* system 286 TSS available */
157#define SDT_SYSLDT       2      /* system local descriptor table */
158#define SDT_SYS286BSY    3      /* system 286 TSS busy */
159#define SDT_SYS286CGT    4      /* system 286 call gate */
160#define SDT_SYSTASKGT    5      /* system task gate */
161#define SDT_SYS286IGT    6      /* system 286 interrupt gate */
162#define SDT_SYS286TGT    7      /* system 286 trap gate */
163#define SDT_SYSNULL2     8      /* system null again */
164#define SDT_SYS386TSS    9      /* system 386 TSS available */
165#define SDT_SYSNULL3    10      /* system null again */
166#define SDT_SYS386BSY   11      /* system 386 TSS busy */
167#define SDT_SYS386CGT   12      /* system 386 call gate */
168#define SDT_SYSNULL4    13      /* system null again */
169#define SDT_SYS386IGT   14      /* system 386 interrupt gate */
170#define SDT_SYS386TGT   15      /* system 386 trap gate */
171
172/* memory segment types */
173#define SDT_MEMRO       16      /* memory read only */
174#define SDT_MEMROA      17      /* memory read only accessed */
175#define SDT_MEMRW       18      /* memory read write */
176#define SDT_MEMRWA      19      /* memory read write accessed */
177#define SDT_MEMROD      20      /* memory read only expand dwn limit */
178#define SDT_MEMRODA     21      /* memory read only expand dwn limit accessed */
179#define SDT_MEMRWD      22      /* memory read write expand dwn limit */
180#define SDT_MEMRWDA     23      /* memory read write expand dwn limit accessed */
181#define SDT_MEME        24      /* memory execute only */
182#define SDT_MEMEA       25      /* memory execute only accessed */
183#define SDT_MEMER       26      /* memory execute read */
184#define SDT_MEMERA      27      /* memory execute read accessed */
185#define SDT_MEMEC       28      /* memory execute only conforming */
186#define SDT_MEMEAC      29      /* memory execute only accessed conforming */
187#define SDT_MEMERC      30      /* memory execute read conforming */
188#define SDT_MEMERAC     31      /* memory execute read accessed conforming */
189
190/*
191 * Entries in the Interrupt Descriptor Table (IDT)
192 */
193#define CPUVEC_MIN      0
194#define CPUVEC_MAX      32      /* reserved entries for CPU exceptions */
195#define LAPICVEC_MIN    CPUVEC_MAX
196#define LAPICVEC_MAX    (LAPICVEC_MIN + 1)
197
198#define NIDT    256     /* total number of IDT entries */
199
Note: See TracBrowser for help on using the repository browser.