nvram.c revision 1.1 1 /* $NetBSD: nvram.c,v 1.1 1996/01/06 20:11:08 leo Exp $ */
2
3 /*
4 * Copyright (c) 1995 Leo Weppelman.
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 Leo Weppelman.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Nvram driver
35 */
36
37 #include <sys/param.h>
38 #include <sys/conf.h>
39 #include <sys/kernel.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/buf.h>
44 #include <sys/uio.h>
45
46 #include <machine/iomap.h>
47
48 #include <atari/dev/clockreg.h>
49 #include <atari/dev/nvramvar.h>
50
51 #include "nvr.h"
52
53 #define MC_NVRAM_CSUM (MC_NVRAM_START + MC_NVRAM_SIZE - 2)
54
55 #if NNVR > 0
56 static void nvram_set_csum __P((u_char csum));
57 static int nvram_csum_valid __P((u_char csum));
58 static u_char nvram_csum __P((void));
59
60 /*
61 * Auto config stuff....
62 */
63 static void nvr_attach __P((struct device *, struct device *, void *));
64 static int nvr_match __P((struct device *, struct cfdata *, void *));
65
66 struct cfdriver nvrcd = {
67 NULL, "nvr", (cfmatch_t)nvr_match, nvr_attach,
68 DV_DULL, sizeof(struct nvr_softc), NULL, 0 };
69
70 /*ARGSUSED*/
71 static int
72 nvr_match(pdp, cfp, auxp)
73 struct device *pdp;
74 struct cfdata *cfp;
75 void *auxp;
76 {
77 if (!strcmp((char *)auxp, "nvr"))
78 return (1);
79 return (0);
80 }
81
82 /*ARGSUSED*/
83 static void
84 nvr_attach(pdp, dp, auxp)
85 struct device *pdp, *dp;
86 void *auxp;
87 {
88 struct nvr_softc *nvr_soft;
89 int nreg;
90
91 /*
92 * Check the validity of the NVram contents
93 */
94 if (!nvram_csum_valid(nvram_csum())) {
95 printf(": Invalid checksum - re-initialized");
96 for (nreg = MC_NVRAM_START; nreg < MC_NVRAM_CSUM; nreg++)
97 mc146818_write(RTC, nreg, 0);
98 nvram_set_csum(nvram_csum());
99 }
100 nvr_soft = nvrcd.cd_devs[0];
101 nvr_soft->nvr_flags = NVR_CONFIGURED;
102 printf("\n");
103 }
104 /*
105 * End of auto config stuff....
106 */
107 #endif /* NNVR > 0 */
108
109 /*
110 * Kernel internal interface
111 */
112 int
113 nvr_get_byte(byteno)
114 int byteno;
115 {
116 #if NNVR > 0
117 struct nvr_softc *nvr_soft;
118
119 nvr_soft = nvrcd.cd_devs[0];
120 if (!(nvr_soft->nvr_flags & NVR_CONFIGURED))
121 return(NVR_INVALID);
122 return (mc146818_read(RTC, byteno + MC_NVRAM_START) & 0xff);
123 #else
124 return(NVR_INVALID);
125 #endif /* NNVR > 0 */
126 }
127
128 #if NNVR > 0
129
130 nvram_uio(uio)
131 struct uio *uio;
132 {
133 int i;
134 off_t offset;
135 int nleft;
136 u_char buf[MC_NVRAM_CSUM - MC_NVRAM_START + 1];
137 u_char *p;
138 struct nvr_softc *nvr_soft;
139
140 nvr_soft = nvrcd.cd_devs[0];
141 if (!(nvr_soft->nvr_flags & NVR_CONFIGURED))
142 return ENXIO;
143
144 #ifdef NV_DEBUG
145 printf("Request to transfer %d bytes offset: %d, %s nvram\n",
146 (long)uio->uio_resid, (long)uio->uio_offset,
147 (uio->uio_rw == UIO_READ) ? "from" : "to");
148 #endif /* NV_DEBUG */
149
150 offset = uio->uio_offset + MC_NVRAM_START;
151 nleft = uio->uio_resid;
152 if (offset + nleft >= MC_NVRAM_CSUM) {
153 if (offset == MC_NVRAM_CSUM)
154 return (0);
155 nleft = MC_NVRAM_CSUM - offset;
156 if (nleft <= 0)
157 return (EINVAL);
158 }
159 #ifdef NV_DEBUG
160 printf("Translated: offset = %d, bytes: %d\n", (long)offset, nleft);
161 #endif /* NV_DEBUG */
162
163 if (uio->uio_rw == UIO_READ) {
164 for (i = 0, p = buf; i < nleft; i++, p++)
165 *p = mc146818_read(RTC, offset + i);
166 }
167 if (i = uiomove(buf, nleft, uio))
168 return (i);
169 if (uio->uio_rw == UIO_WRITE) {
170 for (i = 0, p = buf; i < nleft; i++, p++)
171 mc146818_write(RTC, offset + i, *p);
172 nvram_set_csum(nvram_csum());
173 }
174 return(0);
175 }
176
177 static u_char
178 nvram_csum()
179 {
180 u_char csum;
181 int nreg;
182
183 for (csum = 0, nreg = MC_NVRAM_START; nreg < MC_NVRAM_CSUM; nreg++)
184 csum += mc146818_read(RTC, nreg);
185 return(csum);
186 }
187
188 static int
189 nvram_csum_valid(csum)
190 u_char csum;
191 {
192 if (((~csum & 0xff) != mc146818_read(RTC, MC_NVRAM_CSUM))
193 || (csum != mc146818_read(RTC, MC_NVRAM_CSUM + 1)))
194 return 0;
195 return 1;
196 }
197
198 static void
199 nvram_set_csum(csum)
200 u_char csum;
201 {
202 mc146818_write(RTC, MC_NVRAM_CSUM, ~csum);
203 mc146818_write(RTC, MC_NVRAM_CSUM + 1, csum);
204 }
205 #endif /* NNVR > 0 */
206