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