source: mainline/arch/ia32/src/pm.c@ 87cd61f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 87cd61f was a7a10630, checked in by Jakub Jermar <jakub@…>, 20 years ago

SMP recovery patch #2 (SMP is no longer broken !!!).
Fix missing KA2PA() operation in ap.S which was causing page faults during AP early initialization.
Fix bug in map_page_to_frame(): 'root' was interpretted as kernel address while read_dba() returns physical address.
Make references to page directory and page tables use kernel addresses instead of physical addresses.

Massive frame allocation code cleanup.
Basically revert to what we had had before implementation of userspace.

Usual cosmetics.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <arch/pm.h>
30#include <config.h>
31#include <arch/types.h>
32#include <typedefs.h>
33#include <arch/interrupt.h>
34#include <arch/asm.h>
35#include <arch/context.h>
36#include <panic.h>
37
38/*
39 * Early ia32 configuration functions and data structures.
40 */
41
42/*
43 * We have no use for segmentation so we set up flat mode. In this
44 * mode, we use, for each privilege level, two segments spanning the
45 * whole memory. One is for code and one is for data.
46 */
47struct descriptor gdt[GDT_ITEMS] = {
48 /* NULL descriptor */
49 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
50 /* KTEXT descriptor */
51 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
52 /* KDATA descriptor */
53 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
54 /* UTEXT descriptor */
55 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
56 /* UDATA descriptor */
57 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
58 /* TSS descriptor - set up will be completed later */
59 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
60};
61
62static struct idescriptor idt[IDT_ITEMS];
63
64static struct tss tss;
65
66struct tss *tss_p = NULL;
67
68/* gdtr is changed by kmp before next CPU is initialized */
69struct ptr_16_32 gdtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
70struct ptr_16_32 idtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(idt), .base = KA2PA((__address) idt) };
71
72void gdt_setbase(struct descriptor *d, __address base)
73{
74 d->base_0_15 = base & 0xffff;
75 d->base_16_23 = ((base) >> 16) & 0xff;
76 d->base_24_31 = ((base) >> 24) & 0xff;
77
78}
79
80void gdt_setlimit(struct descriptor *d, __u32 limit)
81{
82 d->limit_0_15 = limit & 0xffff;
83 d->limit_16_19 = (limit >> 16) & 0xf;
84}
85
86void idt_setoffset(struct idescriptor *d, __address offset)
87{
88 /*
89 * Offset is a linear address.
90 */
91 d->offset_0_15 = offset & 0xffff;
92 d->offset_16_31 = offset >> 16;
93}
94
95void tss_initialize(struct tss *t)
96{
97 memsetb((__address) t, sizeof(struct tss), 0);
98}
99
100/*
101 * This function takes care of proper setup of IDT and IDTR.
102 */
103void idt_init(void)
104{
105 struct idescriptor *d;
106 int i;
107
108 for (i = 0; i < IDT_ITEMS; i++) {
109 d = &idt[i];
110
111 d->unused = 0;
112 d->selector = selector(KTEXT_DES);
113
114 d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */
115
116 if (i == VECTOR_SYSCALL) {
117 /*
118 * The syscall interrupt gate must be calleable from userland.
119 */
120 d->access |= DPL_USER;
121 }
122
123 idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size);
124 trap_register(i, null_interrupt);
125 }
126 trap_register(13, gp_fault);
127 trap_register( 7, nm_fault);
128 trap_register(12, ss_fault);
129}
130
131
132void pm_init(void)
133{
134 struct descriptor *gdt_p = (struct descriptor *) PA2KA(gdtr.base);
135
136 /*
137 * Each CPU has its private GDT and TSS.
138 * All CPUs share one IDT.
139 */
140
141 if (config.cpu_active == 1) {
142 idt_init();
143 /*
144 * NOTE: bootstrap CPU has statically allocated TSS, because
145 * the heap hasn't been initialized so far.
146 */
147 tss_p = &tss;
148 }
149 else {
150 tss_p = (struct tss *) malloc(sizeof(struct tss));
151 if (!tss_p)
152 panic("could not allocate TSS\n");
153 }
154
155 tss_initialize(tss_p);
156
157 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
158 gdt_p[TSS_DES].special = 1;
159 gdt_p[TSS_DES].granularity = 1;
160
161 gdt_setbase(&gdt_p[TSS_DES], (__address) tss_p);
162 gdt_setlimit(&gdt_p[TSS_DES], sizeof(struct tss) - 1);
163
164 /*
165 * As of this moment, the current CPU has its own GDT pointing
166 * to its own TSS. We just need to load the TR register.
167 */
168 __asm__("ltr %0" : : "r" ((__u16) selector(TSS_DES)));
169}
Note: See TracBrowser for help on using the repository browser.