xref: /netbsd/sys/arch/macppc/dev/nvram.c (revision c4a72b64)
1 /*	$NetBSD: nvram.c,v 1.8 2002/10/23 09:11:33 jdolecek 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 #include <sys/event.h>
43 
44 #include <machine/autoconf.h>
45 #include <machine/pio.h>
46 
47 #define NVRAM_NONE  0
48 #define NVRAM_IOMEM 1
49 #define NVRAM_PORT  2
50 
51 #define NVRAM_SIZE 0x2000
52 
53 static void nvram_attach __P((struct device *, struct device *, void *));
54 static int nvram_match __P((struct device *, struct cfdata *, void *));
55 
56 struct nvram_softc {
57 	struct device sc_dev;
58 	int nv_type;
59 	char *nv_port;
60 	char *nv_data;
61 };
62 
63 CFATTACH_DECL(nvram, sizeof(struct nvram_softc),
64     nvram_match, nvram_attach, NULL, NULL);
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, nokqfilter,
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