source: mainline/kernel/arch/ppc32/src/ppc32.c@ 63660a3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 63660a3 was 5a5269d, checked in by GitHub <noreply@…>, 6 years ago

Change type of uspace pointers in kernel from pointer type to numeric (#170)

From kernel's perspective, userspace addresses are not valid pointers,
and can only be used in calls to copy_to/from_uspace().
Therefore, we change the type of those arguments and variables to
uspace_addr_t which is an alias for sysarg_t.

This allows the compiler to catch accidental direct accesses to
userspace addresses.

Additionally, to avoid losing the type information in code,
a macro uspace_ptr(type) is used that translates to uspace_addr_t.
I makes no functional difference, but allows keeping the type information
in code in case we implement some sort of static checking for it in the future.

However, ccheck doesn't like that, so instead of using uspace_ptr(char),
we use uspace_ptr_char which is defined as
#define uspace_ptr_char uspace_ptr(char).

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