source: mainline/kernel/arch/amd64/src/amd64.c@ a71c158

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a71c158 was a71c158, checked in by Martin Decky <martin@…>, 16 years ago

kernel output devices now suport multiple instances (except ski and sgcn, which respect the same interface, but behave as singletons)
if more than one output device gets initialized, the output is cloned to all of them
get rid of arch_grab_console() and arch_release_console() (output devices can implement a generic "redraw" method, input devices respect the "silent" global variable)
related cleanups and modifications

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 * Copyright (c) 2005 Ondrej Palkovsky
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/** @addtogroup amd64
30 * @{
31 */
32/** @file
33 */
34
35#include <arch.h>
36
37#include <arch/types.h>
38
39#include <config.h>
40
41#include <proc/thread.h>
42#include <genarch/multiboot/multiboot.h>
43#include <genarch/drivers/legacy/ia32/io.h>
44#include <genarch/drivers/ega/ega.h>
45#include <arch/drivers/vesa.h>
46#include <genarch/drivers/i8042/i8042.h>
47#include <genarch/kbrd/kbrd.h>
48#include <arch/drivers/i8254.h>
49#include <arch/drivers/i8259.h>
50#include <arch/boot/boot.h>
51
52#ifdef CONFIG_SMP
53#include <arch/smp/apic.h>
54#endif
55
56#include <arch/bios/bios.h>
57#include <arch/cpu.h>
58#include <print.h>
59#include <arch/cpuid.h>
60#include <genarch/acpi/acpi.h>
61#include <panic.h>
62#include <interrupt.h>
63#include <arch/syscall.h>
64#include <arch/debugger.h>
65#include <syscall/syscall.h>
66#include <console/console.h>
67#include <ddi/irq.h>
68#include <sysinfo/sysinfo.h>
69
70/** Disable I/O on non-privileged levels
71 *
72 * Clean IOPL(12,13) and NT(14) flags in EFLAGS register
73 */
74static void clean_IOPL_NT_flags(void)
75{
76 asm volatile (
77 "pushfq\n"
78 "pop %%rax\n"
79 "and $~(0x7000), %%rax\n"
80 "pushq %%rax\n"
81 "popfq\n"
82 ::: "%rax"
83 );
84}
85
86/** Disable alignment check
87 *
88 * Clean AM(18) flag in CR0 register
89 */
90static void clean_AM_flag(void)
91{
92 asm volatile (
93 "mov %%cr0, %%rax\n"
94 "and $~(0x40000), %%rax\n"
95 "mov %%rax, %%cr0\n"
96 ::: "%rax"
97 );
98}
99
100/** Perform amd64-specific initialization before main_bsp() is called.
101 *
102 * @param signature Should contain the multiboot signature.
103 * @param mi Pointer to the multiboot information structure.
104 */
105void arch_pre_main(uint32_t signature, const multiboot_info_t *mi)
106{
107 /* Parse multiboot information obtained from the bootloader. */
108 multiboot_info_parse(signature, mi);
109
110#ifdef CONFIG_SMP
111 /* Copy AP bootstrap routines below 1 MB. */
112 memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
113 (size_t) &_hardcoded_unmapped_size);
114#endif
115}
116
117void arch_pre_mm_init(void)
118{
119 /* Enable no-execute pages */
120 set_efer_flag(AMD_NXE_FLAG);
121 /* Enable FPU */
122 cpu_setup_fpu();
123
124 /* Initialize segmentation */
125 pm_init();
126
127 /* Disable I/O on nonprivileged levels
128 * clear the NT (nested-thread) flag
129 */
130 clean_IOPL_NT_flags();
131 /* Disable alignment check */
132 clean_AM_flag();
133
134 if (config.cpu_active == 1) {
135 interrupt_init();
136 bios_init();
137
138 /* PIC */
139 i8259_init();
140 }
141}
142
143
144void arch_post_mm_init(void)
145{
146 if (config.cpu_active == 1) {
147 /* Initialize IRQ routing */
148 irq_init(IRQ_COUNT, IRQ_COUNT);
149
150 /* hard clock */
151 i8254_init();
152
153#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
154 bool vesa = false;
155#endif
156
157#ifdef CONFIG_FB
158 vesa = vesa_init();
159#endif
160
161#ifdef CONFIG_EGA
162 if (!vesa) {
163 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
164 if (egadev)
165 stdout_wire(egadev);
166 }
167#endif
168
169 /* Enable debugger */
170 debugger_init();
171 /* Merge all memory zones to 1 big zone */
172 zone_merge_all();
173 }
174
175 /* Setup fast SYSCALL/SYSRET */
176 syscall_setup_cpu();
177}
178
179void arch_post_cpu_init()
180{
181#ifdef CONFIG_SMP
182 if (config.cpu_active > 1) {
183 l_apic_init();
184 l_apic_debug();
185 }
186#endif
187}
188
189void arch_pre_smp_init(void)
190{
191 if (config.cpu_active == 1) {
192#ifdef CONFIG_SMP
193 acpi_init();
194#endif /* CONFIG_SMP */
195 }
196}
197
198void arch_post_smp_init(void)
199{
200#ifdef CONFIG_PC_KBD
201 /*
202 * Initialize the i8042 controller. Then initialize the keyboard
203 * module and connect it to i8042. Enable keyboard interrupts.
204 */
205 i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
206 if (i8042_instance) {
207 kbrd_instance_t *kbrd_instance = kbrd_init();
208 if (kbrd_instance) {
209 indev_t *sink = stdin_wire();
210 indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
211 i8042_wire(i8042_instance, kbrd);
212 trap_virtual_enable_irqs(1 << IRQ_KBD);
213 }
214 }
215
216 /*
217 * This is the necessary evil until the userspace driver is entirely
218 * self-sufficient.
219 */
220 sysinfo_set_item_val("kbd", NULL, true);
221 sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
222 sysinfo_set_item_val("kbd.address.physical", NULL,
223 (uintptr_t) I8042_BASE);
224 sysinfo_set_item_val("kbd.address.kernel", NULL,
225 (uintptr_t) I8042_BASE);
226#endif
227}
228
229void calibrate_delay_loop(void)
230{
231 i8254_calibrate_delay_loop();
232 if (config.cpu_active == 1) {
233 /*
234 * This has to be done only on UP.
235 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
236 */
237 i8254_normal_operation();
238 }
239}
240
241/** Set thread-local-storage pointer
242 *
243 * TLS pointer is set in FS register. Unfortunately the 64-bit
244 * part can be set only in CPL0 mode.
245 *
246 * The specs say, that on %fs:0 there is stored contents of %fs register,
247 * we need not to go to CPL0 to read it.
248 */
249unative_t sys_tls_set(unative_t addr)
250{
251 THREAD->arch.tls = addr;
252 write_msr(AMD_MSR_FS, addr);
253 return 0;
254}
255
256/** Construct function pointer
257 *
258 * @param fptr function pointer structure
259 * @param addr function address
260 * @param caller calling function address
261 *
262 * @return address of the function pointer
263 *
264 */
265void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
266{
267 return addr;
268}
269
270void arch_reboot(void)
271{
272#ifdef CONFIG_PC_KBD
273 i8042_cpu_reset((i8042_t *) I8042_BASE);
274#endif
275}
276
277/** @}
278 */
Note: See TracBrowser for help on using the repository browser.