source: mainline/kernel/arch/ia32/src/ia32.c@ acc7ce4

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

uspace interrupt controller drivers for i8259 and APIC (non-functional yet)
convert NE2000 driver to use these drivers (not enabling the IRQ in kernel), this solves the "spurious interrupt" issue
(however, on SMP machines this renders the driver unusable for now since the APIC driver does not do anything yet)

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Jakub Jermar
3 * Copyright (c) 2009 Jiri Svoboda
4 * Copyright (c) 2009 Martin Decky
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/** @addtogroup ia32
32 * @{
33 */
34/** @file
35 */
36
37#include <arch.h>
38
39#include <typedefs.h>
40
41#include <arch/pm.h>
42
43#include <genarch/multiboot/multiboot.h>
44#include <genarch/drivers/legacy/ia32/io.h>
45#include <genarch/drivers/ega/ega.h>
46#include <arch/drivers/vesa.h>
47#include <genarch/drivers/i8042/i8042.h>
48#include <genarch/kbrd/kbrd.h>
49#include <arch/drivers/i8254.h>
50#include <arch/drivers/i8259.h>
51
52#include <arch/context.h>
53
54#include <config.h>
55
56#include <arch/interrupt.h>
57#include <arch/asm.h>
58#include <genarch/acpi/acpi.h>
59
60#include <arch/bios/bios.h>
61
62#include <interrupt.h>
63#include <ddi/irq.h>
64#include <arch/debugger.h>
65#include <proc/thread.h>
66#include <syscall/syscall.h>
67#include <console/console.h>
68#include <sysinfo/sysinfo.h>
69#include <arch/boot/boot.h>
70#include <memstr.h>
71
72#ifdef CONFIG_SMP
73#include <arch/smp/apic.h>
74#endif
75
76/** Perform ia32-specific initialization before main_bsp() is called.
77 *
78 * @param signature Should contain the multiboot signature.
79 * @param mi Pointer to the multiboot information structure.
80 */
81void arch_pre_main(uint32_t signature, const multiboot_info_t *mi)
82{
83 /* Parse multiboot information obtained from the bootloader. */
84 multiboot_info_parse(signature, mi);
85
86#ifdef CONFIG_SMP
87 /* Copy AP bootstrap routines below 1 MB. */
88 memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
89 (size_t) &_hardcoded_unmapped_size);
90#endif
91}
92
93void arch_pre_mm_init(void)
94{
95 pm_init();
96
97 if (config.cpu_active == 1) {
98 interrupt_init();
99 bios_init();
100
101 /* PIC */
102 i8259_init();
103 }
104}
105
106void arch_post_mm_init(void)
107{
108 if (config.cpu_active == 1) {
109 /* Initialize IRQ routing */
110 irq_init(IRQ_COUNT, IRQ_COUNT);
111
112 /* hard clock */
113 i8254_init();
114
115#if (defined(CONFIG_FB) || defined(CONFIG_EGA))
116 bool vesa = false;
117#endif
118
119#ifdef CONFIG_FB
120 vesa = vesa_init();
121#endif
122
123#ifdef CONFIG_EGA
124 if (!vesa) {
125 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
126 if (egadev)
127 stdout_wire(egadev);
128 }
129#endif
130
131 /* Enable debugger */
132 debugger_init();
133 /* Merge all memory zones to 1 big zone */
134 zone_merge_all();
135 }
136}
137
138void arch_post_cpu_init()
139{
140#ifdef CONFIG_SMP
141 if (config.cpu_active > 1) {
142 l_apic_init();
143 l_apic_debug();
144 }
145#endif
146}
147
148void arch_pre_smp_init(void)
149{
150 if (config.cpu_active == 1) {
151#ifdef CONFIG_SMP
152 acpi_init();
153#endif /* CONFIG_SMP */
154 }
155}
156
157void arch_post_smp_init(void)
158{
159 /* Currently the only supported platform for ia32 is 'pc'. */
160 static const char *platform = "pc";
161
162 sysinfo_set_item_data("platform", NULL, (void *) platform,
163 str_size(platform));
164
165#ifdef CONFIG_PC_KBD
166 /*
167 * Initialize the i8042 controller. Then initialize the keyboard
168 * module and connect it to i8042. Enable keyboard interrupts.
169 */
170 i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
171 if (i8042_instance) {
172 kbrd_instance_t *kbrd_instance = kbrd_init();
173 if (kbrd_instance) {
174 indev_t *sink = stdin_wire();
175 indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
176 i8042_wire(i8042_instance, kbrd);
177 trap_virtual_enable_irqs(1 << IRQ_KBD);
178 trap_virtual_enable_irqs(1 << IRQ_MOUSE);
179 }
180 }
181
182 /*
183 * This is the necessary evil until the userspace driver is entirely
184 * self-sufficient.
185 */
186 sysinfo_set_item_val("i8042", NULL, true);
187 sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
188 sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
189 sysinfo_set_item_val("i8042.address.physical", NULL,
190 (uintptr_t) I8042_BASE);
191 sysinfo_set_item_val("i8042.address.kernel", NULL,
192 (uintptr_t) I8042_BASE);
193#endif
194
195 if (irqs_info != NULL)
196 sysinfo_set_item_val(irqs_info, NULL, true);
197
198 sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
199}
200
201void calibrate_delay_loop(void)
202{
203 i8254_calibrate_delay_loop();
204 if (config.cpu_active == 1) {
205 /*
206 * This has to be done only on UP.
207 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
208 */
209 i8254_normal_operation();
210 }
211}
212
213/** Set thread-local-storage pointer
214 *
215 * TLS pointer is set in GS register. That means, the GS contains
216 * selector, and the descriptor->base is the correct address.
217 */
218sysarg_t sys_tls_set(sysarg_t addr)
219{
220 THREAD->arch.tls = addr;
221 set_tls_desc(addr);
222
223 return 0;
224}
225
226/** Construct function pointer
227 *
228 * @param fptr function pointer structure
229 * @param addr function address
230 * @param caller calling function address
231 *
232 * @return address of the function pointer
233 *
234 */
235void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
236{
237 return addr;
238}
239
240void arch_reboot(void)
241{
242#ifdef CONFIG_PC_KBD
243 i8042_cpu_reset((i8042_t *) I8042_BASE);
244#endif
245}
246
247void irq_initialize_arch(irq_t *irq)
248{
249 (void) irq;
250}
251
252/** @}
253 */
Note: See TracBrowser for help on using the repository browser.