|
|
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.