Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jul 2020 18:15:16 +0000 (UTC)
From:      Jessica Clarke <jrtc27@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r363571 - in head/sys: conf dev/goldfish riscv/conf
Message-ID:  <202007261815.06QIFG2F030071@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007261815.06QIFG2F030071>