Rev 576 | Rev 803 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 576 | Rev 799 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | * Copyright (C) 2001-2004 Jakub Jermar |
2 | * Copyright (C) 2001-2004 Jakub Jermar |
- | 3 | * Copyright (C) 2005-2006 Ondrej Palkovsky |
|
3 | * All rights reserved. |
4 | * All rights reserved. |
4 | * |
5 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * are met: |
Line 165... | Line 166... | ||
165 | d->selector = gdtselector(KTEXT_DES); |
166 | d->selector = gdtselector(KTEXT_DES); |
166 | 167 | ||
167 | d->present = 1; |
168 | d->present = 1; |
168 | d->type = AR_INTERRUPT; /* masking interrupt */ |
169 | d->type = AR_INTERRUPT; /* masking interrupt */ |
169 | 170 | ||
170 | if (i == VECTOR_SYSCALL) { |
- | |
171 | /* |
- | |
172 | * The syscall interrupt gate must be calleable from userland. |
- | |
173 | */ |
- | |
174 | d->dpl |= PL_USER; |
- | |
175 | } |
- | |
176 | - | ||
177 | idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size); |
171 | idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size); |
178 | exc_register(i, "undef", null_interrupt); |
172 | exc_register(i, "undef", (iroutine)null_interrupt); |
179 | } |
173 | } |
180 | exc_register(13, "gp_fault", gp_fault); |
174 | exc_register(13, "gp_fault", gp_fault); |
181 | exc_register( 7, "nm_fault", nm_fault); |
175 | exc_register( 7, "nm_fault", nm_fault); |
182 | exc_register(12, "ss_fault", ss_fault); |
176 | exc_register(12, "ss_fault", ss_fault); |
183 | } |
177 | } |
184 | 178 | ||
185 | - | ||
186 | /* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
- | |
187 | static void clean_IOPL_NT_flags(void) |
- | |
188 | { |
- | |
189 | asm |
- | |
190 | ( |
- | |
191 | "pushfq;" |
- | |
192 | "pop %%rax;" |
- | |
193 | "and $~(0x7000),%%rax;" |
- | |
194 | "pushq %%rax;" |
- | |
195 | "popfq;" |
- | |
196 | : |
- | |
197 | : |
- | |
198 | :"%rax" |
- | |
199 | ); |
- | |
200 | } |
- | |
201 | - | ||
202 | /* Clean AM(18) flag in CR0 register */ |
179 | /** Initialize segmentation - code/data/idt tables |
203 | static void clean_AM_flag(void) |
- | |
204 | { |
- | |
205 | asm |
- | |
206 | ( |
180 | * |
207 | "mov %%cr0,%%rax;" |
- | |
208 | "and $~(0x40000),%%rax;" |
- | |
209 | "mov %%rax,%%cr0;" |
- | |
210 | : |
- | |
211 | : |
- | |
212 | :"%rax" |
- | |
213 | ); |
181 | */ |
214 | } |
- | |
215 | - | ||
216 | void pm_init(void) |
182 | void pm_init(void) |
217 | { |
183 | { |
218 | struct descriptor *gdt_p = (struct descriptor *) gdtr.base; |
184 | struct descriptor *gdt_p = (struct descriptor *) gdtr.base; |
219 | struct tss_descriptor *tss_desc; |
185 | struct tss_descriptor *tss_desc; |
220 | 186 | ||
Line 252... | Line 218... | ||
252 | /* |
218 | /* |
253 | * As of this moment, the current CPU has its own GDT pointing |
219 | * As of this moment, the current CPU has its own GDT pointing |
254 | * to its own TSS. We just need to load the TR register. |
220 | * to its own TSS. We just need to load the TR register. |
255 | */ |
221 | */ |
256 | __asm__("ltr %0" : : "r" ((__u16) gdtselector(TSS_DES))); |
222 | __asm__("ltr %0" : : "r" ((__u16) gdtselector(TSS_DES))); |
257 | - | ||
258 | clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels */ |
- | |
259 | clean_AM_flag(); /* Disable alignment check */ |
- | |
260 | } |
223 | } |