38
38
#define DPRINTF (fmt , ...)
39
39
#endif
40
40
41
- #define RTC_DR 0x00 /* Data read register */
42
- #define RTC_MR 0x04 /* Match register */
43
- #define RTC_LR 0x08 /* Data load register */
44
- #define RTC_CR 0x0c /* Control register */
45
- #define RTC_IMSC 0x10 /* Interrupt mask and set register */
46
- #define RTC_RIS 0x14 /* Raw interrupt status register */
47
- #define RTC_MIS 0x18 /* Masked interrupt status register */
48
- #define RTC_ICR 0x1c /* Interrupt clear register */
41
+ #define TIMER_CR1_OFFSET 0x00
42
+ #define TIMER_CR2_OFFSET 0x04
43
+ #define TIMER_SMCR_OFFSET 0x08
44
+ #define TIMER_DIER_OFFSET 0x0c
45
+ #define TIMER_SR_OFFSET 0x10
46
+ #define TIMER_EGR_OFFSET 0x14
47
+ #define TIMER_CCMR1_OFFSET 0x18
48
+ #define TIMER_CCMR2_OFFSET 0x1c
49
+ #define TIMER_CCER_OFFSET 0x20
50
+ #define TIMER_CNT_OFFSET 0x24
51
+ #define TIMER_PSC_OFFSET 0x28
52
+ #define TIMER_APR_OFFSET 0x2c
53
+ #define TIMER_RCR_OFFSET 0x30
54
+ #define TIMER_CCR1_OFFSET 0x34
55
+ #define TIMER_CCR2_OFFSET 0x38
56
+ #define TIMER_CCR3_OFFSET 0x3c
57
+ #define TIMER_CCR4_OFFSET 0x40
58
+ #define TIMER_DCR_OFFSET 0x48
59
+ #define TIMER_DMAR_OFFSET 0x4C
49
60
50
61
typedef struct {
51
62
SysBusDevice busdev ;
52
63
MemoryRegion iomem ;
53
- QEMUTimer * timer ;
54
- qemu_irq irq ;
64
+ QEMUTimer * timer ;
65
+ qemu_irq irq ;
55
66
56
67
/* Needed to preserve the tick_count across migration, even if the
57
68
* absolute value of the rtc_clock is different on the source and
@@ -60,112 +71,137 @@ typedef struct {
60
71
uint32_t tick_offset_vmstate ;
61
72
uint32_t tick_offset ;
62
73
63
- uint32_t mr ;
64
- uint32_t lr ;
65
- uint32_t cr ;
66
- uint32_t im ;
67
- uint32_t is ;
68
- } pl031_state ;
69
-
70
- static const unsigned char pl031_id [] = {
71
- 0x31 , 0x10 , 0x14 , 0x00 , /* Device ID */
72
- 0x0d , 0xf0 , 0x05 , 0xb1 /* Cell ID */
73
- };
74
-
75
- static void pl031_update (pl031_state * s )
74
+ uint32_t cr1 ;
75
+ uint32_t cr2 ;
76
+ uint32_t smcr ;
77
+ uint32_t dier ;
78
+ uint32_t sr ;
79
+ uint32_t egr ;
80
+ uint32_t ccmr1 ;
81
+ uint32_t ccmr2 ;
82
+ uint32_t ccer ;
83
+ uint32_t cnt ;
84
+ uint32_t psc ;
85
+ uint32_t apr ;
86
+ uint32_t rcr ;
87
+ uint32_t ccr1 ;
88
+ uint32_t ccr2 ;
89
+ uint32_t ccr3 ;
90
+ uint32_t ccr4 ;
91
+ uint32_t dcr ;
92
+ uint32_t dmar ;
93
+
94
+ } stm32_tm_state ;
95
+
96
+ static void stm32_update (stm32_tm_state * s )
76
97
{
77
98
qemu_set_irq (s -> irq , s -> is & s -> im );
78
99
}
79
100
80
- static void pl031_interrupt (void * opaque )
101
+ static void stm32_interrupt (void * opaque )
81
102
{
82
- pl031_state * s = (pl031_state * )opaque ;
103
+ stm32_tm_state * s = (stm32_tm_state * )opaque ;
83
104
84
105
s -> is = 1 ;
85
106
DPRINTF ("Alarm raised\n" );
86
- pl031_update (s );
107
+ stm32_update (s );
87
108
}
88
109
89
- static uint32_t pl031_get_count ( pl031_state * s )
110
+ static uint32_t stm32_get_count ( stm32_tm_state * s )
90
111
{
91
112
int64_t now = qemu_get_clock_ns (rtc_clock );
92
113
return s -> tick_offset + now / get_ticks_per_sec ();
93
114
}
94
115
95
- static void pl031_set_alarm ( pl031_state * s )
116
+ static void stm32_set_alarm ( stm32_tm_state * s )
96
117
{
97
118
uint32_t ticks ;
98
119
99
120
/* The timer wraps around. This subtraction also wraps in the same way,
100
121
and gives correct results when alarm < now_ticks. */
101
- ticks = s -> mr - pl031_get_count (s );
122
+ ticks = s -> mr - stm32_get_count (s );
102
123
DPRINTF ("Alarm set in %ud ticks\n" , ticks );
103
124
if (ticks == 0 ) {
104
125
qemu_del_timer (s -> timer );
105
- pl031_interrupt (s );
126
+ stm32_interrupt (s );
106
127
} else {
107
128
int64_t now = qemu_get_clock_ns (rtc_clock );
108
129
qemu_mod_timer (s -> timer , now + (int64_t )ticks * get_ticks_per_sec ());
109
130
}
110
131
}
111
132
112
- static uint64_t pl031_read (void * opaque , hwaddr offset ,
133
+ static uint64_t stm32_read (void * opaque , hwaddr offset ,
113
134
unsigned size )
114
135
{
115
- pl031_state * s = (pl031_state * )opaque ;
116
-
117
- if (offset >= 0xfe0 && offset < 0x1000 )
118
- return pl031_id [(offset - 0xfe0 ) >> 2 ];
136
+ stm32_tm_state * s = (stm32_tm_state * )opaque ;
119
137
120
138
switch (offset ) {
121
- case RTC_DR :
122
- return pl031_get_count (s );
123
- case RTC_MR :
124
- return s -> mr ;
125
- case RTC_IMSC :
126
- return s -> im ;
127
- case RTC_RIS :
128
- return s -> is ;
129
- case RTC_LR :
130
- return s -> lr ;
131
- case RTC_CR :
132
- /* RTC is permanently enabled. */
133
- return 1 ;
134
- case RTC_MIS :
135
- return s -> is & s -> im ;
136
- case RTC_ICR :
137
- qemu_log_mask (LOG_GUEST_ERROR ,
138
- "pl031: read of write-only register at offset 0x%x\n" ,
139
- (int )offset );
140
- break ;
139
+ case TIMER_CR1_OFFSET :
140
+ return s -> cr1 ;
141
+ case TIMER_CR2_OFFSET :
142
+ return s -> cr2 ;
143
+ case TIMER_SMCR_OFFSET :
144
+ return s -> smcr ;
145
+ case TIMER_DIER_OFFSET :
146
+ return s -> dier ;
147
+ case TIMER_SR_OFFSET :
148
+ return s -> sr ;
149
+ case TIMER_EGR_OFFSET :
150
+ return s -> egr ;
151
+ case TIMER_CCMR1_OFFSET :
152
+ return s -> ccmr1 ;
153
+ case TIMER_CCMR2_OFFSET :
154
+ return s -> ccmr2 ;
155
+ case TIMER_CCER_OFFSET :
156
+ return s -> ccer ;
157
+ case TIMER_CNT_OFFSET :
158
+ return s -> cnt ;
159
+ case TIMER_PSC_OFFSET :
160
+ return s -> psc ;
161
+ case TIMER_APR_OFFSET :
162
+ return s -> apr ;
163
+ case TIMER_RCR_OFFSET :
164
+ return s -> rcr ;
165
+ case TIMER_CCR1_OFFSET :
166
+ return s -> ccr1 ;
167
+ case TIMER_CCR2_OFFSET :
168
+ return s -> ccr2 ;
169
+ case TIMER_CCR3_OFFSET :
170
+ return s -> ccr3 ;
171
+ case TIMER_CCR4_OFFSET :
172
+ return s -> ccr4 ;
173
+ case TIMER_DCR_OFFSET :
174
+ return s -> dcr ;
175
+ case TIMER_DMAR_OFFSET :
176
+ return s -> dmar ;
141
177
default :
142
178
qemu_log_mask (LOG_GUEST_ERROR ,
143
- "pl031_read : Bad offset 0x%x\n" , (int )offset );
179
+ "stm32_read : Bad offset 0x%x\n" , (int )offset );
144
180
break ;
145
181
}
146
182
147
183
return 0 ;
148
184
}
149
185
150
- static void pl031_write (void * opaque , hwaddr offset ,
186
+ static void stm32_write (void * opaque , hwaddr offset ,
151
187
uint64_t value , unsigned size )
152
188
{
153
- pl031_state * s = (pl031_state * )opaque ;
189
+ stm32_tm_state * s = (stm32_tm_state * )opaque ;
154
190
155
191
156
192
switch (offset ) {
157
193
case RTC_LR :
158
- s -> tick_offset += value - pl031_get_count (s );
159
- pl031_set_alarm (s );
194
+ s -> tick_offset += value - stm32_get_count (s );
195
+ stm32_set_alarm (s );
160
196
break ;
161
197
case RTC_MR :
162
198
s -> mr = value ;
163
- pl031_set_alarm (s );
199
+ stm32_set_alarm (s );
164
200
break ;
165
201
case RTC_IMSC :
166
202
s -> im = value & 1 ;
167
203
DPRINTF ("Interrupt mask %d\n" , s -> im );
168
- pl031_update (s );
204
+ stm32_update (s );
169
205
break ;
170
206
case RTC_ICR :
171
207
/* The PL031 documentation (DDI0224B) states that the interrupt is
@@ -174,7 +210,7 @@ static void pl031_write(void * opaque, hwaddr offset,
174
210
cleared when any value is written. */
175
211
DPRINTF ("Interrupt cleared" );
176
212
s -> is = 0 ;
177
- pl031_update (s );
213
+ stm32_update (s );
178
214
break ;
179
215
case RTC_CR :
180
216
/* Written value is ignored. */
@@ -184,96 +220,96 @@ static void pl031_write(void * opaque, hwaddr offset,
184
220
case RTC_MIS :
185
221
case RTC_RIS :
186
222
qemu_log_mask (LOG_GUEST_ERROR ,
187
- "pl031 : write to read-only register at offset 0x%x\n" ,
223
+ "stm32 : write to read-only register at offset 0x%x\n" ,
188
224
(int )offset );
189
225
break ;
190
226
191
227
default :
192
228
qemu_log_mask (LOG_GUEST_ERROR ,
193
- "pl031_write : Bad offset 0x%x\n" , (int )offset );
229
+ "stm32_write : Bad offset 0x%x\n" , (int )offset );
194
230
break ;
195
231
}
196
232
}
197
233
198
- static const MemoryRegionOps pl031_ops = {
199
- .read = pl031_read ,
200
- .write = pl031_write ,
234
+ static const MemoryRegionOps stm32_ops = {
235
+ .read = stm32_read ,
236
+ .write = stm32_write ,
201
237
.endianness = DEVICE_NATIVE_ENDIAN ,
202
238
};
203
239
204
- static int pl031_init (SysBusDevice * dev )
240
+ static int stm32_init (SysBusDevice * dev )
205
241
{
206
- pl031_state * s = FROM_SYSBUS (pl031_state , dev );
242
+ stm32_tm_state * s = FROM_SYSBUS (stm32_tm_state , dev );
207
243
struct tm tm ;
208
244
209
- memory_region_init_io (& s -> iomem , & pl031_ops , s , "pl031 " , 0x1000 );
245
+ memory_region_init_io (& s -> iomem , & stm32_ops , s , "stm32 " , 0x1000 );
210
246
sysbus_init_mmio (dev , & s -> iomem );
211
247
212
248
sysbus_init_irq (dev , & s -> irq );
213
249
qemu_get_timedate (& tm , 0 );
214
250
s -> tick_offset = mktimegm (& tm ) - qemu_get_clock_ns (rtc_clock ) / get_ticks_per_sec ();
215
251
216
- s -> timer = qemu_new_timer_ns (rtc_clock , pl031_interrupt , s );
252
+ s -> timer = qemu_new_timer_ns (rtc_clock , stm32_interrupt , s );
217
253
return 0 ;
218
254
}
219
255
220
- static void pl031_pre_save (void * opaque )
256
+ static void stm32_pre_save (void * opaque )
221
257
{
222
- pl031_state * s = opaque ;
258
+ stm32_tm_state * s = opaque ;
223
259
224
260
/* tick_offset is base_time - rtc_clock base time. Instead, we want to
225
261
* store the base time relative to the vm_clock for backwards-compatibility. */
226
262
int64_t delta = qemu_get_clock_ns (rtc_clock ) - qemu_get_clock_ns (vm_clock );
227
263
s -> tick_offset_vmstate = s -> tick_offset + delta / get_ticks_per_sec ();
228
264
}
229
265
230
- static int pl031_post_load (void * opaque , int version_id )
266
+ static int stm32_post_load (void * opaque , int version_id )
231
267
{
232
- pl031_state * s = opaque ;
268
+ stm32_tm_state * s = opaque ;
233
269
234
270
int64_t delta = qemu_get_clock_ns (rtc_clock ) - qemu_get_clock_ns (vm_clock );
235
271
s -> tick_offset = s -> tick_offset_vmstate - delta / get_ticks_per_sec ();
236
- pl031_set_alarm (s );
272
+ stm32_set_alarm (s );
237
273
return 0 ;
238
274
}
239
275
240
- static const VMStateDescription vmstate_pl031 = {
241
- .name = "pl031 " ,
276
+ static const VMStateDescription vmstate_stm32 = {
277
+ .name = "stm32 " ,
242
278
.version_id = 1 ,
243
279
.minimum_version_id = 1 ,
244
- .pre_save = pl031_pre_save ,
245
- .post_load = pl031_post_load ,
280
+ .pre_save = stm32_pre_save ,
281
+ .post_load = stm32_post_load ,
246
282
.fields = (VMStateField []) {
247
- VMSTATE_UINT32 (tick_offset_vmstate , pl031_state ),
248
- VMSTATE_UINT32 (mr , pl031_state ),
249
- VMSTATE_UINT32 (lr , pl031_state ),
250
- VMSTATE_UINT32 (cr , pl031_state ),
251
- VMSTATE_UINT32 (im , pl031_state ),
252
- VMSTATE_UINT32 (is , pl031_state ),
283
+ VMSTATE_UINT32 (tick_offset_vmstate , stm32_tm_state ),
284
+ VMSTATE_UINT32 (mr , stm32_tm_state ),
285
+ VMSTATE_UINT32 (lr , stm32_tm_state ),
286
+ VMSTATE_UINT32 (cr , stm32_tm_state ),
287
+ VMSTATE_UINT32 (im , stm32_tm_state ),
288
+ VMSTATE_UINT32 (is , stm32_tm_state ),
253
289
VMSTATE_END_OF_LIST ()
254
290
}
255
291
};
256
292
257
- static void pl031_class_init (ObjectClass * klass , void * data )
293
+ static void stm32_class_init (ObjectClass * klass , void * data )
258
294
{
259
295
DeviceClass * dc = DEVICE_CLASS (klass );
260
296
SysBusDeviceClass * k = SYS_BUS_DEVICE_CLASS (klass );
261
297
262
- k -> init = pl031_init ;
298
+ k -> init = stm32_init ;
263
299
dc -> no_user = 1 ;
264
- dc -> vmsd = & vmstate_pl031 ;
300
+ dc -> vmsd = & vmstate_stm32 ;
265
301
}
266
302
267
- static const TypeInfo pl031_info = {
268
- .name = "pl031 " ,
303
+ static const TypeInfo stm32_info = {
304
+ .name = "stm32 " ,
269
305
.parent = TYPE_SYS_BUS_DEVICE ,
270
- .instance_size = sizeof (pl031_state ),
271
- .class_init = pl031_class_init ,
306
+ .instance_size = sizeof (stm32_tm_state ),
307
+ .class_init = stm32_class_init ,
272
308
};
273
309
274
- static void pl031_register_types (void )
310
+ static void stm32_register_types (void )
275
311
{
276
- type_register_static (& pl031_info );
312
+ type_register_static (& stm32_info );
277
313
}
278
314
279
- type_init (pl031_register_types )
315
+ type_init (stm32_register_types )
0 commit comments