diff options
author | joshua stein <jcs@cvs.openbsd.org> | 2004-10-03 21:28:35 +0000 |
---|---|---|
committer | joshua stein <jcs@cvs.openbsd.org> | 2004-10-03 21:28:35 +0000 |
commit | 07213120b6c32c6aa12e0a83ac2101eca62e7a47 (patch) | |
tree | f7a3ddd795023aebd94d90e3622ab554e5b8b18b /sys | |
parent | c9bf6a6b57e48177a91b3e065f6745a671922e83 (diff) |
nvram driver for i386 through /dev/nvram
currently read-only
ok grange@, marius@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 5 | ||||
-rw-r--r-- | sys/arch/i386/i386/conf.c | 12 | ||||
-rw-r--r-- | sys/arch/i386/i386/nvram.c | 163 |
4 files changed, 180 insertions, 3 deletions
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index a71ca96fd60..592a73fb8d5 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.378 2004/09/16 10:37:21 grange Exp $ +# $OpenBSD: GENERIC,v 1.379 2004/10/03 21:28:34 jcs Exp $ # # GENERIC -- everything that's currently supported # @@ -569,6 +569,7 @@ scsibus* at ioprbs? pseudo-device pctr 1 pseudo-device mtrr 1 # Memory range attributes control +pseudo-device nvram 1 pseudo-device sequencer 1 #pseudo-device raid 4 # RAIDframe disk driver pseudo-device bio 1 # ioctl multiplexing device diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 0492169db7d..a2ab778cb38 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.128 2004/09/16 09:14:03 mickey Exp $ +# $OpenBSD: files.i386,v 1.129 2004/10/03 21:28:34 jcs Exp $ # # new style config file for i386 architecture # @@ -218,6 +218,9 @@ file arch/i386/i386/pctr.c pctr needs-flag pseudo-device mtrr file arch/i386/i386/mtrr.c mtrr needs-flag +pseudo-device nvram +file arch/i386/i386/nvram.c nvram needs-flag + # # EISA-only drivers # diff --git a/sys/arch/i386/i386/conf.c b/sys/arch/i386/i386/conf.c index 20f4b26245c..38072585d96 100644 --- a/sys/arch/i386/i386/conf.c +++ b/sys/arch/i386/i386/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.108 2004/06/03 18:13:13 grange Exp $ */ +/* $OpenBSD: conf.c,v 1.109 2004/10/03 21:28:34 jcs Exp $ */ /* $NetBSD: conf.c,v 1.75 1996/05/03 19:40:20 christos Exp $ */ /* @@ -120,6 +120,13 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]); (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ (dev_type_stop((*))) enodev, 0, seltrue, (dev_type_mmap((*))) enodev } +/* open, close, read */ +#define cdev_nvram_init(c,n) { \ + dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ + (dev_type_write((*))) enodev, (dev_type_ioctl((*))) enodev, \ + (dev_type_stop((*))) enodev, 0, seltrue, \ + (dev_type_mmap((*))) enodev, 0 } + #define mmread mmrw #define mmwrite mmrw @@ -184,6 +191,8 @@ cdev_decl(wdt); cdev_decl(cztty); #include "radio.h" #include "gpr.h" +#include "nvram.h" +cdev_decl(nvram); /* XXX -- this needs to be supported by config(8)! */ #if (NCOM > 0) && (NPCCOM > 0) @@ -314,6 +323,7 @@ struct cdevsw cdevsw[] = cdev_ptm_init(NPTY,ptm), /* 81: pseudo-tty ptm device */ cdev_hotplug_init(NHOTPLUG,hotplug), /* 82: devices hot plugging */ cdev_gpio_init(NGPIO,gpio), /* 83: GPIO interface */ + cdev_nvram_init(NNVRAM,nvram), /* 84: NVRAM interface */ }; int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]); diff --git a/sys/arch/i386/i386/nvram.c b/sys/arch/i386/i386/nvram.c new file mode 100644 index 00000000000..4ea95891f35 --- /dev/null +++ b/sys/arch/i386/i386/nvram.c @@ -0,0 +1,163 @@ +/* $OpenBSD: nvram.c,v 1.1 2004/10/03 21:28:34 jcs Exp $ */ + +/* + * Copyright (c) 2004 Joshua Stein <jcs@openbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/uio.h> +#include <sys/fcntl.h> +#include <sys/conf.h> + +#include <dev/ic/mc146818reg.h> +#include <i386/isa/nvram.h> + +/* checksum is calculated over bytes 2 to 31 and stored in byte 32 */ +#define NVRAM_CSUM_START (MC_NVRAM_START + 2) +#define NVRAM_CSUM_END (MC_NVRAM_START + 31) +#define NVRAM_CSUM_LOC (MC_NVRAM_START + 32) + +#define NVRAM_SIZE (128 - MC_NVRAM_START) + +/* #define NVRAM_DEBUG 1 */ + +void nvramattach(int); + +int nvramopen(dev_t dev, int flag, int mode, struct proc *p); +int nvramclose(dev_t dev, int flag, int mode, struct proc *p); +int nvramread(dev_t dev, struct uio *uio, int flags); + +int nvram_csum_valid(void); +int nvram_get_byte(int byteno); + +static int nvram_opened; +static int nvram_initialized; + +void +nvramattach(int num) +{ + if (num > 1) + return; + + if (nvram_initialized || nvram_csum_valid()) { +#ifdef NVRAM_DEBUG + printf("nvram: initialized\n"); +#endif NVRAM_DEBUG + + nvram_initialized = 1; + nvram_opened = 0; + } else + printf("nvram: invalid checksum\n"); +} + +int +nvramopen(dev_t dev, int flag, int mode, struct proc *p) +{ + /* TODO: re-calc checksum on every open? */ + + if ((minor(dev) != 0) || (!nvram_initialized)) + return (ENXIO); + + if (nvram_opened) + return (EBUSY); + + if ((flag & FWRITE)) + return (EPERM); + + nvram_opened = 1; + + return (0); +} + +int +nvramclose(dev_t dev, int flag, int mode, struct proc *p) +{ + nvram_opened = 0; + + return (0); +} + +int +nvramread(dev_t dev, struct uio *uio, int flags) +{ + u_char buf[NVRAM_SIZE]; + u_int pos = uio->uio_offset; + u_char *tmp; + int count = min(sizeof(buf), uio->uio_resid); + int ret; + + if (!nvram_initialized) + return (ENXIO); + + if (uio->uio_resid == 0) + return (0); + +#ifdef NVRAM_DEBUG + printf("attempting to read %d bytes at offset %d\n", count, pos); +#endif + + for (tmp = buf; count-- > 0 && pos < NVRAM_SIZE; ++pos, ++tmp) + *tmp = nvram_get_byte(pos); + +#ifdef NVRAM_DEBUG + printf("nvramread read %d bytes (%s)\n", (tmp - buf), tmp); +#endif + + ret = uiomove((caddr_t)buf, (tmp - buf), uio); + + uio->uio_offset += uio->uio_resid; + + return (ret); +} + +int +nvram_get_byte(int byteno) +{ + if (!nvram_initialized) + return (ENXIO); + + return (mc146818_read(NULL, byteno + MC_NVRAM_START) & 0xff); +} + +int +nvram_csum_valid() +{ + u_short csum = 0; + u_short csumexpect; + int nreg; + + for (nreg = NVRAM_CSUM_START; nreg <= NVRAM_CSUM_END; nreg++) + csum += mc146818_read(NULL, nreg); + + csumexpect = mc146818_read(NULL, NVRAM_CSUM_LOC) << 8 | + mc146818_read(NULL, NVRAM_CSUM_LOC + 1); + +#ifdef NVRAM_DEBUG + printf("nvram: checksum is %x, expecting %x\n", (csum & 0xffff), + csumexpect); +#endif + + return ((csum & 0xffff) == csumexpect); +} |