xref: /haiku/src/system/boot/platform/u-boot/start.cpp (revision 7a74a5df454197933bc6e80a542102362ee98703)
1 /*
2  * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "serial.h"
8 #include "console.h"
9 #include "cpu.h"
10 #include "mmu.h"
11 #include "smp.h"
12 #include "uimage.h"
13 #include "keyboard.h"
14 
15 #include <KernelExport.h>
16 #include <boot/platform.h>
17 #include <boot/heap.h>
18 #include <boot/stage2.h>
19 #include <arch/cpu.h>
20 #include <platform_arch.h>
21 
22 #include <string.h>
23 
24 
25 #define HEAP_SIZE (128 * 1024)
26 
27 
28 typedef struct uboot_gd {
29 	// those are the only few members that we can trust
30 	// others depend on compile-time config
31 	struct board_data *bd;
32 	uint32 flags;
33 	uint32 baudrate;
34 	// those are ARM-only
35 	uint32 have_console;
36 	uint32 reloc_off;
37 	uint32 env_addr;
38 	uint32 env_valid;
39 	uint32 fb_base;
40 } uboot_gd;
41 
42 
43 // GCC defined globals
44 extern void (*__ctor_list)(void);
45 extern void (*__ctor_end)(void);
46 extern uint8 __bss_start;
47 extern uint8 _end;
48 
49 extern "C" int main(stage2_args *args);
50 extern "C" void _start(void);
51 extern "C" int start_raw(int argc, const char **argv);
52 extern "C" void dump_uimage(struct image_header *image);
53 
54 // declared in shell.S
55 // those are initialized to NULL but not in the BSS
56 extern struct image_header *gUImage;
57 extern uboot_gd *gUBootGlobalData;
58 extern uint32 gUBootOS;
59 extern void *gFDT;
60 
61 static uint32 sBootOptions;
62 
63 
64 static void
65 clear_bss(void)
66 {
67 	memset(&__bss_start, 0, &_end - &__bss_start);
68 }
69 
70 
71 static void
72 call_ctors(void)
73 {
74 	void (**f)(void);
75 
76 	for (f = &__ctor_list; f < &__ctor_end; f++) {
77 		(**f)();
78 	}
79 }
80 
81 
82 /* needed for libgcc unwind XXX */
83 extern "C" void
84 abort(void)
85 {
86 	panic("abort");
87 }
88 
89 
90 extern "C" void
91 platform_start_kernel(void)
92 {
93 	addr_t kernelEntry = gKernelArgs.kernel_image.elf_header.e_entry;
94 	addr_t stackTop
95 		= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
96 
97 //	smp_init_other_cpus();
98 	serial_cleanup();
99 	mmu_init_for_kernel();
100 //	smp_boot_other_cpus();
101 
102 	dprintf("kernel entry at %lx\n",
103 		gKernelArgs.kernel_image.elf_header.e_entry);
104 
105 	status_t error = arch_start_kernel(&gKernelArgs, kernelEntry,
106 		stackTop);
107 
108 	panic("kernel returned!\n");
109 }
110 
111 
112 extern "C" void
113 platform_exit(void)
114 {
115 }
116 
117 
118 extern "C" int
119 start_netbsd(struct board_info *bd, struct image_header *image,
120 	const char *consdev, const char *cmdline)
121 {
122 	const char *argv[] = { "haiku", cmdline };
123 	int argc = 1;
124 	if (cmdline)
125 		argc++;
126 	gUImage = image;
127 	return start_raw(argc, argv);
128 }
129 
130 
131 extern "C" int
132 start_linux(int argc, int archnum, void *atags)
133 {
134 	return 1;
135 }
136 
137 
138 extern "C" int
139 start_linux_ppc_old(void */*board_info*/,
140 	void */*initrd_start*/, void */*initrd_end*/,
141 	const char */*cmdline_start*/, const char */*cmdline_end*/)
142 {
143 	return 1;
144 }
145 
146 
147 extern "C" int
148 start_linux_ppc_fdt(void *fdt, long/*UNUSED*/, long/*UNUSED*/,
149 	uint32 epapr_magic, uint32 initial_mem_size)
150 {
151 	gFDT = fdt;	//XXX: make a copy?
152 	return start_raw(0, NULL);
153 }
154 
155 
156 extern "C" int
157 start_raw(int argc, const char **argv)
158 {
159 	stage2_args args;
160 
161 	clear_bss();
162 		// call C++ constructors before doing anything else
163 	call_ctors();
164 	args.heap_size = HEAP_SIZE;
165 	args.arguments = NULL;
166 	args.platform.boot_tgz_data = NULL;
167 	args.platform.boot_tgz_size = 0;
168 
169 	serial_init();
170 	console_init();
171 	cpu_init();
172 
173 	// if we get passed a uimage, try to find the second blob
174 	if (gUImage != NULL
175 		&& image_multi_getimg(gUImage, 1,
176 			(uint32*)&args.platform.boot_tgz_data,
177 			&args.platform.boot_tgz_size)) {
178 		dprintf("Found boot tgz @ %p, %" B_PRIu32 " bytes\n",
179 			args.platform.boot_tgz_data, args.platform.boot_tgz_size);
180 	}
181 
182 	{ //DEBUG:
183 		int i;
184 		dprintf("argc = %d\n", argc);
185 		for (i = 0; i < argc; i++)
186 			dprintf("argv[%d] @%lx = '%s'\n", i, (uint32)argv[i], argv[i]);
187 		dprintf("os: %d\n", (int)gUBootOS);
188 		dprintf("gd @ %p\n", gUBootGlobalData);
189 		dprintf("gd->bd @ %p\n", gUBootGlobalData->bd);
190 		//dprintf("fb_base %p\n", (void*)gUBootGlobalData->fb_base);
191 		dprintf("uimage @ %p\n", gUImage);
192 		if (gUImage)
193 			dump_uimage(gUImage);
194 	}
195 
196 	mmu_init();
197 
198 	// wait a bit to give the user the opportunity to press a key
199 //	spin(750000);
200 
201 	// reading the keyboard doesn't seem to work in graphics mode
202 	// (maybe a bochs problem)
203 //	sBootOptions = check_for_boot_keys();
204 	//if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT)
205 		serial_enable();
206 
207 	main(&args);
208 	return 0;
209 }
210 
211 
212 extern "C" uint32
213 platform_boot_options(void)
214 {
215 	return sBootOptions;
216 }
217