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

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

as kernel little brother drivers are not needed anymore, the device numbers do not have to be correlated between kernel and uspace in any way
introduce new syscall sys_device_assign_devno() for generating system-wide unique device numbers for uspace

  • Property mode set to 100644
File size: 6.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/** @addtogroup ia64
30 * @{
31 */
32/** @file
33 */
34
35#include <arch.h>
36#include <arch/ski/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 strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name,
91 CONFIG_TASK_NAME_BUFLEN);
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 SKI
152 indev_t *in;
153 in = skiin_init();
154 if (in)
155 srln_init(in);
156 skiout_init();
157#endif
158
159#ifdef CONFIG_EGA
160 ega_init(EGA_BASE, EGA_VIDEORAM);
161#endif
162
163#ifdef CONFIG_NS16550
164 indev_t *kbrdin_ns16550
165 = ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL);
166 if (kbrdin_ns16550)
167 srln_init(kbrdin_ns16550);
168
169 sysinfo_set_item_val("kbd", NULL, true);
170 sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
171 sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
172 sysinfo_set_item_val("kbd.address.physical", NULL,
173 (uintptr_t) NS16550_BASE);
174 sysinfo_set_item_val("kbd.address.kernel", NULL,
175 (uintptr_t) NS16550_BASE);
176#endif
177
178#ifdef CONFIG_I8042
179 indev_t *kbrdin_i8042 = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
180 if (kbrdin_i8042)
181 kbrd_init(kbrdin_i8042);
182
183 sysinfo_set_item_val("kbd", NULL, true);
184 sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
185 sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
186 sysinfo_set_item_val("kbd.address.physical", NULL,
187 (uintptr_t) I8042_BASE);
188 sysinfo_set_item_val("kbd.address.kernel", NULL,
189 (uintptr_t) I8042_BASE);
190#endif
191
192 sysinfo_set_item_val("ia64_iospace", NULL, true);
193 sysinfo_set_item_val("ia64_iospace.address", NULL, true);
194 sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
195}
196
197
198/** Enter userspace and never return. */
199void userspace(uspace_arg_t *kernel_uarg)
200{
201 psr_t psr;
202 rsc_t rsc;
203
204 psr.value = psr_read();
205 psr.cpl = PL_USER;
206 psr.i = true; /* start with interrupts enabled */
207 psr.ic = true;
208 psr.ri = 0; /* start with instruction #0 */
209 psr.bn = 1; /* start in bank 0 */
210
211 asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
212 rsc.loadrs = 0;
213 rsc.be = false;
214 rsc.pl = PL_USER;
215 rsc.mode = 3; /* eager mode */
216
217 switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
218 ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
219 ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
220 ((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
221 (uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
222
223 while (1)
224 ;
225}
226
227/** Set thread-local-storage pointer.
228 *
229 * We use r13 (a.k.a. tp) for this purpose.
230 */
231unative_t sys_tls_set(unative_t addr)
232{
233 return 0;
234}
235
236/** Acquire console back for kernel
237 *
238 */
239void arch_grab_console(void)
240{
241#ifdef SKI
242 ski_kbd_grab();
243#endif
244}
245
246/** Return console to userspace
247 *
248 */
249void arch_release_console(void)
250{
251#ifdef SKI
252 ski_kbd_release();
253#endif
254}
255
256void arch_reboot(void)
257{
258 pio_write_8((ioport8_t *)0x64, 0xfe);
259 while (1)
260 ;
261}
262
263/** Construct function pointer
264 *
265 * @param fptr function pointer structure
266 * @param addr function address
267 * @param caller calling function address
268 *
269 * @return address of the function pointer
270 *
271 */
272void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
273{
274 fptr->fnc = (unative_t) addr;
275 fptr->gp = ((unative_t *) caller)[1];
276
277 return (void *) fptr;
278}
279
280/** @}
281 */
Note: See TracBrowser for help on using the repository browser.