source: mainline/kernel/arch/amd64/src/pm.c@ f1380b7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f1380b7 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * Copyright (c) 2005-2006 Ondrej Palkovsky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup amd64
31 * @{
32 */
33/** @file
34 */
35
36#include <arch.h>
37#include <arch/pm.h>
38#include <arch/asm.h>
39#include <mm/as.h>
40#include <mm/frame.h>
41#include <mem.h>
42#include <mm/slab.h>
43
44/*
45 * There is no segmentation in long mode so we set up flat mode. In this
46 * mode, we use, for each privilege level, two segments spanning the
47 * whole memory. One is for code and one is for data.
48 */
49
50descriptor_t gdt[GDT_ITEMS] = {
51 [NULL_DES] = {
52 0
53 },
54 [KTEXT_DES] = {
55 .limit_0_15 = 0xffffU,
56 .limit_16_19 = 0xfU,
57 .access = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE,
58 .longmode = 1,
59 .granularity = 1
60 },
61 [KDATA_DES] = {
62 .limit_0_15 = 0xffffU,
63 .limit_16_19 = 0xfU,
64 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL,
65 .granularity = 1
66 },
67 [UDATA_DES] = {
68 .limit_0_15 = 0xffffU,
69 .limit_16_19 = 0xfU,
70 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER,
71 .special = 1,
72 .granularity = 1
73 },
74 [UTEXT_DES] = {
75 .limit_0_15 = 0xffffU,
76 .limit_16_19 = 0xfU,
77 .access = AR_PRESENT | AR_CODE | DPL_USER,
78 .longmode = 1,
79 .granularity = 1
80 },
81 [KTEXT32_DES] = {
82 .limit_0_15 = 0xffffU,
83 .limit_16_19 = 0xfU,
84 .access = AR_PRESENT | AR_CODE | DPL_KERNEL | AR_READABLE,
85 .special = 1,
86 .granularity = 1
87 },
88 /*
89 * TSS descriptor - set up will be completed later,
90 * on AMD64 it is 64-bit - 2 items in the table
91 */
92 [TSS_DES] = {
93 0
94 },
95 [TSS_DES + 1] = {
96 0
97 },
98 /* VESA Init descriptor */
99#ifdef CONFIG_FB
100 [VESA_INIT_CODE_DES] = {
101 .limit_0_15 = 0xffff,
102 .limit_16_19 = 0xf,
103 .base_16_23 = VESA_INIT_SEGMENT >> 12,
104 .access = AR_PRESENT | AR_CODE | AR_READABLE | DPL_KERNEL
105 },
106 [VESA_INIT_DATA_DES] = {
107 .limit_0_15 = 0xffff,
108 .limit_16_19 = 0xf,
109 .base_16_23 = VESA_INIT_SEGMENT >> 12,
110 .access = AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL
111 }
112#endif
113};
114
115idescriptor_t idt[IDT_ITEMS];
116
117ptr_16_64_t gdtr = {
118 .limit = sizeof(gdt),
119 .base = (uint64_t) gdt
120};
121ptr_16_64_t idtr = {
122 .limit = sizeof(idt),
123 .base = (uint64_t) idt
124};
125
126static tss_t tss;
127tss_t *tss_p = NULL;
128
129void gdt_tss_setbase(descriptor_t *d, uintptr_t base)
130{
131 tss_descriptor_t *td = (tss_descriptor_t *) d;
132
133 td->base_0_15 = base & 0xffffU;
134 td->base_16_23 = ((base) >> 16) & 0xffU;
135 td->base_24_31 = ((base) >> 24) & 0xffU;
136 td->base_32_63 = ((base) >> 32);
137}
138
139void gdt_tss_setlimit(descriptor_t *d, uint32_t limit)
140{
141 tss_descriptor_t *td = (tss_descriptor_t *) d;
142
143 td->limit_0_15 = limit & 0xffffU;
144 td->limit_16_19 = (limit >> 16) & 0x0fU;
145}
146
147void idt_setoffset(idescriptor_t *d, uintptr_t offset)
148{
149 /*
150 * Offset is a linear address.
151 */
152 d->offset_0_15 = offset & 0xffffU;
153 d->offset_16_31 = (offset >> 16) & 0xffffU;
154 d->offset_32_63 = offset >> 32;
155}
156
157void tss_initialize(tss_t *t)
158{
159 memsetb(t, sizeof(tss_t), 0);
160}
161
162/*
163 * This function takes care of proper setup of IDT and IDTR.
164 */
165void idt_init(void)
166{
167 idescriptor_t *d;
168 unsigned int i;
169
170 for (i = 0; i < IDT_ITEMS; i++) {
171 d = &idt[i];
172
173 d->unused = 0;
174 d->selector = GDT_SELECTOR(KTEXT_DES);
175
176 d->present = 1;
177 d->type = AR_INTERRUPT; /* masking interrupt */
178 }
179
180 d = &idt[0];
181 idt_setoffset(d++, (uintptr_t) &int_0);
182 idt_setoffset(d++, (uintptr_t) &int_1);
183 idt_setoffset(d++, (uintptr_t) &int_2);
184 idt_setoffset(d++, (uintptr_t) &int_3);
185 idt_setoffset(d++, (uintptr_t) &int_4);
186 idt_setoffset(d++, (uintptr_t) &int_5);
187 idt_setoffset(d++, (uintptr_t) &int_6);
188 idt_setoffset(d++, (uintptr_t) &int_7);
189 idt_setoffset(d++, (uintptr_t) &int_8);
190 idt_setoffset(d++, (uintptr_t) &int_9);
191 idt_setoffset(d++, (uintptr_t) &int_10);
192 idt_setoffset(d++, (uintptr_t) &int_11);
193 idt_setoffset(d++, (uintptr_t) &int_12);
194 idt_setoffset(d++, (uintptr_t) &int_13);
195 idt_setoffset(d++, (uintptr_t) &int_14);
196 idt_setoffset(d++, (uintptr_t) &int_15);
197 idt_setoffset(d++, (uintptr_t) &int_16);
198 idt_setoffset(d++, (uintptr_t) &int_17);
199 idt_setoffset(d++, (uintptr_t) &int_18);
200 idt_setoffset(d++, (uintptr_t) &int_19);
201 idt_setoffset(d++, (uintptr_t) &int_20);
202 idt_setoffset(d++, (uintptr_t) &int_21);
203 idt_setoffset(d++, (uintptr_t) &int_22);
204 idt_setoffset(d++, (uintptr_t) &int_23);
205 idt_setoffset(d++, (uintptr_t) &int_24);
206 idt_setoffset(d++, (uintptr_t) &int_25);
207 idt_setoffset(d++, (uintptr_t) &int_26);
208 idt_setoffset(d++, (uintptr_t) &int_27);
209 idt_setoffset(d++, (uintptr_t) &int_28);
210 idt_setoffset(d++, (uintptr_t) &int_29);
211 idt_setoffset(d++, (uintptr_t) &int_30);
212 idt_setoffset(d++, (uintptr_t) &int_31);
213 idt_setoffset(d++, (uintptr_t) &int_32);
214 idt_setoffset(d++, (uintptr_t) &int_33);
215 idt_setoffset(d++, (uintptr_t) &int_34);
216 idt_setoffset(d++, (uintptr_t) &int_35);
217 idt_setoffset(d++, (uintptr_t) &int_36);
218 idt_setoffset(d++, (uintptr_t) &int_37);
219 idt_setoffset(d++, (uintptr_t) &int_38);
220 idt_setoffset(d++, (uintptr_t) &int_39);
221 idt_setoffset(d++, (uintptr_t) &int_40);
222 idt_setoffset(d++, (uintptr_t) &int_41);
223 idt_setoffset(d++, (uintptr_t) &int_42);
224 idt_setoffset(d++, (uintptr_t) &int_43);
225 idt_setoffset(d++, (uintptr_t) &int_44);
226 idt_setoffset(d++, (uintptr_t) &int_45);
227 idt_setoffset(d++, (uintptr_t) &int_46);
228 idt_setoffset(d++, (uintptr_t) &int_47);
229 idt_setoffset(d++, (uintptr_t) &int_48);
230 idt_setoffset(d++, (uintptr_t) &int_49);
231 idt_setoffset(d++, (uintptr_t) &int_50);
232 idt_setoffset(d++, (uintptr_t) &int_51);
233 idt_setoffset(d++, (uintptr_t) &int_52);
234 idt_setoffset(d++, (uintptr_t) &int_53);
235 idt_setoffset(d++, (uintptr_t) &int_54);
236 idt_setoffset(d++, (uintptr_t) &int_55);
237 idt_setoffset(d++, (uintptr_t) &int_56);
238 idt_setoffset(d++, (uintptr_t) &int_57);
239 idt_setoffset(d++, (uintptr_t) &int_58);
240 idt_setoffset(d++, (uintptr_t) &int_59);
241 idt_setoffset(d++, (uintptr_t) &int_60);
242 idt_setoffset(d++, (uintptr_t) &int_61);
243 idt_setoffset(d++, (uintptr_t) &int_62);
244 idt_setoffset(d++, (uintptr_t) &int_63);
245}
246
247/** Initialize segmentation - code/data/idt tables
248 *
249 */
250void pm_init(void)
251{
252 descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
253 tss_descriptor_t *tss_desc;
254
255 /*
256 * Each CPU has its private GDT and TSS.
257 * All CPUs share one IDT.
258 */
259
260 if (config.cpu_active == 1) {
261 idt_init();
262 /*
263 * NOTE: bootstrap CPU has statically allocated TSS, because
264 * the heap hasn't been initialized so far.
265 */
266 tss_p = &tss;
267 } else {
268 /* We are going to use malloc, which may return
269 * non boot-mapped pointer, initialize the CR3 register
270 * ahead of page_init */
271 write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
272
273 tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
274 if (!tss_p)
275 panic("Cannot allocate TSS.");
276 }
277
278 tss_initialize(tss_p);
279
280 tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
281 tss_desc->present = 1;
282 tss_desc->type = AR_TSS;
283 tss_desc->dpl = PL_KERNEL;
284
285 gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
286 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
287
288 gdtr_load(&gdtr);
289 idtr_load(&idtr);
290 /*
291 * As of this moment, the current CPU has its own GDT pointing
292 * to its own TSS. We just need to load the TR register.
293 */
294 tr_load(GDT_SELECTOR(TSS_DES));
295}
296
297/** @}
298 */
Note: See TracBrowser for help on using the repository browser.