1 /* $OpenBSD: opendev.c,v 1.9 2006/03/09 23:06:19 miod 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/psl.h> 38 39 #include <dev/ofw/openfirm.h> 40 41 extern void ofw_stack(void); 42 extern void ofbcopy(const void *, void *, size_t); 43 44 int 45 OF_instance_to_package(int ihandle) 46 { 47 static struct { 48 char *name; 49 int nargs; 50 int nreturns; 51 int ihandle; 52 int phandle; 53 } args = { 54 "instance-to-package", 55 1, 56 1, 57 }; 58 59 ofw_stack(); 60 args.ihandle = ihandle; 61 if (openfirmware(&args) == -1) 62 return -1; 63 return args.phandle; 64 } 65 66 int 67 OF_package_to_path(int phandle, char *buf, int buflen) 68 { 69 static struct { 70 char *name; 71 int nargs; 72 int nreturns; 73 int phandle; 74 char *buf; 75 int buflen; 76 int length; 77 } args = { 78 "package-to-path", 79 3, 80 1, 81 }; 82 83 ofw_stack(); 84 if (buflen > PAGE_SIZE) 85 return -1; 86 args.phandle = phandle; 87 args.buf = OF_buf; 88 args.buflen = buflen; 89 if (openfirmware(&args) < 0) 90 return -1; 91 if (args.length > 0) 92 ofbcopy(OF_buf, buf, args.length); 93 return args.length; 94 } 95 96 97 int 98 OF_call_method(char *method, int ihandle, int nargs, int nreturns, ...) 99 { 100 va_list ap; 101 static struct { 102 char *name; 103 int nargs; 104 int nreturns; 105 char *method; 106 int ihandle; 107 int args_n_results[12]; 108 } args = { 109 "call-method", 110 2, 111 1, 112 }; 113 int *ip, n; 114 115 if (nargs > 6) 116 return -1; 117 args.nargs = nargs + 2; 118 args.nreturns = nreturns + 1; 119 args.method = method; 120 args.ihandle = ihandle; 121 va_start(ap, nreturns); 122 for (ip = args.args_n_results + (n = nargs); --n >= 0;) 123 *--ip = va_arg(ap, int); 124 ofw_stack(); 125 if (openfirmware(&args) == -1) { 126 va_end(ap); 127 return -1; 128 } 129 if (args.args_n_results[nargs]) { 130 va_end(ap); 131 return args.args_n_results[nargs]; 132 } 133 for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) 134 *va_arg(ap, int *) = *--ip; 135 va_end(ap); 136 return 0; 137 } 138 int 139 OF_call_method_1(char *method, int ihandle, int nargs, ...) 140 { 141 va_list ap; 142 static struct { 143 char *name; 144 int nargs; 145 int nreturns; 146 char *method; 147 int ihandle; 148 int args_n_results[8]; 149 } args = { 150 "call-method", 151 2, 152 2, 153 }; 154 int *ip, n; 155 156 if (nargs > 6) 157 return -1; 158 args.nargs = nargs + 2; 159 args.method = method; 160 args.ihandle = ihandle; 161 va_start(ap, nargs); 162 for (ip = args.args_n_results + (n = nargs); --n >= 0;) 163 *--ip = va_arg(ap, int); 164 va_end(ap); 165 ofw_stack(); 166 if (openfirmware(&args) == -1) 167 return -1; 168 if (args.args_n_results[nargs]) 169 return -1; 170 return args.args_n_results[nargs + 1]; 171 } 172 173 int 174 OF_open(char *dname) 175 { 176 static struct { 177 char *name; 178 int nargs; 179 int nreturns; 180 char *dname; 181 int handle; 182 } args = { 183 "open", 184 1, 185 1, 186 }; 187 int l; 188 189 ofw_stack(); 190 if ((l = strlen(dname)) >= PAGE_SIZE) 191 return -1; 192 ofbcopy(dname, OF_buf, l + 1); 193 args.dname = OF_buf; 194 if (openfirmware(&args) == -1) 195 return -1; 196 return args.handle; 197 } 198 199 void 200 OF_close(int handle) 201 { 202 static struct { 203 char *name; 204 int nargs; 205 int nreturns; 206 int handle; 207 } args = { 208 "close", 209 1, 210 0, 211 }; 212 213 ofw_stack(); 214 args.handle = handle; 215 openfirmware(&args); 216 } 217 218 /* 219 * This assumes that character devices don't read in multiples of PAGE_SIZE. 220 */ 221 int 222 OF_read(int handle, void *addr, int len) 223 { 224 static struct { 225 char *name; 226 int nargs; 227 int nreturns; 228 int ihandle; 229 void *addr; 230 int len; 231 int actual; 232 } args = { 233 "read", 234 3, 235 1, 236 }; 237 int l, act = 0; 238 239 ofw_stack(); 240 args.ihandle = handle; 241 args.addr = OF_buf; 242 for (; len > 0; len -= l, addr += l) { 243 l = min(PAGE_SIZE, len); 244 args.len = l; 245 if (openfirmware(&args) == -1) 246 return -1; 247 if (args.actual > 0) { 248 ofbcopy(OF_buf, addr, args.actual); 249 act += args.actual; 250 } 251 if (args.actual < l) { 252 if (act) 253 return act; 254 else 255 return args.actual; 256 } 257 } 258 return act; 259 } 260 261 int 262 OF_write(int handle, void *addr, int len) 263 { 264 static struct { 265 char *name; 266 int nargs; 267 int nreturns; 268 int ihandle; 269 void *addr; 270 int len; 271 int actual; 272 } args = { 273 "write", 274 3, 275 1, 276 }; 277 int l, act = 0; 278 279 ofw_stack(); 280 args.ihandle = handle; 281 args.addr = OF_buf; 282 for (; len > 0; len -= l, addr += l) { 283 l = min(PAGE_SIZE, len); 284 ofbcopy(addr, OF_buf, l); 285 args.len = l; 286 if (openfirmware(&args) == -1) 287 return -1; 288 l = args.actual; 289 act += l; 290 } 291 return act; 292 } 293 294 int 295 OF_seek(int handle, u_quad_t pos) 296 { 297 static struct { 298 char *name; 299 int nargs; 300 int nreturns; 301 int handle; 302 int poshi; 303 int poslo; 304 int status; 305 } args = { 306 "seek", 307 3, 308 1, 309 }; 310 311 ofw_stack(); 312 args.handle = handle; 313 args.poshi = (int)(pos >> 32); 314 args.poslo = (int)pos; 315 if (openfirmware(&args) == -1) 316 return -1; 317 return args.status; 318 } 319