xref: /openbsd/sys/arch/macppc/macppc/opendev.c (revision f6aab3d8)
1 /*	$OpenBSD: opendev.c,v 1.10 2020/04/02 19:27:51 gkoehler Exp $	*/
2 /*	$NetBSD: openfirm.c,v 1.1 1996/09/30 16:34:52 ws Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
6  * Copyright (C) 1995, 1996 TooLs GmbH.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by TooLs GmbH.
20  * 4. The name of TooLs GmbH may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/stdarg.h>
37 #include <machine/cpu.h>
38 #include <machine/psl.h>
39 
40 #include <dev/ofw/openfirm.h>
41 #include "ofw_machdep.h"
42 
43 extern void ofbcopy(const void *, void *, size_t);
44 
45 int
46 OF_instance_to_package(int ihandle)
47 {
48 	static struct {
49 		char *name;
50 		int nargs;
51 		int nreturns;
52 		int ihandle;
53 		int phandle;
54 	} args = {
55 		"instance-to-package",
56 		1,
57 		1,
58 	};
59 	uint32_t s;
60 	int ret;
61 
62 	s = ofw_msr();
63 	args.ihandle = ihandle;
64 	if (openfirmware(&args) == -1)
65 		ret = -1;
66 	else
67 		ret = args.phandle;
68 	ppc_mtmsr(s);
69 	return ret;
70 }
71 
72 int
73 OF_package_to_path(int phandle, char *buf, int buflen)
74 {
75 	static struct {
76 		char *name;
77 		int nargs;
78 		int nreturns;
79 		int phandle;
80 		char *buf;
81 		int buflen;
82 		int length;
83 	} args = {
84 		"package-to-path",
85 		3,
86 		1,
87 	};
88 	uint32_t s;
89 	int ret;
90 
91 	if (buflen > PAGE_SIZE)
92 		return -1;
93 	s = ofw_msr();
94 	args.phandle = phandle;
95 	args.buf = OF_buf;
96 	args.buflen = buflen;
97 	if (openfirmware(&args) < 0)
98 		ret = -1;
99 	else {
100 		if (args.length > 0)
101 			ofbcopy(OF_buf, buf, args.length);
102 		ret = args.length;
103 	}
104 	ppc_mtmsr(s);
105 	return ret;
106 }
107 
108 
109 int
110 OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...)
111 {
112 	va_list ap;
113 	static struct {
114 		char *name;
115 		int nargs;
116 		int nreturns;
117 		char *method;
118 		int ihandle;
119 		int args_n_results[12];
120 	} args = {
121 		"call-method",
122 		2,
123 		1,
124 	};
125 	uint32_t s;
126 	int *ip, n, ret;
127 
128 	if (nargs > 6)
129 		return -1;
130 	s = ofw_msr();
131 	args.nargs = nargs + 2;
132 	args.nreturns = nreturns + 1;
133 	args.method = method;
134 	args.ihandle = ihandle;
135 	va_start(ap, nreturns);
136 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
137 		*--ip = va_arg(ap, int);
138 	if (openfirmware(&args) == -1)
139 		ret = -1;
140 	else if (args.args_n_results[nargs])
141 		ret = args.args_n_results[nargs];
142 	else {
143 		for (ip = args.args_n_results + nargs + (n = args.nreturns);
144 		    --n > 0;)
145 			*va_arg(ap, int *) = *--ip;
146 		ret = 0;
147 	}
148 	va_end(ap);
149 	ppc_mtmsr(s);
150 	return ret;
151 }
152 int
153 OF_call_method_1(char *method, int ihandle, int nargs, ...)
154 {
155 	va_list ap;
156 	static struct {
157 		char *name;
158 		int nargs;
159 		int nreturns;
160 		char *method;
161 		int ihandle;
162 		int args_n_results[8];
163 	} args = {
164 		"call-method",
165 		2,
166 		2,
167 	};
168 	uint32_t s;
169 	int *ip, n, ret;
170 
171 	if (nargs > 6)
172 		return -1;
173 	s = ofw_msr();
174 	args.nargs = nargs + 2;
175 	args.method = method;
176 	args.ihandle = ihandle;
177 	va_start(ap, nargs);
178 	for (ip = args.args_n_results + (n = nargs); --n >= 0;)
179 		*--ip = va_arg(ap, int);
180 	va_end(ap);
181 	if (openfirmware(&args) == -1)
182 		ret = -1;
183 	else if (args.args_n_results[nargs])
184 		ret = -1;
185 	else
186 		ret = args.args_n_results[nargs + 1];
187 	ppc_mtmsr(s);
188 	return ret;
189 }
190 
191 int
192 OF_open(char *dname)
193 {
194 	static struct {
195 		char *name;
196 		int nargs;
197 		int nreturns;
198 		char *dname;
199 		int handle;
200 	} args = {
201 		"open",
202 		1,
203 		1,
204 	};
205 	uint32_t s;
206 	int l, ret;
207 
208 	if ((l = strlen(dname)) >= PAGE_SIZE)
209 		return -1;
210 	s = ofw_msr();
211 	ofbcopy(dname, OF_buf, l + 1);
212 	args.dname = OF_buf;
213 	if (openfirmware(&args) == -1)
214 		ret = -1;
215 	else
216 		ret = args.handle;
217 	ppc_mtmsr(s);
218 	return ret;
219 }
220 
221 void
222 OF_close(int handle)
223 {
224 	static struct {
225 		char *name;
226 		int nargs;
227 		int nreturns;
228 		int handle;
229 	} args = {
230 		"close",
231 		1,
232 		0,
233 	};
234 	uint32_t s;
235 
236 	s = ofw_msr();
237 	args.handle = handle;
238 	openfirmware(&args);
239 	ppc_mtmsr(s);
240 }
241 
242 /*
243  * This assumes that character devices don't read in multiples of PAGE_SIZE.
244  */
245 int
246 OF_read(int handle, void *addr, int len)
247 {
248 	static struct {
249 		char *name;
250 		int nargs;
251 		int nreturns;
252 		int ihandle;
253 		void *addr;
254 		int len;
255 		int actual;
256 	} args = {
257 		"read",
258 		3,
259 		1,
260 	};
261 	uint32_t s;
262 	int act = 0, l, ret;
263 
264 	s = ofw_msr();
265 	args.ihandle = handle;
266 	args.addr = OF_buf;
267 	for (; len > 0; len -= l, addr += l) {
268 		l = min(PAGE_SIZE, len);
269 		args.len = l;
270 		if (openfirmware(&args) == -1) {
271 			ret = -1;
272 			goto out;
273 		}
274 		if (args.actual > 0) {
275 			ofbcopy(OF_buf, addr, args.actual);
276 			act += args.actual;
277 		}
278 		if (args.actual < l) {
279 			if (act)
280 				ret = act;
281 			else
282 				ret = args.actual;
283 			goto out;
284 		}
285 	}
286 	ret = act;
287 out:
288 	ppc_mtmsr(s);
289 	return ret;
290 }
291 
292 int
293 OF_write(int handle, void *addr, int len)
294 {
295 	static struct {
296 		char *name;
297 		int nargs;
298 		int nreturns;
299 		int ihandle;
300 		void *addr;
301 		int len;
302 		int actual;
303 	} args = {
304 		"write",
305 		3,
306 		1,
307 	};
308 	uint32_t s;
309 	int act = 0, l, ret;
310 
311 	s = ofw_msr();
312 	args.ihandle = handle;
313 	args.addr = OF_buf;
314 	for (; len > 0; len -= l, addr += l) {
315 		l = min(PAGE_SIZE, len);
316 		ofbcopy(addr, OF_buf, l);
317 		args.len = l;
318 		if (openfirmware(&args) == -1) {
319 			ret = -1;
320 			goto out;
321 		}
322 		l = args.actual;
323 		act += l;
324 	}
325 	ret = act;
326 out:
327 	ppc_mtmsr(s);
328 	return ret;
329 }
330 
331 int
332 OF_seek(int handle, u_quad_t pos)
333 {
334 	static struct {
335 		char *name;
336 		int nargs;
337 		int nreturns;
338 		int handle;
339 		int poshi;
340 		int poslo;
341 		int status;
342 	} args = {
343 		"seek",
344 		3,
345 		1,
346 	};
347 	uint32_t s;
348 	int ret;
349 
350 	s = ofw_msr();
351 	args.handle = handle;
352 	args.poshi = (int)(pos >> 32);
353 	args.poslo = (int)pos;
354 	if (openfirmware(&args) == -1)
355 		ret = -1;
356 	else
357 		ret = args.status;
358 	ppc_mtmsr(s);
359 	return ret;
360 }
361