source: mainline/kernel/arch/ia64/src/ia64.c@ d9ee2ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d9ee2ea 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: 7.2 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/** @addtogroup ia64
30 * @{
31 */
32/** @file
33 */
34
35#include <arch.h>
36#include <arch/drivers/ski.h>
37#include <arch/drivers/it.h>
38#include <arch/interrupt.h>
39#include <arch/barrier.h>
40#include <arch/asm.h>
41#include <arch/register.h>
42#include <arch/types.h>
43#include <arch/context.h>
44#include <arch/stack.h>
45#include <arch/mm/page.h>
46#include <mm/as.h>
47#include <config.h>
48#include <userspace.h>
49#include <console/console.h>
50#include <proc/uarg.h>
51#include <syscall/syscall.h>
52#include <ddi/irq.h>
53#include <arch/bootinfo.h>
54#include <genarch/drivers/legacy/ia32/io.h>
55#include <genarch/drivers/ega/ega.h>
56#include <genarch/kbrd/kbrd.h>
57#include <genarch/srln/srln.h>
58#include <genarch/drivers/i8042/i8042.h>
59#include <genarch/drivers/ns16550/ns16550.h>
60#include <arch/drivers/kbd.h>
61#include <smp/smp.h>
62#include <smp/ipi.h>
63#include <arch/atomic.h>
64#include <panic.h>
65#include <print.h>
66#include <sysinfo/sysinfo.h>
67#include <string.h>
68
69/* NS16550 as a COM 1 */
70#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
71
72bootinfo_t *bootinfo;
73
74static uint64_t iosapic_base = 0xfec00000;
75
76/** Performs ia64-specific initialization before main_bsp() is called. */
77void arch_pre_main(void)
78{
79 /* Setup usermode init tasks. */
80
81 unsigned int i;
82
83 init.cnt = bootinfo->taskmap.count;
84
85 for (i = 0; i < init.cnt; i++) {
86 init.tasks[i].addr =
87 ((unsigned long) bootinfo->taskmap.tasks[i].addr) |
88 VRN_MASK;
89 init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
90 str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
91 bootinfo->taskmap.tasks[i].name);
92 }
93}
94
95void arch_pre_mm_init(void)
96{
97 /*
98 * Set Interruption Vector Address (i.e. location of interruption vector
99 * table).
100 */
101 iva_write((uintptr_t) &ivt);
102 srlz_d();
103
104}
105
106static void iosapic_init(void)
107{
108 uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET;
109 int i;
110
111 int myid, myeid;
112
113 myid = ia64_get_cpu_id();
114 myeid = ia64_get_cpu_eid();
115
116 for (i = 0; i < 16; i++) {
117 if (i == 2)
118 continue; /* Disable Cascade interrupt */
119 ((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i;
120 srlz_d();
121 ((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i;
122 srlz_d();
123 ((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1;
124 srlz_d();
125 ((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) |
126 myeid << (48 - 32);
127 srlz_d();
128 }
129
130}
131
132void arch_post_mm_init(void)
133{
134 if (config.cpu_active == 1) {
135 iosapic_init();
136 irq_init(INR_COUNT, INR_COUNT);
137 }
138 it_init();
139}
140
141void arch_post_cpu_init(void)
142{
143}
144
145void arch_pre_smp_init(void)
146{
147}
148
149void arch_post_smp_init(void)
150{
151#ifdef MACHINE_ski
152 ski_instance_t *ski_instance = skiin_init();
153 if (ski_instance) {
154 srln_instance_t *srln_instance = srln_init();
155 if (srln_instance) {
156 indev_t *sink = stdin_wire();
157 indev_t *srln = srln_wire(srln_instance, sink);
158 skiin_wire(ski_instance, srln);
159 }
160 }
161
162 outdev_t *skidev = skiout_init();
163 if (skidev)
164 stdout_wire(skidev);
165#endif
166
167#ifdef CONFIG_EGA
168 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM);
169 if (egadev)
170 stdout_wire(egadev);
171#endif
172
173#ifdef CONFIG_NS16550
174 ns16550_instance_t *ns16550_instance
175 = ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL);
176 if (ns16550_instance) {
177 srln_instance_t *srln_instance = srln_init();
178 if (srln_instance) {
179 indev_t *sink = stdin_wire();
180 indev_t *srln = srln_wire(srln_instance, sink);
181 ns16550_wire(ns16550_instance, srln);
182 }
183 }
184
185 sysinfo_set_item_val("kbd", NULL, true);
186 sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
187 sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
188 sysinfo_set_item_val("kbd.address.physical", NULL,
189 (uintptr_t) NS16550_BASE);
190 sysinfo_set_item_val("kbd.address.kernel", NULL,
191 (uintptr_t) NS16550_BASE);
192#endif
193
194#ifdef CONFIG_I8042
195 i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
196 if (i8042_instance) {
197 kbrd_instance_t *kbrd_instance = kbrd_init();
198 if (kbrd_instance) {
199 indev_t *sink = stdin_wire();
200 indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
201 i8042_wire(i8042_instance, kbrd);
202 }
203 }
204
205 sysinfo_set_item_val("kbd", NULL, true);
206 sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
207 sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
208 sysinfo_set_item_val("kbd.address.physical", NULL,
209 (uintptr_t) I8042_BASE);
210 sysinfo_set_item_val("kbd.address.kernel", NULL,
211 (uintptr_t) I8042_BASE);
212#endif
213
214 sysinfo_set_item_val("ia64_iospace", NULL, true);
215 sysinfo_set_item_val("ia64_iospace.address", NULL, true);
216 sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
217}
218
219
220/** Enter userspace and never return. */
221void userspace(uspace_arg_t *kernel_uarg)
222{
223 psr_t psr;
224 rsc_t rsc;
225
226 psr.value = psr_read();
227 psr.cpl = PL_USER;
228 psr.i = true; /* start with interrupts enabled */
229 psr.ic = true;
230 psr.ri = 0; /* start with instruction #0 */
231 psr.bn = 1; /* start in bank 0 */
232
233 asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
234 rsc.loadrs = 0;
235 rsc.be = false;
236 rsc.pl = PL_USER;
237 rsc.mode = 3; /* eager mode */
238
239 switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
240 ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
241 ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
242 ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
243 (uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
244
245 while (1)
246 ;
247}
248
249/** Set thread-local-storage pointer.
250 *
251 * We use r13 (a.k.a. tp) for this purpose.
252 */
253unative_t sys_tls_set(unative_t addr)
254{
255 return 0;
256}
257
258void arch_reboot(void)
259{
260 pio_write_8((ioport8_t *)0x64, 0xfe);
261 while (1)
262 ;
263}
264
265/** Construct function pointer
266 *
267 * @param fptr function pointer structure
268 * @param addr function address
269 * @param caller calling function address
270 *
271 * @return address of the function pointer
272 *
273 */
274void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
275{
276 fptr->fnc = (unative_t) addr;
277 fptr->gp = ((unative_t *) caller)[1];
278
279 return (void *) fptr;
280}
281
282/** @}
283 */
Note: See TracBrowser for help on using the repository browser.