source: mainline/kernel/arch/ppc32/src/ppc32.c@ 2d884ab

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2d884ab was 2902e1bb, checked in by Martin Decky <martin@…>, 14 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: 7.6 KB
Line 
1/*
2 * Copyright (c) 2005 Martin Decky
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 ppc32
30 * @{
31 */
32/** @file
33 */
34
35#include <config.h>
36#include <arch.h>
37#include <arch/boot/boot.h>
38#include <genarch/drivers/via-cuda/cuda.h>
39#include <genarch/kbrd/kbrd.h>
40#include <arch/interrupt.h>
41#include <interrupt.h>
42#include <genarch/fb/fb.h>
43#include <abi/fb/visuals.h>
44#include <genarch/ofw/ofw_tree.h>
45#include <genarch/ofw/pci.h>
46#include <userspace.h>
47#include <mm/page.h>
48#include <mm/km.h>
49#include <abi/proc/uarg.h>
50#include <console/console.h>
51#include <sysinfo/sysinfo.h>
52#include <ddi/irq.h>
53#include <arch/drivers/pic.h>
54#include <align.h>
55#include <macros.h>
56#include <str.h>
57#include <print.h>
58
59#define IRQ_COUNT 64
60#define IRQ_CUDA 10
61
62bootinfo_t bootinfo;
63
64static cir_t pic_cir;
65static void *pic_cir_arg;
66
67/** Performs ppc32-specific initialization before main_bsp() is called. */
68void arch_pre_main(bootinfo_t *bootinfo)
69{
70 /* Copy tasks map. */
71 init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
72 size_t i;
73 for (i = 0; i < init.cnt; i++) {
74 init.tasks[i].paddr = KA2PA(bootinfo->taskmap.tasks[i].addr);
75 init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
76 str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
77 bootinfo->taskmap.tasks[i].name);
78 }
79
80 /* Copy physical memory map. */
81 memmap.total = bootinfo->memmap.total;
82 memmap.cnt = min(bootinfo->memmap.cnt, MEMMAP_MAX_RECORDS);
83 for (i = 0; i < memmap.cnt; i++) {
84 memmap.zones[i].start = bootinfo->memmap.zones[i].start;
85 memmap.zones[i].size = bootinfo->memmap.zones[i].size;
86 }
87
88 /* Copy boot allocations info. */
89 ballocs.base = bootinfo->ballocs.base;
90 ballocs.size = bootinfo->ballocs.size;
91
92 /* Copy OFW tree. */
93 ofw_tree_init(bootinfo->ofw_root);
94}
95
96void arch_pre_mm_init(void)
97{
98 /* Initialize dispatch table */
99 interrupt_init();
100
101 /* Start decrementer */
102 start_decrementer();
103}
104
105static bool display_register(ofw_tree_node_t *node, void *arg)
106{
107 uintptr_t fb_addr = 0;
108 uint32_t fb_width = 0;
109 uint32_t fb_height = 0;
110 uint32_t fb_scanline = 0;
111 unsigned int visual = VISUAL_UNKNOWN;
112
113 ofw_tree_property_t *prop = ofw_tree_getprop(node, "address");
114 if ((prop) && (prop->value))
115 fb_addr = *((uintptr_t *) prop->value);
116
117 prop = ofw_tree_getprop(node, "width");
118 if ((prop) && (prop->value))
119 fb_width = *((uint32_t *) prop->value);
120
121 prop = ofw_tree_getprop(node, "height");
122 if ((prop) && (prop->value))
123 fb_height = *((uint32_t *) prop->value);
124
125 prop = ofw_tree_getprop(node, "depth");
126 if ((prop) && (prop->value)) {
127 uint32_t fb_bpp = *((uint32_t *) prop->value);
128 switch (fb_bpp) {
129 case 8:
130 visual = VISUAL_INDIRECT_8;
131 break;
132 case 15:
133 visual = VISUAL_RGB_5_5_5_BE;
134 break;
135 case 16:
136 visual = VISUAL_RGB_5_6_5_BE;
137 break;
138 case 24:
139 visual = VISUAL_BGR_8_8_8;
140 break;
141 case 32:
142 visual = VISUAL_RGB_0_8_8_8;
143 break;
144 default:
145 visual = VISUAL_UNKNOWN;
146 }
147 }
148
149 prop = ofw_tree_getprop(node, "linebytes");
150 if ((prop) && (prop->value))
151 fb_scanline = *((uint32_t *) prop->value);
152
153 if ((fb_addr) && (fb_width > 0) && (fb_height > 0)
154 && (fb_scanline > 0) && (visual != VISUAL_UNKNOWN)) {
155 fb_properties_t fb_prop = {
156 .addr = fb_addr,
157 .offset = 0,
158 .x = fb_width,
159 .y = fb_height,
160 .scan = fb_scanline,
161 .visual = visual,
162 };
163
164 outdev_t *fbdev = fb_init(&fb_prop);
165 if (fbdev)
166 stdout_wire(fbdev);
167 }
168
169 return true;
170}
171
172void arch_post_mm_init(void)
173{
174 if (config.cpu_active == 1) {
175#ifdef CONFIG_FB
176 ofw_tree_walk_by_device_type("display", display_register, NULL);
177#endif
178 /* Map OFW information into sysinfo */
179 ofw_sysinfo_map();
180
181 /* Initialize IRQ routing */
182 irq_init(IRQ_COUNT, IRQ_COUNT);
183
184 /* Merge all zones to 1 big zone */
185 zone_merge_all();
186 }
187}
188
189void arch_post_cpu_init(void)
190{
191}
192
193void arch_pre_smp_init(void)
194{
195}
196
197static bool macio_register(ofw_tree_node_t *node, void *arg)
198{
199 ofw_pci_reg_t *assigned_address = NULL;
200
201 ofw_tree_property_t *prop = ofw_tree_getprop(node, "assigned-addresses");
202 if ((prop) && (prop->value))
203 assigned_address = ((ofw_pci_reg_t *) prop->value);
204
205 if (assigned_address) {
206 /* Initialize PIC */
207 pic_init(assigned_address[0].addr, PAGE_SIZE, &pic_cir,
208 &pic_cir_arg);
209
210#ifdef CONFIG_MAC_KBD
211 uintptr_t pa = assigned_address[0].addr + 0x16000;
212 uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
213 size_t offset = pa - aligned_addr;
214 size_t size = 2 * PAGE_SIZE;
215
216 cuda_t *cuda = (cuda_t *) (km_map(aligned_addr, offset + size,
217 PAGE_WRITE | PAGE_NOT_CACHEABLE) + offset);
218
219 /* Initialize I/O controller */
220 cuda_instance_t *cuda_instance =
221 cuda_init(cuda, IRQ_CUDA, pic_cir, pic_cir_arg);
222 if (cuda_instance) {
223 kbrd_instance_t *kbrd_instance = kbrd_init();
224 if (kbrd_instance) {
225 indev_t *sink = stdin_wire();
226 indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
227 cuda_wire(cuda_instance, kbrd);
228 pic_enable_interrupt(IRQ_CUDA);
229 }
230 }
231
232 /*
233 * This is the necessary evil until the userspace driver is entirely
234 * self-sufficient.
235 */
236 sysinfo_set_item_val("cuda", NULL, true);
237 sysinfo_set_item_val("cuda.inr", NULL, IRQ_CUDA);
238 sysinfo_set_item_val("cuda.address.physical", NULL, pa);
239#endif
240 }
241
242 /* Consider only a single device for now */
243 return false;
244}
245
246void irq_initialize_arch(irq_t *irq)
247{
248 irq->cir = pic_cir;
249 irq->cir_arg = pic_cir_arg;
250 irq->preack = true;
251}
252
253void arch_post_smp_init(void)
254{
255 /* Currently the only supported platform for ppc32 is 'mac'. */
256 static const char *platform = "mac";
257
258 sysinfo_set_item_data("platform", NULL, (void *) platform,
259 str_size(platform));
260
261 ofw_tree_walk_by_device_type("mac-io", macio_register, NULL);
262}
263
264void calibrate_delay_loop(void)
265{
266}
267
268void userspace(uspace_arg_t *kernel_uarg)
269{
270 userspace_asm((uintptr_t) kernel_uarg->uspace_uarg,
271 (uintptr_t) kernel_uarg->uspace_stack +
272 kernel_uarg->uspace_stack_size - SP_DELTA,
273 (uintptr_t) kernel_uarg->uspace_entry);
274
275 /* Unreachable */
276 while (true);
277}
278
279/** Construct function pointer
280 *
281 * @param fptr function pointer structure
282 * @param addr function address
283 * @param caller calling function address
284 *
285 * @return address of the function pointer
286 *
287 */
288void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
289{
290 return addr;
291}
292
293void arch_reboot(void)
294{
295 // TODO
296 while (true);
297}
298
299/** @}
300 */
Note: See TracBrowser for help on using the repository browser.