167204Sobrien/*	$NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $	*/
267204Sobrien
3139749Simp/*-
467204Sobrien * Copyright (C) 1995, 1996 Wolfgang Solfrank.
567204Sobrien * Copyright (C) 1995, 1996 TooLs GmbH.
667204Sobrien * All rights reserved.
767204Sobrien *
867204Sobrien * Redistribution and use in source and binary forms, with or without
967204Sobrien * modification, are permitted provided that the following conditions
1067204Sobrien * are met:
1167204Sobrien * 1. Redistributions of source code must retain the above copyright
1267204Sobrien *    notice, this list of conditions and the following disclaimer.
1367204Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1467204Sobrien *    notice, this list of conditions and the following disclaimer in the
1567204Sobrien *    documentation and/or other materials provided with the distribution.
1667204Sobrien * 3. All advertising materials mentioning features or use of this software
1767204Sobrien *    must display the following acknowledgement:
1867204Sobrien *	This product includes software developed by TooLs GmbH.
1967204Sobrien * 4. The name of TooLs GmbH may not be used to endorse or promote products
2067204Sobrien *    derived from this software without specific prior written permission.
2167204Sobrien *
2267204Sobrien * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
2367204Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2467204Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2567204Sobrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2667204Sobrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2767204Sobrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2867204Sobrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2967204Sobrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
3067204Sobrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
3167204Sobrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3267204Sobrien */
33139749Simp/*-
3467204Sobrien * Copyright (C) 2000 Benno Rice.
3567204Sobrien * All rights reserved.
3667204Sobrien *
3767204Sobrien * Redistribution and use in source and binary forms, with or without
3867204Sobrien * modification, are permitted provided that the following conditions
3967204Sobrien * are met:
4067204Sobrien * 1. Redistributions of source code must retain the above copyright
4167204Sobrien *    notice, this list of conditions and the following disclaimer.
4267204Sobrien * 2. Redistributions in binary form must reproduce the above copyright
4367204Sobrien *    notice, this list of conditions and the following disclaimer in the
4467204Sobrien *    documentation and/or other materials provided with the distribution.
4567204Sobrien *
4667204Sobrien * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
4767204Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
4867204Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4967204Sobrien * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5067204Sobrien * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
5167204Sobrien * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
5267204Sobrien * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5367204Sobrien * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
5467204Sobrien * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
5567204Sobrien * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5667204Sobrien */
5767204Sobrien
58170838Smarius#include <sys/cdefs.h>
59170838Smarius__FBSDID("$FreeBSD$");
60170838Smarius
6180697Sjake#include <sys/param.h>
6286557Stmm#include <sys/kernel.h>
6386557Stmm#include <sys/malloc.h>
6478346Sbenno#include <sys/systm.h>
6578346Sbenno
6667204Sobrien#include <machine/stdarg.h>
6767204Sobrien
68194138Smarius#include <dev/ofw/ofwvar.h>
6978346Sbenno#include <dev/ofw/openfirm.h>
70194138Smarius
71186347Snwhitehorn#include "ofw_if.h"
7268548Sbenno
73208614Srajstatic int ofw_std_init(ofw_t ofw, void *openfirm);
74186347Snwhitehornstatic int ofw_std_test(ofw_t ofw, const char *name);
75186347Snwhitehornstatic int ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns,
76212477Smarius    cell_t *returns);
77186347Snwhitehornstatic phandle_t ofw_std_peer(ofw_t ofw, phandle_t node);
78186347Snwhitehornstatic phandle_t ofw_std_child(ofw_t ofw, phandle_t node);
79186347Snwhitehornstatic phandle_t ofw_std_parent(ofw_t ofw, phandle_t node);
80186347Snwhitehornstatic phandle_t ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance);
81186347Snwhitehornstatic ssize_t ofw_std_getproplen(ofw_t ofw, phandle_t package,
82186347Snwhitehorn    const char *propname);
83186347Snwhitehornstatic ssize_t ofw_std_getprop(ofw_t ofw, phandle_t package,
84186347Snwhitehorn    const char *propname, void *buf, size_t buflen);
85186347Snwhitehornstatic int ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous,
86186347Snwhitehorn    char *buf, size_t);
87194025Savgstatic int ofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname,
88194025Savg    const void *buf, size_t len);
89186347Snwhitehornstatic ssize_t ofw_std_canon(ofw_t ofw, const char *device, char *buf,
90186347Snwhitehorn    size_t len);
91186347Snwhitehornstatic phandle_t ofw_std_finddevice(ofw_t ofw, const char *device);
92186347Snwhitehornstatic ssize_t ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance,
93186347Snwhitehorn    char *buf, size_t len);
94186347Snwhitehornstatic ssize_t ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf,
95186347Snwhitehorn    size_t len);
96186347Snwhitehornstatic int ofw_std_call_method(ofw_t ofw, ihandle_t instance,
97212477Smarius    const char *method, int nargs, int nreturns, cell_t *args_and_returns);
98186347Snwhitehornstatic ihandle_t ofw_std_open(ofw_t ofw, const char *device);
99186347Snwhitehornstatic void ofw_std_close(ofw_t ofw, ihandle_t instance);
100186347Snwhitehornstatic ssize_t ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr,
101186347Snwhitehorn    size_t len);
102186347Snwhitehornstatic ssize_t ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr,
103186347Snwhitehorn    size_t len);
104194138Smariusstatic int ofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos);
105186347Snwhitehornstatic caddr_t ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align);
106186347Snwhitehornstatic void ofw_std_release(ofw_t ofw, void *virt, size_t size);
107186347Snwhitehornstatic void ofw_std_enter(ofw_t ofw);
108186347Snwhitehornstatic void ofw_std_exit(ofw_t ofw);
10986557Stmm
110186347Snwhitehornstatic ofw_method_t ofw_std_methods[] = {
111186347Snwhitehorn	OFWMETHOD(ofw_init,			ofw_std_init),
112186347Snwhitehorn	OFWMETHOD(ofw_peer,			ofw_std_peer),
113186347Snwhitehorn	OFWMETHOD(ofw_child,			ofw_std_child),
114186347Snwhitehorn	OFWMETHOD(ofw_parent,			ofw_std_parent),
115186347Snwhitehorn	OFWMETHOD(ofw_instance_to_package,	ofw_std_instance_to_package),
116186347Snwhitehorn	OFWMETHOD(ofw_getproplen,		ofw_std_getproplen),
117186347Snwhitehorn	OFWMETHOD(ofw_getprop,			ofw_std_getprop),
118186347Snwhitehorn	OFWMETHOD(ofw_nextprop,			ofw_std_nextprop),
119186347Snwhitehorn	OFWMETHOD(ofw_setprop,			ofw_std_setprop),
120186347Snwhitehorn	OFWMETHOD(ofw_canon,			ofw_std_canon),
121186347Snwhitehorn	OFWMETHOD(ofw_finddevice,		ofw_std_finddevice),
122186347Snwhitehorn	OFWMETHOD(ofw_instance_to_path,		ofw_std_instance_to_path),
123186347Snwhitehorn	OFWMETHOD(ofw_package_to_path,		ofw_std_package_to_path),
12467204Sobrien
125186347Snwhitehorn	OFWMETHOD(ofw_test,			ofw_std_test),
126186347Snwhitehorn	OFWMETHOD(ofw_call_method,		ofw_std_call_method),
127186347Snwhitehorn	OFWMETHOD(ofw_interpret,		ofw_std_interpret),
128186347Snwhitehorn	OFWMETHOD(ofw_open,			ofw_std_open),
129186347Snwhitehorn	OFWMETHOD(ofw_close,			ofw_std_close),
130186347Snwhitehorn	OFWMETHOD(ofw_read,			ofw_std_read),
131186347Snwhitehorn	OFWMETHOD(ofw_write,			ofw_std_write),
132186347Snwhitehorn	OFWMETHOD(ofw_seek,			ofw_std_seek),
133186347Snwhitehorn	OFWMETHOD(ofw_claim,			ofw_std_claim),
134186347Snwhitehorn	OFWMETHOD(ofw_release,			ofw_std_release),
135186347Snwhitehorn	OFWMETHOD(ofw_enter,			ofw_std_enter),
136186347Snwhitehorn	OFWMETHOD(ofw_exit,			ofw_std_exit),
13767204Sobrien
138186347Snwhitehorn	{ 0, 0 }
139186347Snwhitehorn};
14078346Sbenno
141186347Snwhitehornstatic ofw_def_t ofw_std = {
142186347Snwhitehorn	OFW_STD_DIRECT,
143186347Snwhitehorn	ofw_std_methods,
144186347Snwhitehorn	0
145186347Snwhitehorn};
146186347SnwhitehornOFW_DEF(ofw_std);
14767204Sobrien
148186347Snwhitehornstatic int (*openfirmware)(void *);
149186347Snwhitehorn
150194138Smarius/* Initializer */
151186347Snwhitehorn
152208614Srajstatic int
153186347Snwhitehornofw_std_init(ofw_t ofw, void *openfirm)
15478346Sbenno{
155194138Smarius
156186347Snwhitehorn	openfirmware = (int (*)(void *))openfirm;
157208614Sraj	return (0);
15878346Sbenno}
15978346Sbenno
16067204Sobrien/*
16167204Sobrien * Generic functions
16267204Sobrien */
16367204Sobrien
16467204Sobrien/* Test to see if a service exists. */
165186347Snwhitehornstatic int
166186347Snwhitehornofw_std_test(ofw_t ofw, const char *name)
16767204Sobrien{
168205496Snwhitehorn	struct {
169170838Smarius		cell_t name;
170170838Smarius		cell_t nargs;
171170838Smarius		cell_t nreturns;
172170838Smarius		cell_t service;
173170838Smarius		cell_t missing;
17467204Sobrien	} args = {
17580697Sjake		(cell_t)"test",
17667204Sobrien		1,
17767204Sobrien		1,
17867204Sobrien	};
17967204Sobrien
18080697Sjake	args.service = (cell_t)name;
18167204Sobrien	if (openfirmware(&args) == -1)
182170838Smarius		return (-1);
183170838Smarius	return (args.missing);
18467204Sobrien}
18567204Sobrien
186186347Snwhitehornstatic int
187212477Smariusofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, cell_t *returns)
188115973Sjake{
189205496Snwhitehorn	struct {
190115973Sjake		cell_t name;
191115973Sjake		cell_t nargs;
192115973Sjake		cell_t nreturns;
193115973Sjake		cell_t slot[16];
194115973Sjake	} args = {
195115973Sjake		(cell_t)"interpret",
196170838Smarius		1,
197115973Sjake	};
198115973Sjake	cell_t status;
199186347Snwhitehorn	int i = 0, j = 0;
200115973Sjake
201115973Sjake	args.nreturns = ++nreturns;
202115973Sjake	args.slot[i++] = (cell_t)cmd;
203194138Smarius	if (openfirmware(&args) == -1)
204115973Sjake		return (-1);
205115973Sjake	status = args.slot[i++];
206115973Sjake	while (i < 1 + nreturns)
207190522Smarius		returns[j++] = args.slot[i++];
208115973Sjake	return (status);
209115973Sjake}
210115973Sjake
21167204Sobrien/*
21267204Sobrien * Device tree functions
21367204Sobrien */
21467204Sobrien
21567204Sobrien/* Return the next sibling of this node or 0. */
216186347Snwhitehornstatic phandle_t
217186347Snwhitehornofw_std_peer(ofw_t ofw, phandle_t node)
21867204Sobrien{
219205496Snwhitehorn	struct {
220170838Smarius		cell_t name;
221170838Smarius		cell_t nargs;
222170838Smarius		cell_t nreturns;
223170838Smarius		cell_t node;
224170838Smarius		cell_t next;
22567204Sobrien	} args = {
22680697Sjake		(cell_t)"peer",
22767204Sobrien		1,
22867204Sobrien		1,
22967204Sobrien	};
23067204Sobrien
231170838Smarius	args.node = node;
23267204Sobrien	if (openfirmware(&args) == -1)
233170838Smarius		return (-1);
234170838Smarius	return (args.next);
23567204Sobrien}
23667204Sobrien
23767204Sobrien/* Return the first child of this node or 0. */
238186347Snwhitehornstatic phandle_t
239186347Snwhitehornofw_std_child(ofw_t ofw, phandle_t node)
24067204Sobrien{
241205496Snwhitehorn	struct {
242170838Smarius		cell_t name;
243170838Smarius		cell_t nargs;
244170838Smarius		cell_t nreturns;
245170838Smarius		cell_t node;
246170838Smarius		cell_t child;
24767204Sobrien	} args = {
24880697Sjake		(cell_t)"child",
24967204Sobrien		1,
25067204Sobrien		1,
25167204Sobrien	};
25267204Sobrien
253170838Smarius	args.node = node;
25467204Sobrien	if (openfirmware(&args) == -1)
255170838Smarius		return (-1);
256170838Smarius	return (args.child);
25767204Sobrien}
25867204Sobrien
25967204Sobrien/* Return the parent of this node or 0. */
260186347Snwhitehornstatic phandle_t
261186347Snwhitehornofw_std_parent(ofw_t ofw, phandle_t node)
26267204Sobrien{
263205496Snwhitehorn	struct {
264170838Smarius		cell_t name;
265170838Smarius		cell_t nargs;
266170838Smarius		cell_t nreturns;
267170838Smarius		cell_t node;
268170838Smarius		cell_t parent;
26967204Sobrien	} args = {
27080697Sjake		(cell_t)"parent",
27167204Sobrien		1,
27267204Sobrien		1,
27367204Sobrien	};
27467204Sobrien
275170838Smarius	args.node = node;
27667204Sobrien	if (openfirmware(&args) == -1)
277170838Smarius		return (-1);
278170838Smarius	return (args.parent);
27967204Sobrien}
28067204Sobrien
28167204Sobrien/* Return the package handle that corresponds to an instance handle. */
282186347Snwhitehornstatic phandle_t
283186347Snwhitehornofw_std_instance_to_package(ofw_t ofw, ihandle_t instance)
28467204Sobrien{
285205496Snwhitehorn	struct {
286170838Smarius		cell_t name;
287170838Smarius		cell_t nargs;
288170838Smarius		cell_t nreturns;
289170838Smarius		cell_t instance;
290170838Smarius		cell_t package;
29167204Sobrien	} args = {
29280697Sjake		(cell_t)"instance-to-package",
29367204Sobrien		1,
29467204Sobrien		1,
29567204Sobrien	};
296170838Smarius
297170838Smarius	args.instance = instance;
29867204Sobrien	if (openfirmware(&args) == -1)
299170838Smarius		return (-1);
300170838Smarius	return (args.package);
30167204Sobrien}
30267204Sobrien
30367204Sobrien/* Get the length of a property of a package. */
304186347Snwhitehornstatic ssize_t
305186347Snwhitehornofw_std_getproplen(ofw_t ofw, phandle_t package, const char *propname)
30667204Sobrien{
307205496Snwhitehorn	struct {
308170838Smarius		cell_t name;
309170838Smarius		cell_t nargs;
310170838Smarius		cell_t nreturns;
311170838Smarius		cell_t package;
312170838Smarius		cell_t propname;
313170838Smarius		cell_t proplen;
31467204Sobrien	} args = {
31580697Sjake		(cell_t)"getproplen",
31667204Sobrien		2,
31767204Sobrien		1,
31867204Sobrien	};
31967204Sobrien
320170838Smarius	args.package = package;
32180697Sjake	args.propname = (cell_t)propname;
32267204Sobrien	if (openfirmware(&args) == -1)
323170838Smarius		return (-1);
324170838Smarius	return (args.proplen);
32567204Sobrien}
32667204Sobrien
32767204Sobrien/* Get the value of a property of a package. */
328186347Snwhitehornstatic ssize_t
329186347Snwhitehornofw_std_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf,
330186347Snwhitehorn    size_t buflen)
33167204Sobrien{
332205496Snwhitehorn	struct {
333170838Smarius		cell_t name;
334170838Smarius		cell_t nargs;
335170838Smarius		cell_t nreturns;
336170838Smarius		cell_t package;
337170838Smarius		cell_t propname;
338170838Smarius		cell_t buf;
339170838Smarius		cell_t buflen;
340170838Smarius		cell_t size;
34167204Sobrien	} args = {
34280697Sjake		(cell_t)"getprop",
34367204Sobrien		4,
34467204Sobrien		1,
34567204Sobrien	};
346170838Smarius
347170838Smarius	args.package = package;
34880697Sjake	args.propname = (cell_t)propname;
34980697Sjake	args.buf = (cell_t)buf;
350170838Smarius	args.buflen = buflen;
35167204Sobrien	if (openfirmware(&args) == -1)
352170838Smarius		return (-1);
353170838Smarius	return (args.size);
35467204Sobrien}
35567204Sobrien
35667204Sobrien/* Get the next property of a package. */
357186347Snwhitehornstatic int
358186347Snwhitehornofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf,
359186347Snwhitehorn    size_t size)
36067204Sobrien{
361205496Snwhitehorn	struct {
362170838Smarius		cell_t name;
363170838Smarius		cell_t nargs;
364170838Smarius		cell_t nreturns;
365170838Smarius		cell_t package;
366170838Smarius		cell_t previous;
367170838Smarius		cell_t buf;
368170838Smarius		cell_t flag;
36967204Sobrien	} args = {
37080697Sjake		(cell_t)"nextprop",
37167204Sobrien		3,
37267204Sobrien		1,
37367204Sobrien	};
37467204Sobrien
375170838Smarius	args.package = package;
37680697Sjake	args.previous = (cell_t)previous;
37780697Sjake	args.buf = (cell_t)buf;
37867204Sobrien	if (openfirmware(&args) == -1)
379170838Smarius		return (-1);
380170838Smarius	return (args.flag);
38167204Sobrien}
38267204Sobrien
38367204Sobrien/* Set the value of a property of a package. */
38467204Sobrien/* XXX Has a bug on FirePower */
385186347Snwhitehornstatic int
386194025Savgofw_std_setprop(ofw_t ofw, phandle_t package, const char *propname,
387194025Savg    const void *buf, size_t len)
38867204Sobrien{
389205496Snwhitehorn	struct {
390170838Smarius		cell_t name;
391170838Smarius		cell_t nargs;
392170838Smarius		cell_t nreturns;
393170838Smarius		cell_t package;
394170838Smarius		cell_t propname;
395170838Smarius		cell_t buf;
396170838Smarius		cell_t len;
397170838Smarius		cell_t size;
39867204Sobrien	} args = {
39980697Sjake		(cell_t)"setprop",
40067204Sobrien		4,
40167204Sobrien		1,
40267204Sobrien	};
403170838Smarius
404170838Smarius	args.package = package;
40580697Sjake	args.propname = (cell_t)propname;
40680697Sjake	args.buf = (cell_t)buf;
407170838Smarius	args.len = len;
40867204Sobrien	if (openfirmware(&args) == -1)
409170838Smarius		return (-1);
410170838Smarius	return (args.size);
41167204Sobrien}
41267204Sobrien
41367204Sobrien/* Convert a device specifier to a fully qualified pathname. */
414186347Snwhitehornstatic ssize_t
415186347Snwhitehornofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len)
41667204Sobrien{
417205496Snwhitehorn	struct {
418170838Smarius		cell_t name;
419170838Smarius		cell_t nargs;
420170838Smarius		cell_t nreturns;
421170838Smarius		cell_t device;
422170838Smarius		cell_t buf;
423170838Smarius		cell_t len;
424170838Smarius		cell_t size;
42567204Sobrien	} args = {
42680697Sjake		(cell_t)"canon",
42767204Sobrien		3,
42867204Sobrien		1,
42967204Sobrien	};
430170838Smarius
43180697Sjake	args.device = (cell_t)device;
43280697Sjake	args.buf = (cell_t)buf;
433170838Smarius	args.len = len;
43467204Sobrien	if (openfirmware(&args) == -1)
435170838Smarius		return (-1);
436170838Smarius	return (args.size);
43767204Sobrien}
43867204Sobrien
43967204Sobrien/* Return a package handle for the specified device. */
440186347Snwhitehornstatic phandle_t
441186347Snwhitehornofw_std_finddevice(ofw_t ofw, const char *device)
44267204Sobrien{
443205496Snwhitehorn	struct {
444170838Smarius		cell_t name;
445170838Smarius		cell_t nargs;
446170838Smarius		cell_t nreturns;
447170838Smarius		cell_t device;
448170838Smarius		cell_t package;
44967204Sobrien	} args = {
45080697Sjake		(cell_t)"finddevice",
45167204Sobrien		1,
45267204Sobrien		1,
453170838Smarius	};
454170838Smarius
45580697Sjake	args.device = (cell_t)device;
45667204Sobrien	if (openfirmware(&args) == -1)
457170838Smarius		return (-1);
458170838Smarius	return (args.package);
45967204Sobrien}
46067204Sobrien
46167204Sobrien/* Return the fully qualified pathname corresponding to an instance. */
462186347Snwhitehornstatic ssize_t
463186347Snwhitehornofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
46467204Sobrien{
465205496Snwhitehorn	struct {
466170838Smarius		cell_t name;
467170838Smarius		cell_t nargs;
468170838Smarius		cell_t nreturns;
469170838Smarius		cell_t instance;
470170838Smarius		cell_t buf;
471170838Smarius		cell_t len;
472170838Smarius		cell_t size;
47367204Sobrien	} args = {
47480697Sjake		(cell_t)"instance-to-path",
47567204Sobrien		3,
47667204Sobrien		1,
47767204Sobrien	};
47867204Sobrien
479170838Smarius	args.instance = instance;
48080697Sjake	args.buf = (cell_t)buf;
481170838Smarius	args.len = len;
48267204Sobrien	if (openfirmware(&args) == -1)
483170838Smarius		return (-1);
484170838Smarius	return (args.size);
48567204Sobrien}
48667204Sobrien
48767204Sobrien/* Return the fully qualified pathname corresponding to a package. */
488186347Snwhitehornstatic ssize_t
489186347Snwhitehornofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
49067204Sobrien{
491205496Snwhitehorn	struct {
492170838Smarius		cell_t name;
493170838Smarius		cell_t nargs;
494170838Smarius		cell_t nreturns;
495170838Smarius		cell_t package;
496170838Smarius		cell_t buf;
497170838Smarius		cell_t len;
498170838Smarius		cell_t size;
49967204Sobrien	} args = {
50080697Sjake		(cell_t)"package-to-path",
50167204Sobrien		3,
50267204Sobrien		1,
50367204Sobrien	};
50467204Sobrien
505170838Smarius	args.package = package;
50680697Sjake	args.buf = (cell_t)buf;
507170838Smarius	args.len = len;
50867204Sobrien	if (openfirmware(&args) == -1)
509170838Smarius		return (-1);
510170838Smarius	return (args.size);
51167204Sobrien}
51267204Sobrien
51367204Sobrien/*  Call the method in the scope of a given instance. */
514186347Snwhitehornstatic int
515186347Snwhitehornofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method,
516209801Snwhitehorn    int nargs, int nreturns, cell_t *args_and_returns)
51767204Sobrien{
518205496Snwhitehorn	struct {
519170838Smarius		cell_t name;
520170838Smarius		cell_t nargs;
521170838Smarius		cell_t nreturns;
522170838Smarius		cell_t method;
523170838Smarius		cell_t instance;
524170838Smarius		cell_t args_n_results[12];
52567204Sobrien	} args = {
52680697Sjake		(cell_t)"call-method",
52767204Sobrien		2,
52867204Sobrien		1,
52967204Sobrien	};
530212477Smarius	cell_t *ap, *cp;
53180697Sjake	int n;
53267204Sobrien
53367204Sobrien	if (nargs > 6)
534170838Smarius		return (-1);
535170838Smarius	args.nargs = nargs + 2;
536170838Smarius	args.nreturns = nreturns + 1;
53780697Sjake	args.method = (cell_t)method;
538170838Smarius	args.instance = instance;
539186347Snwhitehorn
540186347Snwhitehorn	ap = args_and_returns;
541170838Smarius	for (cp = args.args_n_results + (n = nargs); --n >= 0;)
542186347Snwhitehorn		*--cp = *(ap++);
54367204Sobrien	if (openfirmware(&args) == -1)
544170838Smarius		return (-1);
54567204Sobrien	if (args.args_n_results[nargs])
546170838Smarius		return (args.args_n_results[nargs]);
547170838Smarius	for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
548186347Snwhitehorn		*(ap++) = *--cp;
549170838Smarius	return (0);
55067204Sobrien}
55167204Sobrien
55267204Sobrien/*
553170838Smarius * Device I/O functions
55467204Sobrien */
55567204Sobrien
55667204Sobrien/* Open an instance for a device. */
557186347Snwhitehornstatic ihandle_t
558186347Snwhitehornofw_std_open(ofw_t ofw, const char *device)
55967204Sobrien{
560205496Snwhitehorn	struct {
561170838Smarius		cell_t name;
562170838Smarius		cell_t nargs;
563170838Smarius		cell_t nreturns;
564170838Smarius		cell_t device;
565170838Smarius		cell_t instance;
56667204Sobrien	} args = {
56780697Sjake		(cell_t)"open",
56867204Sobrien		1,
56967204Sobrien		1,
57067204Sobrien	};
571170838Smarius
57280697Sjake	args.device = (cell_t)device;
573194138Smarius	if (openfirmware(&args) == -1 || args.instance == 0)
574170838Smarius		return (-1);
575170838Smarius	return (args.instance);
57667204Sobrien}
57767204Sobrien
57867204Sobrien/* Close an instance. */
579186347Snwhitehornstatic void
580186347Snwhitehornofw_std_close(ofw_t ofw, ihandle_t instance)
58167204Sobrien{
582205496Snwhitehorn	struct {
583170838Smarius		cell_t name;
584170838Smarius		cell_t nargs;
585170838Smarius		cell_t nreturns;
586170838Smarius		cell_t instance;
58767204Sobrien	} args = {
58880697Sjake		(cell_t)"close",
58967204Sobrien		1,
590206116Smarius		0,
59167204Sobrien	};
592170838Smarius
593170838Smarius	args.instance = instance;
59467204Sobrien	openfirmware(&args);
59567204Sobrien}
59667204Sobrien
59767204Sobrien/* Read from an instance. */
598186347Snwhitehornstatic ssize_t
599186347Snwhitehornofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
60067204Sobrien{
601205496Snwhitehorn	struct {
602170838Smarius		cell_t name;
603170838Smarius		cell_t nargs;
604170838Smarius		cell_t nreturns;
605170838Smarius		cell_t instance;
606170838Smarius		cell_t addr;
607170838Smarius		cell_t len;
608170838Smarius		cell_t actual;
60967204Sobrien	} args = {
61080697Sjake		(cell_t)"read",
61167204Sobrien		3,
61267204Sobrien		1,
61367204Sobrien	};
61467204Sobrien
615170838Smarius	args.instance = instance;
61680697Sjake	args.addr = (cell_t)addr;
617170838Smarius	args.len = len;
61867204Sobrien	if (openfirmware(&args) == -1)
619170838Smarius		return (-1);
62068548Sbenno
621170838Smarius	return (args.actual);
62267204Sobrien}
62367204Sobrien
62467204Sobrien/* Write to an instance. */
625186347Snwhitehornstatic ssize_t
626186347Snwhitehornofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
62767204Sobrien{
628205496Snwhitehorn	struct {
629170838Smarius		cell_t name;
630170838Smarius		cell_t nargs;
631170838Smarius		cell_t nreturns;
632170838Smarius		cell_t instance;
633170838Smarius		cell_t addr;
634170838Smarius		cell_t len;
635170838Smarius		cell_t actual;
63667204Sobrien	} args = {
63780697Sjake		(cell_t)"write",
63867204Sobrien		3,
63967204Sobrien		1,
64067204Sobrien	};
64167204Sobrien
642170838Smarius	args.instance = instance;
64380697Sjake	args.addr = (cell_t)addr;
644170838Smarius	args.len = len;
64567204Sobrien	if (openfirmware(&args) == -1)
646170838Smarius		return (-1);
647170838Smarius	return (args.actual);
64867204Sobrien}
64967204Sobrien
65067204Sobrien/* Seek to a position. */
651186347Snwhitehornstatic int
652194138Smariusofw_std_seek(ofw_t ofw, ihandle_t instance, uint64_t pos)
65367204Sobrien{
654205496Snwhitehorn	struct {
655170838Smarius		cell_t name;
656170838Smarius		cell_t nargs;
657170838Smarius		cell_t nreturns;
658170838Smarius		cell_t instance;
659170838Smarius		cell_t poshi;
660170838Smarius		cell_t poslo;
661170838Smarius		cell_t status;
66267204Sobrien	} args = {
66380697Sjake		(cell_t)"seek",
66467204Sobrien		3,
66567204Sobrien		1,
66667204Sobrien	};
667170838Smarius
668170838Smarius	args.instance = instance;
669170838Smarius	args.poshi = pos >> 32;
670170838Smarius	args.poslo = pos;
67167204Sobrien	if (openfirmware(&args) == -1)
672170838Smarius		return (-1);
673170838Smarius	return (args.status);
67467204Sobrien}
67567204Sobrien
67667204Sobrien/*
677170838Smarius * Memory functions
67867204Sobrien */
67967204Sobrien
68067204Sobrien/* Claim an area of memory. */
681186347Snwhitehornstatic caddr_t
682186347Snwhitehornofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align)
68367204Sobrien{
684205496Snwhitehorn	struct {
685170838Smarius		cell_t name;
686170838Smarius		cell_t nargs;
687170838Smarius		cell_t nreturns;
688170838Smarius		cell_t virt;
689170838Smarius		cell_t size;
690170838Smarius		cell_t align;
691170838Smarius		cell_t baseaddr;
69267204Sobrien	} args = {
69380697Sjake		(cell_t)"claim",
69467204Sobrien		3,
69567204Sobrien		1,
69667204Sobrien	};
69767204Sobrien
69880697Sjake	args.virt = (cell_t)virt;
699170838Smarius	args.size = size;
700170838Smarius	args.align = align;
70167204Sobrien	if (openfirmware(&args) == -1)
702170838Smarius		return ((void *)-1);
703170838Smarius	return ((void *)args.baseaddr);
70467204Sobrien}
70567204Sobrien
70667204Sobrien/* Release an area of memory. */
707186347Snwhitehornstatic void
708186347Snwhitehornofw_std_release(ofw_t ofw, void *virt, size_t size)
70967204Sobrien{
710205496Snwhitehorn	struct {
711170838Smarius		cell_t name;
712170838Smarius		cell_t nargs;
713170838Smarius		cell_t nreturns;
714170838Smarius		cell_t virt;
715170838Smarius		cell_t size;
71667204Sobrien	} args = {
71780697Sjake		(cell_t)"release",
71867204Sobrien		2,
719206116Smarius		0,
72067204Sobrien	};
721170838Smarius
72280697Sjake	args.virt = (cell_t)virt;
723170838Smarius	args.size = size;
72467204Sobrien	openfirmware(&args);
72567204Sobrien}
72667204Sobrien
72767204Sobrien/*
728170838Smarius * Control transfer functions
72967204Sobrien */
73067204Sobrien
731133862Smarius/* Suspend and drop back to the Open Firmware interface. */
732186347Snwhitehornstatic void
733186347Snwhitehornofw_std_enter(ofw_t ofw)
73467204Sobrien{
735205496Snwhitehorn	struct {
73680697Sjake		cell_t name;
73780697Sjake		cell_t nargs;
73880697Sjake		cell_t nreturns;
73967204Sobrien	} args = {
74080697Sjake		(cell_t)"enter",
741206116Smarius		0,
742206116Smarius		0,
74367204Sobrien	};
74467204Sobrien
74567204Sobrien	openfirmware(&args);
746170838Smarius	/* We may come back. */
74767204Sobrien}
74867204Sobrien
749133862Smarius/* Shut down and drop back to the Open Firmware interface. */
750186347Snwhitehornstatic void
751186347Snwhitehornofw_std_exit(ofw_t ofw)
75267204Sobrien{
753205496Snwhitehorn	struct {
75480697Sjake		cell_t name;
75580697Sjake		cell_t nargs;
75680697Sjake		cell_t nreturns;
75767204Sobrien	} args = {
75880697Sjake		(cell_t)"exit",
759206116Smarius		0,
760206116Smarius		0,
76167204Sobrien	};
76267204Sobrien
76367204Sobrien	openfirmware(&args);
764170838Smarius	for (;;)			/* just in case */
765170838Smarius		;
76667204Sobrien}
767