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 | |
parent | c9bf6a6b57e48177a91b3e065f6745a671922e83 (diff) |
nvram driver for i386 through /dev/nvram
currently read-only
ok grange@, marius@
-rw-r--r-- | etc/etc.i386/MAKEDEV.md | 6 | ||||
-rw-r--r-- | share/man/man4/man4.i386/nvram.4 | 63 | ||||
-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 |
6 files changed, 248 insertions, 4 deletions
diff --git a/etc/etc.i386/MAKEDEV.md b/etc/etc.i386/MAKEDEV.md index b8935c7634a..246531eabd1 100644 --- a/etc/etc.i386/MAKEDEV.md +++ b/etc/etc.i386/MAKEDEV.md @@ -1,5 +1,5 @@ vers(__file__, - {-$OpenBSD: MAKEDEV.md,v 1.27 2004/09/06 10:06:05 deraadt Exp $-}, + {-$OpenBSD: MAKEDEV.md,v 1.28 2004/10/03 21:28:34 jcs Exp $-}, etc.MACHINE)dnl dnl dnl Copyright (c) 2001-2004 Todd T. Fries <todd@OpenBSD.org> @@ -17,6 +17,8 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl dnl +__devitem(nvram, nvram, NVRAM access)dnl +_mkdev(nvram, nvram, {-M nvram c major_nvram_c 0 440 kmem-})dnl _TITLE(make) _DEV(all) _DEV(ramdisk) @@ -76,6 +78,7 @@ _DEV(iop, 75) _DEV(joy, 26) _DEV(lkm, 28) _DEV(music, 53) +_DEV(nvram, 84) _DEV(pci, 72) _DEV(pctr, 46) _DEV(pf, 73) @@ -127,6 +130,7 @@ target(all, vnd, 0, 1, 2, 3)dnl target(all, ccd, 0, 1, 2, 3)dnl target(all, bktr, 0)dnl target(all, gpio, 0, 1, 2)dnl +target(all, nvram)dnl target(ramd, tty0, 0, 1, 2, 3)dnl twrget(ramd, wsdisp, ttyC, 0)dnl target(ramd, wt, 0)dnl diff --git a/share/man/man4/man4.i386/nvram.4 b/share/man/man4/man4.i386/nvram.4 new file mode 100644 index 00000000000..c131dc1cfda --- /dev/null +++ b/share/man/man4/man4.i386/nvram.4 @@ -0,0 +1,63 @@ +.\" $OpenBSD: nvram.4,v 1.1 2004/10/03 21:28:34 jcs Exp $ +.\" +.\" Copyright 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. +.\" +.Dd October 3, 2004 +.Dt NVRAM 4 i386 +.Os +.Sh NAME +.Nm nvram +.Nd driver for reading PC NVRAM contents +.Sh SYNOPSIS +.Cd "pseudo-device nvram 1" +.Sh DESCRIPTION +The +.Nm +device provides read-only access to the non-volatile memory contained in the +MC146818 real-time clock. +.Pp +This data is provided as a seekable character device, +.Pa /dev/nvram . +Checksums of the NVRAM contents are calculated over bytes 2 to 31 and stored +in byte 32. +A valid checksum is required for the driver to initialize. +.Pp +Only one process may have this device open at any given time; +.Xr open 2 +and +.Xr close 2 +are used to lock and relinquish it. +An attempt to +.Fn open +when another process has the device locked will return \-1 with an +.Er EBUSY +error indication. +.Sh FILES +.Bl -tag -width /dev/nvram +.It Pa /dev/nvram +.El +.Sh HISTORY +.Nm +support was originally included in +.Ox 3.7 . 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); +} |