1 1.3 tsutsui /* $NetBSD: promlib.c,v 1.3 2011/05/21 15:50:42 tsutsui Exp $ */ 2 1.1 cdi 3 1.1 cdi /*- 4 1.1 cdi * Copyright (c) 2005 The NetBSD Foundation, Inc. 5 1.1 cdi * All rights reserved. 6 1.1 cdi * 7 1.1 cdi * This code is derived from software contributed to The NetBSD Foundation 8 1.1 cdi * by Paul Kranenburg. 9 1.1 cdi * 10 1.1 cdi * Redistribution and use in source and binary forms, with or without 11 1.1 cdi * modification, are permitted provided that the following conditions 12 1.1 cdi * are met: 13 1.1 cdi * 1. Redistributions of source code must retain the above copyright 14 1.1 cdi * notice, this list of conditions and the following disclaimer. 15 1.1 cdi * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 cdi * notice, this list of conditions and the following disclaimer in the 17 1.1 cdi * documentation and/or other materials provided with the distribution. 18 1.1 cdi * 19 1.1 cdi * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 cdi * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 cdi * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 cdi * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 cdi * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 cdi * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 cdi * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 cdi * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 cdi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 cdi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 cdi * POSSIBILITY OF SUCH DAMAGE. 30 1.1 cdi */ 31 1.1 cdi 32 1.1 cdi /* 33 1.1 cdi * OPENPROM functions. These are here mainly to hide the OPENPROM interface 34 1.1 cdi * from the rest of the kernel. 35 1.1 cdi */ 36 1.1 cdi 37 1.1 cdi #include <sys/types.h> 38 1.1 cdi #include <machine/promlib.h> 39 1.1 cdi 40 1.3 tsutsui #include <lib/libsa/stand.h> 41 1.3 tsutsui #include <lib/libkern/libkern.h> 42 1.3 tsutsui 43 1.1 cdi #include "openfirm.h" 44 1.1 cdi 45 1.1 cdi 46 1.1 cdi void *romp; 47 1.1 cdi struct promops promops; 48 1.1 cdi 49 1.1 cdi 50 1.1 cdi static void 51 1.1 cdi openfirmware_fatal(void) 52 1.1 cdi { 53 1.1 cdi printf("Invalid Openfirmware environment\n"); 54 1.1 cdi exit(0); 55 1.1 cdi } 56 1.1 cdi 57 1.1 cdi static int 58 1.1 cdi openfirmware_chosen(void) 59 1.1 cdi { 60 1.1 cdi static int phandle = -1; 61 1.1 cdi 62 1.1 cdi if (phandle == -1) { 63 1.1 cdi if ( (phandle = OF_finddevice("/chosen")) == -1) { 64 1.1 cdi exit(0); 65 1.1 cdi } 66 1.1 cdi } 67 1.1 cdi 68 1.1 cdi return (phandle); 69 1.1 cdi } 70 1.1 cdi 71 1.1 cdi static const char* 72 1.1 cdi openfirmware_bootpath(void) 73 1.1 cdi { 74 1.1 cdi static char bootpath[PROM_MAX_PATH]; 75 1.1 cdi 76 1.1 cdi if (_prom_getprop(openfirmware_chosen(), "bootpath", bootpath, 77 1.1 cdi sizeof(bootpath)) < 0) { 78 1.1 cdi openfirmware_fatal(); 79 1.1 cdi } 80 1.1 cdi 81 1.1 cdi return bootpath; 82 1.1 cdi } 83 1.1 cdi 84 1.1 cdi static const char* 85 1.1 cdi openfirmware_bootfile(void) 86 1.1 cdi { 87 1.1 cdi /* Default image name */ 88 1.1 cdi return "netbsd"; 89 1.1 cdi } 90 1.1 cdi 91 1.1 cdi static const char* 92 1.1 cdi openfirmware_bootargs(void) 93 1.1 cdi { 94 1.1 cdi static char bootargs[PROM_MAX_PATH * 2]; 95 1.1 cdi 96 1.1 cdi if (_prom_getprop(openfirmware_chosen(), "bootargs", bootargs, 97 1.1 cdi sizeof(bootargs)) < 0) { 98 1.1 cdi openfirmware_fatal(); 99 1.1 cdi } 100 1.1 cdi 101 1.1 cdi return bootargs; 102 1.1 cdi } 103 1.1 cdi 104 1.1 cdi static int 105 1.1 cdi openfirmware_getchar(void) 106 1.1 cdi { 107 1.1 cdi unsigned char ch = '\0'; 108 1.1 cdi int l; 109 1.1 cdi 110 1.1 cdi while ((l = OF_read(prom_stdin(), &ch, 1)) != 1) 111 1.1 cdi if (l != -2 && l != 0) 112 1.1 cdi return -1; 113 1.1 cdi return ch; 114 1.1 cdi } 115 1.1 cdi 116 1.1 cdi static void 117 1.1 cdi openfirmware_putchar(int c) 118 1.1 cdi { 119 1.1 cdi char ch = c; 120 1.1 cdi 121 1.1 cdi if (c == '\n') 122 1.1 cdi putchar('\r'); 123 1.1 cdi OF_write(prom_stdout(), &ch, 1); 124 1.1 cdi } 125 1.1 cdi 126 1.1 cdi void 127 1.1 cdi prom_halt(void) 128 1.1 cdi { 129 1.1 cdi _prom_halt(); 130 1.1 cdi } 131 1.1 cdi 132 1.1 cdi int 133 1.1 cdi prom_findroot(void) 134 1.1 cdi { 135 1.1 cdi return OF_peer(0); 136 1.1 cdi } 137 1.1 cdi 138 1.1 cdi void 139 1.1 cdi prom_init(void) 140 1.1 cdi { 141 1.1 cdi int phandle, size; 142 1.1 cdi 143 1.1 cdi OF_initialize(); 144 1.1 cdi 145 1.3 tsutsui memset(&promops, 0, sizeof(promops)); 146 1.1 cdi 147 1.1 cdi /* Access to boot arguments */ 148 1.1 cdi promops.po_bootpath = openfirmware_bootpath; 149 1.1 cdi promops.po_bootfile = openfirmware_bootfile; 150 1.1 cdi promops.po_bootargs = openfirmware_bootargs; 151 1.1 cdi 152 1.1 cdi /* I/O functions */ 153 1.1 cdi promops.po_getchar = openfirmware_getchar; 154 1.1 cdi promops.po_putchar = openfirmware_putchar; 155 1.1 cdi promops.po_open = OF_open; 156 1.1 cdi promops.po_close = OF_close; 157 1.1 cdi promops.po_read = OF_read; 158 1.1 cdi promops.po_write = OF_write; 159 1.1 cdi promops.po_seek = OF_seek; 160 1.1 cdi 161 1.1 cdi promops.po_instance_to_package = OF_instance_to_package; 162 1.1 cdi 163 1.1 cdi /* Program termination control */ 164 1.1 cdi promops.po_halt = OF_exit; 165 1.1 cdi promops.po_abort = OF_enter; 166 1.1 cdi promops.po_ticks = OF_milliseconds; 167 1.1 cdi 168 1.1 cdi /* Device node traversal */ 169 1.1 cdi promops.po_firstchild = OF_child; 170 1.1 cdi promops.po_nextsibling = OF_peer; 171 1.1 cdi 172 1.1 cdi /* Device node properties */ 173 1.1 cdi promops.po_getprop = OF_getprop; 174 1.1 cdi 175 1.1 cdi /* Device discovery */ 176 1.1 cdi promops.po_finddevice = OF_finddevice; 177 1.1 cdi 178 1.1 cdi /* Console I/O */ 179 1.1 cdi phandle = openfirmware_chosen(); 180 1.1 cdi size = _prom_getprop(phandle, "stdin", &promops.po_stdin, 181 1.1 cdi sizeof(promops.po_stdin)); 182 1.1 cdi size += _prom_getprop(phandle, "stdout", &promops.po_stdout, 183 1.1 cdi sizeof(promops.po_stdout)); 184 1.1 cdi if (size != (sizeof(promops.po_stdin) + sizeof(promops.po_stdout))) { 185 1.1 cdi prom_halt(); 186 1.1 cdi } 187 1.1 cdi } 188