nvram.c revision 1.5 1 /* $NetBSD: nvram.c,v 1.5 2002/09/06 13:18:43 gehenna Exp $ */
2
3 /*-
4 * Copyright (C) 1998 Internet Research Institute, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by
18 * Internet Research Institute, Inc.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/conf.h>
38 #include <sys/kernel.h>
39 #include <sys/device.h>
40 #include <sys/malloc.h>
41 #include <sys/conf.h>
42
43 #include <machine/autoconf.h>
44 #include <machine/pio.h>
45
46 #define NVRAM_NONE 0
47 #define NVRAM_IOMEM 1
48 #define NVRAM_PORT 2
49
50 #define NVRAM_SIZE 0x2000
51
52 static void nvram_attach __P((struct device *, struct device *, void *));
53 static int nvram_match __P((struct device *, struct cfdata *, void *));
54
55 struct nvram_softc {
56 struct device sc_dev;
57 int nv_type;
58 char *nv_port;
59 char *nv_data;
60 };
61
62 struct cfattach nvram_ca = {
63 sizeof(struct nvram_softc), nvram_match, nvram_attach
64 };
65
66 extern struct cfdriver nvram_cd;
67
68 dev_type_read(nvramread);
69 dev_type_write(nvramwrite);
70 dev_type_mmap(nvrammmap);
71
72 const struct cdevsw nvram_cdevsw = {
73 nullopen, nullclose, nvramread, nvramwrite, noioctl,
74 nostop, notty, nopoll, nvrammmap,
75 };
76
77 int
78 nvram_match(parent, cf, aux)
79 struct device *parent;
80 struct cfdata *cf;
81 void *aux;
82 {
83 struct confargs *ca = aux;
84
85 if (strcmp(ca->ca_name, "nvram") != 0)
86 return 0;
87
88 if (ca->ca_nreg == 0)
89 return 0;
90
91 return 1;
92 }
93
94 void
95 nvram_attach(parent, self, aux)
96 struct device *parent, *self;
97 void *aux;
98 {
99 struct nvram_softc *sc = (struct nvram_softc *)self;
100 struct confargs *ca = aux;
101 int *reg = ca->ca_reg;
102
103 printf("\n");
104
105 switch (ca->ca_nreg) {
106
107 case 8: /* untested */
108 sc->nv_type = NVRAM_IOMEM;
109 sc->nv_data = mapiodev(ca->ca_baseaddr + reg[0], reg[1]);
110 break;
111
112 case 16:
113 sc->nv_type = NVRAM_PORT;
114 sc->nv_port = mapiodev(ca->ca_baseaddr + reg[0], reg[1]);
115 sc->nv_data = mapiodev(ca->ca_baseaddr + reg[2], reg[3]);
116 break;
117
118 case 0:
119 default:
120 sc->nv_type = NVRAM_NONE;
121 return;
122 }
123 }
124
125 int
126 nvramread(dev, uio, flag)
127 dev_t dev;
128 struct uio *uio;
129 int flag;
130 {
131 struct nvram_softc *sc;
132 u_int off, cnt;
133 int i;
134 int error = 0;
135 char *buf;
136
137 sc = nvram_cd.cd_devs[0];
138
139 off = uio->uio_offset;
140 cnt = uio->uio_resid;
141
142 if (off > NVRAM_SIZE || cnt > NVRAM_SIZE)
143 return EFAULT;
144
145 if (off + cnt > NVRAM_SIZE)
146 cnt = NVRAM_SIZE - off;
147
148 buf = malloc(NVRAM_SIZE, M_DEVBUF, M_WAITOK);
149 if (buf == NULL) {
150 error = EAGAIN;
151 goto out;
152 }
153
154 switch (sc->nv_type) {
155
156 case NVRAM_IOMEM:
157 for (i = 0; i < NVRAM_SIZE; i++)
158 buf[i] = sc->nv_data[i * 16];
159
160 break;
161
162 case NVRAM_PORT:
163 for (i = 0; i < NVRAM_SIZE; i += 32) {
164 int j;
165
166 out8(sc->nv_port, i / 32);
167 for (j = 0; j < 32; j++) {
168 buf[i + j] = sc->nv_data[j * 16];
169 }
170 }
171 break;
172
173 default:
174 goto out;
175 }
176
177 error = uiomove(buf + off, cnt, uio);
178
179 out:
180 if (buf)
181 free(buf, M_DEVBUF);
182
183 return error;
184 }
185
186 int
187 nvramwrite(dev, uio, flag)
188 dev_t dev;
189 struct uio *uio;
190 int flag;
191 {
192 return ENXIO;
193 }
194
195 paddr_t
196 nvrammmap(dev, off, prot)
197 dev_t dev;
198 off_t off;
199 int prot;
200 {
201 return -1;
202 }
203