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

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

rename ia32_cboot() to arch_pre_main() and move it to ia32.c (to be in line with other platforms)

  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[f761f1eb]1/*
[df4ed85]2 * Copyright (c) 2001-2004 Jakub Jermar
[deca67b]3 * Copyright (c) 2009 Jiri Svoboda
4 * Copyright (c) 2009 Martin Decky
[f761f1eb]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
[06e1e95]31/** @addtogroup ia32
[b45c443]32 * @{
33 */
34/** @file
35 */
36
[f761f1eb]37#include <arch.h>
38
39#include <arch/types.h>
40
41#include <arch/pm.h>
42
[91825d90]43#include <genarch/drivers/legacy/ia32/io.h>
[f245145]44#include <genarch/drivers/ega/ega.h>
[80d31883]45#include <arch/drivers/vesa.h>
[287920f]46#include <genarch/kbd/i8042.h>
[80d31883]47#include <arch/drivers/i8254.h>
48#include <arch/drivers/i8259.h>
[f761f1eb]49
50#include <arch/context.h>
51
52#include <config.h>
53
54#include <arch/interrupt.h>
[ad36bd6]55#include <arch/asm.h>
[e16e036a]56#include <genarch/acpi/acpi.h>
[9c0a9b3]57
58#include <arch/bios/bios.h>
59
[fcfac420]60#include <interrupt.h>
[cea12e9]61#include <ddi/irq.h>
[23d22eb]62#include <arch/debugger.h>
[281b607]63#include <proc/thread.h>
64#include <syscall/syscall.h>
[41d33ac]65#include <console/console.h>
[cea12e9]66#include <ddi/device.h>
[4c7257b]67#include <sysinfo/sysinfo.h>
[deca67b]68#include <arch/boot/boot.h>
69#include <string.h>
70#include <macros.h>
[ad36bd6]71
[26678e5]72#ifdef CONFIG_SMP
73#include <arch/smp/apic.h>
74#endif
75
[deca67b]76/** Extract command name from the multiboot module command line.
77 *
78 * @param buf Destination buffer (will always null-terminate).
79 * @param n Size of destination buffer.
80 * @param cmd_line Input string (the command line).
81 *
82 */
83static void extract_command(char *buf, size_t n, const char *cmd_line)
84{
85 const char *start, *end, *cp;
86 size_t max_len;
87
88 /* Find the first space. */
89 end = strchr(cmd_line, ' ');
90 if (end == NULL)
91 end = cmd_line + strlen(cmd_line);
92
93 /*
94 * Find last occurence of '/' before 'end'. If found, place start at
95 * next character. Otherwise, place start at beginning of buffer.
96 */
97 cp = end;
98 start = buf;
99 while (cp != start) {
100 if (*cp == '/') {
101 start = cp + 1;
102 break;
103 }
104 --cp;
105 }
106
107 /* Copy the command and null-terminate the string. */
108 max_len = min(n - 1, (size_t) (end - start));
109 strncpy(buf, start, max_len + 1);
110 buf[max_len] = '\0';
111}
112
113/** C part of ia32 boot sequence.
114 *
115 * @param signature Should contain the multiboot signature.
116 * @param mi Pointer to the multiboot information structure.
117 */
118void arch_pre_main(uint32_t signature, const mb_info_t *mi)
119{
120 uint32_t flags;
121 mb_mod_t *mods;
122 uint32_t i;
123
124 if (signature == MULTIBOOT_LOADER_MAGIC)
125 flags = mi->flags;
126 else {
127 /* No multiboot info available. */
128 flags = 0;
129 }
130
131 /* Copy module information. */
132
133 if ((flags & MBINFO_FLAGS_MODS) != 0) {
134 init.cnt = mi->mods_count;
135 mods = mi->mods_addr;
136
137 for (i = 0; i < init.cnt; i++) {
138 init.tasks[i].addr = mods[i].start + 0x80000000;
139 init.tasks[i].size = mods[i].end - mods[i].start;
140
141 /* Copy command line, if available. */
142 if (mods[i].string) {
143 extract_command(init.tasks[i].name,
144 CONFIG_TASK_NAME_BUFLEN,
145 mods[i].string);
146 } else
147 init.tasks[i].name[0] = '\0';
148 }
149 } else
150 init.cnt = 0;
151
152 /* Copy memory map. */
153
154 int32_t mmap_length;
155 mb_mmap_t *mme;
156 uint32_t size;
157
158 if ((flags & MBINFO_FLAGS_MMAP) != 0) {
159 mmap_length = mi->mmap_length;
160 mme = mi->mmap_addr;
161 e820counter = 0;
162
163 i = 0;
164 while (mmap_length > 0) {
165 e820table[i++] = mme->mm_info;
166
167 /* Compute address of next structure. */
168 size = sizeof(mme->size) + mme->size;
169 mme = ((void *) mme) + size;
170 mmap_length -= size;
171 }
172
173 e820counter = i;
174 } else
175 e820counter = 0;
176
177#ifdef CONFIG_SMP
178 /* Copy AP bootstrap routines below 1 MB. */
179 memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
180 (size_t) &_hardcoded_unmapped_size);
181#endif
182}
183
[f07bba5]184void arch_pre_mm_init(void)
[f761f1eb]185{
186 pm_init();
187
188 if (config.cpu_active == 1) {
[cea12e9]189 interrupt_init();
[dba84ff]190 bios_init();
[5dce48b9]191
[cea12e9]192 /* PIC */
193 i8259_init();
[f761f1eb]194 }
195}
196
[6ba143d]197void arch_post_mm_init(void)
[7eade45]198{
[425913b]199 if (config.cpu_active == 1) {
[cea12e9]200 /* Initialize IRQ routing */
201 irq_init(IRQ_COUNT, IRQ_COUNT);
202
203 /* hard clock */
204 i8254_init();
[22cf454d]205
206#ifdef CONFIG_FB
[381465e]207 if (vesa_present())
208 vesa_init();
[22cf454d]209 else
210#endif
[f245145]211 ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
[22cf454d]212
[23d22eb]213 /* Enable debugger */
214 debugger_init();
[381465e]215 /* Merge all memory zones to 1 big zone */
216 zone_merge_all();
[babcb148]217 }
218}
219
[26678e5]220void arch_post_cpu_init()
221{
222#ifdef CONFIG_SMP
223 if (config.cpu_active > 1) {
224 l_apic_init();
225 l_apic_debug();
226 }
227#endif
228}
229
[7453929]230void arch_pre_smp_init(void)
[babcb148]231{
232 if (config.cpu_active == 1) {
[f619ec11]233#ifdef CONFIG_SMP
[85bfdcc8]234 acpi_init();
[f619ec11]235#endif /* CONFIG_SMP */
[425913b]236 }
[7eade45]237}
238
[7453929]239void arch_post_smp_init(void)
240{
[4c7257b]241 devno_t devno = device_assign_devno();
[cea12e9]242 /* keyboard controller */
[4c7257b]243 (void) i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD);
244
245 /*
246 * This is the necessary evil until the userspace driver is entirely
247 * self-sufficient.
248 */
249 sysinfo_set_item_val("kbd", NULL, true);
250 sysinfo_set_item_val("kbd.devno", NULL, devno);
251 sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
[7453929]252}
253
[f761f1eb]254void calibrate_delay_loop(void)
255{
256 i8254_calibrate_delay_loop();
[f701b236]257 if (config.cpu_active == 1) {
258 /*
259 * This has to be done only on UP.
260 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
261 */
262 i8254_normal_operation();
263 }
[f761f1eb]264}
[281b607]265
[e1be3b6]266/** Set thread-local-storage pointer
[281b607]267 *
[3b712407]268 * TLS pointer is set in GS register. That means, the GS contains
269 * selector, and the descriptor->base is the correct address.
[281b607]270 */
[7f1c620]271unative_t sys_tls_set(unative_t addr)
[281b607]272{
[a6d4ceb]273 THREAD->arch.tls = addr;
[281b607]274 set_tls_desc(addr);
275
276 return 0;
277}
[41d33ac]278
279/** Acquire console back for kernel
280 *
281 */
282void arch_grab_console(void)
283{
[76fca31]284#ifdef CONFIG_FB
285 vesa_redraw();
286#else
287 ega_redraw();
288#endif
[41d33ac]289}
[76fca31]290
[41d33ac]291/** Return console to userspace
292 *
293 */
294void arch_release_console(void)
295{
296}
[b45c443]297
[6da1013f]298/** Construct function pointer
299 *
300 * @param fptr function pointer structure
301 * @param addr function address
302 * @param caller calling function address
303 *
304 * @return address of the function pointer
305 *
306 */
307void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
308{
309 return addr;
310}
311
[06e1e95]312/** @}
[b45c443]313 */
Note: See TracBrowser for help on using the repository browser.