|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Driver for Non-volatile RAM. ! 27: */ ! 28: #import <sys/param.h> ! 29: #import <sys/systm.h> ! 30: #import <sys/conf.h> ! 31: #import <sys/ioctl.h> ! 32: #import <sys/tty.h> ! 33: #import <sys/proc.h> ! 34: #import <sys/uio.h> ! 35: #include <machdep/ppc/DeviceTree.h> ! 36: #include <machdep/ppc/proc_reg.h> ! 37: #include <machdep/ppc/powermac.h> ! 38: ! 39: #define NVRAM_SIZE 8192 ! 40: ! 41: enum { ! 42: NVRAM_IOMEM, ! 43: NVRAM_PORT, ! 44: NVRAM_PMU, ! 45: NVRAM_NONE ! 46: } nvram_kind = NVRAM_NONE; ! 47: ! 48: static volatile unsigned char *nvram_data = NULL; ! 49: static volatile unsigned char *nvram_port = NULL; ! 50: ! 51: int nvopened; ! 52: ! 53: typedef struct { ! 54: long address; ! 55: long length; ! 56: } nvram_reg; ! 57: ! 58: nvprobe() ! 59: { ! 60: DTEntryIterator iter; ! 61: DTEntry entry; ! 62: char *str; ! 63: int dummy; ! 64: int result; ! 65: nvram_reg *regs; ! 66: int len; ! 67: ! 68: if ( HasPMU() ) { ! 69: nvram_kind = NVRAM_PMU; ! 70: return; ! 71: } ! 72: ! 73: if (DTLookupEntry(NULL, "/", &entry) != kSuccess) { ! 74: return; // failed ! 75: } ! 76: if (DTCreateEntryIterator(0, &iter) != kSuccess) { ! 77: return; // failed ! 78: } ! 79: do { ! 80: result = DTGetProperty(entry, "device_type", (void **)&str, &dummy); ! 81: if (result == kSuccess && strcmp(str, "nvram") == 0) { ! 82: result = DTGetProperty(entry, "reg", (void **)®s, &len); ! 83: if (result == kSuccess) { ! 84: switch (len) { ! 85: case 8: ! 86: nvram_kind = NVRAM_IOMEM; ! 87: nvram_data = (volatile unsigned char *) ! 88: PCI_IO_BASE_PHYS+regs[0].address; ! 89: break; ! 90: case 16: ! 91: nvram_kind = NVRAM_PORT; ! 92: nvram_port = (volatile unsigned char *) ! 93: PCI_IO_BASE_PHYS+regs[0].address; ! 94: nvram_data = (volatile unsigned char *) ! 95: PCI_IO_BASE_PHYS+regs[1].address; ! 96: break; ! 97: default: ! 98: break; ! 99: } ! 100: break; ! 101: } ! 102: } ! 103: ! 104: while ((result = DTIterateEntries(iter, &entry)) == kIterationDone) { ! 105: if ((result = DTExitEntry(iter, &entry)) != kSuccess) { ! 106: break; ! 107: } ! 108: } ! 109: if (result == kSuccess) { ! 110: result = DTEnterEntry(iter, entry); ! 111: } ! 112: } while (result == kSuccess); ! 113: ! 114: DTDisposeEntryIterator(iter); ! 115: } ! 116: ! 117: /*ARGSUSED*/ ! 118: nvopen(dev, flag, devtype, pp) ! 119: dev_t dev; ! 120: int flag, devtype; ! 121: struct proc *pp; ! 122: { ! 123: if (!nvopened) { ! 124: nvprobe(); ! 125: } ! 126: if (nvram_kind == NVRAM_NONE) { ! 127: return (ENODEV); ! 128: } ! 129: return 0; ! 130: } ! 131: ! 132: /*ARGSUSED*/ ! 133: nvclose(dev, flag, mode, pp) ! 134: dev_t dev; ! 135: int flag, mode; ! 136: struct proc *pp; ! 137: { ! 138: return 0; ! 139: } ! 140: ! 141: /*ARGSUSED*/ ! 142: nvread(dev, uio, ioflag) ! 143: dev_t dev; ! 144: struct uio *uio; ! 145: int ioflag; ! 146: { ! 147: register struct iovec *iov; ! 148: long offset; ! 149: long size; ! 150: int c; ! 151: unsigned char cc; ! 152: long read = 0; ! 153: int error = 0; ! 154: ! 155: offset = uio->uio_offset; ! 156: if (offset >= NVRAM_SIZE) { ! 157: error = EIO; ! 158: goto failed; ! 159: } ! 160: ! 161: size = uio->uio_resid; ! 162: ! 163: if (offset+size > NVRAM_SIZE) { ! 164: size = NVRAM_SIZE-offset; ! 165: } ! 166: ! 167: switch (nvram_kind) { ! 168: case NVRAM_IOMEM: ! 169: for (read = 0; read < size; read++, offset++) { ! 170: c = nvram_data[offset << 4]; ! 171: eieio(); /* better safe than sorry! */ ! 172: error = ureadc(c, uio); ! 173: if (error) ! 174: goto failed; ! 175: } ! 176: break; ! 177: ! 178: case NVRAM_PORT: ! 179: for (read = 0; read < size; read++, offset++) { ! 180: *nvram_port = offset >> 5; eieio(); ! 181: c = nvram_data[(offset & 0x1f) << 4]; ! 182: eieio(); ! 183: error = ureadc(c, uio); ! 184: if (error) ! 185: goto failed; ! 186: } ! 187: break; ! 188: ! 189: case NVRAM_PMU: ! 190: for (read = 0; read < size; read++, offset++) { ! 191: ReadNVRAM(offset, 1, &cc); ! 192: c = (int)cc; ! 193: error = ureadc(c, uio); ! 194: if (error) ! 195: goto failed; ! 196: } ! 197: break; ! 198: } ! 199: failed: ! 200: return error; ! 201: } ! 202: ! 203: /*ARGSUSED*/ ! 204: nvwrite(dev, uio, ioflag) ! 205: dev_t dev; ! 206: struct uio *uio; ! 207: int ioflag; ! 208: { ! 209: register struct iovec *iov; ! 210: long offset; ! 211: long size; ! 212: int c; ! 213: unsigned char cc; ! 214: long wrote = 0; ! 215: ! 216: offset = uio->uio_offset; ! 217: if (offset >= NVRAM_SIZE) { ! 218: return EIO; ! 219: } ! 220: ! 221: size = uio->uio_resid; ! 222: if (offset+size > NVRAM_SIZE) ! 223: size = NVRAM_SIZE-offset; ! 224: ! 225: switch (nvram_kind) { ! 226: case NVRAM_IOMEM: ! 227: for (wrote = 0; wrote < size; wrote++, offset++) { ! 228: c = uwritec(uio); ! 229: if (c < 0) ! 230: goto failed; ! 231: nvram_data[offset << 4] = c; ! 232: eieio(); ! 233: } ! 234: break; ! 235: ! 236: case NVRAM_PORT: ! 237: for (wrote = 0; wrote < size; wrote++, offset++) { ! 238: c = uwritec(uio); ! 239: if (c < 0) ! 240: goto failed; ! 241: *nvram_port = offset >> 5; eieio(); ! 242: nvram_data[(offset & 0x1f) << 4] = c; ! 243: eieio(); ! 244: } ! 245: break; ! 246: ! 247: case NVRAM_PMU: ! 248: for (wrote = 0; wrote < size; wrote++, offset++) { ! 249: c = uwritec(uio); ! 250: if (c < 0) ! 251: goto failed; ! 252: cc = (unsigned char)c; ! 253: WriteNVRAM(offset, 1, &cc); ! 254: } ! 255: break; ! 256: } ! 257: failed: ! 258: return 0; ! 259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.