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