ckrm_E16rc1 mem controller version 1
[linux-2.6.git] / arch / i386 / kernel / entry_trampoline.c
1 /*
2  * linux/arch/i386/kernel/entry_trampoline.c
3  *
4  * (C) Copyright 2003 Ingo Molnar
5  *
6  * This file contains the needed support code for 4GB userspace
7  */
8
9 #include <linux/init.h>
10 #include <linux/smp.h>
11 #include <linux/mm.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/highmem.h>
16 #include <asm/desc.h>
17 #include <asm/atomic_kmap.h>
18
19 extern char __entry_tramp_start, __entry_tramp_end, __start___entry_text;
20
21 void __init init_entry_mappings(void)
22 {
23 #ifdef CONFIG_X86_HIGH_ENTRY
24
25         void *tramp;
26         int p;
27
28         /*
29          * We need a high IDT and GDT for the 4G/4G split:
30          */
31         trap_init_virtual_IDT();
32
33         __set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL_EXEC);
34         __set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL_EXEC);
35         tramp = (void *)fix_to_virt(FIX_ENTRY_TRAMPOLINE_0);
36
37         printk("mapped 4G/4G trampoline to %p.\n", tramp);
38         BUG_ON((void *)&__start___entry_text != tramp);
39         /*
40          * Virtual kernel stack:
41          */
42         BUG_ON(__kmap_atomic_vaddr(KM_VSTACK_TOP) & (THREAD_SIZE-1));
43         BUG_ON(sizeof(struct desc_struct)*NR_CPUS*GDT_ENTRIES > 2*PAGE_SIZE);
44         BUG_ON((unsigned int)&__entry_tramp_end - (unsigned int)&__entry_tramp_start > 2*PAGE_SIZE);
45
46         /*
47          * set up the initial thread's virtual stack related
48          * fields:
49          */
50         for (p = 0; p < ARRAY_SIZE(current->thread.stack_page); p++)
51                 current->thread.stack_page[p] = virt_to_page((char *)current->thread_info + (p*PAGE_SIZE));
52
53         current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK_TOP);
54
55         for (p = 0; p < ARRAY_SIZE(current->thread.stack_page); p++) {
56                 __kunmap_atomic_type(KM_VSTACK_TOP-p);
57                 __kmap_atomic(current->thread.stack_page[p], KM_VSTACK_TOP-p);
58         }
59 #endif
60         current->thread_info->real_stack = (void *)current->thread_info;
61         current->thread_info->user_pgd = NULL;
62         current->thread.esp0 = (unsigned long)current->thread_info->real_stack + THREAD_SIZE;
63 }
64
65
66
67 void __init entry_trampoline_setup(void)
68 {
69         /*
70          * old IRQ entries set up by the boot code will still hang
71          * around - they are a sign of hw trouble anyway, now they'll
72          * produce a double fault message.
73          */
74         trap_init_virtual_GDT();
75 }