Skip to content

Commit de0f5c9

Browse files
committed
getting it done
1 parent ca1c608 commit de0f5c9

File tree

1 file changed

+133
-97
lines changed

1 file changed

+133
-97
lines changed

hw/timer/stm32.c renamed to hw/timer/stm32_timer.c

Lines changed: 133 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,31 @@
3838
#define DPRINTF(fmt, ...)
3939
#endif
4040

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
4960

5061
typedef struct {
5162
SysBusDevice busdev;
5263
MemoryRegion iomem;
53-
QEMUTimer *timer;
54-
qemu_irq irq;
64+
QEMUTimer *timer;
65+
qemu_irq irq;
5566

5667
/* Needed to preserve the tick_count across migration, even if the
5768
* absolute value of the rtc_clock is different on the source and
@@ -60,112 +71,137 @@ typedef struct {
6071
uint32_t tick_offset_vmstate;
6172
uint32_t tick_offset;
6273

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)
7697
{
7798
qemu_set_irq(s->irq, s->is & s->im);
7899
}
79100

80-
static void pl031_interrupt(void * opaque)
101+
static void stm32_interrupt(void * opaque)
81102
{
82-
pl031_state *s = (pl031_state *)opaque;
103+
stm32_tm_state *s = (stm32_tm_state *)opaque;
83104

84105
s->is = 1;
85106
DPRINTF("Alarm raised\n");
86-
pl031_update(s);
107+
stm32_update(s);
87108
}
88109

89-
static uint32_t pl031_get_count(pl031_state *s)
110+
static uint32_t stm32_get_count(stm32_tm_state *s)
90111
{
91112
int64_t now = qemu_get_clock_ns(rtc_clock);
92113
return s->tick_offset + now / get_ticks_per_sec();
93114
}
94115

95-
static void pl031_set_alarm(pl031_state *s)
116+
static void stm32_set_alarm(stm32_tm_state *s)
96117
{
97118
uint32_t ticks;
98119

99120
/* The timer wraps around. This subtraction also wraps in the same way,
100121
and gives correct results when alarm < now_ticks. */
101-
ticks = s->mr - pl031_get_count(s);
122+
ticks = s->mr - stm32_get_count(s);
102123
DPRINTF("Alarm set in %ud ticks\n", ticks);
103124
if (ticks == 0) {
104125
qemu_del_timer(s->timer);
105-
pl031_interrupt(s);
126+
stm32_interrupt(s);
106127
} else {
107128
int64_t now = qemu_get_clock_ns(rtc_clock);
108129
qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
109130
}
110131
}
111132

112-
static uint64_t pl031_read(void *opaque, hwaddr offset,
133+
static uint64_t stm32_read(void *opaque, hwaddr offset,
113134
unsigned size)
114135
{
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;
119137

120138
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;
141177
default:
142178
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);
144180
break;
145181
}
146182

147183
return 0;
148184
}
149185

150-
static void pl031_write(void * opaque, hwaddr offset,
186+
static void stm32_write(void * opaque, hwaddr offset,
151187
uint64_t value, unsigned size)
152188
{
153-
pl031_state *s = (pl031_state *)opaque;
189+
stm32_tm_state *s = (stm32_tm_state *)opaque;
154190

155191

156192
switch (offset) {
157193
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);
160196
break;
161197
case RTC_MR:
162198
s->mr = value;
163-
pl031_set_alarm(s);
199+
stm32_set_alarm(s);
164200
break;
165201
case RTC_IMSC:
166202
s->im = value & 1;
167203
DPRINTF("Interrupt mask %d\n", s->im);
168-
pl031_update(s);
204+
stm32_update(s);
169205
break;
170206
case RTC_ICR:
171207
/* The PL031 documentation (DDI0224B) states that the interrupt is
@@ -174,7 +210,7 @@ static void pl031_write(void * opaque, hwaddr offset,
174210
cleared when any value is written. */
175211
DPRINTF("Interrupt cleared");
176212
s->is = 0;
177-
pl031_update(s);
213+
stm32_update(s);
178214
break;
179215
case RTC_CR:
180216
/* Written value is ignored. */
@@ -184,96 +220,96 @@ static void pl031_write(void * opaque, hwaddr offset,
184220
case RTC_MIS:
185221
case RTC_RIS:
186222
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",
188224
(int)offset);
189225
break;
190226

191227
default:
192228
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);
194230
break;
195231
}
196232
}
197233

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,
201237
.endianness = DEVICE_NATIVE_ENDIAN,
202238
};
203239

