18abaaaf7SAxel Dörfler/*
27a3fa7d3SAxel Dörfler * Copyright 2003, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3d5cd4a9dSPulkoMandy * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk
47a3fa7d3SAxel Dörfler * Distributed under the terms of the MIT License.
57a3fa7d3SAxel Dörfler */
68abaaaf7SAxel Dörfler
7957a1b17SIngo Weinhold#include <platform/openfirmware/openfirmware.h>
88abaaaf7SAxel Dörfler
98abaaaf7SAxel Dörfler#include <stdarg.h>
108abaaaf7SAxel Dörfler
118abaaaf7SAxel Dörfler
128abaaaf7SAxel Dörfler// OpenFirmware entry function
13d5cd4a9dSPulkoMandystatic intptr_t (*gCallOpenFirmware)(void *) = 0;
14d5cd4a9dSPulkoMandyintptr_t gChosen;
158abaaaf7SAxel Dörfler
168abaaaf7SAxel Dörfler
1767e8a139SAxel Dörflerstatus_t
18d5cd4a9dSPulkoMandyof_init(intptr_t (*openFirmwareEntry)(void *))
198abaaaf7SAxel Dörfler{
208abaaaf7SAxel Dörfler	gCallOpenFirmware = openFirmwareEntry;
2167e8a139SAxel Dörfler
2267e8a139SAxel Dörfler	gChosen = of_finddevice("/chosen");
2367e8a139SAxel Dörfler	if (gChosen == OF_FAILED)
2467e8a139SAxel Dörfler		return B_ERROR;
2567e8a139SAxel Dörfler
2667e8a139SAxel Dörfler	return B_OK;
278abaaaf7SAxel Dörfler}
288abaaaf7SAxel Dörfler
298abaaaf7SAxel Dörfler
31d5cd4a9dSPulkoMandyof_call_client_function(const char *method, intptr_t numArgs,
32d5cd4a9dSPulkoMandy	intptr_t numReturns, ...)
338abaaaf7SAxel Dörfler{
348abaaaf7SAxel Dörfler	struct {
358abaaaf7SAxel Dörfler		const char	*name;
36d5cd4a9dSPulkoMandy		intptr_t	num_args;
37d5cd4a9dSPulkoMandy		intptr_t	num_returns;
388abaaaf7SAxel Dörfler		void		*args[10];
398abaaaf7SAxel Dörfler	} args = {method, numArgs, numReturns};
408abaaaf7SAxel Dörfler	va_list list;
418abaaaf7SAxel Dörfler	int i;
428abaaaf7SAxel Dörfler
438abaaaf7SAxel Dörfler	// iterate over all arguments and copy them into the
448abaaaf7SAxel Dörfler	// structure passed over to the OpenFirmware
458abaaaf7SAxel Dörfler
468abaaaf7SAxel Dörfler	va_start(list, numReturns);
478abaaaf7SAxel Dörfler	for (i = 0; i < numArgs; i++) {
488abaaaf7SAxel Dörfler		// copy args
498abaaaf7SAxel Dörfler		args.args[i] = (void *)va_arg(list, void *);
508abaaaf7SAxel Dörfler	}
518abaaaf7SAxel Dörfler	for (i = numArgs; i < numArgs + numReturns; i++) {
528abaaaf7SAxel Dörfler		// clear return values
538abaaaf7SAxel Dörfler		args.args[i] = NULL;
548abaaaf7SAxel Dörfler	}
55bd185b41SIngo Weinhold
568abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
578abaaaf7SAxel Dörfler		return OF_FAILED;
588abaaaf7SAxel Dörfler
598abaaaf7SAxel Dörfler	if (numReturns > 0) {
608abaaaf7SAxel Dörfler		// copy return values over to the provided location
61bd185b41SIngo Weinhold
628abaaaf7SAxel Dörfler		for (i = numArgs; i < numArgs + numReturns; i++) {
638abaaaf7SAxel Dörfler			void **store = va_arg(list, void **);
648abaaaf7SAxel Dörfler			if (store)
658abaaaf7SAxel Dörfler				*store = args.args[i];
668abaaaf7SAxel Dörfler		}
678abaaaf7SAxel Dörfler	}
688abaaaf7SAxel Dörfler	va_end(list);
698abaaaf7SAxel Dörfler
708abaaaf7SAxel Dörfler	return 0;
718abaaaf7SAxel Dörfler}
728abaaaf7SAxel Dörfler
738abaaaf7SAxel Dörfler
75d5cd4a9dSPulkoMandyof_interpret(const char *command, intptr_t numArgs, intptr_t numReturns, ...)
76b821ceccSIngo Weinhold{
77b821ceccSIngo Weinhold	struct {
78b821ceccSIngo Weinhold		const char	*name;
79d5cd4a9dSPulkoMandy		intptr_t	num_args;
80d5cd4a9dSPulkoMandy		intptr_t	num_returns;
81b821ceccSIngo Weinhold			// "IN:	[string] cmd, stack_arg1, ..., stack_argP
82b821ceccSIngo Weinhold			// OUT:	catch-result, stack_result1, ..., stack_resultQ
83b821ceccSIngo Weinhold			// [...]
84b821ceccSIngo Weinhold			// An implementation shall allow at least six stack_arg and six
85b821ceccSIngo Weinhold			// stack_result items."
86b821ceccSIngo Weinhold		const char	*command;
87b821ceccSIngo Weinhold		void		*args[13];
8822a65222SIngo Weinhold	} args = {"interpret", numArgs + 1, numReturns + 1, command};
8922a65222SIngo Weinhold	va_list list;
9022a65222SIngo Weinhold	int i;
9122a65222SIngo Weinhold
9222a65222SIngo Weinhold	// iterate over all arguments and copy them into the
9322a65222SIngo Weinhold	// structure passed over to the OpenFirmware
9422a65222SIngo Weinhold
9522a65222SIngo Weinhold	va_start(list, numReturns);
9622a65222SIngo Weinhold	for (i = 0; i < numArgs; i++) {
9722a65222SIngo Weinhold		// copy args
9822a65222SIngo Weinhold		args.args[i] = (void *)va_arg(list, void *);
9922a65222SIngo Weinhold	}
10022a65222SIngo Weinhold	for (i = numArgs; i < numArgs + numReturns + 1; i++) {
10122a65222SIngo Weinhold		// clear return values
10222a65222SIngo Weinhold		args.args[i] = NULL;
10322a65222SIngo Weinhold	}
10422a65222SIngo Weinhold
10522a65222SIngo Weinhold	// args.args[numArgs] is the "catch-result" return value
10622a65222SIngo Weinhold	if (gCallOpenFirmware(&args) == OF_FAILED || args.args[numArgs])
10722a65222SIngo Weinhold		return OF_FAILED;
10822a65222SIngo Weinhold
10922a65222SIngo Weinhold	if (numReturns > 0) {
11022a65222SIngo Weinhold		// copy return values over to the provided location
111bd185b41SIngo Weinhold
11222a65222SIngo Weinhold		for (i = numArgs + 1; i < numArgs + 1 + numReturns; i++) {
11322a65222SIngo Weinhold			void **store = va_arg(list, void **);
11422a65222SIngo Weinhold			if (store)
11522a65222SIngo Weinhold				*store = args.args[i];
11622a65222SIngo Weinhold		}
11722a65222SIngo Weinhold	}
11822a65222SIngo Weinhold	va_end(list);
11922a65222SIngo Weinhold
12022a65222SIngo Weinhold	return 0;
12122a65222SIngo Weinhold}
12222a65222SIngo Weinhold
12322a65222SIngo Weinhold
125d5cd4a9dSPulkoMandyof_call_method(intptr_t handle, const char *method, intptr_t numArgs,
126d5cd4a9dSPulkoMandy	intptr_t numReturns, ...)
12722a65222SIngo Weinhold{
12822a65222SIngo Weinhold	struct {
12922a65222SIngo Weinhold		const char	*name;
130d5cd4a9dSPulkoMandy		intptr_t	num_args;
131d5cd4a9dSPulkoMandy		intptr_t	num_returns;
13222a65222SIngo Weinhold			// "IN:	[string] method, ihandle, stack_arg1, ..., stack_argP
13322a65222SIngo Weinhold			// OUT:	catch-result, stack_result1, ..., stack_resultQ
13422a65222SIngo Weinhold			// [...]
13522a65222SIngo Weinhold			// An implementation shall allow at least six stack_arg and six
13622a65222SIngo Weinhold			// stack_result items."
13722a65222SIngo Weinhold		const char	*method;
138d5cd4a9dSPulkoMandy		intptr_t	handle;
13922a65222SIngo Weinhold		void		*args[13];
14022a65222SIngo Weinhold	} args = {"call-method", numArgs + 2, numReturns + 1, method, handle};
141b821ceccSIngo Weinhold	va_list list;
142b821ceccSIngo Weinhold	int i;
143b821ceccSIngo Weinhold
144b821ceccSIngo Weinhold	// iterate over all arguments and copy them into the
145b821ceccSIngo Weinhold	// structure passed over to the OpenFirmware
146b821ceccSIngo Weinhold
147b821ceccSIngo Weinhold	va_start(list, numReturns);
148b821ceccSIngo Weinhold	for (i = 0; i < numArgs; i++) {
149b821ceccSIngo Weinhold		// copy args
150b821ceccSIngo Weinhold		args.args[i] = (void *)va_arg(list, void *);
151b821ceccSIngo Weinhold	}
152b821ceccSIngo Weinhold	for (i = numArgs; i < numArgs + numReturns + 1; i++) {
153b821ceccSIngo Weinhold		// clear return values
154b821ceccSIngo Weinhold		args.args[i] = NULL;
155b821ceccSIngo Weinhold	}
156b821ceccSIngo Weinhold
157b821ceccSIngo Weinhold	// args.args[numArgs] is the "catch-result" return value
158b821ceccSIngo Weinhold	if (gCallOpenFirmware(&args) == OF_FAILED || args.args[numArgs])
159b821ceccSIngo Weinhold		return OF_FAILED;
160b821ceccSIngo Weinhold
161b821ceccSIngo Weinhold	if (numReturns > 0) {
162b821ceccSIngo Weinhold		// copy return values over to the provided location
163bd185b41SIngo Weinhold
164b821ceccSIngo Weinhold		for (i = numArgs + 1; i < numArgs + 1 + numReturns; i++) {
165b821ceccSIngo Weinhold			void **store = va_arg(list, void **);
166b821ceccSIngo Weinhold			if (store)
167b821ceccSIngo Weinhold				*store = args.args[i];
168b821ceccSIngo Weinhold		}
169b821ceccSIngo Weinhold	}
170b821ceccSIngo Weinhold	va_end(list);
171b821ceccSIngo Weinhold
172b821ceccSIngo Weinhold	return 0;
173b821ceccSIngo Weinhold}
174b821ceccSIngo Weinhold
175b821ceccSIngo Weinhold
1778abaaaf7SAxel Dörflerof_finddevice(const char *device)
1788abaaaf7SAxel Dörfler{
1798abaaaf7SAxel Dörfler	struct {
1808abaaaf7SAxel Dörfler		const char	*name;
181d5cd4a9dSPulkoMandy		intptr_t	num_args;
182d5cd4a9dSPulkoMandy		intptr_t	num_returns;
1838abaaaf7SAxel Dörfler		const char	*device;
184d5cd4a9dSPulkoMandy		intptr_t	handle;
1858abaaaf7SAxel Dörfler	} args = {"finddevice", 1, 1, device, 0};
1868abaaaf7SAxel Dörfler
1878abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
1888abaaaf7SAxel Dörfler		return OF_FAILED;
1898abaaaf7SAxel Dörfler
1908abaaaf7SAxel Dörfler	return args.handle;
1918abaaaf7SAxel Dörfler}
1928abaaaf7SAxel Dörfler
1938abaaaf7SAxel Dörfler
1948abaaaf7SAxel Dörfler/** Returns the first child of the given node
1958abaaaf7SAxel Dörfler */
1968abaaaf7SAxel Dörfler
198d5cd4a9dSPulkoMandyof_child(intptr_t node)
1998abaaaf7SAxel Dörfler{
2008abaaaf7SAxel Dörfler	struct {
2018abaaaf7SAxel Dörfler		const char	*name;
202d5cd4a9dSPulkoMandy		intptr_t	num_args;
203d5cd4a9dSPulkoMandy		intptr_t	num_returns;
204d5cd4a9dSPulkoMandy		intptr_t	node;
205d5cd4a9dSPulkoMandy		intptr_t	child;
2068abaaaf7SAxel Dörfler	} args = {"child", 1, 1, node, 0};
2078abaaaf7SAxel Dörfler
2088abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
2098abaaaf7SAxel Dörfler		return OF_FAILED;
2108abaaaf7SAxel Dörfler
2118abaaaf7SAxel Dörfler	return args.child;
2128abaaaf7SAxel Dörfler}
2138abaaaf7SAxel Dörfler
2148abaaaf7SAxel Dörfler
2158abaaaf7SAxel Dörfler/** Returns the next sibling of the given node
2168abaaaf7SAxel Dörfler */
2178abaaaf7SAxel Dörfler
219d5cd4a9dSPulkoMandyof_peer(intptr_t node)
2208abaaaf7SAxel Dörfler{
2218abaaaf7SAxel Dörfler	struct {
2228abaaaf7SAxel Dörfler		const char	*name;
223d5cd4a9dSPulkoMandy		intptr_t	num_args;
224d5cd4a9dSPulkoMandy		intptr_t	num_returns;
225d5cd4a9dSPulkoMandy		intptr_t	node;
226d5cd4a9dSPulkoMandy		intptr_t	next_sibling;
2278abaaaf7SAxel Dörfler	} args = {"peer", 1, 1, node, 0};
2288abaaaf7SAxel Dörfler
2298abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
2308abaaaf7SAxel Dörfler		return OF_FAILED;
2318abaaaf7SAxel Dörfler
2328abaaaf7SAxel Dörfler	return args.next_sibling;
2338abaaaf7SAxel Dörfler}
2348abaaaf7SAxel Dörfler
2358abaaaf7SAxel Dörfler
2368abaaaf7SAxel Dörfler/** Returns the parent of the given node
2378abaaaf7SAxel Dörfler */
2388abaaaf7SAxel Dörfler
240d5cd4a9dSPulkoMandyof_parent(intptr_t node)
2418abaaaf7SAxel Dörfler{
2428abaaaf7SAxel Dörfler	struct {
2438abaaaf7SAxel Dörfler		const char	*name;
244d5cd4a9dSPulkoMandy		intptr_t	num_args;
245d5cd4a9dSPulkoMandy		intptr_t	num_returns;
246d5cd4a9dSPulkoMandy		intptr_t	node;
247d5cd4a9dSPulkoMandy		intptr_t	parent;
2488abaaaf7SAxel Dörfler	} args = {"parent", 1, 1, node, 0};
2498abaaaf7SAxel Dörfler
2508abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
2518abaaaf7SAxel Dörfler		return OF_FAILED;
2528abaaaf7SAxel Dörfler
2538abaaaf7SAxel Dörfler	return args.parent;
2548abaaaf7SAxel Dörfler}
2558abaaaf7SAxel Dörfler
2568abaaaf7SAxel Dörfler
258d5cd4a9dSPulkoMandyof_instance_to_path(uint32_t instance, char *pathBuffer, intptr_t bufferSize)
2598abaaaf7SAxel Dörfler{
2608abaaaf7SAxel Dörfler	struct {
2618abaaaf7SAxel Dörfler		const char	*name;
262d5cd4a9dSPulkoMandy		intptr_t	num_args;
263d5cd4a9dSPulkoMandy		intptr_t	num_returns;
264d5cd4a9dSPulkoMandy		intptr_t	instance;
2658abaaaf7SAxel Dörfler		char		*path_buffer;
266d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
267d5cd4a9dSPulkoMandy		intptr_t	size;
2688abaaaf7SAxel Dörfler	} args = {"instance-to-path", 3, 1, instance, pathBuffer, bufferSize, 0};
2698abaaaf7SAxel Dörfler
2708abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
2718abaaaf7SAxel Dörfler		return OF_FAILED;
2728abaaaf7SAxel Dörfler
2738abaaaf7SAxel Dörfler	return args.size;
2748abaaaf7SAxel Dörfler}
2758abaaaf7SAxel Dörfler
2768abaaaf7SAxel Dörfler
278d5cd4a9dSPulkoMandyof_instance_to_package(uint32_t instance)
2798abaaaf7SAxel Dörfler{
2808abaaaf7SAxel Dörfler	struct {
2818abaaaf7SAxel Dörfler		const char	*name;
282d5cd4a9dSPulkoMandy		intptr_t	num_args;
283d5cd4a9dSPulkoMandy		intptr_t	num_returns;
284d5cd4a9dSPulkoMandy		intptr_t	instance;
285d5cd4a9dSPulkoMandy		intptr_t	package;
2868abaaaf7SAxel Dörfler	} args = {"instance-to-package", 1, 1, instance, 0};
2878abaaaf7SAxel Dörfler
2888abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
2898abaaaf7SAxel Dörfler		return OF_FAILED;
2908abaaaf7SAxel Dörfler
2918abaaaf7SAxel Dörfler	return args.package;
2928abaaaf7SAxel Dörfler}
2938abaaaf7SAxel Dörfler
2948abaaaf7SAxel Dörfler
296d5cd4a9dSPulkoMandyof_getprop(intptr_t package, const char *property, void *buffer, intptr_t bufferSize)
2978abaaaf7SAxel Dörfler{
2988abaaaf7SAxel Dörfler	struct {
2998abaaaf7SAxel Dörfler		const char	*name;
300d5cd4a9dSPulkoMandy		intptr_t	num_args;
301d5cd4a9dSPulkoMandy		intptr_t	num_returns;
302d5cd4a9dSPulkoMandy		intptr_t	package;
3038abaaaf7SAxel Dörfler		const char	*property;
3048abaaaf7SAxel Dörfler		void		*buffer;
305d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
306d5cd4a9dSPulkoMandy		intptr_t	size;
3078abaaaf7SAxel Dörfler	} args = {"getprop", 4, 1, package, property, buffer, bufferSize, 0};
3088abaaaf7SAxel Dörfler
3098abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
3108abaaaf7SAxel Dörfler		return OF_FAILED;
3118abaaaf7SAxel Dörfler
3128abaaaf7SAxel Dörfler	return args.size;
3138abaaaf7SAxel Dörfler}
3148abaaaf7SAxel Dörfler
3158abaaaf7SAxel Dörfler
317d5cd4a9dSPulkoMandyof_setprop(intptr_t package, const char *property, const void *buffer,
318d5cd4a9dSPulkoMandy	intptr_t bufferSize)
3198abaaaf7SAxel Dörfler{
3208abaaaf7SAxel Dörfler	struct {
3218abaaaf7SAxel Dörfler		const char	*name;
322d5cd4a9dSPulkoMandy		intptr_t	num_args;
323d5cd4a9dSPulkoMandy		intptr_t	num_returns;
324d5cd4a9dSPulkoMandy		intptr_t	package;
3258abaaaf7SAxel Dörfler		const char	*property;
3268abaaaf7SAxel Dörfler		const void	*buffer;
327d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
328d5cd4a9dSPulkoMandy		intptr_t	size;
3298abaaaf7SAxel Dörfler	} args = {"setprop", 4, 1, package, property, buffer, bufferSize, 0};
3308abaaaf7SAxel Dörfler
3318abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
3328abaaaf7SAxel Dörfler		return OF_FAILED;
3338abaaaf7SAxel Dörfler
3348abaaaf7SAxel Dörfler	return args.size;
3358abaaaf7SAxel Dörfler}
3368abaaaf7SAxel Dörfler
3378abaaaf7SAxel Dörfler
339d5cd4a9dSPulkoMandyof_getproplen(intptr_t package, const char *property)
3408abaaaf7SAxel Dörfler{
3418abaaaf7SAxel Dörfler	struct {
3428abaaaf7SAxel Dörfler		const char	*name;
343d5cd4a9dSPulkoMandy		intptr_t	num_args;
344d5cd4a9dSPulkoMandy		intptr_t	num_returns;
345d5cd4a9dSPulkoMandy		intptr_t	package;
3468abaaaf7SAxel Dörfler		const char	*property;
347d5cd4a9dSPulkoMandy		intptr_t	size;
3488abaaaf7SAxel Dörfler	} args = {"getproplen", 2, 1, package, property, 0};
3498abaaaf7SAxel Dörfler
3508abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
3518abaaaf7SAxel Dörfler		return OF_FAILED;
3528abaaaf7SAxel Dörfler
3538abaaaf7SAxel Dörfler	return args.size;
3548abaaaf7SAxel Dörfler}
3558abaaaf7SAxel Dörfler
3568abaaaf7SAxel Dörfler
358d5cd4a9dSPulkoMandyof_nextprop(intptr_t package, const char *previousProperty, char *nextProperty)
3598abaaaf7SAxel Dörfler{
3608abaaaf7SAxel Dörfler	struct {
3618abaaaf7SAxel Dörfler		const char	*name;
362d5cd4a9dSPulkoMandy		intptr_t	num_args;
363d5cd4a9dSPulkoMandy		intptr_t	num_returns;
364d5cd4a9dSPulkoMandy		intptr_t	package;
3658abaaaf7SAxel Dörfler		const char	*previous_property;
3668abaaaf7SAxel Dörfler		char		*next_property;
367d5cd4a9dSPulkoMandy		intptr_t	flag;
3688abaaaf7SAxel Dörfler	} args = {"nextprop", 3, 1, package, previousProperty, nextProperty, 0};
3698abaaaf7SAxel Dörfler
3708abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
3718abaaaf7SAxel Dörfler		return OF_FAILED;
3728abaaaf7SAxel Dörfler
3738abaaaf7SAxel Dörfler	return args.flag;
3748abaaaf7SAxel Dörfler}
3758abaaaf7SAxel Dörfler
3768abaaaf7SAxel Dörfler
378d5cd4a9dSPulkoMandyof_package_to_path(intptr_t package, char *pathBuffer, intptr_t bufferSize)
3798abaaaf7SAxel Dörfler{
3808abaaaf7SAxel Dörfler	struct {
3818abaaaf7SAxel Dörfler		const char	*name;
382d5cd4a9dSPulkoMandy		intptr_t	num_args;
383d5cd4a9dSPulkoMandy		intptr_t	num_returns;
384d5cd4a9dSPulkoMandy		intptr_t	package;
3858abaaaf7SAxel Dörfler		char		*path_buffer;
386d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
387d5cd4a9dSPulkoMandy		intptr_t	size;
3888abaaaf7SAxel Dörfler	} args = {"package-to-path", 3, 1, package, pathBuffer, bufferSize, 0};
3898abaaaf7SAxel Dörfler
3908abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
3918abaaaf7SAxel Dörfler		return OF_FAILED;
3928abaaaf7SAxel Dörfler
3938abaaaf7SAxel Dörfler	return args.size;
3948abaaaf7SAxel Dörfler}
3958abaaaf7SAxel Dörfler
3968abaaaf7SAxel Dörfler
3978abaaaf7SAxel Dörfler//	I/O functions
3988abaaaf7SAxel Dörfler
3998abaaaf7SAxel Dörfler
4018abaaaf7SAxel Dörflerof_open(const char *nodeName)
4028abaaaf7SAxel Dörfler{
4038abaaaf7SAxel Dörfler	struct {
4048abaaaf7SAxel Dörfler		const char	*name;
405d5cd4a9dSPulkoMandy		intptr_t	num_args;
406d5cd4a9dSPulkoMandy		intptr_t	num_returns;
4078abaaaf7SAxel Dörfler		const char	*node_name;
408d5cd4a9dSPulkoMandy		intptr_t	handle;
4098abaaaf7SAxel Dörfler	} args = {"open", 1, 1, nodeName, 0};
4108abaaaf7SAxel Dörfler
4118abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED || args.handle == 0)
4128abaaaf7SAxel Dörfler		return OF_FAILED;
4138abaaaf7SAxel Dörfler
4148abaaaf7SAxel Dörfler	return args.handle;
4158abaaaf7SAxel Dörfler}
4168abaaaf7SAxel Dörfler
4178abaaaf7SAxel Dörfler
4188abaaaf7SAxel Dörflervoid
419d5cd4a9dSPulkoMandyof_close(intptr_t handle)
4208abaaaf7SAxel Dörfler{
4218abaaaf7SAxel Dörfler	struct {
4228abaaaf7SAxel Dörfler		const char	*name;
423d5cd4a9dSPulkoMandy		intptr_t	num_args;
424d5cd4a9dSPulkoMandy		intptr_t	num_returns;
425d5cd4a9dSPulkoMandy		intptr_t	handle;
4268abaaaf7SAxel Dörfler	} args = {"close", 1, 0, handle};
4278abaaaf7SAxel Dörfler
4288abaaaf7SAxel Dörfler	gCallOpenFirmware(&args);
4298abaaaf7SAxel Dörfler}
4308abaaaf7SAxel Dörfler
4318abaaaf7SAxel Dörfler
433d5cd4a9dSPulkoMandyof_read(intptr_t handle, void *buffer, intptr_t bufferSize)
4348abaaaf7SAxel Dörfler{
4358abaaaf7SAxel Dörfler	struct {
4368abaaaf7SAxel Dörfler		const char	*name;
437d5cd4a9dSPulkoMandy		intptr_t	num_args;
438d5cd4a9dSPulkoMandy		intptr_t	num_returns;
439d5cd4a9dSPulkoMandy		intptr_t	handle;
4408abaaaf7SAxel Dörfler		void		*buffer;
441d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
442d5cd4a9dSPulkoMandy		intptr_t	size;
4438abaaaf7SAxel Dörfler	} args = {"read", 3, 1, handle, buffer, bufferSize, 0};
4448abaaaf7SAxel Dörfler
4458abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
4468abaaaf7SAxel Dörfler		return OF_FAILED;
4478abaaaf7SAxel Dörfler
4488abaaaf7SAxel Dörfler	return args.size;
4498abaaaf7SAxel Dörfler}
4508abaaaf7SAxel Dörfler
4518abaaaf7SAxel Dörfler
453d5cd4a9dSPulkoMandyof_write(intptr_t handle, const void *buffer, intptr_t bufferSize)
4548abaaaf7SAxel Dörfler{
4558abaaaf7SAxel Dörfler	struct {
4568abaaaf7SAxel Dörfler		const char	*name;
457d5cd4a9dSPulkoMandy		intptr_t	num_args;
458d5cd4a9dSPulkoMandy		intptr_t	num_returns;
459d5cd4a9dSPulkoMandy		intptr_t	handle;
4608abaaaf7SAxel Dörfler		const void	*buffer;
461d5cd4a9dSPulkoMandy		intptr_t	buffer_size;
462d5cd4a9dSPulkoMandy		intptr_t	size;
4638abaaaf7SAxel Dörfler	} args = {"write", 3, 1, handle, buffer, bufferSize, 0};
4648abaaaf7SAxel Dörfler
4658abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
4668abaaaf7SAxel Dörfler		return OF_FAILED;
4678abaaaf7SAxel Dörfler
4688abaaaf7SAxel Dörfler	return args.size;
4698abaaaf7SAxel Dörfler}
4708abaaaf7SAxel Dörfler
4718abaaaf7SAxel Dörfler
473d5cd4a9dSPulkoMandyof_seek(intptr_t handle, off_t pos)
4748abaaaf7SAxel Dörfler{
4758abaaaf7SAxel Dörfler	struct {
4768abaaaf7SAxel Dörfler		const char	*name;
477d5cd4a9dSPulkoMandy		intptr_t	num_args;
478d5cd4a9dSPulkoMandy		intptr_t	num_returns;
479d5cd4a9dSPulkoMandy		intptr_t	handle;
4808abaaaf7SAxel Dörfler		int64		pos;
481d5cd4a9dSPulkoMandy		intptr_t	status;
4828abaaaf7SAxel Dörfler	} args = {"seek", 3, 1, handle, pos, 0};
4838abaaaf7SAxel Dörfler
4848abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
4858abaaaf7SAxel Dörfler		return OF_FAILED;
4868abaaaf7SAxel Dörfler
4878abaaaf7SAxel Dörfler	return args.status;
4888abaaaf7SAxel Dörfler}
4898abaaaf7SAxel Dörfler
4908abaaaf7SAxel Dörfler
4918abaaaf7SAxel Dörfler// memory functions
4928abaaaf7SAxel Dörfler
4938abaaaf7SAxel Dörfler
495d5cd4a9dSPulkoMandyof_release(void *virtualAddress, intptr_t size)
4968abaaaf7SAxel Dörfler{
4978abaaaf7SAxel Dörfler	struct {
4988abaaaf7SAxel Dörfler		const char *name;
499d5cd4a9dSPulkoMandy		intptr_t	num_args;
500d5cd4a9dSPulkoMandy		intptr_t	num_returns;
501bd185b41SIngo Weinhold		void		*virtualAddress;
502d5cd4a9dSPulkoMandy		intptr_t	size;
503bd185b41SIngo Weinhold	} args = {"release", 2, 0, virtualAddress, size};
504bd185b41SIngo Weinhold
5058abaaaf7SAxel Dörfler	return gCallOpenFirmware(&args);
5068abaaaf7SAxel Dörfler}
5078abaaaf7SAxel Dörfler
5088abaaaf7SAxel Dörfler
5098abaaaf7SAxel Dörflervoid *
510d5cd4a9dSPulkoMandyof_claim(void *virtualAddress, intptr_t size, intptr_t align)
5118abaaaf7SAxel Dörfler{
5128abaaaf7SAxel Dörfler	struct {
5138abaaaf7SAxel Dörfler		const char	*name;
514d5cd4a9dSPulkoMandy		intptr_t	num_args;
515d5cd4a9dSPulkoMandy		intptr_t	num_returns;
516bd185b41SIngo Weinhold		void		*virtualAddress;
517d5cd4a9dSPulkoMandy		intptr_t	size;
518d5cd4a9dSPulkoMandy		intptr_t	align;
5198abaaaf7SAxel Dörfler		void		*address;
520bd185b41SIngo Weinhold	} args = {"claim", 3, 1, virtualAddress, size, align};
5218abaaaf7SAxel Dörfler
5228abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
5238abaaaf7SAxel Dörfler		return NULL;
5248abaaaf7SAxel Dörfler
5258abaaaf7SAxel Dörfler	return args.address;
5268abaaaf7SAxel Dörfler}
5278abaaaf7SAxel Dörfler
5288abaaaf7SAxel Dörfler
5298abaaaf7SAxel Dörfler// misc functions
5308abaaaf7SAxel Dörfler
5318abaaaf7SAxel Dörfler
5328abaaaf7SAxel Dörfler/** tests if the given service is missing
5338abaaaf7SAxel Dörfler */
5348abaaaf7SAxel Dörfler
5368abaaaf7SAxel Dörflerof_test(const char *service)
5378abaaaf7SAxel Dörfler{
5388abaaaf7SAxel Dörfler	struct {
5398abaaaf7SAxel Dörfler		const char	*name;
540d5cd4a9dSPulkoMandy		intptr_t	num_args;
541d5cd4a9dSPulkoMandy		intptr_t	num_returns;
5428abaaaf7SAxel Dörfler		const char	*service;
543d5cd4a9dSPulkoMandy		intptr_t	missing;
5448abaaaf7SAxel Dörfler	} args = {"test", 1, 1, service, 0};
5458abaaaf7SAxel Dörfler
5468abaaaf7SAxel Dörfler	if (gCallOpenFirmware(&args) == OF_FAILED)
5478abaaaf7SAxel Dörfler		return OF_FAILED;
5488abaaaf7SAxel Dörfler
5498abaaaf7SAxel Dörfler	return args.missing;
5508abaaaf7SAxel Dörfler}
5518abaaaf7SAxel Dörfler
5528abaaaf7SAxel Dörfler
5538abaaaf7SAxel Dörfler/** Returns the millisecond counter
5548abaaaf7SAxel Dörfler */
5558abaaaf7SAxel Dörfler
5578abaaaf7SAxel Dörflerof_milliseconds(void)
5588abaaaf7SAxel Dörfler{
5598abaaaf7SAxel Dörfler	struct {
5608abaaaf7SAxel Dörfler		const char	*name;
561d5cd4a9dSPulkoMandy		intptr_t	num_args;
562d5cd4a9dSPulkoMandy		intptr_t	num_returns;
563d5cd4a9dSPulkoMandy		intptr_t	milliseconds;
5648abaaaf7SAxel Dörfler	} args = {"milliseconds", 0, 1, 0};
5658abaaaf7SAxel Dörfler
566b62981b9SAndreas Färber	if (gCallOpenFirmware(&args) == OF_FAILED)
567b62981b9SAndreas Färber		return OF_FAILED;
5688abaaaf7SAxel Dörfler
5698abaaaf7SAxel Dörfler	return args.milliseconds;
5708abaaaf7SAxel Dörfler}
5718abaaaf7SAxel Dörfler
5728abaaaf7SAxel Dörfler
5738abaaaf7SAxel Dörflervoid
5748abaaaf7SAxel Dörflerof_exit(void)
5758abaaaf7SAxel Dörfler{
5768abaaaf7SAxel Dörfler	struct {
5778abaaaf7SAxel Dörfler		const char	*name;
578d5cd4a9dSPulkoMandy		intptr_t	num_args;
579d5cd4a9dSPulkoMandy		intptr_t	num_returns;
5808abaaaf7SAxel Dörfler	} args = {"exit", 0, 0};
5818abaaaf7SAxel Dörfler
5828abaaaf7SAxel Dörfler	gCallOpenFirmware(&args);
5838abaaaf7SAxel Dörfler}
5848abaaaf7SAxel Dörfler