2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
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>
17 #include "kernel_base.h"
18 #include "kernel_bootmem.h"
19 #include "kernel_debug.h"
20 #include "kernel_intern.h"
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
);
36 void core_kick(struct TagItem
*bootMsg
, void *target
)
38 const struct TagItem
*bss
= LibFindTagItem(KRN_KernelBss
, bootMsg
);
40 /* First clear .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
)
52 for (i
= 0; i
< size
; i
++)
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
));
101 static void kernel_start(const struct TagItem
*bootMsg
)
104 char *serial_options
= NULL
;
107 wrmsr(rdmsr() | MSR_FP
);
109 tag
= LibFindTagItem(KRN_CmdLine
, bootMsg
);
112 char *opts
= strcasestr((char *)tag
->ti_Data
, "debug=serial");
115 serial_options
= opts
+ 12;
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
));
135 * This is our first start.
136 * Set up BootData and relocate boot taglist to safe place.
138 struct TagItem
*dest
;
141 struct vbe_mode
*vmode
= NULL
;
142 char *cmdline
= NULL
;
144 tag
= LibFindTagItem(KRN_KernelHighest
, bootMsg
);
147 D(bug("Incomplete information from the bootstrap\n"));
148 D(bug("Highest kickstart address is not supplied\n"));
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
;
169 while ((tag
= LibNextTagItem(&bootMsg
)))
171 dest
->ti_Tag
= tag
->ti_Tag
;
172 dest
->ti_Data
= tag
->ti_Data
;
175 dest
->ti_Tag
= TAG_DONE
;
178 __BootData
->bd_BootMem
= dest
;
180 /* Now relocate linked data */
181 mlen
= LibGetTagData(KRN_MMAPLength
, 0, BootMsg
);
183 while ((tag
= LibNextTagItem(&bootMsg
)))
186 struct KernelBSS
*bss
;
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
);
198 case KRN_OpenFirmwareTree
:
199 tag
->ti_Data
= (IPTR
)krnCopyOFWTree((struct OFWNode
*)tag
->ti_Data
);
202 case KRN_VBEModeInfo
:
203 RelocateTagData(tag
, sizeof(struct vbe_mode
));
204 vmode
= (struct vbe_mode
*)tag
->ti_Data
;
207 case KRN_VBEControllerInfo
:
208 RelocateTagData(tag
, sizeof(struct vbe_controller
));
212 l
= strlen((char *)tag
->ti_Data
) + 1;
213 RelocateTagData(tag
, l
);
214 cmdline
= (char *)tag
->ti_Data
;
218 l
= strlen((char *)tag
->ti_Data
) + 1;
219 RelocateTagData(tag
, l
);
228 /* Our boot-time stack */
229 static char boot_stack
[STACK_SIZE
] __attribute__((aligned(16)));
231 __attribute__((section(".data"))) struct BootData
*__BootData
= NULL
;