[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 10/19] hw/timer/bcm2835: Add the BCM2835 SYS_timer
From: |
Philippe Mathieu-Daudé |
Subject: |
[PATCH 10/19] hw/timer/bcm2835: Add the BCM2835 SYS_timer |
Date: |
Thu, 26 Sep 2019 19:34:18 +0200 |
Add the 64-bit free running timer. Do not model the COMPARE register
(no IRQ generated).
This timer is used by U-Boot and recent Linux kernels:
https://github.com/u-boot/u-boot/blob/v2019.07/include/configs/rpi.h#L19
Datasheet used:
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
---
Since which kernels? 4.19 seems to use it.
checkpatch warning:
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
This is OK because the regex are:
F: hw/*/bcm283*
F: include/hw/*/bcm283*
---
hw/timer/Makefile.objs | 1 +
hw/timer/bcm2835_systmr.c | 100 ++++++++++++++++++++++++++++++
hw/timer/trace-events | 4 ++
include/hw/timer/bcm2835_systmr.h | 30 +++++++++
4 files changed, 135 insertions(+)
create mode 100644 hw/timer/bcm2835_systmr.c
create mode 100644 include/hw/timer/bcm2835_systmr.h
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 123d92c969..696cda5905 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -47,3 +47,4 @@ common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
common-obj-$(CONFIG_CMSDK_APB_DUALTIMER) += cmsdk-apb-dualtimer.o
common-obj-$(CONFIG_MSF2) += mss-timer.o
+common-obj-$(CONFIG_RASPI) += bcm2835_systmr.o
diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c
new file mode 100644
index 0000000000..c4d2b488bd
--- /dev/null
+++ b/hw/timer/bcm2835_systmr.c
@@ -0,0 +1,100 @@
+/*
+ * BCM2835 SYS timer emulation
+ *
+ * Copyright (C) 2019 Philippe Mathieu-Daudé <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ *
+ * Datasheet: BCM2835 ARM Peripherals (C6357-M-1398)
+ * https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
+ *
+ * Only the free running 64-bit counter is implemented.
+ * The 4 COMPARE registers and the interruption are not implemented.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/timer.h"
+#include "qemu/log.h"
+#include "hw/registerfields.h"
+#include "hw/timer/bcm2835_systmr.h"
+#include "trace.h"
+
+REG32(CTRL_STATUS, 0x00)
+REG32(COUNTER_LOW, 0x04)
+REG32(COUNTER_HIGH, 0x08)
+REG32(COMPARE0, 0x0c)
+REG32(COMPARE1, 0x10)
+REG32(COMPARE2, 0x14)
+REG32(COMPARE3, 0x18)
+
+static uint64_t bcm2835_sys_timer_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ uint64_t r = 0;
+
+ switch (offset) {
+ case A_CTRL_STATUS:
+ case A_COMPARE0 ... A_COMPARE3:
+ break;
+ case A_COUNTER_LOW:
+ case A_COUNTER_HIGH:
+ /* Free running counter at 1MHz */
+ r = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+ r >>= 8 * (offset - A_COUNTER_LOW);
+ r &= UINT32_MAX;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ break;
+ }
+ trace_bcm2835_sys_timer_read(offset, r);
+
+ return r;
+}
+
+static void bcm2835_sys_timer_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ trace_bcm2835_sys_timer_write(offset, value);
+
+ qemu_log_mask(LOG_UNIMP, "%s: bad offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+}
+
+static const MemoryRegionOps bcm2835_sys_timer_ops = {
+ .read = bcm2835_sys_timer_read,
+ .write = bcm2835_sys_timer_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static void bcm2835_sys_timer_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ BCM2835SysTimerState *s = BCM2835_SYSTIMER(obj);
+
+ memory_region_init_io(&s->iomem, obj, &bcm2835_sys_timer_ops,
+ s, "bcm2835-sys-timer", 0x20);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
+}
+
+static const TypeInfo bcm2835_sys_timer_info = {
+ .name = TYPE_BCM2835_SYSTIMER,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2835SysTimerState),
+ .instance_init = bcm2835_sys_timer_init,
+};
+
+static void bcm2835_sys_timer_register_types(void)
+{
+ type_register_static(&bcm2835_sys_timer_info);
+}
+
+type_init(bcm2835_sys_timer_register_types);
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index db02a9142c..81967a1a19 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -87,3 +87,7 @@ pl031_read(uint32_t addr, uint32_t value) "addr 0x%08x value
0x%08x"
pl031_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
pl031_alarm_raised(void) "alarm raised"
pl031_set_alarm(uint32_t ticks) "alarm set for %u ticks"
+
+# bcm2835_systmr.c
+bcm2835_sys_timer_read(uint64_t offset, uint64_t data) "timer read: offset
0x%" PRIx64 " data 0x%" PRIx64
+bcm2835_sys_timer_write(uint64_t offset, uint64_t data) "timer write: offset
0x%" PRIx64 " data 0x%" PRIx64
diff --git a/include/hw/timer/bcm2835_systmr.h
b/include/hw/timer/bcm2835_systmr.h
new file mode 100644
index 0000000000..6ac7f8ec5a
--- /dev/null
+++ b/include/hw/timer/bcm2835_systmr.h
@@ -0,0 +1,30 @@
+/*
+ * BCM2835 SYS timer emulation
+ *
+ * Copyright (c) 2019 Philippe Mathieu-Daudé <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+#ifndef BCM2835_SYSTIMER_H
+#define BCM2835_SYSTIMER_H
+
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+
+#define TYPE_BCM2835_SYSTIMER "bcm2835-sys-timer"
+#define BCM2835_SYSTIMER(obj) \
+ OBJECT_CHECK(BCM2835SysTimerState, (obj), TYPE_BCM2835_SYSTIMER)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+ qemu_irq irq;
+} BCM2835SysTimerState;
+
+#endif
--
2.20.1
- [PATCH 00/19] hw/arm/raspi: Improve Raspberry Pi 2/3 reliability, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 01/19] hw/arm/raspi: Use the IEC binary prefix definitions, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 02/19] hw/arm/bcm2835_peripherals: Improve logging, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 03/19] hw/arm/bcm2835_peripherals: Name various address spaces, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 04/19] hw/arm/bcm2835: Rename some definitions, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 05/19] hw/arm/bcm2835: Add various unimplemented peripherals, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 06/19] hw/char/bcm2835_aux: Add trace events, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 09/19] hw/arm/bcm2835_peripherals: Use the thermal sensor block, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 07/19] hw/misc/bcm2835_mbox: Add trace events, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 08/19] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 10/19] hw/timer/bcm2835: Add the BCM2835 SYS_timer,
Philippe Mathieu-Daudé <=
- [PATCH 11/19] hw/arm/bcm2835_peripherals: Use the SYS_timer, Philippe Mathieu-Daudé, 2019/09/26
- [PATCH 14/19] python/qemu/machine: Allow to use other serial consoles than default, Philippe Mathieu-Daudé, 2019/09/26
[PATCH 13/19] hw/arm/raspi: Define various blocks base addresses, Philippe Mathieu-Daudé, 2019/09/26
[PATCH 12/19] hw/arm/bcm2835_peripherals: Add Clock/Power/Reset Manager blocks, Philippe Mathieu-Daudé, 2019/09/26
[PATCH 15/19] tests/boot_linux_console: Extract the gunzip() helper, Philippe Mathieu-Daudé, 2019/09/26
[PATCH 16/19] tests/boot_linux_console: Add a test for the Raspberry Pi 2, Philippe Mathieu-Daudé, 2019/09/26