source: mainline/kernel/arch/mips64/src/mips64.c@ 32c2c8f

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

add support for variable uspace stack size
create individual address space areas for stacks of additional threads (instead of allocating the stack from heap)
avoid memory leaks in program_create()

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2003-2004 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 mips64
30 * @{
31 */
32/** @file
33 */
34
35#include <arch.h>
36#include <typedefs.h>
37#include <errno.h>
38#include <interrupt.h>
39#include <macros.h>
40#include <str.h>
41#include <memstr.h>
42#include <userspace.h>
43#include <console/console.h>
44#include <syscall/syscall.h>
45#include <sysinfo/sysinfo.h>
46#include <arch/debug.h>
47#include <arch/debugger.h>
48#include <arch/drivers/msim.h>
49#include <genarch/fb/fb.h>
50#include <genarch/drivers/dsrln/dsrlnin.h>
51#include <genarch/drivers/dsrln/dsrlnout.h>
52#include <genarch/srln/srln.h>
53
54/* Size of the code jumping to the exception handler code
55 * - J+NOP
56 */
57#define EXCEPTION_JUMP_SIZE 8
58
59#define TLB_EXC ((char *) 0xffffffff80000000)
60#define NORM_EXC ((char *) 0xffffffff80000180)
61#define CACHE_EXC ((char *) 0xffffffff80000100)
62
63
64/* Why the linker moves the variable 64K away in assembler
65 * when not in .text section?
66 */
67
68/* Stack pointer saved when entering user mode */
69uintptr_t supervisor_sp __attribute__ ((section (".text")));
70
71size_t cpu_count = 0;
72
73/** Performs mips64-specific initialization before main_bsp() is called. */
74void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
75{
76 init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
77
78 size_t i;
79 for (i = 0; i < init.cnt; i++) {
80 init.tasks[i].paddr = KA2PA(bootinfo->tasks[i].addr);
81 init.tasks[i].size = bootinfo->tasks[i].size;
82 str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
83 bootinfo->tasks[i].name);
84 }
85
86 for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
87 if ((bootinfo->cpumap & (1 << i)) != 0)
88 cpu_count++;
89 }
90}
91
92void arch_pre_mm_init(void)
93{
94 /* It is not assumed by default */
95 interrupts_disable();
96
97 /* Initialize dispatch table */
98 exception_init();
99
100 /* Copy the exception vectors to the right places */
101 memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE);
102 smc_coherence_block(TLB_EXC, EXCEPTION_JUMP_SIZE);
103 memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE);
104 smc_coherence_block(NORM_EXC, EXCEPTION_JUMP_SIZE);
105 memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE);
106 smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE);
107
108 /*
109 * Switch to BEV normal level so that exception vectors point to the
110 * kernel. Clear the error level.
111 */
112 cp0_status_write(cp0_status_read() &
113 ~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit));
114
115 /*
116 * Mask all interrupts
117 */
118 cp0_mask_all_int();
119
120 debugger_init();
121}
122
123void arch_post_mm_init(void)
124{
125 interrupt_init();
126
127#ifdef CONFIG_MIPS_PRN
128 outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
129 if (dsrlndev)
130 stdout_wire(dsrlndev);
131#endif
132}
133
134void arch_post_cpu_init(void)
135{
136}
137
138void arch_pre_smp_init(void)
139{
140}
141
142void arch_post_smp_init(void)
143{
144 static const char *platform;
145
146 /* Set platform name. */
147#ifdef MACHINE_msim
148 platform = "msim";
149#endif
150 sysinfo_set_item_data("platform", NULL, (void *) platform,
151 str_size(platform));
152
153#ifdef CONFIG_MIPS_KBD
154 /*
155 * Initialize the msim/GXemul keyboard port. Then initialize the serial line
156 * module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
157 */
158 dsrlnin_instance_t *dsrlnin_instance
159 = dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ);
160 if (dsrlnin_instance) {
161 srln_instance_t *srln_instance = srln_init();
162 if (srln_instance) {
163 indev_t *sink = stdin_wire();
164 indev_t *srln = srln_wire(srln_instance, sink);
165 dsrlnin_wire(dsrlnin_instance, srln);
166 cp0_unmask_int(MSIM_KBD_IRQ);
167 }
168 }
169
170 /*
171 * This is the necessary evil until the userspace driver is entirely
172 * self-sufficient.
173 */
174 sysinfo_set_item_val("kbd", NULL, true);
175 sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
176 sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
177#endif
178}
179
180void calibrate_delay_loop(void)
181{
182}
183
184void userspace(uspace_arg_t *kernel_uarg)
185{
186 /* EXL = 1, UM = 1, IE = 1 */
187 cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
188 cp0_status_um_bit | cp0_status_ie_enabled_bit));
189 cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
190 userspace_asm(((uintptr_t) kernel_uarg->uspace_stack +
191 kernel_uarg->uspace_stack_size),
192 (uintptr_t) kernel_uarg->uspace_uarg,
193 (uintptr_t) kernel_uarg->uspace_entry);
194
195 while (1);
196}
197
198/** Perform mips64 specific tasks needed before the new task is run. */
199void before_task_runs_arch(void)
200{
201}
202
203/** Perform mips64 specific tasks needed before the new thread is scheduled. */
204void before_thread_runs_arch(void)
205{
206 supervisor_sp =
207 (uintptr_t) &THREAD->kstack[STACK_SIZE - SP_DELTA];
208}
209
210void after_thread_ran_arch(void)
211{
212}
213
214/** Set thread-local-storage pointer
215 *
216 * We have it currently in K1, it is
217 * possible to have it separately in the future.
218 */
219sysarg_t sys_tls_set(uintptr_t addr)
220{
221 return EOK;
222}
223
224void arch_reboot(void)
225{
226 ___halt();
227 while (1);
228}
229
230/** Construct function pointer
231 *
232 * @param fptr function pointer structure
233 * @param addr function address
234 * @param caller calling function address
235 *
236 * @return address of the function pointer
237 *
238 */
239void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
240{
241 return addr;
242}
243
244void irq_initialize_arch(irq_t *irq)
245{
246 (void) irq;
247}
248
249/** @}
250 */
Note: See TracBrowser for help on using the repository browser.