source: mainline/arch/ia32/src/smp/smp.c@ ba18512

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ba18512 was 9c0a9b3, checked in by Jakub Vana <jakub.vana@…>, 20 years ago

1) memcopy and _memcopy functions rewriten to ANSI C norm.
2) Repaired ia32,ia64 and mips version of SPARTAN to work with this memcopy functions
3) Warning for non declared funcions added and repaired ia32,ia64 and mips versions to pass build process with this warning and Werror option

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * Copyright (C) 2005 Jakub Jermar
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#include <smp/smp.h>
30#include <arch/smp/smp.h>
31#include <arch/smp/mps.h>
32#include <arch/smp/ap.h>
33#include <arch/acpi/acpi.h>
34#include <arch/acpi/madt.h>
35#include <config.h>
36#include <synch/waitq.h>
37#include <arch/pm.h>
38#include <func.h>
39#include <panic.h>
40#include <debug.h>
41#include <arch/asm.h>
42#include <mm/frame.h>
43#include <mm/page.h>
44#include <mm/heap.h>
45#include <print.h>
46#include <memstr.h>
47#include <arch/i8259.h>
48
49#ifdef __SMP__
50
51static struct smp_config_operations *ops = NULL;
52
53void smp_init(void)
54{
55 if (acpi_madt) {
56 acpi_madt_parse();
57 ops = &madt_config_operations;
58 }
59 if (config.cpu_count == 1) {
60 mps_init();
61 ops = &mps_config_operations;
62 }
63
64 if (config.cpu_count > 1) {
65 map_page_to_frame((__address) l_apic, (__address) l_apic, PAGE_NOT_CACHEABLE, 0);
66 map_page_to_frame((__address) io_apic, (__address) io_apic, PAGE_NOT_CACHEABLE, 0);
67 }
68
69 /*
70 * Must be initialized outside the kmp thread, since it is waited
71 * on before the kmp thread is created.
72 */
73 waitq_initialize(&kmp_completion_wq);
74
75}
76
77/*
78 * Kernel thread for bringing up application processors. It becomes clear
79 * that we need an arrangement like this (AP's being initialized by a kernel
80 * thread), for a thread has its dedicated stack. (The stack used during the
81 * BSP initialization (prior the very first call to scheduler()) will be used
82 * as an initialization stack for each AP.)
83 */
84void kmp(void *arg)
85{
86 __address src, dst;
87 int i;
88
89 ASSERT(ops != NULL);
90
91 waitq_initialize(&ap_completion_wq);
92
93 /*
94 * We need to access data in frame 0.
95 * We boldly make use of kernel address space mapping.
96 */
97
98 /*
99 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
100 */
101 *((__u16 *) (PA2KA(0x467+0))) = ((__address) ap_boot) >> 4; /* segment */
102 *((__u16 *) (PA2KA(0x467+2))) = 0; /* offset */
103
104 /*
105 * Save 0xa to address 0xf of the CMOS RAM.
106 * BIOS will not do the POST after the INIT signal.
107 */
108 outb(0x70,0xf);
109 outb(0x71,0xa);
110
111 cpu_priority_high();
112
113 pic_disable_irqs(0xffff);
114 apic_init();
115
116 for (i = 0; i < ops->cpu_count(); i++) {
117 struct descriptor *gdt_new;
118
119 /*
120 * Skip processors marked unusable.
121 */
122 if (!ops->cpu_enabled(i))
123 continue;
124
125 /*
126 * The bootstrap processor is already up.
127 */
128 if (ops->cpu_bootstrap(i))
129 continue;
130
131 if (ops->cpu_apic_id(i) == l_apic_id()) {
132 printf("kmp: bad processor entry #%d, will not send IPI to myself\n", i);
133 continue;
134 }
135
136 /*
137 * Prepare new GDT for CPU in question.
138 */
139 if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor))))
140 panic("couldn't allocate memory for GDT\n");
141
142 memcopy(gdt_new, gdt, GDT_ITEMS*sizeof(struct descriptor)); // swaped
143 memsetb((__address)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
144 gdtr.base = KA2PA((__address) gdt_new);
145
146 if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
147 /*
148 * There may be just one AP being initialized at
149 * the time. After it comes completely up, it is
150 * supposed to wake us up.
151 */
152 waitq_sleep(&ap_completion_wq);
153 }
154 else {
155 printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
156 }
157 }
158
159 /*
160 * Wakeup the kinit thread so that
161 * system initialization can go on.
162 */
163 waitq_wakeup(&kmp_completion_wq, WAKEUP_FIRST);
164}
165
166#endif /* __SMP__ */
Note: See TracBrowser for help on using the repository browser.