Annotation of sys/arch/solbourne/solbourne/prom_machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: prom_machdep.c,v 1.1 2005/04/19 21:30:18 miod Exp $ */
! 2: /*
! 3: * Copyright (c) 2005, Miodrag Vallat
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: *
! 14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 15: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 16: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 17: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 18: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 19: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 20: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 22: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 23: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 24: * POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: /*
! 28: * Routines to hide the Solbourne PROM specifics.
! 29: */
! 30:
! 31: #include <sys/param.h>
! 32: #include <sys/systm.h>
! 33:
! 34: #include <machine/autoconf.h>
! 35: #include <machine/bsd_openprom.h> /* romboot() prototype */
! 36: #include <machine/idt.h>
! 37: #include <machine/kap.h>
! 38: #include <machine/prom.h>
! 39:
! 40: #include <uvm/uvm_extern.h>
! 41:
! 42: #include <sparc/sparc/asm.h>
! 43:
! 44: int sysmodel;
! 45:
! 46: void myetheraddr(u_char *);
! 47: void prom_map(void);
! 48: void prom_unmap(void);
! 49:
! 50: extern void tlb_flush_all(void);
! 51:
! 52: /*
! 53: * Lookup a variable in the environment strings.
! 54: */
! 55: const char *
! 56: prom_getenv(const char *var)
! 57: {
! 58: u_int i;
! 59: const char *eq, *env;
! 60: size_t len;
! 61: extern char **prom_environ;
! 62:
! 63: len = strlen(var);
! 64:
! 65: for (i = 0; (env = prom_environ[i]) != NULL; i++) {
! 66: eq = strchr(env, '=');
! 67: #ifdef DIAGNOSTIC
! 68: if (eq == NULL)
! 69: continue; /* can't happen */
! 70: #endif
! 71: if (eq - env != len)
! 72: continue;
! 73:
! 74: if (strncasecmp(var, env, len) == 0) {
! 75: return (eq + 1);
! 76: }
! 77: }
! 78:
! 79: return (NULL);
! 80: }
! 81:
! 82: void
! 83: myetheraddr(u_char *cp)
! 84: {
! 85: const char *enetaddr;
! 86: int i;
! 87:
! 88: enetaddr = prom_getenv(ENV_ETHERADDR);
! 89: if (enetaddr == NULL) {
! 90: cp[0] = cp[1] = cp[2] = cp[3] = cp[4] = cp[5] = 0xff;
! 91: } else {
! 92: for (i = 0; i < 6; i++) {
! 93: cp[i] = 0;
! 94: for (;;) {
! 95: if (*enetaddr >= '0' && *enetaddr <= '9')
! 96: cp[i] = cp[i] * 0x10 +
! 97: (*enetaddr - '0');
! 98: else if (*enetaddr >= 'A' && *enetaddr <= 'F')
! 99: cp[i] = cp[i] * 0x10 +
! 100: (*enetaddr + 10 - 'A');
! 101: else if (*enetaddr >= 'a' && *enetaddr <= 'f')
! 102: cp[i] = cp[i] * 0x10 +
! 103: (*enetaddr + 10 - 'a');
! 104: else
! 105: break;
! 106:
! 107: enetaddr++;
! 108: }
! 109: if (*enetaddr++ != ':')
! 110: break;
! 111: }
! 112: /* fill remaining digits if necessary */
! 113: while (i++ < 6)
! 114: cp[i] = 0;
! 115: }
! 116: }
! 117:
! 118: /*
! 119: * Set up PROM-friendly mappings
! 120: */
! 121:
! 122: void
! 123: prom_map(void)
! 124: {
! 125: sta(0, ASI_PTW0, PTW0_DEFAULT);
! 126: tlb_flush_all();
! 127: }
! 128:
! 129: void
! 130: prom_unmap(void)
! 131: {
! 132: sta(0, ASI_PTW0, 0);
! 133: tlb_flush_all();
! 134: }
! 135:
! 136: /*
! 137: * Prom property access
! 138: *
! 139: * Note that if we are passed addresses in the fd va window, we need to
! 140: * temporarily copy these pointers to a ``safe'' address (in this case,
! 141: * a global variable, thus in the f0 or f1 window).
! 142: */
! 143:
! 144: int
! 145: getprop(int node, char *name, void *buf, int bufsiz)
! 146: {
! 147: struct prom_node *n = (struct prom_node *)node;
! 148: struct prom_prop *p;
! 149: char *propname, *eq;
! 150: int len, proplen;
! 151:
! 152: len = strlen(name);
! 153:
! 154: #ifdef DIAGNOSTIC
! 155: if (node == 0)
! 156: #if 0
! 157: node = findroot();
! 158: #else
! 159: panic("getprop(%s) invoked on invalid node", name);
! 160: #endif
! 161: #endif
! 162:
! 163: for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
! 164: propname = p->pp_data;
! 165: eq = strchr(propname, '=');
! 166: #ifdef DIAGNOSTIC
! 167: if (eq == NULL)
! 168: continue; /* can't happen */
! 169: #endif
! 170: if (eq - propname != len)
! 171: continue;
! 172:
! 173: if (strncmp(name, propname, len) == 0) {
! 174: proplen = p->pp_size;
! 175: if (proplen > bufsiz) {
! 176: printf("node %p property %s length %d > %d",
! 177: node, name, proplen, bufsiz);
! 178: #ifdef DEBUG
! 179: panic("getprop");
! 180: #else
! 181: return (0);
! 182: #endif
! 183: } else
! 184: bcopy(eq + 1, buf, proplen);
! 185: break;
! 186: }
! 187: }
! 188:
! 189: if (p == NULL)
! 190: proplen = -1;
! 191:
! 192: return (proplen);
! 193: }
! 194:
! 195: int
! 196: getproplen(int node, char *name)
! 197: {
! 198: struct prom_node *n = (struct prom_node *)node;
! 199: struct prom_prop *p;
! 200: char *propname, *eq;
! 201: int len, proplen;
! 202:
! 203: #ifdef DIAGNOSTIC
! 204: if (node == 0)
! 205: panic("getproplen(%s) invoked on invalid node", name);
! 206: #endif
! 207:
! 208: len = strlen(name);
! 209:
! 210: for (p = (struct prom_prop *)n->pn_props; p != NULL; p = p->pp_next) {
! 211: propname = p->pp_data;
! 212: eq = strchr(propname, '=');
! 213: #ifdef DIAGNOSTIC
! 214: if (eq == NULL)
! 215: continue; /* can't happen */
! 216: #endif
! 217: if (eq - propname != len)
! 218: continue;
! 219:
! 220: if (strncmp(name, propname, len) == 0) {
! 221: proplen = p->pp_size;
! 222: break;
! 223: }
! 224: }
! 225:
! 226: if (p == NULL)
! 227: proplen = -1;
! 228:
! 229: return (proplen);
! 230: }
! 231:
! 232: int
! 233: firstchild(int node)
! 234: {
! 235: return ((struct prom_node *)node)->pn_child;
! 236: }
! 237:
! 238: int
! 239: nextsibling(int node)
! 240: {
! 241: if (node == 0)
! 242: return (findroot());
! 243: else
! 244: return (((struct prom_node *)node)->pn_sibling);
! 245: }
! 246:
! 247: int
! 248: findroot()
! 249: {
! 250: struct sb_prom *sp;
! 251:
! 252: sp = (struct sb_prom *)PROM_DATA_VA;
! 253: if (sp->sp_interface >= PROM_INTERFACE)
! 254: return (sp->sp_rootnode);
! 255:
! 256: panic("findroot: PROM communication interface is too old (%d)",
! 257: sp->sp_interface);
! 258: /* NOTREACHED */
! 259: }
! 260:
! 261: /*
! 262: * Shutdown and reboot interface
! 263: */
! 264:
! 265: void
! 266: romhalt()
! 267: {
! 268: struct sb_prom *sp;
! 269:
! 270: sp = (struct sb_prom *)PROM_DATA_VA;
! 271: if (sp->sp_interface >= PROM_INTERFACE) {
! 272: prom_map();
! 273: (*sp->sp_interp)("reset " PROM_RESET_HALT);
! 274: prom_unmap();
! 275: }
! 276:
! 277: panic("PROM exit failed");
! 278: }
! 279:
! 280: void
! 281: romboot(char *str)
! 282: {
! 283: char command[256];
! 284: struct sb_prom *sp;
! 285:
! 286: if (*str != '\0') {
! 287: strlcpy(command, "boot ", sizeof command);
! 288: strlcat(command, str, sizeof command);
! 289: } else {
! 290: strlcpy(command, "reset ", sizeof command);
! 291: strlcat(command, PROM_RESET_WARM, sizeof command);
! 292: }
! 293:
! 294: sp = (struct sb_prom *)PROM_DATA_VA;
! 295: if (sp->sp_interface >= PROM_INTERFACE) {
! 296: prom_map();
! 297: (*sp->sp_interp)(command);
! 298: prom_unmap();
! 299: }
! 300:
! 301: panic("PROM boot failed");
! 302: }
CVSweb