1/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 2 3/*- 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33/*- 34 * Copyright (C) 2000 Benno Rice. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58#include <sys/cdefs.h>
| 1/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai Exp $ */ 2 3/*- 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33/*- 34 * Copyright (C) 2000 Benno Rice. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58#include <sys/cdefs.h>
|
59__FBSDID("$FreeBSD: head/sys/dev/ofw/openfirm.c 171265 2007-07-06 00:47:44Z peter $");
| 59__FBSDID("$FreeBSD: head/sys/dev/ofw/ofw_standard.c 186347 2008-12-20 00:33:10Z nwhitehorn $");
|
60 61#include <sys/param.h> 62#include <sys/kernel.h> 63#include <sys/malloc.h> 64#include <sys/systm.h> 65 66#include <machine/stdarg.h> 67 68#include <dev/ofw/openfirm.h>
| 60 61#include <sys/param.h> 62#include <sys/kernel.h> 63#include <sys/malloc.h> 64#include <sys/systm.h> 65 66#include <machine/stdarg.h> 67 68#include <dev/ofw/openfirm.h>
|
| 69#include <dev/ofw/ofwvar.h> 70#include "ofw_if.h"
|
69
| 71
|
70MALLOC_DEFINE(M_OFWPROP, "openfirm", "Open Firmware properties");
| 72static void ofw_std_init(ofw_t ofw, void *openfirm); 73static int ofw_std_test(ofw_t ofw, const char *name); 74static int ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, 75 unsigned long *returns); 76static phandle_t ofw_std_peer(ofw_t ofw, phandle_t node); 77static phandle_t ofw_std_child(ofw_t ofw, phandle_t node); 78static phandle_t ofw_std_parent(ofw_t ofw, phandle_t node); 79static phandle_t ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance); 80static ssize_t ofw_std_getproplen(ofw_t ofw, phandle_t package, 81 const char *propname); 82static ssize_t ofw_std_getprop(ofw_t ofw, phandle_t package, 83 const char *propname, void *buf, size_t buflen); 84static int ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, 85 char *buf, size_t); 86static int ofw_std_setprop(ofw_t ofw, phandle_t package, char *propname, 87 void *buf, size_t len); 88static ssize_t ofw_std_canon(ofw_t ofw, const char *device, char *buf, 89 size_t len); 90static phandle_t ofw_std_finddevice(ofw_t ofw, const char *device); 91static ssize_t ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, 92 char *buf, size_t len); 93static ssize_t ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, 94 size_t len); 95static int ofw_std_call_method(ofw_t ofw, ihandle_t instance, 96 const char *method, int nargs, int nreturns, 97 unsigned long *args_and_returns); 98static ihandle_t ofw_std_open(ofw_t ofw, const char *device); 99static void ofw_std_close(ofw_t ofw, ihandle_t instance); 100static ssize_t ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, 101 size_t len); 102static ssize_t ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, 103 size_t len); 104static int ofw_std_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos); 105static caddr_t ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align); 106static void ofw_std_release(ofw_t ofw, void *virt, size_t size); 107static void ofw_std_enter(ofw_t ofw); 108static void ofw_std_exit(ofw_t ofw);
|
71
| 109
|
72static ihandle_t stdout;
| 110static ofw_method_t ofw_std_methods[] = { 111 OFWMETHOD(ofw_init, ofw_std_init), 112 OFWMETHOD(ofw_peer, ofw_std_peer), 113 OFWMETHOD(ofw_child, ofw_std_child), 114 OFWMETHOD(ofw_parent, ofw_std_parent), 115 OFWMETHOD(ofw_instance_to_package, ofw_std_instance_to_package), 116 OFWMETHOD(ofw_getproplen, ofw_std_getproplen), 117 OFWMETHOD(ofw_getprop, ofw_std_getprop), 118 OFWMETHOD(ofw_nextprop, ofw_std_nextprop), 119 OFWMETHOD(ofw_setprop, ofw_std_setprop), 120 OFWMETHOD(ofw_canon, ofw_std_canon), 121 OFWMETHOD(ofw_finddevice, ofw_std_finddevice), 122 OFWMETHOD(ofw_instance_to_path, ofw_std_instance_to_path), 123 OFWMETHOD(ofw_package_to_path, ofw_std_package_to_path),
|
73
| 124
|
74/* Initialiser */
| 125 OFWMETHOD(ofw_test, ofw_std_test), 126 OFWMETHOD(ofw_call_method, ofw_std_call_method), 127 OFWMETHOD(ofw_interpret, ofw_std_interpret), 128 OFWMETHOD(ofw_open, ofw_std_open), 129 OFWMETHOD(ofw_close, ofw_std_close), 130 OFWMETHOD(ofw_read, ofw_std_read), 131 OFWMETHOD(ofw_write, ofw_std_write), 132 OFWMETHOD(ofw_seek, ofw_std_seek), 133 OFWMETHOD(ofw_claim, ofw_std_claim), 134 OFWMETHOD(ofw_release, ofw_std_release), 135 OFWMETHOD(ofw_enter, ofw_std_enter), 136 OFWMETHOD(ofw_exit, ofw_std_exit),
|
75
| 137
|
76void 77OF_init(int (*openfirm)(void *)) 78{ 79 phandle_t chosen;
| 138 { 0, 0 } 139};
|
80
| 140
|
81 set_openfirm_callback(openfirm); 82 if ((chosen = OF_finddevice("/chosen")) == -1) 83 OF_exit(); 84 if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) 85 OF_exit(); 86}
| 141static ofw_def_t ofw_std = { 142 OFW_STD_DIRECT, 143 ofw_std_methods, 144 0 145}; 146OFW_DEF(ofw_std);
|
87
| 147
|
88void 89OF_printf(const char *fmt, ...) 90{ 91 va_list va; 92 char buf[1024];
| 148static int (*openfirmware)(void *);
|
93
| 149
|
94 va_start(va, fmt); 95 vsprintf(buf, fmt, va); 96 OF_write(stdout, buf, strlen(buf)); 97 va_end(va);
| 150/* Initialiser */ 151 152static void 153ofw_std_init(ofw_t ofw, void *openfirm) 154{ 155 openfirmware = (int (*)(void *))openfirm;
|
98} 99 100/* 101 * Generic functions 102 */ 103 104/* Test to see if a service exists. */
| 156} 157 158/* 159 * Generic functions 160 */ 161 162/* Test to see if a service exists. */
|
105int 106OF_test(char *name)
| 163static int 164ofw_std_test(ofw_t ofw, const char *name)
|
107{ 108 static struct { 109 cell_t name; 110 cell_t nargs; 111 cell_t nreturns; 112 cell_t service; 113 cell_t missing; 114 } args = { 115 (cell_t)"test", 116 1, 117 1, 118 }; 119 120 args.service = (cell_t)name; 121 if (openfirmware(&args) == -1) 122 return (-1); 123 return (args.missing); 124} 125
| 165{ 166 static struct { 167 cell_t name; 168 cell_t nargs; 169 cell_t nreturns; 170 cell_t service; 171 cell_t missing; 172 } args = { 173 (cell_t)"test", 174 1, 175 1, 176 }; 177 178 args.service = (cell_t)name; 179 if (openfirmware(&args) == -1) 180 return (-1); 181 return (args.missing); 182} 183
|
126int 127OF_interpret(char *cmd, int nreturns, ...)
| 184static int 185ofw_std_interpret(ofw_t ofw, const char *cmd, int nreturns, 186 unsigned long *returns)
|
128{
| 187{
|
129 va_list ap;
| |
130 static struct { 131 cell_t name; 132 cell_t nargs; 133 cell_t nreturns; 134 cell_t slot[16]; 135 } args = { 136 (cell_t)"interpret", 137 1, 138 }; 139 cell_t status;
| 188 static struct { 189 cell_t name; 190 cell_t nargs; 191 cell_t nreturns; 192 cell_t slot[16]; 193 } args = { 194 (cell_t)"interpret", 195 1, 196 }; 197 cell_t status;
|
140 int i = 0;
| 198 int i = 0, j = 0;
|
141
| 199
|
142 va_start(ap, nreturns);
| |
143 args.nreturns = ++nreturns; 144 args.slot[i++] = (cell_t)cmd;
| 200 args.nreturns = ++nreturns; 201 args.slot[i++] = (cell_t)cmd;
|
145 while (i < 1) 146 args.slot[i++] = va_arg(ap, cell_t);
| |
147 if (openfirmware(&args) == -1) {
| 202 if (openfirmware(&args) == -1) {
|
148 va_end(ap);
| |
149 return (-1); 150 } 151 status = args.slot[i++]; 152 while (i < 1 + nreturns)
| 203 return (-1); 204 } 205 status = args.slot[i++]; 206 while (i < 1 + nreturns)
|
153 *va_arg(ap, cell_t *) = args.slot[i++]; 154 va_end(ap);
| 207 returns[j] = args.slot[i++];
|
155 return (status); 156} 157
| 208 return (status); 209} 210
|
158/* Return firmware millisecond count. */ 159int 160OF_milliseconds() 161{ 162 static struct { 163 cell_t name; 164 cell_t nargs; 165 cell_t nreturns; 166 cell_t ms; 167 } args = { 168 (cell_t)"milliseconds", 169 0, 170 1, 171 }; 172 173 openfirmware(&args); 174 return (args.ms); 175} 176
| |
177/* 178 * Device tree functions 179 */ 180 181/* Return the next sibling of this node or 0. */
| 211/* 212 * Device tree functions 213 */ 214 215/* Return the next sibling of this node or 0. */
|
182phandle_t 183OF_peer(phandle_t node)
| 216static phandle_t 217ofw_std_peer(ofw_t ofw, phandle_t node)
|
184{ 185 static struct { 186 cell_t name; 187 cell_t nargs; 188 cell_t nreturns; 189 cell_t node; 190 cell_t next; 191 } args = { 192 (cell_t)"peer", 193 1, 194 1, 195 }; 196 197 args.node = node; 198 if (openfirmware(&args) == -1) 199 return (-1); 200 return (args.next); 201} 202 203/* Return the first child of this node or 0. */
| 218{ 219 static struct { 220 cell_t name; 221 cell_t nargs; 222 cell_t nreturns; 223 cell_t node; 224 cell_t next; 225 } args = { 226 (cell_t)"peer", 227 1, 228 1, 229 }; 230 231 args.node = node; 232 if (openfirmware(&args) == -1) 233 return (-1); 234 return (args.next); 235} 236 237/* Return the first child of this node or 0. */
|
204phandle_t 205OF_child(phandle_t node)
| 238static phandle_t 239ofw_std_child(ofw_t ofw, phandle_t node)
|
206{ 207 static struct { 208 cell_t name; 209 cell_t nargs; 210 cell_t nreturns; 211 cell_t node; 212 cell_t child; 213 } args = { 214 (cell_t)"child", 215 1, 216 1, 217 }; 218 219 args.node = node; 220 if (openfirmware(&args) == -1) 221 return (-1); 222 return (args.child); 223} 224 225/* Return the parent of this node or 0. */
| 240{ 241 static struct { 242 cell_t name; 243 cell_t nargs; 244 cell_t nreturns; 245 cell_t node; 246 cell_t child; 247 } args = { 248 (cell_t)"child", 249 1, 250 1, 251 }; 252 253 args.node = node; 254 if (openfirmware(&args) == -1) 255 return (-1); 256 return (args.child); 257} 258 259/* Return the parent of this node or 0. */
|
226phandle_t 227OF_parent(phandle_t node)
| 260static phandle_t 261ofw_std_parent(ofw_t ofw, phandle_t node)
|
228{ 229 static struct { 230 cell_t name; 231 cell_t nargs; 232 cell_t nreturns; 233 cell_t node; 234 cell_t parent; 235 } args = { 236 (cell_t)"parent", 237 1, 238 1, 239 }; 240 241 args.node = node; 242 if (openfirmware(&args) == -1) 243 return (-1); 244 return (args.parent); 245} 246 247/* Return the package handle that corresponds to an instance handle. */
| 262{ 263 static struct { 264 cell_t name; 265 cell_t nargs; 266 cell_t nreturns; 267 cell_t node; 268 cell_t parent; 269 } args = { 270 (cell_t)"parent", 271 1, 272 1, 273 }; 274 275 args.node = node; 276 if (openfirmware(&args) == -1) 277 return (-1); 278 return (args.parent); 279} 280 281/* Return the package handle that corresponds to an instance handle. */
|
248phandle_t 249OF_instance_to_package(ihandle_t instance)
| 282static phandle_t 283ofw_std_instance_to_package(ofw_t ofw, ihandle_t instance)
|
250{ 251 static struct { 252 cell_t name; 253 cell_t nargs; 254 cell_t nreturns; 255 cell_t instance; 256 cell_t package; 257 } args = { 258 (cell_t)"instance-to-package", 259 1, 260 1, 261 }; 262 263 args.instance = instance; 264 if (openfirmware(&args) == -1) 265 return (-1); 266 return (args.package); 267} 268 269/* Get the length of a property of a package. */
| 284{ 285 static struct { 286 cell_t name; 287 cell_t nargs; 288 cell_t nreturns; 289 cell_t instance; 290 cell_t package; 291 } args = { 292 (cell_t)"instance-to-package", 293 1, 294 1, 295 }; 296 297 args.instance = instance; 298 if (openfirmware(&args) == -1) 299 return (-1); 300 return (args.package); 301} 302 303/* Get the length of a property of a package. */
|
270int 271OF_getproplen(phandle_t package, char *propname)
| 304static ssize_t 305ofw_std_getproplen(ofw_t ofw, phandle_t package, const char *propname)
|
272{ 273 static struct { 274 cell_t name; 275 cell_t nargs; 276 cell_t nreturns; 277 cell_t package; 278 cell_t propname; 279 cell_t proplen; 280 } args = { 281 (cell_t)"getproplen", 282 2, 283 1, 284 }; 285 286 args.package = package; 287 args.propname = (cell_t)propname; 288 if (openfirmware(&args) == -1) 289 return (-1); 290 return (args.proplen); 291} 292 293/* Get the value of a property of a package. */
| 306{ 307 static struct { 308 cell_t name; 309 cell_t nargs; 310 cell_t nreturns; 311 cell_t package; 312 cell_t propname; 313 cell_t proplen; 314 } args = { 315 (cell_t)"getproplen", 316 2, 317 1, 318 }; 319 320 args.package = package; 321 args.propname = (cell_t)propname; 322 if (openfirmware(&args) == -1) 323 return (-1); 324 return (args.proplen); 325} 326 327/* Get the value of a property of a package. */
|
294int 295OF_getprop(phandle_t package, char *propname, void *buf, int buflen)
| 328static ssize_t 329ofw_std_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, 330 size_t buflen)
|
296{ 297 static struct { 298 cell_t name; 299 cell_t nargs; 300 cell_t nreturns; 301 cell_t package; 302 cell_t propname; 303 cell_t buf; 304 cell_t buflen; 305 cell_t size; 306 } args = { 307 (cell_t)"getprop", 308 4, 309 1, 310 }; 311 312 args.package = package; 313 args.propname = (cell_t)propname; 314 args.buf = (cell_t)buf; 315 args.buflen = buflen; 316 if (openfirmware(&args) == -1) 317 return (-1); 318 return (args.size); 319} 320
| 331{ 332 static struct { 333 cell_t name; 334 cell_t nargs; 335 cell_t nreturns; 336 cell_t package; 337 cell_t propname; 338 cell_t buf; 339 cell_t buflen; 340 cell_t size; 341 } args = { 342 (cell_t)"getprop", 343 4, 344 1, 345 }; 346 347 args.package = package; 348 args.propname = (cell_t)propname; 349 args.buf = (cell_t)buf; 350 args.buflen = buflen; 351 if (openfirmware(&args) == -1) 352 return (-1); 353 return (args.size); 354} 355
|
321/* 322 * Store the value of a property of a package into newly allocated memory 323 * (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a 324 * single element, the number of elements is return in number. 325 */ 326int 327OF_getprop_alloc(phandle_t package, char *propname, int elsz, void **buf) 328{ 329 int len; 330 331 *buf = NULL; 332 if ((len = OF_getproplen(package, propname)) == -1 || 333 len % elsz != 0) 334 return (-1); 335 336 *buf = malloc(len, M_OFWPROP, M_WAITOK); 337 if (OF_getprop(package, propname, *buf, len) == -1) { 338 free(*buf, M_OFWPROP); 339 *buf = NULL; 340 return (-1); 341 } 342 return (len / elsz); 343} 344
| |
345/* Get the next property of a package. */
| 356/* Get the next property of a package. */
|
346int 347OF_nextprop(phandle_t package, char *previous, char *buf)
| 357static int 358ofw_std_nextprop(ofw_t ofw, phandle_t package, const char *previous, char *buf, 359 size_t size)
|
348{ 349 static struct { 350 cell_t name; 351 cell_t nargs; 352 cell_t nreturns; 353 cell_t package; 354 cell_t previous; 355 cell_t buf; 356 cell_t flag; 357 } args = { 358 (cell_t)"nextprop", 359 3, 360 1, 361 }; 362 363 args.package = package; 364 args.previous = (cell_t)previous; 365 args.buf = (cell_t)buf; 366 if (openfirmware(&args) == -1) 367 return (-1); 368 return (args.flag); 369} 370 371/* Set the value of a property of a package. */ 372/* XXX Has a bug on FirePower */
| 360{ 361 static struct { 362 cell_t name; 363 cell_t nargs; 364 cell_t nreturns; 365 cell_t package; 366 cell_t previous; 367 cell_t buf; 368 cell_t flag; 369 } args = { 370 (cell_t)"nextprop", 371 3, 372 1, 373 }; 374 375 args.package = package; 376 args.previous = (cell_t)previous; 377 args.buf = (cell_t)buf; 378 if (openfirmware(&args) == -1) 379 return (-1); 380 return (args.flag); 381} 382 383/* Set the value of a property of a package. */ 384/* XXX Has a bug on FirePower */
|
373int 374OF_setprop(phandle_t package, char *propname, void *buf, int len)
| 385static int 386ofw_std_setprop(ofw_t ofw, phandle_t package, char *propname, void *buf, 387 size_t len)
|
375{ 376 static struct { 377 cell_t name; 378 cell_t nargs; 379 cell_t nreturns; 380 cell_t package; 381 cell_t propname; 382 cell_t buf; 383 cell_t len; 384 cell_t size; 385 } args = { 386 (cell_t)"setprop", 387 4, 388 1, 389 }; 390 391 args.package = package; 392 args.propname = (cell_t)propname; 393 args.buf = (cell_t)buf; 394 args.len = len; 395 if (openfirmware(&args) == -1) 396 return (-1); 397 return (args.size); 398} 399 400/* Convert a device specifier to a fully qualified pathname. */
| 388{ 389 static struct { 390 cell_t name; 391 cell_t nargs; 392 cell_t nreturns; 393 cell_t package; 394 cell_t propname; 395 cell_t buf; 396 cell_t len; 397 cell_t size; 398 } args = { 399 (cell_t)"setprop", 400 4, 401 1, 402 }; 403 404 args.package = package; 405 args.propname = (cell_t)propname; 406 args.buf = (cell_t)buf; 407 args.len = len; 408 if (openfirmware(&args) == -1) 409 return (-1); 410 return (args.size); 411} 412 413/* Convert a device specifier to a fully qualified pathname. */
|
401int 402OF_canon(const char *device, char *buf, int len)
| 414static ssize_t 415ofw_std_canon(ofw_t ofw, const char *device, char *buf, size_t len)
|
403{ 404 static struct { 405 cell_t name; 406 cell_t nargs; 407 cell_t nreturns; 408 cell_t device; 409 cell_t buf; 410 cell_t len; 411 cell_t size; 412 } args = { 413 (cell_t)"canon", 414 3, 415 1, 416 }; 417 418 args.device = (cell_t)device; 419 args.buf = (cell_t)buf; 420 args.len = len; 421 if (openfirmware(&args) == -1) 422 return (-1); 423 return (args.size); 424} 425 426/* Return a package handle for the specified device. */
| 416{ 417 static struct { 418 cell_t name; 419 cell_t nargs; 420 cell_t nreturns; 421 cell_t device; 422 cell_t buf; 423 cell_t len; 424 cell_t size; 425 } args = { 426 (cell_t)"canon", 427 3, 428 1, 429 }; 430 431 args.device = (cell_t)device; 432 args.buf = (cell_t)buf; 433 args.len = len; 434 if (openfirmware(&args) == -1) 435 return (-1); 436 return (args.size); 437} 438 439/* Return a package handle for the specified device. */
|
427phandle_t 428OF_finddevice(const char *device)
| 440static phandle_t 441ofw_std_finddevice(ofw_t ofw, const char *device)
|
429{ 430 static struct { 431 cell_t name; 432 cell_t nargs; 433 cell_t nreturns; 434 cell_t device; 435 cell_t package; 436 } args = { 437 (cell_t)"finddevice", 438 1, 439 1, 440 }; 441 442 args.device = (cell_t)device; 443 if (openfirmware(&args) == -1) 444 return (-1); 445 return (args.package); 446} 447 448/* Return the fully qualified pathname corresponding to an instance. */
| 442{ 443 static struct { 444 cell_t name; 445 cell_t nargs; 446 cell_t nreturns; 447 cell_t device; 448 cell_t package; 449 } args = { 450 (cell_t)"finddevice", 451 1, 452 1, 453 }; 454 455 args.device = (cell_t)device; 456 if (openfirmware(&args) == -1) 457 return (-1); 458 return (args.package); 459} 460 461/* Return the fully qualified pathname corresponding to an instance. */
|
449int 450OF_instance_to_path(ihandle_t instance, char *buf, int len)
| 462static ssize_t 463ofw_std_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len)
|
451{ 452 static struct { 453 cell_t name; 454 cell_t nargs; 455 cell_t nreturns; 456 cell_t instance; 457 cell_t buf; 458 cell_t len; 459 cell_t size; 460 } args = { 461 (cell_t)"instance-to-path", 462 3, 463 1, 464 }; 465 466 args.instance = instance; 467 args.buf = (cell_t)buf; 468 args.len = len; 469 if (openfirmware(&args) == -1) 470 return (-1); 471 return (args.size); 472} 473 474/* Return the fully qualified pathname corresponding to a package. */
| 464{ 465 static struct { 466 cell_t name; 467 cell_t nargs; 468 cell_t nreturns; 469 cell_t instance; 470 cell_t buf; 471 cell_t len; 472 cell_t size; 473 } args = { 474 (cell_t)"instance-to-path", 475 3, 476 1, 477 }; 478 479 args.instance = instance; 480 args.buf = (cell_t)buf; 481 args.len = len; 482 if (openfirmware(&args) == -1) 483 return (-1); 484 return (args.size); 485} 486 487/* Return the fully qualified pathname corresponding to a package. */
|
475int 476OF_package_to_path(phandle_t package, char *buf, int len)
| 488static ssize_t 489ofw_std_package_to_path(ofw_t ofw, phandle_t package, char *buf, size_t len)
|
477{ 478 static struct { 479 cell_t name; 480 cell_t nargs; 481 cell_t nreturns; 482 cell_t package; 483 cell_t buf; 484 cell_t len; 485 cell_t size; 486 } args = { 487 (cell_t)"package-to-path", 488 3, 489 1, 490 }; 491 492 args.package = package; 493 args.buf = (cell_t)buf; 494 args.len = len; 495 if (openfirmware(&args) == -1) 496 return (-1); 497 return (args.size); 498} 499 500/* Call the method in the scope of a given instance. */
| 490{ 491 static struct { 492 cell_t name; 493 cell_t nargs; 494 cell_t nreturns; 495 cell_t package; 496 cell_t buf; 497 cell_t len; 498 cell_t size; 499 } args = { 500 (cell_t)"package-to-path", 501 3, 502 1, 503 }; 504 505 args.package = package; 506 args.buf = (cell_t)buf; 507 args.len = len; 508 if (openfirmware(&args) == -1) 509 return (-1); 510 return (args.size); 511} 512 513/* Call the method in the scope of a given instance. */
|
501int 502OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...)
| 514static int 515ofw_std_call_method(ofw_t ofw, ihandle_t instance, const char *method, 516 int nargs, int nreturns, unsigned long *args_and_returns)
|
503{
| 517{
|
504 va_list ap;
| |
505 static struct { 506 cell_t name; 507 cell_t nargs; 508 cell_t nreturns; 509 cell_t method; 510 cell_t instance; 511 cell_t args_n_results[12]; 512 } args = { 513 (cell_t)"call-method", 514 2, 515 1, 516 }; 517 cell_t *cp;
| 518 static struct { 519 cell_t name; 520 cell_t nargs; 521 cell_t nreturns; 522 cell_t method; 523 cell_t instance; 524 cell_t args_n_results[12]; 525 } args = { 526 (cell_t)"call-method", 527 2, 528 1, 529 }; 530 cell_t *cp;
|
| 531 unsigned long *ap;
|
518 int n; 519 520 if (nargs > 6) 521 return (-1); 522 args.nargs = nargs + 2; 523 args.nreturns = nreturns + 1; 524 args.method = (cell_t)method; 525 args.instance = instance;
| 532 int n; 533 534 if (nargs > 6) 535 return (-1); 536 args.nargs = nargs + 2; 537 args.nreturns = nreturns + 1; 538 args.method = (cell_t)method; 539 args.instance = instance;
|
526 va_start(ap, nreturns);
| 540 541 ap = args_and_returns;
|
527 for (cp = args.args_n_results + (n = nargs); --n >= 0;)
| 542 for (cp = args.args_n_results + (n = nargs); --n >= 0;)
|
528 *--cp = va_arg(ap, cell_t);
| 543 *--cp = *(ap++);
|
529 if (openfirmware(&args) == -1) 530 return (-1); 531 if (args.args_n_results[nargs]) 532 return (args.args_n_results[nargs]); 533 for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
| 544 if (openfirmware(&args) == -1) 545 return (-1); 546 if (args.args_n_results[nargs]) 547 return (args.args_n_results[nargs]); 548 for (cp = args.args_n_results + nargs + (n = args.nreturns); --n > 0;)
|
534 *va_arg(ap, cell_t *) = *--cp; 535 va_end(ap);
| 549 *(ap++) = *--cp;
|
536 return (0); 537} 538 539/* 540 * Device I/O functions 541 */ 542 543/* Open an instance for a device. */
| 550 return (0); 551} 552 553/* 554 * Device I/O functions 555 */ 556 557/* Open an instance for a device. */
|
544ihandle_t 545OF_open(char *device)
| 558static ihandle_t 559ofw_std_open(ofw_t ofw, const char *device)
|
546{ 547 static struct { 548 cell_t name; 549 cell_t nargs; 550 cell_t nreturns; 551 cell_t device; 552 cell_t instance; 553 } args = { 554 (cell_t)"open", 555 1, 556 1, 557 }; 558 559 args.device = (cell_t)device; 560 if (openfirmware(&args) == -1 || args.instance == 0) { 561 return (-1); 562 } 563 return (args.instance); 564} 565 566/* Close an instance. */
| 560{ 561 static struct { 562 cell_t name; 563 cell_t nargs; 564 cell_t nreturns; 565 cell_t device; 566 cell_t instance; 567 } args = { 568 (cell_t)"open", 569 1, 570 1, 571 }; 572 573 args.device = (cell_t)device; 574 if (openfirmware(&args) == -1 || args.instance == 0) { 575 return (-1); 576 } 577 return (args.instance); 578} 579 580/* Close an instance. */
|
567void 568OF_close(ihandle_t instance)
| 581static void 582ofw_std_close(ofw_t ofw, ihandle_t instance)
|
569{ 570 static struct { 571 cell_t name; 572 cell_t nargs; 573 cell_t nreturns; 574 cell_t instance; 575 } args = { 576 (cell_t)"close", 577 1, 578 }; 579 580 args.instance = instance; 581 openfirmware(&args); 582} 583 584/* Read from an instance. */
| 583{ 584 static struct { 585 cell_t name; 586 cell_t nargs; 587 cell_t nreturns; 588 cell_t instance; 589 } args = { 590 (cell_t)"close", 591 1, 592 }; 593 594 args.instance = instance; 595 openfirmware(&args); 596} 597 598/* Read from an instance. */
|
585int 586OF_read(ihandle_t instance, void *addr, int len)
| 599static ssize_t 600ofw_std_read(ofw_t ofw, ihandle_t instance, void *addr, size_t len)
|
587{ 588 static struct { 589 cell_t name; 590 cell_t nargs; 591 cell_t nreturns; 592 cell_t instance; 593 cell_t addr; 594 cell_t len; 595 cell_t actual; 596 } args = { 597 (cell_t)"read", 598 3, 599 1, 600 }; 601 602 args.instance = instance; 603 args.addr = (cell_t)addr; 604 args.len = len; 605 if (openfirmware(&args) == -1) 606 return (-1); 607 608 return (args.actual); 609} 610 611/* Write to an instance. */
| 601{ 602 static struct { 603 cell_t name; 604 cell_t nargs; 605 cell_t nreturns; 606 cell_t instance; 607 cell_t addr; 608 cell_t len; 609 cell_t actual; 610 } args = { 611 (cell_t)"read", 612 3, 613 1, 614 }; 615 616 args.instance = instance; 617 args.addr = (cell_t)addr; 618 args.len = len; 619 if (openfirmware(&args) == -1) 620 return (-1); 621 622 return (args.actual); 623} 624 625/* Write to an instance. */
|
612int 613OF_write(ihandle_t instance, void *addr, int len)
| 626static ssize_t 627ofw_std_write(ofw_t ofw, ihandle_t instance, const void *addr, size_t len)
|
614{ 615 static struct { 616 cell_t name; 617 cell_t nargs; 618 cell_t nreturns; 619 cell_t instance; 620 cell_t addr; 621 cell_t len; 622 cell_t actual; 623 } args = { 624 (cell_t)"write", 625 3, 626 1, 627 }; 628 629 args.instance = instance; 630 args.addr = (cell_t)addr; 631 args.len = len; 632 if (openfirmware(&args) == -1) 633 return (-1); 634 return (args.actual); 635} 636 637/* Seek to a position. */
| 628{ 629 static struct { 630 cell_t name; 631 cell_t nargs; 632 cell_t nreturns; 633 cell_t instance; 634 cell_t addr; 635 cell_t len; 636 cell_t actual; 637 } args = { 638 (cell_t)"write", 639 3, 640 1, 641 }; 642 643 args.instance = instance; 644 args.addr = (cell_t)addr; 645 args.len = len; 646 if (openfirmware(&args) == -1) 647 return (-1); 648 return (args.actual); 649} 650 651/* Seek to a position. */
|
638int 639OF_seek(ihandle_t instance, u_int64_t pos)
| 652static int 653ofw_std_seek(ofw_t ofw, ihandle_t instance, u_int64_t pos)
|
640{ 641 static struct { 642 cell_t name; 643 cell_t nargs; 644 cell_t nreturns; 645 cell_t instance; 646 cell_t poshi; 647 cell_t poslo; 648 cell_t status; 649 } args = { 650 (cell_t)"seek", 651 3, 652 1, 653 }; 654 655 args.instance = instance; 656 args.poshi = pos >> 32; 657 args.poslo = pos; 658 if (openfirmware(&args) == -1) 659 return (-1); 660 return (args.status); 661} 662 663/* 664 * Memory functions 665 */ 666 667/* Claim an area of memory. */
| 654{ 655 static struct { 656 cell_t name; 657 cell_t nargs; 658 cell_t nreturns; 659 cell_t instance; 660 cell_t poshi; 661 cell_t poslo; 662 cell_t status; 663 } args = { 664 (cell_t)"seek", 665 3, 666 1, 667 }; 668 669 args.instance = instance; 670 args.poshi = pos >> 32; 671 args.poslo = pos; 672 if (openfirmware(&args) == -1) 673 return (-1); 674 return (args.status); 675} 676 677/* 678 * Memory functions 679 */ 680 681/* Claim an area of memory. */
|
668void * 669OF_claim(void *virt, u_int size, u_int align)
| 682static caddr_t 683ofw_std_claim(ofw_t ofw, void *virt, size_t size, u_int align)
|
670{ 671 static struct { 672 cell_t name; 673 cell_t nargs; 674 cell_t nreturns; 675 cell_t virt; 676 cell_t size; 677 cell_t align; 678 cell_t baseaddr; 679 } args = { 680 (cell_t)"claim", 681 3, 682 1, 683 }; 684 685 args.virt = (cell_t)virt; 686 args.size = size; 687 args.align = align; 688 if (openfirmware(&args) == -1) 689 return ((void *)-1); 690 return ((void *)args.baseaddr); 691} 692 693/* Release an area of memory. */
| 684{ 685 static struct { 686 cell_t name; 687 cell_t nargs; 688 cell_t nreturns; 689 cell_t virt; 690 cell_t size; 691 cell_t align; 692 cell_t baseaddr; 693 } args = { 694 (cell_t)"claim", 695 3, 696 1, 697 }; 698 699 args.virt = (cell_t)virt; 700 args.size = size; 701 args.align = align; 702 if (openfirmware(&args) == -1) 703 return ((void *)-1); 704 return ((void *)args.baseaddr); 705} 706 707/* Release an area of memory. */
|
694void 695OF_release(void *virt, u_int size)
| 708static void 709ofw_std_release(ofw_t ofw, void *virt, size_t size)
|
696{ 697 static struct { 698 cell_t name; 699 cell_t nargs; 700 cell_t nreturns; 701 cell_t virt; 702 cell_t size; 703 } args = { 704 (cell_t)"release", 705 2, 706 }; 707 708 args.virt = (cell_t)virt; 709 args.size = size; 710 openfirmware(&args); 711} 712 713/* 714 * Control transfer functions 715 */ 716
| 710{ 711 static struct { 712 cell_t name; 713 cell_t nargs; 714 cell_t nreturns; 715 cell_t virt; 716 cell_t size; 717 } args = { 718 (cell_t)"release", 719 2, 720 }; 721 722 args.virt = (cell_t)virt; 723 args.size = size; 724 openfirmware(&args); 725} 726 727/* 728 * Control transfer functions 729 */ 730
|
717/* Reset the system and call "boot <bootspec>". */ 718void 719OF_boot(char *bootspec) 720{ 721 static struct { 722 cell_t name; 723 cell_t nargs; 724 cell_t nreturns; 725 cell_t bootspec; 726 } args = { 727 (cell_t)"boot", 728 1, 729 }; 730 731 args.bootspec = (cell_t)bootspec; 732 openfirmware(&args); 733 for (;;) /* just in case */ 734 ; 735} 736
| |
737/* Suspend and drop back to the Open Firmware interface. */
| 731/* Suspend and drop back to the Open Firmware interface. */
|
738void 739OF_enter()
| 732static void 733ofw_std_enter(ofw_t ofw)
|
740{ 741 static struct { 742 cell_t name; 743 cell_t nargs; 744 cell_t nreturns; 745 } args = { 746 (cell_t)"enter", 747 }; 748 749 openfirmware(&args); 750 /* We may come back. */ 751} 752 753/* Shut down and drop back to the Open Firmware interface. */
| 734{ 735 static struct { 736 cell_t name; 737 cell_t nargs; 738 cell_t nreturns; 739 } args = { 740 (cell_t)"enter", 741 }; 742 743 openfirmware(&args); 744 /* We may come back. */ 745} 746 747/* Shut down and drop back to the Open Firmware interface. */
|
754void 755OF_exit()
| 748static void 749ofw_std_exit(ofw_t ofw)
|
756{ 757 static struct { 758 cell_t name; 759 cell_t nargs; 760 cell_t nreturns; 761 } args = { 762 (cell_t)"exit", 763 }; 764 765 openfirmware(&args); 766 for (;;) /* just in case */ 767 ; 768} 769
| 750{ 751 static struct { 752 cell_t name; 753 cell_t nargs; 754 cell_t nreturns; 755 } args = { 756 (cell_t)"exit", 757 }; 758 759 openfirmware(&args); 760 for (;;) /* just in case */ 761 ; 762} 763
|
770/* Free <size> bytes starting at <virt>, then call <entry> with <arg>. */ 771#if 0 772void 773OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) 774{ 775 static struct { 776 cell_t name; 777 cell_t nargs; 778 cell_t nreturns; 779 cell_t virt; 780 cell_t size; 781 cell_t entry; 782 cell_t arg; 783 cell_t len; 784 } args = { 785 (cell_t)"chain", 786 5, 787 }; 788 789 args.virt = (cell_t)virt; 790 args.size = size; 791 args.entry = (cell_t)entry; 792 args.arg = (cell_t)arg; 793 args.len = len; 794 openfirmware(&args); 795} 796#else 797void 798OF_chain(void *virt, u_int size, 799 void (*entry)(void *, u_int, void *, void *, u_int), void *arg, u_int len) 800{ 801 /* 802 * This is a REALLY dirty hack till the firmware gets this going 803 */ 804#if 0 805 if (size > 0) 806 OF_release(virt, size); 807#endif 808 entry(0, 0, openfirmware, arg, len); 809} 810#endif
| |
| |