source: mainline/arch/ia32/src/pm.c@ ba18512

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ba18512 was 9c0a9b3, checked in by Jakub Vana <jakub.vana@…>, 20 years ago

1) memcopy and _memcopy functions rewriten to ANSI C norm.
2) Repaired ia32,ia64 and mips version of SPARTAN to work with this memcopy functions
3) Warning for non declared funcions added and repaired ia32,ia64 and mips versions to pass build process with this warning and Werror option

  • Property mode set to 100644
File size: 5.5 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#include <arch/mm/page.h>
38#include <mm/heap.h>
39#include <memstr.h>
40
41/*
42 * Early ia32 configuration functions and data structures.
43 */
44
45/*
46 * We have no use for segmentation so we set up flat mode. In this
47 * mode, we use, for each privilege level, two segments spanning the
48 * whole memory. One is for code and one is for data.
49 */
50struct descriptor gdt[GDT_ITEMS] = {
51 /* NULL descriptor */
52 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
53 /* KTEXT descriptor */
54 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
55 /* KDATA descriptor */
56 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
57 /* UTEXT descriptor */
58 { 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
59 /* UDATA descriptor */
60 { 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
61 /* TSS descriptor - set up will be completed later */
62 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
63};
64
65static struct idescriptor idt[IDT_ITEMS];
66
67static struct tss tss;
68
69struct tss *tss_p = NULL;
70
71/* gdtr is changed by kmp before next CPU is initialized */
72struct ptr_16_32 gdtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
73struct ptr_16_32 idtr __attribute__ ((section ("K_DATA_START"))) = { .limit = sizeof(idt), .base = KA2PA((__address) idt) };
74
75void gdt_setbase(struct descriptor *d, __address base)
76{
77 d->base_0_15 = base & 0xffff;
78 d->base_16_23 = ((base) >> 16) & 0xff;
79 d->base_24_31 = ((base) >> 24) & 0xff;
80}
81
82void gdt_setlimit(struct descriptor *d, __u32 limit)
83{
84 d->limit_0_15 = limit & 0xffff;
85 d->limit_16_19 = (limit >> 16) & 0xf;
86}
87
88void idt_setoffset(struct idescriptor *d, __address offset)
89{
90 /*
91 * Offset is a linear address.
92 */
93 d->offset_0_15 = offset & 0xffff;
94 d->offset_16_31 = offset >> 16;
95}
96
97void tss_initialize(struct tss *t)
98{
99 memsetb((__address) t, sizeof(struct tss), 0);
100}
101
102/*
103 * This function takes care of proper setup of IDT and IDTR.
104 */
105void idt_init(void)
106{
107 struct idescriptor *d;
108 int i;
109
110 for (i = 0; i < IDT_ITEMS; i++) {
111 d = &idt[i];
112
113 d->unused = 0;
114 d->selector = selector(KTEXT_DES);
115
116 d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */
117
118 if (i == VECTOR_SYSCALL) {
119 /*
120 * The syscall interrupt gate must be calleable from userland.
121 */
122 d->access |= DPL_USER;
123 }
124
125 idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size);
126 trap_register(i, null_interrupt);
127 }
128 trap_register(13, gp_fault);
129 trap_register( 7, nm_fault);
130 trap_register(12, ss_fault);
131}
132
133
134/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
135static void clean_IOPL_NT_flags(void)
136{
137 asm
138 (
139 "pushfl;"
140 "pop %%eax;"
141 "and $0xffff8fff,%%eax;"
142 "push %%eax;"
143 "popfl;"
144 :
145 :
146 :"%eax"
147 );
148}
149
150/* Clean AM(18) flag in CR0 register */
151static void clean_AM_flag(void)
152{
153 asm
154 (
155 "mov %%cr0,%%eax;"
156 "and $0xFFFBFFFF,%%eax;"
157 "mov %%eax,%%cr0;"
158 :
159 :
160 :"%eax"
161 );
162}
163
164void pm_init(void)
165{
166 struct descriptor *gdt_p = (struct descriptor *) PA2KA(gdtr.base);
167
168 /*
169 * Each CPU has its private GDT and TSS.
170 * All CPUs share one IDT.
171 */
172
173 if (config.cpu_active == 1) {
174 idt_init();
175 /*
176 * NOTE: bootstrap CPU has statically allocated TSS, because
177 * the heap hasn't been initialized so far.
178 */
179 tss_p = &tss;
180 }
181 else {
182 tss_p = (struct tss *) malloc(sizeof(struct tss));
183 if (!tss_p)
184 panic("could not allocate TSS\n");
185 }
186
187 tss_initialize(tss_p);
188
189 gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
190 gdt_p[TSS_DES].special = 1;
191 gdt_p[TSS_DES].granularity = 1;
192
193 gdt_setbase(&gdt_p[TSS_DES], (__address) tss_p);
194 gdt_setlimit(&gdt_p[TSS_DES], sizeof(struct tss) - 1);
195
196 /*
197 * As of this moment, the current CPU has its own GDT pointing
198 * to its own TSS. We just need to load the TR register.
199 */
200 __asm__("ltr %0" : : "r" ((__u16) selector(TSS_DES)));
201
202 clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels */
203 clean_AM_flag(); /* Disable alignment check */
204}
Note: See TracBrowser for help on using the repository browser.