204-
static int pl031_init(SysBusDevice *dev)
240+
static int stm32_init(SysBusDevice *dev)
205241
{
206-
pl031_state *s = FROM_SYSBUS(pl031_state, dev);
242+
stm32_tm_state *s = FROM_SYSBUS(stm32_tm_state, dev);
207243
struct tm tm;
208244

209-
memory_region_init_io(&s->iomem, &pl031_ops, s, "pl031", 0x1000);
245+
memory_region_init_io(&s->iomem, &stm32_ops, s, "stm32", 0x1000);
210246
sysbus_init_mmio(dev, &s->iomem);
211247

212248
sysbus_init_irq(dev, &s->irq);
213249
qemu_get_timedate(&tm, 0);
214250
s->tick_offset = mktimegm(&tm) - qemu_get_clock_ns(rtc_clock) / get_ticks_per_sec();
215251

216-
s->timer = qemu_new_timer_ns(rtc_clock, pl031_interrupt, s);
252+
s->timer = qemu_new_timer_ns(rtc_clock, stm32_interrupt, s);
217253
return 0;
218254
}
219255

220-
static void pl031_pre_save(void *opaque)
256+
static void stm32_pre_save(void *opaque)
221257
{
222-
pl031_state *s = opaque;
258+
stm32_tm_state *s = opaque;
223259

224260
/* tick_offset is base_time - rtc_clock base time. Instead, we want to
225261
* store the base time relative to the vm_clock for backwards-compatibility. */
226262
int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
227263
s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
228264
}
229265

230-
static int pl031_post_load(void *opaque, int version_id)
266+
static int stm32_post_load(void *opaque, int version_id)
231267
{
232-
pl031_state *s = opaque;
268+
stm32_tm_state *s = opaque;
233269

234270
int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
235271
s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
236-
pl031_set_alarm(s);
272+
stm32_set_alarm(s);
237273
return 0;
238274
}
239275

240-
static const VMStateDescription vmstate_pl031 = {
241-
.name = "pl031",
276+
static const VMStateDescription vmstate_stm32 = {
277+
.name = "stm32",
242278
.version_id = 1,
243279
.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,
246282
.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),
253289
VMSTATE_END_OF_LIST()
254290
}
255291
};
256292

257-
static void pl031_class_init(ObjectClass *klass, void *data)
293+
static void stm32_class_init(ObjectClass *klass, void *data)
258294
{
259295
DeviceClass *dc = DEVICE_CLASS(klass);
260296
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
261297

262-
k->init = pl031_init;
298+
k->init = stm32_init;
263299
dc->no_user = 1;
264-
dc->vmsd = &vmstate_pl031;
300+
dc->vmsd = &vmstate_stm32;
265301
}
266302

267-
static const TypeInfo pl031_info = {
268-
.name = "pl031",
303+
static const TypeInfo stm32_info = {
304+
.name = "stm32",
269305
.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,
272308
};
273309

274-
static void pl031_register_types(void)
310+
static void stm32_register_types(void)
275311
{
276-
type_register_static(&pl031_info);
312+
type_register_static(&stm32_info);
277313
}
278314

279-
type_init(pl031_register_types)
315+
type_init(stm32_register_types)

0 commit comments

Comments
 (0)