svn commit: r363571 - in head/sys: conf dev/goldfish riscv/conf
Jessica Clarke
jrtc27 at FreeBSD.org
Sun Jul 26 18:15:17 UTC 2020
Author: jrtc27
Date: Sun Jul 26 18:15:16 2020
New Revision: 363571
URL: https://svnweb.freebsd.org/changeset/base/363571
Log:
Add Goldfish RTC device driver for RISC-V
This device was originally used as part of the goldfish virtual hardware
platform used for emulating Android on QEMU, but is now also used as the
RTC for the RISC-V virt machine in QEMU. It provides a simple 64-bit
nanosecond timer exposed via a pair of memory-mapped 32-bit registers,
although only with 1s granularity.
Reviewed by: brooks (mentor), jhb (mentor), kp
Approved by: brooks (mentor), jhb (mentor), kp
Obtained from: CheriBSD
Differential Revision: https://reviews.freebsd.org/D25717
Added:
head/sys/dev/goldfish/
head/sys/dev/goldfish/goldfish_rtc.c (contents, props changed)
Modified:
head/sys/conf/files
head/sys/riscv/conf/GENERIC
Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Sun Jul 26 18:12:54 2020 (r363570)
+++ head/sys/conf/files Sun Jul 26 18:15:16 2020 (r363571)
@@ -1736,6 +1736,7 @@ dev/fxp/if_fxp.c optional fxp
dev/fxp/inphy.c optional fxp
dev/gem/if_gem.c optional gem
dev/gem/if_gem_pci.c optional gem pci
+dev/goldfish/goldfish_rtc.c optional goldfish_rtc fdt
dev/gpio/dwgpio/dwgpio.c optional gpio dwgpio fdt
dev/gpio/dwgpio/dwgpio_bus.c optional gpio dwgpio fdt
dev/gpio/dwgpio/dwgpio_if.m optional gpio dwgpio fdt
Added: head/sys/dev/goldfish/goldfish_rtc.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/goldfish/goldfish_rtc.c Sun Jul 26 18:15:16 2020 (r363571)
@@ -0,0 +1,182 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Jessica Clarke <jrtc27 at FreeBSD.org>
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+/*
+ * RTC for the goldfish virtual hardware platform implemented in QEMU,
+ * initially for Android but now also used for RISC-V's virt machine.
+ *
+ * https://android.googlesource.com/platform/external/qemu/+/master/docs/GOLDFISH-VIRTUAL-HARDWARE.TXT
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/types.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include "clock_if.h"
+
+#define GOLDFISH_RTC_TIME_LOW 0x00
+#define GOLDFISH_RTC_TIME_HIGH 0x04
+
+struct goldfish_rtc_softc {
+ struct resource *res;
+ int rid;
+ struct mtx mtx;
+};
+
+static int
+goldfish_rtc_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_is_compatible(dev, "google,goldfish-rtc")) {
+ device_set_desc(dev, "Goldfish RTC");
+ return (BUS_PROBE_DEFAULT);
+ }
+
+ return (ENXIO);
+}
+
+static int
+goldfish_rtc_attach(device_t dev)
+{
+ struct goldfish_rtc_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ sc->rid = 0;
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
+ RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not allocate resource\n");
+ return (ENXIO);
+ }
+
+ mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+ /*
+ * Register as a system realtime clock with 1 second resolution.
+ */
+ clock_register_flags(dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
+ clock_schedule(dev, 1);
+
+ return (0);
+}
+
+static int
+goldfish_rtc_detach(device_t dev)
+{
+ struct goldfish_rtc_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ clock_unregister(dev);
+ mtx_destroy(&sc->mtx);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
+
+ return (0);
+}
+
+static int
+goldfish_rtc_gettime(device_t dev, struct timespec *ts)
+{
+ struct goldfish_rtc_softc *sc;
+ uint64_t low, high, nsec;
+
+ sc = device_get_softc(dev);
+
+ /*
+ * Reading TIME_HIGH is defined in the documentation to give the high
+ * 32 bits corresponding to the last TIME_LOW read, so must be done in
+ * that order, but means we have atomicity guaranteed.
+ */
+ mtx_lock(&sc->mtx);
+ low = bus_read_4(sc->res, GOLDFISH_RTC_TIME_LOW);
+ high = bus_read_4(sc->res, GOLDFISH_RTC_TIME_HIGH);
+ mtx_unlock(&sc->mtx);
+
+ nsec = (high << 32) | low;
+ ts->tv_sec = nsec / 1000000000;
+ ts->tv_nsec = nsec % 1000000000;
+
+ return (0);
+}
+
+static int
+goldfish_rtc_settime(device_t dev, struct timespec *ts)
+{
+ struct goldfish_rtc_softc *sc;
+ uint64_t nsec;
+
+ sc = device_get_softc(dev);
+
+ nsec = (uint64_t)ts->tv_sec * 1000000000 + ts->tv_nsec;
+
+ mtx_lock(&sc->mtx);
+ bus_write_4(sc->res, GOLDFISH_RTC_TIME_HIGH, nsec >> 32);
+ bus_write_4(sc->res, GOLDFISH_RTC_TIME_LOW, nsec);
+ mtx_unlock(&sc->mtx);
+
+ return (0);
+}
+
+static device_method_t goldfish_rtc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, goldfish_rtc_probe),
+ DEVMETHOD(device_attach, goldfish_rtc_attach),
+ DEVMETHOD(device_detach, goldfish_rtc_detach),
+
+ /* Clock interface */
+ DEVMETHOD(clock_gettime, goldfish_rtc_gettime),
+ DEVMETHOD(clock_settime, goldfish_rtc_settime),
+
+ DEVMETHOD_END,
+};
+
+DEFINE_CLASS_0(goldfish_rtc, goldfish_rtc_driver, goldfish_rtc_methods,
+ sizeof(struct goldfish_rtc_softc));
+static devclass_t goldfish_rtc_devclass;
+
+DRIVER_MODULE(goldfish_rtc, simplebus, goldfish_rtc_driver,
+ goldfish_rtc_devclass, NULL, NULL);
Modified: head/sys/riscv/conf/GENERIC
==============================================================================
--- head/sys/riscv/conf/GENERIC Sun Jul 26 18:12:54 2020 (r363570)
+++ head/sys/riscv/conf/GENERIC Sun Jul 26 18:15:16 2020 (r363571)
@@ -101,6 +101,8 @@ device uart # Generic UART driver
device uart_lowrisc # lowRISC UART driver
device uart_ns8250 # ns8250-type UART driver
+# RTC
+device goldfish_rtc # QEMU RTC
# Ethernet drivers
device miibus # MII bus support
More information about the svn-src-head
mailing list