summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorjoshua stein <jcs@cvs.openbsd.org>2004-10-03 21:28:35 +0000
committerjoshua stein <jcs@cvs.openbsd.org>2004-10-03 21:28:35 +0000
commit07213120b6c32c6aa12e0a83ac2101eca62e7a47 (patch)
treef7a3ddd795023aebd94d90e3622ab554e5b8b18b /sys/arch
parentc9bf6a6b57e48177a91b3e065f6745a671922e83 (diff)
nvram driver for i386 through /dev/nvram
currently read-only ok grange@, marius@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/conf/GENERIC3
-rw-r--r--sys/arch/i386/conf/files.i3865
-rw-r--r--sys/arch/i386/i386/conf.c12
-rw-r--r--sys/arch/i386/i386/nvram.c163
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);
+}