]> git.proxmox.com Git - mirror_qemu.git/blob - include/hw/timer/sse-counter.h
hw/timer/sse-counter: Model the SSE Subsystem System Counter
[mirror_qemu.git] / include / hw / timer / sse-counter.h
1 /*
2 * Arm SSE Subsystem System Counter
3 *
4 * Copyright (c) 2020 Linaro Limited
5 * Written by Peter Maydell
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 or
9 * (at your option) any later version.
10 */
11
12 /*
13 * This is a model of the "System counter" which is documented in
14 * the Arm SSE-123 Example Subsystem Technical Reference Manual:
15 * https://developer.arm.com/documentation/101370/latest/
16 *
17 * QEMU interface:
18 * + Clock input "CLK": clock
19 * + sysbus MMIO region 0: the control register frame
20 * + sysbus MMIO region 1: the status register frame
21 *
22 * Consumers of the system counter's timestamp, such as the SSE
23 * System Timer device, can also use the APIs sse_counter_for_timestamp(),
24 * sse_counter_tick_to_time() and sse_counter_register_consumer() to
25 * interact with an instance of the System Counter. Generally the
26 * consumer device should have a QOM link property which the board
27 * code can set to the appropriate instance of the system counter.
28 */
29
30 #ifndef SSE_COUNTER_H
31 #define SSE_COUNTER_H
32
33 #include "hw/sysbus.h"
34 #include "qom/object.h"
35 #include "qemu/notify.h"
36
37 #define TYPE_SSE_COUNTER "sse-counter"
38 OBJECT_DECLARE_SIMPLE_TYPE(SSECounter, SSE_COUNTER)
39
40 struct SSECounter {
41 /*< private >*/
42 SysBusDevice parent_obj;
43
44 /*< public >*/
45 MemoryRegion control_mr;
46 MemoryRegion status_mr;
47 Clock *clk;
48 NotifierList notifier_list;
49
50 uint32_t cntcr;
51 uint32_t cntscr0;
52
53 /*
54 * These are used for handling clock frequency changes: they are a
55 * tuple of (QEMU_CLOCK_VIRTUAL timestamp, CNTCV at that time),
56 * taken when the clock frequency changes. sse_cntcv() needs them
57 * to calculate the current CNTCV.
58 */
59 uint64_t ns_then;
60 uint64_t ticks_then;
61 };
62
63 /*
64 * These functions are the interface by which a consumer of
65 * the system timestamp (such as the SSE system timer device)
66 * can communicate with the SSECounter.
67 */
68
69 /**
70 * sse_counter_for_timestamp:
71 * @counter: SSECounter
72 * @ns: timestamp of QEMU_CLOCK_VIRTUAL in nanoseconds
73 *
74 * Returns the value of the timestamp counter at the specified
75 * point in time (assuming that no changes to scale factor, enable, etc
76 * happen in the meantime).
77 */
78 uint64_t sse_counter_for_timestamp(SSECounter *counter, uint64_t ns);
79
80 /**
81 * sse_counter_tick_to_time:
82 * @counter: SSECounter
83 * @tick: tick value
84 *
85 * Returns the time (a QEMU_CLOCK_VIRTUAL timestamp in nanoseconds)
86 * when the timestamp counter will reach the specified tick count.
87 * If the counter is not currently running, returns UINT64_MAX.
88 */
89 uint64_t sse_counter_tick_to_time(SSECounter *counter, uint64_t tick);
90
91 /**
92 * sse_counter_register_consumer:
93 * @counter: SSECounter
94 * @notifier: Notifier which is notified on counter changes
95 *
96 * Registers @notifier with the SSECounter. When the counter's
97 * configuration changes in a way that might invalidate information
98 * previously returned via sse_counter_for_timestamp() or
99 * sse_counter_tick_to_time(), the notifier will be called.
100 * Devices which consume the timestamp counter can use this as
101 * a cue to recalculate timer events.
102 */
103 void sse_counter_register_consumer(SSECounter *counter, Notifier *notifier);
104
105 #endif