Home | History | Annotate | Line # | Download | only in isa
      1  1.14   thorpej /*	$NetBSD: cmos.c,v 1.14 2023/12/20 15:00:07 thorpej Exp $	*/
      2   1.1    dyoung 
      3   1.1    dyoung /*
      4   1.1    dyoung  * Copyright (C) 2003 JONE System Co., Inc.
      5   1.1    dyoung  * All right reserved.
      6   1.1    dyoung  *
      7   1.1    dyoung  * Copyright (C) 1999, 2000, 2001, 2002 JEPRO Co., Ltd.
      8   1.1    dyoung  * All right reserved.
      9   1.1    dyoung  *
     10   1.1    dyoung  * Redistribution and use in source and binary forms, with or without
     11   1.1    dyoung  * modification, are permitted provided that the following conditions
     12   1.1    dyoung  * are met:
     13   1.1    dyoung  *
     14   1.1    dyoung  * 1. Redistributions of source code must retain the above copyright
     15   1.1    dyoung  *    notice, this list of conditions and the following disclaimer.
     16   1.1    dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     17   1.1    dyoung  *    notice, this list of conditions and the following disclaimer in the
     18   1.1    dyoung  *    documentation and/or other materials provided with the distribution.
     19   1.1    dyoung  *
     20   1.1    dyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     21   1.1    dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22   1.1    dyoung  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23   1.1    dyoung  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     24   1.1    dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25   1.1    dyoung  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     26   1.1    dyoung  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27   1.1    dyoung  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     28   1.1    dyoung  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29   1.1    dyoung  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     30   1.1    dyoung  * SUCH DAMAGE.
     31   1.1    dyoung  *
     32   1.1    dyoung  */
     33   1.1    dyoung /*
     34   1.1    dyoung  * Copyright (c) 2007 David Young.  All right reserved.
     35   1.1    dyoung  *
     36   1.1    dyoung  * Redistribution and use in source and binary forms, with or
     37   1.1    dyoung  * without modification, are permitted provided that the following
     38   1.1    dyoung  * conditions are met:
     39   1.1    dyoung  *
     40   1.1    dyoung  * 1. Redistributions of source code must retain the above copyright
     41   1.1    dyoung  *    notice, this list of conditions and the following disclaimer.
     42   1.1    dyoung  * 2. Redistributions in binary form must reproduce the above
     43   1.1    dyoung  *    copyright notice, this list of conditions and the following
     44   1.1    dyoung  *    disclaimer in the documentation and/or other materials provided
     45   1.1    dyoung  *    with the distribution.
     46   1.1    dyoung  *
     47   1.1    dyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     48   1.1    dyoung  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     49   1.1    dyoung  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     50   1.1    dyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
     51   1.1    dyoung  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     52   1.1    dyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
     53   1.1    dyoung  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     54   1.1    dyoung  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     55   1.1    dyoung  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     56   1.1    dyoung  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     57   1.1    dyoung  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     58   1.1    dyoung  * SUCH DAMAGE.
     59   1.1    dyoung  */
     60   1.2     lukem 
     61   1.2     lukem #include <sys/cdefs.h>
     62  1.14   thorpej __KERNEL_RCSID(0, "$NetBSD: cmos.c,v 1.14 2023/12/20 15:00:07 thorpej Exp $");
     63   1.2     lukem 
     64   1.1    dyoung #include <sys/param.h>
     65   1.1    dyoung #include <sys/systm.h>
     66   1.1    dyoung #include <sys/kernel.h>
     67   1.1    dyoung #include <sys/ioctl.h>
     68   1.1    dyoung #include <sys/proc.h>
     69   1.1    dyoung #include <sys/device.h>
     70   1.1    dyoung #include <sys/conf.h>
     71   1.1    dyoung #include <sys/kauth.h>
     72   1.1    dyoung 
     73   1.9    dyoung #include <sys/bus.h>
     74   1.1    dyoung #include <machine/intr.h>
     75   1.1    dyoung 
     76   1.1    dyoung #include <dev/isa/isareg.h>
     77   1.1    dyoung #include <dev/isa/isavar.h>
     78   1.1    dyoung #include <dev/ic/mc146818reg.h>
     79   1.1    dyoung #include <i386/isa/nvram.h>
     80   1.1    dyoung 
     81  1.12  christos #include "ioconf.h"
     82  1.12  christos 
     83   1.1    dyoung #define	CMOS_SUM	32
     84   1.1    dyoung #define	CMOS_BIOSSPEC	34	/* start of BIOS-specific configuration data */
     85   1.1    dyoung 
     86   1.1    dyoung #define	NVRAM_SUM	(MC_NVRAM_START + CMOS_SUM)
     87   1.1    dyoung #define	NVRAM_BIOSSPEC	(MC_NVRAM_START + CMOS_BIOSSPEC)
     88   1.1    dyoung 
     89   1.1    dyoung #define	CMOS_SIZE	NVRAM_BIOSSPEC
     90   1.1    dyoung 
     91   1.1    dyoung dev_type_open(cmos_open);
     92   1.1    dyoung dev_type_read(cmos_read);
     93   1.1    dyoung dev_type_write(cmos_write);
     94   1.1    dyoung 
     95   1.1    dyoung static void cmos_sum(uint8_t *, int, int, int);
     96   1.1    dyoung 
     97   1.1    dyoung const struct cdevsw cmos_cdevsw = {
     98  1.10  dholland 	.d_open = cmos_open,
     99  1.10  dholland 	.d_close = nullclose,
    100  1.10  dholland 	.d_read = cmos_read,
    101  1.10  dholland 	.d_write = cmos_write,
    102  1.10  dholland 	.d_ioctl = noioctl,
    103  1.10  dholland 	.d_stop = nostop,
    104  1.10  dholland 	.d_tty = notty,
    105  1.10  dholland 	.d_poll = nopoll,
    106  1.10  dholland 	.d_mmap = nommap,
    107  1.10  dholland 	.d_kqfilter = nokqfilter,
    108  1.11  dholland 	.d_discard = nodiscard,
    109  1.10  dholland 	.d_flag = D_OTHER | D_MPSAFE
    110   1.1    dyoung };
    111   1.1    dyoung 
    112   1.5        ad static kmutex_t cmos_lock;
    113   1.6        ad static uint8_t cmos_buf[CMOS_SIZE];
    114   1.5        ad 
    115   1.1    dyoung void
    116   1.1    dyoung cmosattach(int n)
    117   1.1    dyoung {
    118   1.4        ad 
    119   1.5        ad 	mutex_init(&cmos_lock, MUTEX_DEFAULT, IPL_NONE);
    120   1.1    dyoung }
    121   1.1    dyoung 
    122   1.1    dyoung int
    123   1.1    dyoung cmos_open(dev_t dev, int flags, int ifmt, struct lwp *l)
    124   1.1    dyoung {
    125   1.1    dyoung 
    126  1.13  christos 	return kauth_authorize_machdep(l->l_cred,
    127   1.7      elad 	    KAUTH_MACHDEP_NVRAM, NULL, NULL, NULL, NULL);
    128   1.1    dyoung }
    129   1.1    dyoung 
    130   1.1    dyoung static void
    131   1.6        ad cmos_fetch(void)
    132   1.1    dyoung {
    133   1.1    dyoung 	int i, s;
    134   1.1    dyoung 	uint8_t *p;
    135   1.1    dyoung 
    136   1.6        ad 	p = cmos_buf;
    137   1.1    dyoung 	s = splclock();
    138   1.1    dyoung 	for (i = 0; i < CMOS_SIZE; i++)
    139   1.6        ad 		*p++ = mc146818_read(NULL, i);
    140   1.1    dyoung 	splx(s);
    141   1.1    dyoung }
    142   1.1    dyoung 
    143   1.1    dyoung int
    144   1.1    dyoung cmos_read(dev_t dev, struct uio *uio, int ioflag)
    145   1.1    dyoung {
    146   1.5        ad 	int error;
    147   1.1    dyoung 
    148   1.5        ad 	if (uio->uio_offset + uio->uio_resid > CMOS_SIZE)
    149   1.1    dyoung 		return EINVAL;
    150   1.1    dyoung 
    151   1.5        ad 	mutex_enter(&cmos_lock);
    152   1.6        ad 	cmos_fetch();
    153   1.6        ad 	error = uiomove(cmos_buf + uio->uio_offset, uio->uio_resid, uio);
    154   1.5        ad 	mutex_exit(&cmos_lock);
    155   1.1    dyoung 
    156   1.5        ad 	return error;
    157   1.1    dyoung }
    158   1.1    dyoung 
    159   1.1    dyoung int
    160   1.1    dyoung cmos_write(dev_t dev, struct uio *uio, int ioflag)
    161   1.1    dyoung {
    162   1.1    dyoung 	int error = 0, i, s;
    163   1.1    dyoung 
    164   1.5        ad 	if (uio->uio_offset + uio->uio_resid > CMOS_SIZE)
    165   1.5        ad 		return EINVAL;
    166   1.5        ad 
    167   1.5        ad 	mutex_enter(&cmos_lock);
    168   1.6        ad 	cmos_fetch();
    169   1.6        ad 	error = uiomove(cmos_buf + uio->uio_offset, uio->uio_resid, uio);
    170   1.5        ad 	if (error == 0) {
    171   1.6        ad 		cmos_sum(cmos_buf, NVRAM_DISKETTE, NVRAM_SUM, NVRAM_SUM);
    172   1.5        ad 		s = splclock();
    173   1.5        ad 		for (i = NVRAM_DISKETTE; i < CMOS_SIZE; i++)
    174   1.6        ad 			mc146818_write(NULL, i, cmos_buf[i]);
    175   1.5        ad 		splx(s);
    176   1.5        ad 	}
    177   1.5        ad 	mutex_exit(&cmos_lock);
    178   1.1    dyoung 
    179   1.1    dyoung 	return error;
    180   1.1    dyoung }
    181   1.1    dyoung 
    182   1.1    dyoung static void
    183   1.1    dyoung cmos_sum(uint8_t *p, int from, int to, int offset)
    184   1.1    dyoung {
    185   1.1    dyoung 	int i;
    186   1.1    dyoung 	uint16_t sum;
    187   1.1    dyoung 
    188   1.1    dyoung #ifdef CMOS_DEBUG
    189   1.1    dyoung 	printf("%s: from %d to %d and store %d\n", __func__, from, to, offset);
    190   1.1    dyoung #endif
    191   1.1    dyoung 
    192   1.1    dyoung 	sum = 0;
    193   1.1    dyoung 	for (i = from; i < to; i++)
    194   1.1    dyoung 		sum += p[i];
    195   1.1    dyoung 	p[offset] = sum >> 8;
    196   1.1    dyoung 	p[offset + 1] = sum & 0xff;
    197   1.1    dyoung }
    198