Added a test for MUIA_Listview_SelectChange.
[AROS.git] / arch / ppc-chrp / pegasos / kernel / kernel_startup.c
blob2def5dc2b0f750fcefdbbd41302891be2f031930
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/kernel.h>
7 #include <aros/macros.h>
8 #include <aros/multiboot.h>
9 #include <asm/ppc/ppc740.h>
10 #include <hardware/openfirmware.h>
11 #include <proto/arossupport.h>
13 #include <bootconsole.h>
14 #include <inttypes.h>
15 #include <string.h>
17 #include "kernel_base.h"
18 #include "kernel_bootmem.h"
19 #include "kernel_debug.h"
20 #include "kernel_intern.h"
22 #define D(x) x
24 static char boot_stack[];
25 static void kernel_start(const struct TagItem *bootMsg);
27 int __startup kernel_entry(struct TagItem *bootMsg, ULONG magic)
29 if (magic == AROS_BOOT_MAGIC)
31 core_kick(bootMsg, kernel_start);
33 return -1;
36 void core_kick(struct TagItem *bootMsg, void *target)
38 const struct TagItem *bss = LibFindTagItem(KRN_KernelBss, bootMsg);
40 /* First clear .bss */
41 if (bss)
42 __clear_bss((const struct KernelBSS *)bss->ti_Data);
44 asm volatile("mr %%r1, %1; bctr"::"c"(target),"r"(boot_stack + STACK_SIZE - SP_OFFSET));
47 /* Own memory copy routine because memcpy() can rely on CopyMem() which is not available yet */
48 static inline void __boot_memcpy(unsigned char *dest, unsigned char *src, unsigned int size)
50 unsigned int i;
52 for (i = 0; i < size; i++)
53 *dest++ = *src++;
56 static void RelocateTagData(struct TagItem *tag, unsigned long size)
58 unsigned char *src = (unsigned char *)tag->ti_Data;
59 unsigned char *dest = krnAllocBootMem(size);
61 tag->ti_Data = (IPTR)dest;
62 __boot_memcpy(dest, src, size);
65 static struct OFWNode *krnCopyOFWTree(struct OFWNode *orig)
67 uint32_t node_length = sizeof(struct OFWNode) + strlen(orig->on_name) + 1;
68 struct OFWNode *new_node = krnAllocBootMem(node_length);
69 struct OFWNode *child;
70 struct OFWProperty *prop, *new_prop;
72 new_node->on_name = new_node->on_storage;
74 __boot_memcpy(new_node->on_name, orig->on_name, strlen(orig->on_name) + 1);
75 NEWLIST(&new_node->on_children);
76 NEWLIST(&new_node->on_properties);
78 ForeachNode(&orig->on_properties, prop)
80 uint32_t prop_name_length = strlen(prop->op_name) + 1;
81 uint32_t prop_length = sizeof(struct OFWProperty) + prop_name_length + prop->op_length;
83 new_prop = krnAllocBootMem(prop_length);
85 new_prop->op_name = new_prop->op_storage;
86 new_prop->op_value = &new_prop->op_storage[prop_name_length];
87 new_prop->op_length = prop->op_length;
89 __boot_memcpy(new_prop->op_name, prop->op_name, strlen(prop->op_name)+1);
90 __boot_memcpy(new_prop->op_value, prop->op_value, prop->op_length);
92 ADDTAIL(&new_node->on_properties, new_prop);
95 ForeachNode(&orig->on_children, child)
96 ADDTAIL(&new_node->on_children, krnCopyOFWTree(child));
98 return new_node;
101 static void kernel_start(const struct TagItem *bootMsg)
103 struct TagItem *tag;
104 char *serial_options = NULL;
106 /* Enable FPU */
107 wrmsr(rdmsr() | MSR_FP);
109 tag = LibFindTagItem(KRN_CmdLine, bootMsg);
110 if (tag)
112 char *opts = strcasestr((char *)tag->ti_Data, "debug=serial");
114 if (opts)
115 serial_options = opts + 12;
119 * Pegasos defaults.
120 * Machine's only serial port is configured as Serial2 (0x2F8, IRQ 3).
121 * ISA I/O space is mapped at 0xFE000000.
123 IO_Base = (void *)0xFE000000;
124 Serial_Base = 0x02F8;
125 serial_Init(serial_options);
127 D(bug("AROS64 - The AROS Research OS, PegasosPPC version. Compiled %s\n", __DATE__));
128 D(bug("[Kernel] kernel.resource entry: 0x%p\n", kernel_entry));
129 D(bug("[Kernel] Boot stack: 0x%p - 0x%p\n", boot_stack, boot_stack + STACK_SIZE));
130 D(bug("[Kernel] Boot data: 0x%p\n", __BootData));
132 if (!__BootData)
135 * This is our first start.
136 * Set up BootData and relocate boot taglist to safe place.
138 struct TagItem *dest;
139 unsigned long mlen;
140 IPTR ptr;
141 struct vbe_mode *vmode = NULL;
142 char *cmdline = NULL;
144 tag = LibFindTagItem(KRN_KernelHighest, bootMsg);
145 if (!tag)
147 D(bug("Incomplete information from the bootstrap\n"));
148 D(bug("Highest kickstart address is not supplied\n"));
150 for(;;) HALT;
153 /* Align kickstart top address (we are going to place a structure after it) */
154 ptr = AROS_ROUNDUP2(tag->ti_Data + 1, sizeof(APTR));
156 memset((void *)ptr, 0, sizeof(struct BootData));
157 __BootData = (struct BootData *)ptr;
159 D(bug("[Kernel] KRN_Highest 0x%p, BootData 0x%p\n", tag->ti_Data, ptr));
162 * Our boot taglist is placed by the bootstrap just somewhere in memory.
163 * The first thing is to move it into some safe place.
165 ptr = AROS_ROUNDUP2(ptr + sizeof(struct BootData), sizeof(APTR));
166 BootMsg = (struct TagItem *)ptr;
168 dest = BootMsg;
169 while ((tag = LibNextTagItem(&bootMsg)))
171 dest->ti_Tag = tag->ti_Tag;
172 dest->ti_Data = tag->ti_Data;
173 dest++;
175 dest->ti_Tag = TAG_DONE;
176 dest++;
178 __BootData->bd_BootMem = dest;
180 /* Now relocate linked data */
181 mlen = LibGetTagData(KRN_MMAPLength, 0, BootMsg);
182 bootMsg = BootMsg;
183 while ((tag = LibNextTagItem(&bootMsg)))
185 unsigned long l;
186 struct KernelBSS *bss;
188 switch (tag->ti_Tag)
190 case KRN_KernelBss:
191 l = sizeof(struct KernelBSS);
192 for (bss = (struct KernelBSS *)tag->ti_Data; bss->addr; bss++)
193 l += sizeof(struct KernelBSS);
195 RelocateTagData(tag, l);
196 break;
198 case KRN_OpenFirmwareTree:
199 tag->ti_Data = (IPTR)krnCopyOFWTree((struct OFWNode *)tag->ti_Data);
200 break;
202 case KRN_VBEModeInfo:
203 RelocateTagData(tag, sizeof(struct vbe_mode));
204 vmode = (struct vbe_mode *)tag->ti_Data;
205 break;
207 case KRN_VBEControllerInfo:
208 RelocateTagData(tag, sizeof(struct vbe_controller));
209 break;
211 case KRN_CmdLine:
212 l = strlen((char *)tag->ti_Data) + 1;
213 RelocateTagData(tag, l);
214 cmdline = (char *)tag->ti_Data;
215 break;
217 case KRN_BootLoader:
218 l = strlen((char *)tag->ti_Data) + 1;
219 RelocateTagData(tag, l);
220 break;
225 for (;;);
228 /* Our boot-time stack */
229 static char boot_stack[STACK_SIZE] __attribute__((aligned(16)));
231 __attribute__((section(".data"))) struct BootData *__BootData = NULL;