1/*
2 * Copyright 2003-2010, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com
4 * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk
5 * Distributed under the terms of the MIT License.
6 */
7
8#include "start.h"
9
10#include <string.h>
11#include <OS.h>
12#include <platform/openfirmware/openfirmware.h>
13
14#include "machine.h"
15
16extern "C" void _start(uint32 _unused1, uint32 _unused2,
17	void *openFirmwareEntry);
18
19// XCOFF "entry-point" is actually a pointer to the real code
20extern "C" void *_coff_start;
21void *_coff_start = (void *)&_start;
22
23// GCC defined globals
24extern uint8 __bss_start;
25extern uint8 _end;
26
27
28static void
29clear_bss(void)
30{
31	memset(&__bss_start, 0, &_end - &__bss_start);
32}
33
34
35void
36determine_machine(void)
37{
38	gMachine = MACHINE_UNKNOWN;
39
40	intptr_t root = of_finddevice("/");
41	char buffer[64];
42	int length;
43
44	// TODO : Probe other OpenFirmware platforms and set gMachine as needed
45
46	if ((length = of_getprop(root, "device_type", buffer, sizeof(buffer) - 1))
47		!= OF_FAILED) {
48		buffer[length] = '\0';
49		if (!strcasecmp("chrp", buffer))
50			gMachine = MACHINE_CHRP;
51		else if (!strcasecmp("bootrom", buffer))
52			gMachine = MACHINE_MAC;
53	} else
54		gMachine = MACHINE_MAC;
55
56	if ((length = of_getprop(root, "model", buffer, sizeof(buffer) - 1))
57		!= OF_FAILED) {
58		buffer[length] = '\0';
59		if (!strcasecmp("pegasos", buffer))
60			gMachine |= MACHINE_PEGASOS;
61	}
62
63	if ((length = of_getprop(root, "name", buffer, sizeof(buffer) - 1))
64		!= OF_FAILED) {
65		buffer[length] = '\0';
66		if (!strcasecmp("openbiosteam,openbios", buffer))
67			gMachine |= MACHINE_QEMU;
68	}
69}
70
71
72extern "C" void __attribute__((section(".text.start")))
73_start(uint32 _unused1, uint32 _unused3, void *openFirmwareEntry)
74{
75	// According to the PowerPC bindings, OpenFirmware should have created
76	// a stack of 32kB or higher for us at this point
77
78	clear_bss();
79	call_ctors();
80		// call C++ constructors before doing anything else
81
82	start(openFirmwareEntry);
83}
84