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