2 * Copyright (C) 2006 Martin Decky
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
36 #include <main/main.h>
38 #include <arch/types.h>
44 #include <arch/drivers/xconsole.h>
45 #include <arch/mm/page.h>
47 #include <arch/context.h>
51 #include <arch/interrupt.h>
53 #include <genarch/acpi/acpi.h>
55 #include <arch/bios/bios.h>
57 #include <arch/boot/boot.h>
58 #include <arch/mm/memory_init.h>
59 #include <interrupt.h>
60 #include <arch/debugger.h>
61 #include <proc/thread.h>
62 #include <syscall/syscall.h>
63 #include <console/console.h>
65 start_info_t start_info
;
68 extern void xen_callback(void);
69 extern void xen_failsafe_callback(void);
71 void arch_pre_main(void)
73 xen_vm_assist(VMASST_CMD_ENABLE
, VMASST_TYPE_WRITABLE_PAGETABLES
);
76 memsetb((uintptr_t) &pte
, sizeof(pte
), 0);
80 pte
.frame_address
= ADDR2PFN((uintptr_t) start_info
.shared_info
);
81 xen_update_va_mapping(&shared_info
, pte
, UVMF_INVLPG
);
85 pte
.frame_address
= start_info
.console_mfn
;
86 xen_update_va_mapping(&console_page
, pte
, UVMF_INVLPG
);
88 xen_set_callbacks(XEN_CS
, xen_callback
, XEN_CS
, xen_failsafe_callback
);
90 /* Create identity mapping */
92 meminfo
.start
= ADDR2PFN(ALIGN_UP(KA2PA(start_info
.ptl0
), PAGE_SIZE
)) + start_info
.pt_frames
;
93 meminfo
.size
= start_info
.frames
- meminfo
.start
;
97 index_t last_ptl0
= 0;
98 for (pa
= PFN2ADDR(meminfo
.start
); pa
< PFN2ADDR(meminfo
.start
+ meminfo
.size
); pa
+= FRAME_SIZE
) {
99 uintptr_t va
= PA2KA(pa
);
101 if ((PTL0_INDEX(va
) != last_ptl0
) && (GET_PTL1_FLAGS(start_info
.ptl0
, PTL0_INDEX(va
)) & PAGE_NOT_PRESENT
)) {
102 /* New page directory entry needed */
103 uintptr_t tpa
= PFN2ADDR(meminfo
.start
+ meminfo
.reserved
);
104 uintptr_t tva
= PA2KA(tpa
);
106 memsetb(tva
, PAGE_SIZE
, 0);
108 pte_t
*tptl3
= (pte_t
*) PA2KA(GET_PTL1_ADDRESS(start_info
.ptl0
, PTL0_INDEX(tva
)));
109 SET_FRAME_FLAGS(tptl3
, PTL3_INDEX(tva
), PAGE_PRESENT
);
110 SET_PTL1_ADDRESS(start_info
.ptl0
, PTL0_INDEX(va
), tpa
);
112 last_ptl0
= PTL0_INDEX(va
);
116 pte_t
*ptl3
= (pte_t
*) PA2KA(GET_PTL1_ADDRESS(start_info
.ptl0
, PTL0_INDEX(va
)));
118 SET_FRAME_ADDRESS(ptl3
, PTL3_INDEX(va
), pa
);
119 SET_FRAME_FLAGS(ptl3
, PTL3_INDEX(va
), PAGE_PRESENT
| PAGE_WRITE
);
122 /* Put initial stack safely in the mapped area */
123 stack_safe
= PA2KA(PFN2ADDR(meminfo
.start
+ meminfo
.reserved
));
126 void arch_pre_mm_init(void)
130 if (config
.cpu_active
== 1) {
133 exc_register(VECTOR_SYSCALL
, "syscall", (iroutine
) syscall
);
136 exc_register(VECTOR_TLB_SHOOTDOWN_IPI
, "tlb_shootdown",
137 (iroutine
) tlb_shootdown_ipi
);
138 #endif /* CONFIG_SMP */
142 void arch_post_mm_init(void)
144 if (config
.cpu_active
== 1) {
147 /* Enable debugger */
149 /* Merge all memory zones to 1 big zone */
154 void arch_post_cpu_init(void)
158 void arch_pre_smp_init(void)
160 if (config
.cpu_active
== 1) {
165 #endif /* CONFIG_SMP */
169 void arch_post_smp_init(void)
173 void calibrate_delay_loop(void)
175 // i8254_calibrate_delay_loop();
176 if (config
.cpu_active
== 1) {
178 * This has to be done only on UP.
179 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
181 // i8254_normal_operation();
185 /** Set thread-local-storage pointer
187 * TLS pointer is set in GS register. That means, the GS contains
188 * selector, and the descriptor->base is the correct address.
190 unative_t
sys_tls_set(unative_t addr
)
192 THREAD
->arch
.tls
= addr
;
198 /** Acquire console back for kernel
201 void arch_grab_console(void)
205 /** Return console to userspace
208 void arch_release_console(void)