• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiónf28e129682f5758f68a7b4ac2b76a51006a24895 (tree)
Tiempo2021-05-27 14:10:23
AutorYoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

hw/char: Renesas SCI module.

This module supported SCI / SCIa / SCIF.

Hardware manual.
SCI / SCIF
https://www.renesas.com/us/en/doc/products/mpumcu/001/r01uh0457ej0401_sh7751.pdf
SCIa
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>

Cambiar Resumen

Diferencia incremental

--- a/hw/char/renesas_sci.c
+++ b/hw/char/renesas_sci.c
@@ -1,10 +1,12 @@
11 /*
2- * Renesas Serial Communication Interface
2+ * Renesas Serial Communication Interface (SCI / SCIa / SCIF)
33 *
44 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
55 * (Rev.1.40 R01UH0033EJ0140)
6+ * And SH7751 Group, SH7751R Group User's Manual: Hardware
7+ * (Rev.4.01 R01UH0457EJ0401)
68 *
7- * Copyright (c) 2019 Yoshinori Sato
9+ * Copyright (c) 2020 Yoshinori Sato
810 *
911 * SPDX-License-Identifier: GPL-2.0-or-later
1012 *
@@ -23,15 +25,25 @@
2325
2426 #include "qemu/osdep.h"
2527 #include "qemu/log.h"
28+#include "qapi/error.h"
29+#include "qemu-common.h"
30+#include "hw/hw.h"
2631 #include "hw/irq.h"
32+#include "hw/sysbus.h"
2733 #include "hw/registerfields.h"
28-#include "hw/qdev-properties.h"
2934 #include "hw/qdev-properties-system.h"
35+#include "hw/qdev-clock.h"
3036 #include "hw/char/renesas_sci.h"
3137 #include "migration/vmstate.h"
38+#include "qemu/error-report.h"
3239
33-/* SCI register map */
34-REG8(SMR, 0)
40+/*
41+ * SCI register map
42+ * SCI(a) register size all 8bit.
43+ * SCIF regsister size 8bit and 16bit.
44+ * Allocate 16bit to match the larger one.
45+ */
46+REG32(SMR, 0) /* 8bit */
3547 FIELD(SMR, CKS, 0, 2)
3648 FIELD(SMR, MP, 2, 1)
3749 FIELD(SMR, STOP, 3, 1)
@@ -39,263 +51,840 @@ REG8(SMR, 0)
3951 FIELD(SMR, PE, 5, 1)
4052 FIELD(SMR, CHR, 6, 1)
4153 FIELD(SMR, CM, 7, 1)
42-REG8(BRR, 1)
43-REG8(SCR, 2)
44- FIELD(SCR, CKE, 0, 2)
54+REG32(BRR, 4) /* 8bit */
55+REG32(SCR, 8)
56+ FIELD(SCR, CKE, 0, 2)
4557 FIELD(SCR, TEIE, 2, 1)
4658 FIELD(SCR, MPIE, 3, 1)
59+ FIELD(SCR, REIE, 3, 1)
4760 FIELD(SCR, RE, 4, 1)
4861 FIELD(SCR, TE, 5, 1)
4962 FIELD(SCR, RIE, 6, 1)
5063 FIELD(SCR, TIE, 7, 1)
51-REG8(TDR, 3)
52-REG8(SSR, 4)
64+REG32(TDR, 12) /* 8bit */
65+REG32(SSR, 16) /* 8bit */
5366 FIELD(SSR, MPBT, 0, 1)
5467 FIELD(SSR, MPB, 1, 1)
5568 FIELD(SSR, TEND, 2, 1)
56- FIELD(SSR, ERR, 3, 3)
69+ FIELD(SSR, ERR, 3, 3)
5770 FIELD(SSR, PER, 3, 1)
5871 FIELD(SSR, FER, 4, 1)
5972 FIELD(SSR, ORER, 5, 1)
6073 FIELD(SSR, RDRF, 6, 1)
6174 FIELD(SSR, TDRE, 7, 1)
62-REG8(RDR, 5)
63-REG8(SCMR, 6)
75+REG32(FSR, 16)
76+ FIELD(FSR, DR, 0, 1)
77+ FIELD(FSR, RDF, 1, 1)
78+ FIELD(FSR, RDF_DR, 0, 2)
79+ FIELD(FSR, PER, 2, 1)
80+ FIELD(FSR, FER, 3, 1)
81+ FIELD(FSR, BRK, 4, 1)
82+ FIELD(FSR, TDFE, 5, 1)
83+ FIELD(FSR, TEND, 6, 1)
84+ FIELD(FSR, ER, 7, 1)
85+ FIELD(FSR, FERn, 8, 4)
86+ FIELD(FSR, PERn, 12, 4)
87+REG32(RDR, 20) /* 8bit */
88+REG32(SCMR, 24) /* 8bit */
6489 FIELD(SCMR, SMIF, 0, 1)
6590 FIELD(SCMR, SINV, 2, 1)
6691 FIELD(SCMR, SDIR, 3, 1)
6792 FIELD(SCMR, BCP2, 7, 1)
68-REG8(SEMR, 7)
93+REG32(FCR, 24)
94+ FIELD(FCR, LOOP, 0, 1)
95+ FIELD(FCR, RFRST, 1, 1)
96+ FIELD(FCR, TFRST, 2, 1)
97+ FIELD(FCR, MCE, 3, 1)
98+ FIELD(FCR, TTRG, 4, 2)
99+ FIELD(FCR, RTRG, 6, 2)
100+ FIELD(FCR, RSTRG, 8, 3)
101+REG32(SEMR, 28) /* 8bit */
69102 FIELD(SEMR, ACS0, 0, 1)
70103 FIELD(SEMR, ABCS, 4, 1)
104+REG32(FDR, 28)
105+ FIELD(FDR, Rn, 0, 4)
106+ FIELD(FDR, Tn, 8, 4)
107+REG32(SPTR, 32)
108+ FIELD(SPTR, SPB2DT, 0, 1)
109+ FIELD(SPTR, SPB2IO, 1, 1)
110+ FIELD(SPTR, SCKDT, 2, 1)
111+ FIELD(SPTR, SCKIO, 3, 1)
112+ FIELD(SPTR, CTSDT, 4, 1)
113+ FIELD(SPTR, CTSIO, 5, 1)
114+ FIELD(SPTR, RTSDT, 6, 1)
115+ FIELD(SPTR, RTSIO, 7, 1)
116+ FIELD(SPTR, EIO, 7, 1)
117+REG32(LSR, 36)
118+ FIELD(LSR, ORER, 0, 1)
119+
120+#define SCIF_FIFO_DEPTH 16
71121
72-static int can_receive(void *opaque)
122+static const int sci_rtrg[] = {1, 4, 8, 14};
123+
124+static void update_event_time(RenesasSCIBaseState *sci, int evt, int64_t t)
73125 {
74- RSCIState *sci = RSCI(opaque);
75- if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
76- return 0;
126+ if (t > 0) {
127+ t += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
128+ sci->event[evt].time = t;
129+ if (timer_expire_time_ns(sci->event_timer) > t) {
130+ timer_mod(sci->event_timer, t);
131+ }
77132 } else {
78- return FIELD_EX8(sci->scr, SCR, RE);
133+ sci->event[evt].time = 0;
134+ }
135+}
136+
137+static void sci_irq(RenesasSCIBaseState *sci_common, int req)
138+{
139+ int irq = 0;
140+ int rie;
141+ int tie;
142+ RenesasSCIState *sci = RENESAS_SCI(sci_common);
143+
144+ rie = FIELD_EX16(sci_common->scr, SCR, RIE);
145+ tie = FIELD_EX16(sci_common->scr, SCR, TIE);
146+ switch (req) {
147+ case ERI:
148+ irq = rie && (FIELD_EX16(sci_common->Xsr, SSR, ERR) != 0);
149+ break;
150+ case RXI:
151+ irq = FIELD_EX16(sci_common->Xsr, SSR, RDRF) && rie &&
152+ !FIELD_EX16(sci->sptr, SPTR, EIO);
153+ break;
154+ case TXI:
155+ irq = FIELD_EX16(sci_common->Xsr, SSR, TDRE) && tie;
156+ break;
157+ case BRI_TEI:
158+ irq = FIELD_EX16(sci_common->Xsr, SSR, TEND) &&
159+ FIELD_EX16(sci_common->scr, SCR, TEIE);
160+ break;
79161 }
162+ qemu_set_irq(sci_common->irq[req], irq);
80163 }
81164
82-static void receive(void *opaque, const uint8_t *buf, int size)
165+static void scia_irq(RenesasSCIBaseState *sci, int req)
83166 {
84- RSCIState *sci = RSCI(opaque);
85- sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime;
86- if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) {
87- sci->ssr = FIELD_DP8(sci->ssr, SSR, ORER, 1);
88- if (FIELD_EX8(sci->scr, SCR, RIE)) {
89- qemu_set_irq(sci->irq[ERI], 1);
167+ int irq = 0;
168+ int rie;
169+ int tie;
170+
171+ rie = FIELD_EX16(sci->scr, SCR, RIE);
172+ tie = FIELD_EX16(sci->scr, SCR, TIE);
173+ switch (req) {
174+ case ERI:
175+ irq = (FIELD_EX16(sci->Xsr, SSR, ERR) != 0) && rie;
176+ qemu_set_irq(sci->irq[req], irq);
177+ break;
178+ case RXI:
179+ if (FIELD_EX16(sci->Xsr, SSR, RDRF) && rie) {
180+ qemu_irq_pulse(sci->irq[req]);
90181 }
91- } else {
92- sci->rdr = buf[0];
93- sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 1);
94- if (FIELD_EX8(sci->scr, SCR, RIE)) {
95- qemu_irq_pulse(sci->irq[RXI]);
182+ break;
183+ case TXI:
184+ if (FIELD_EX16(sci->Xsr, SSR, TDRE) && tie) {
185+ qemu_irq_pulse(sci->irq[req]);
186+ }
187+ break;
188+ case BRI_TEI:
189+ irq = FIELD_EX16(sci->Xsr, SSR, TEND) &&
190+ FIELD_EX16(sci->scr, SCR, TEIE);
191+ qemu_set_irq(sci->irq[req], irq);
192+ break;
193+ }
194+}
195+
196+static void scif_irq(RenesasSCIBaseState *sci, int req)
197+{
198+ int irq = 0;
199+ int rie;
200+ int reie;
201+ int tie;
202+
203+ rie = FIELD_EX16(sci->scr, SCR, RIE);
204+ reie = FIELD_EX16(sci->scr, SCR, REIE);
205+ tie = FIELD_EX16(sci->scr, SCR, TIE);
206+ switch (req) {
207+ case ERI:
208+ irq = (rie || reie) && FIELD_EX16(sci->Xsr, FSR, ER);
209+ break;
210+ case RXI:
211+ irq = (FIELD_EX16(sci->Xsr, FSR, RDF_DR) != 0) && rie;
212+ break;
213+ case TXI:
214+ irq = FIELD_EX16(sci->Xsr, FSR, TDFE) & tie;
215+ break;
216+ case BRI_TEI:
217+ irq = (rie || reie) && FIELD_EX16(sci->Xsr, FSR, BRK);
218+ break;
219+ }
220+ qemu_set_irq(sci->irq[req], irq);
221+}
222+
223+static int sci_can_receive(void *opaque)
224+{
225+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
226+ int fifo_free = 0;
227+ if (clock_is_enabled(sci->pck) && FIELD_EX16(sci->scr, SCR, RE)) {
228+ /* Receiver enabled */
229+ fifo_free = fifo8_num_free(&sci->rxfifo);
230+ }
231+ return fifo_free;
232+}
233+
234+static void sci_receive(void *opaque, const uint8_t *buf, int size)
235+{
236+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
237+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
238+ fifo8_push_all(&sci->rxfifo, buf, size);
239+ if (sci->event[RXNEXT].time == 0) {
240+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, RDRF, 1);
241+ update_event_time(sci, RXNEXT, sci->trtime);
242+ rc->irq_fn(sci, RXI);
243+ }
244+}
245+
246+static int scif_can_receive(void *opaque)
247+{
248+ RenesasSCIFState *scif = RENESAS_SCIF(opaque);
249+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
250+ int fifo_free = 0;
251+ if (clock_is_enabled(sci->pck) && FIELD_EX16(sci->scr, SCR, RE)) {
252+ /* Receiver enabled */
253+ fifo_free = fifo8_num_free(&sci->rxfifo);
254+ if (fifo_free == 0) {
255+ /* FIFO overrun */
256+ scif->lsr = FIELD_DP16(scif->lsr, LSR, ORER, 1);
257+ scif_irq(sci, ERI);
258+ }
259+ }
260+ return fifo_free;
261+}
262+
263+static void scif_receive(void *opaque, const uint8_t *buf, int size)
264+{
265+ RenesasSCIFState *scif = RENESAS_SCIF(opaque);
266+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
267+ int rtrg;
268+
269+ fifo8_push_all(&sci->rxfifo, buf, size);
270+ if (sci->event[RXNEXT].time == 0) {
271+ rtrg = sci_rtrg[FIELD_EX16(scif->fcr, FCR, RTRG)];
272+ if (fifo8_num_used(&sci->rxfifo) >= rtrg) {
273+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, RDF, 1);
274+ } else {
275+ update_event_time(sci, RXTOUT, 15 * sci->etu);
96276 }
277+ scif_irq(sci, RXI);
97278 }
98279 }
99280
100-static void send_byte(RSCIState *sci)
281+static void sci_send_byte(RenesasSCIBaseState *sci)
101282 {
102283 if (qemu_chr_fe_backend_connected(&sci->chr)) {
103284 qemu_chr_fe_write_all(&sci->chr, &sci->tdr, 1);
104285 }
105- timer_mod(&sci->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime);
106- sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 0);
107- sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1);
108- qemu_set_irq(sci->irq[TEI], 0);
109- if (FIELD_EX8(sci->scr, SCR, TIE)) {
110- qemu_irq_pulse(sci->irq[TXI]);
286+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TEND, 0);
287+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TDRE, 1);
288+}
289+
290+static int transmit_byte(RenesasSCIFState *scif)
291+{
292+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(scif);
293+ int64_t elapsed;
294+ int byte = 0;
295+ if (sci->tx_start_time > 0) {
296+ elapsed = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - sci->tx_start_time;
297+ byte = elapsed / sci->trtime;
298+ if (byte > scif->tdcnt) {
299+ byte = scif->tdcnt;
300+ }
111301 }
302+ return byte;
112303 }
113304
114-static void txend(void *opaque)
305+static int64_t scif_rx_timeout(RenesasSCIBaseState *sci)
115306 {
116- RSCIState *sci = RSCI(opaque);
117- if (!FIELD_EX8(sci->ssr, SSR, TDRE)) {
118- send_byte(sci);
307+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, DR, 1);
308+ scif_irq(sci, RXI);
309+ return 0;
310+}
311+
312+static int64_t sci_rx_next(RenesasSCIBaseState *sci)
313+{
314+ int64_t next_event = 0;
315+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
316+ if (FIELD_EX16(sci->Xsr, SSR, RDRF)) {
317+ /* Receiver overrun */
318+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, ORER, 1);
319+ rc->irq_fn(sci, ERI);
119320 } else {
120- sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1);
121- if (FIELD_EX8(sci->scr, SCR, TEIE)) {
122- qemu_set_irq(sci->irq[TEI], 1);
321+ if (!fifo8_is_empty(&sci->rxfifo)) {
322+ /* set next event */
323+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, RDRF, 1);
324+ rc->irq_fn(sci, RXI);
325+ next_event = sci->trtime;
123326 }
124327 }
328+ return next_event;
125329 }
126330
127-static void update_trtime(RSCIState *sci)
331+static int64_t sci_tx_empty(RenesasSCIBaseState *sci)
128332 {
129- /* char per bits */
130- sci->trtime = 8 - FIELD_EX8(sci->smr, SMR, CHR);
131- sci->trtime += FIELD_EX8(sci->smr, SMR, PE);
132- sci->trtime += FIELD_EX8(sci->smr, SMR, STOP) + 1;
133- /* x bit transmit time (32 * divrate * brr) / base freq */
134- sci->trtime *= 32 * sci->brr;
135- sci->trtime *= 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS));
136- sci->trtime *= NANOSECONDS_PER_SECOND;
137- sci->trtime /= sci->input_freq;
333+ int64_t ret = 0;
334+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
335+ if (!FIELD_EX16(sci->Xsr, SSR, TDRE)) {
336+ sci_send_byte(sci);
337+ ret = sci->trtime;
338+ rc->irq_fn(sci, TXI);
339+ } else {
340+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TEND, 1);
341+ rc->irq_fn(sci, BRI_TEI);
342+ }
343+ return ret;
138344 }
139345
140-static bool sci_is_tr_enabled(RSCIState *sci)
346+static int64_t scif_tx_empty(RenesasSCIBaseState *sci)
141347 {
142- return FIELD_EX8(sci->scr, SCR, TE) || FIELD_EX8(sci->scr, SCR, RE);
348+ RenesasSCIFState *scif = RENESAS_SCIF(sci);
349+ scif->tdcnt -= transmit_byte(scif);
350+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TDFE, 1);
351+ scif_irq(sci, TXI);
352+ return 0;
143353 }
144354
145-static void sci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
355+static int64_t scif_tx_end(RenesasSCIBaseState *sci)
146356 {
147- RSCIState *sci = RSCI(opaque);
357+ RenesasSCIFState *scif = RENESAS_SCIF(sci);
358+ scif->tdcnt = 0;
359+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TEND, 1);
360+ return 0;
361+}
148362
149- switch (offset) {
150- case A_SMR:
151- if (!sci_is_tr_enabled(sci)) {
152- sci->smr = val;
153- update_trtime(sci);
363+static void sci_timer_event(void *opaque)
364+{
365+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
366+ int64_t now, next, t;
367+ int i;
368+
369+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
370+ next = INT64_MAX;
371+ for (i = 0; i < NR_SCI_EVENT; i++) {
372+ if (sci->event[i].time > 0 && sci->event[i].time <= now) {
373+ t = sci->event[i].handler(sci);
374+ sci->event[i].time = (t > 0) ? now + t : 0;
154375 }
155- break;
156- case A_BRR:
157- if (!sci_is_tr_enabled(sci)) {
158- sci->brr = val;
159- update_trtime(sci);
376+ if (sci->event[i].time > 0) {
377+ next = MIN(next, sci->event[i].time);
160378 }
161- break;
379+ }
380+ if (next < INT64_MAX) {
381+ timer_mod(sci->event_timer, next);
382+ } else {
383+ timer_del(sci->event_timer);
384+ }
385+}
386+
387+static int static_divrate(RenesasSCIBaseState *sci)
388+{
389+ /* SCI / SCIF have static divide rate */
390+ return 32;
391+}
392+
393+static int scia_divrate(RenesasSCIBaseState *sci)
394+{
395+ /*
396+ * SEMR.ABCS = 0 -> 32
397+ * SEMR.ABCS = 1 -> 16
398+ */
399+ RenesasSCIAState *scia = RENESAS_SCIA(sci);
400+ return 16 * (2 - FIELD_EX8(scia->semr, SEMR, ABCS));
401+}
402+
403+static void update_trtime(RenesasSCIBaseState *sci)
404+{
405+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
406+ int cks = 1 << (2 * FIELD_EX16(sci->smr, SMR, CKS));
407+ if (sci->input_freq > 0) {
408+ /* x bit transmit time (divrate * brr) / base freq */
409+ sci->etu = rc->divrate(sci) * cks;
410+ sci->etu *= sci->brr + 1;
411+ sci->etu *= NANOSECONDS_PER_SECOND;
412+ sci->etu /= sci->input_freq;
413+
414+ /* char per bits */
415+ sci->trtime = 8 - FIELD_EX16(sci->smr, SMR, CHR);
416+ sci->trtime += FIELD_EX16(sci->smr, SMR, PE);
417+ sci->trtime += FIELD_EX16(sci->smr, SMR, STOP) + 1 + 1;
418+ sci->trtime *= sci->etu;
419+ }
420+}
421+
422+static void sci_pck_update(void *opaque, ClockEvent evt)
423+{
424+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
425+
426+ sci->input_freq = clock_get_hz(sci->pck);
427+ update_trtime(sci);
428+}
429+
430+#define IS_TR_ENABLED(scr) \
431+ (FIELD_EX16(scr, SCR, TE) || FIELD_EX16(scr, SCR, RE))
432+
433+static hwaddr map_address(RenesasSCIBaseState *sci, hwaddr addr)
434+{
435+ return addr << (2 - sci->regshift);
436+}
437+
438+static void sci_common_write(void *opaque, hwaddr addr,
439+ uint64_t val, unsigned size)
440+{
441+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
442+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(opaque);
443+ switch (addr) {
162444 case A_SCR:
163445 sci->scr = val;
164- if (FIELD_EX8(sci->scr, SCR, TE)) {
165- sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1);
166- sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1);
167- if (FIELD_EX8(sci->scr, SCR, TIE)) {
168- qemu_irq_pulse(sci->irq[TXI]);
169- }
446+ if (FIELD_EX16(sci->scr, SCR, TE)) {
447+ /* Transmitter enable */
448+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TDRE, 1);
449+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TEND, 1);
450+ rc->irq_fn(sci, TXI);
451+ rc->irq_fn(sci, BRI_TEI);
452+ } else {
453+ /* Transmitter disable */
454+ update_event_time(sci, TXEND, 0);
455+ update_event_time(sci, TXEMPTY, 0);
456+ }
457+ break;
458+ case A_SMR:
459+ sci->smr = val;
460+ update_trtime(sci);
461+ break;
462+ case A_BRR:
463+ sci->brr = val;
464+ update_trtime(sci);
465+ break;
466+ default:
467+ qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX
468+ " not implemented\n", addr);
469+ }
470+}
471+
472+static void sci_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
473+{
474+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
475+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
476+ bool tx_start;
477+
478+ if (!clock_is_enabled(sci->pck)) {
479+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCI %d is stopped.\n",
480+ sci->unit);
481+ return ;
482+ }
483+ addr = map_address(sci, addr);
484+ switch (addr) {
485+ case A_TDR:
486+ sci->tdr = val;
487+ break;
488+ case A_SSR:
489+ /* Mask for read only bits */
490+ sci->Xsr = FIELD_DP16(RENESAS_SCI_BASE(sci)->Xsr, SSR, MPBT,
491+ FIELD_EX16(val, SSR, MPBT));
492+ sci->Xsr &= (val | 0x07);
493+ /* Clear ERI */
494+ rc->irq_fn(sci, ERI);
495+ tx_start = FIELD_EX16(sci->read_Xsr, SSR, TDRE) &&
496+ !FIELD_EX16(sci->Xsr, SSR, TDRE) &&
497+ (FIELD_EX16(sci->Xsr, SSR, ERR) == 0);
498+ if (tx_start) {
499+ sci_send_byte(sci);
500+ update_event_time(sci, TXEMPTY, sci->trtime);
501+ rc->irq_fn(sci, TXI);
170502 }
171- if (!FIELD_EX8(sci->scr, SCR, TEIE)) {
172- qemu_set_irq(sci->irq[TEI], 0);
503+ break;
504+ case A_SPTR:
505+ RENESAS_SCI(sci)->sptr = val;
506+ break;
507+ default:
508+ sci_common_write(sci, addr, val, size);
509+ }
510+}
511+
512+static void scia_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
513+{
514+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
515+ RenesasSCIAState *scia = RENESAS_SCIA(opaque);
516+
517+ if (!clock_is_enabled(sci->pck)) {
518+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCIa %d is stopped.\n",
519+ sci->unit);
520+ return ;
521+ }
522+ addr = map_address(sci, addr);
523+ switch (addr) {
524+ case A_SMR:
525+ if (IS_TR_ENABLED(sci->scr)) {
526+ qemu_log_mask(LOG_GUEST_ERROR,
527+ "reneas_sci: SMR write protected.\n");
528+ } else {
529+ sci_common_write(sci, addr, val, size);
173530 }
174- if (!FIELD_EX8(sci->scr, SCR, RIE)) {
175- qemu_set_irq(sci->irq[ERI], 0);
531+ break;
532+ case A_BRR:
533+ if (IS_TR_ENABLED(sci->scr)) {
534+ qemu_log_mask(LOG_GUEST_ERROR,
535+ "reneas_sci: BRR write protected.\n");
536+ break;
537+ } else {
538+ sci_common_write(sci, addr, val, size);
176539 }
177540 break;
178541 case A_TDR:
179542 sci->tdr = val;
180- if (FIELD_EX8(sci->ssr, SSR, TEND)) {
181- send_byte(sci);
543+ if (FIELD_EX16(sci->Xsr, SSR, TEND)) {
544+ update_event_time(sci, TXEMPTY, sci->trtime);
545+ sci_send_byte(sci);
182546 } else {
183- sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0);
547+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, TDRE, 0);
184548 }
549+ scia_irq(sci, TXI);
550+ scia_irq(sci, BRI_TEI);
185551 break;
186552 case A_SSR:
187- sci->ssr = FIELD_DP8(sci->ssr, SSR, MPBT,
188- FIELD_EX8(val, SSR, MPBT));
189- sci->ssr = FIELD_DP8(sci->ssr, SSR, ERR,
190- FIELD_EX8(val, SSR, ERR) & 0x07);
191- if (FIELD_EX8(sci->read_ssr, SSR, ERR) &&
192- FIELD_EX8(sci->ssr, SSR, ERR) == 0) {
193- qemu_set_irq(sci->irq[ERI], 0);
194- }
195- break;
196- case A_RDR:
197- qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: RDR is read only.\n");
553+ /* Mask for read only bits */
554+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, MPBT,
555+ FIELD_EX16(val, SSR, MPBT));
556+ sci->Xsr &= (val | 0xc7);
557+ /* Clear ERI */
558+ scia_irq(sci, ERI);
198559 break;
199560 case A_SCMR:
200- sci->scmr = val; break;
201- case A_SEMR: /* SEMR */
202- sci->semr = val; break;
561+ scia->scmr = val;
562+ break;
563+ case A_SEMR:
564+ scia->semr = val;
565+ break;
203566 default:
204- qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX " "
205- "not implemented\n",
206- offset);
567+ sci_common_write(sci, addr, val, size);
568+ break;
207569 }
208570 }
209571
210-static uint64_t sci_read(void *opaque, hwaddr offset, unsigned size)
572+static void scif_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
211573 {
212- RSCIState *sci = RSCI(opaque);
574+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
575+ RenesasSCIFState *scif = RENESAS_SCIF(opaque);
576+ int txtrg;
577+ int rxtrg;
578+ uint16_t ssr_mask;
579+ uint8_t txd;
580+
581+ if (!clock_is_enabled(sci->pck)) {
582+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCIF %d is stopped.\n",
583+ sci->unit);
584+ return ;
585+ }
586+ txtrg = 1 << (3 - FIELD_EX16(scif->fcr, FCR, TTRG));
587+ addr = map_address(sci, addr);
588+ switch (addr) {
589+ case A_SCR:
590+ sci->scr = val;
591+ if (FIELD_EX16(sci->scr, SCR, TE)) {
592+ /* Transmitter enable */
593+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TEND, 1);
594+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TDFE, 1);
595+ sci->tx_start_time = 0;
596+ scif_irq(sci, TXI);
597+ } else {
598+ /* Transmitter disable */
599+ update_event_time(sci, TXEND, 0);
600+ update_event_time(sci, TXEMPTY, 0);
601+ }
602+ break;
603+ case A_TDR:
604+ if (sci->tx_start_time > 0) {
605+ scif->tdcnt -= transmit_byte(scif);
606+ } else {
607+ sci->tx_start_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
608+ }
609+ if (scif->tdcnt >= SCIF_FIFO_DEPTH) {
610+ break;
611+ }
612+ txd = val;
613+ if (qemu_chr_fe_backend_connected(&sci->chr)) {
614+ qemu_chr_fe_write_all(&sci->chr, &txd, 1);
615+ }
616+ if (FIELD_EX16(scif->fcr, FCR, LOOP) && scif_can_receive(sci) > 0) {
617+ /* Loopback mode */
618+ scif_receive(sci, &txd, 1);
619+ }
620+ scif->tdcnt++;
621+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TEND, 0);
622+ update_event_time(sci, TXEND, scif->tdcnt);
623+ if (scif->tdcnt > txtrg) {
624+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, TDFE, 0);
625+ update_event_time(sci, TXEMPTY, scif->tdcnt - txtrg + 1);
626+ scif_irq(sci, TXI);
627+ }
628+ break;
629+ case A_FSR:
630+ rxtrg = sci_rtrg[FIELD_EX16(scif->fcr, FCR, RTRG)];
631+ ssr_mask = ~(sci->read_Xsr & 0xf3);
632+ scif->tdcnt -= transmit_byte(scif);
633+ if (scif->tdcnt < txtrg) {
634+ ssr_mask = FIELD_DP16(ssr_mask, FSR, TDFE, 1);
635+ }
636+ if (fifo8_num_used(&sci->rxfifo) >= rxtrg) {
637+ ssr_mask = FIELD_DP16(ssr_mask, FSR, RDF, 1);
638+ }
639+ sci->Xsr &= (val | ssr_mask);
640+ scif_irq(sci, ERI);
641+ scif_irq(sci, RXI);
642+ scif_irq(sci, TXI);
643+ break;
644+ case A_FCR:
645+ scif->fcr = val;
646+ if (FIELD_EX16(scif->fcr, FCR, RFRST)) {
647+ fifo8_reset(&sci->rxfifo);
648+ update_event_time(sci, RXTOUT, 0);
649+ update_event_time(sci, RXNEXT, 0);
650+ }
651+ if (FIELD_EX16(scif->fcr, FCR, TFRST)) {
652+ scif->tdcnt = 0;
653+ }
654+ break;
655+ case A_FDR:
656+ qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: FDR is read only.\n");
657+ break;
658+ case A_SPTR:
659+ scif->sptr = val;
660+ break;
661+ case A_LSR:
662+ if (FIELD_EX16(scif->read_lsr, LSR, ORER) != 1) {
663+ val = FIELD_DP16(val, LSR, ORER, 1);
664+ }
665+ scif->lsr &= val;
666+ scif_irq(sci, ERI);
667+ break;
668+ default:
669+ sci_common_write(sci, addr, val, size);
670+ break;
671+ }
672+}
213673
214- switch (offset) {
674+static uint64_t sci_common_read(void *opaque, hwaddr addr, unsigned size)
675+{
676+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
677+ switch (addr) {
215678 case A_SMR:
216679 return sci->smr;
217680 case A_BRR:
218681 return sci->brr;
219682 case A_SCR:
220683 return sci->scr;
221- case A_TDR:
222- return sci->tdr;
223- case A_SSR:
224- sci->read_ssr = sci->ssr;
225- return sci->ssr;
684+ case A_FSR: /* A_SSR */
685+ sci->read_Xsr = sci->Xsr;
686+ return sci->Xsr;
226687 case A_RDR:
227- sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 0);
228- return sci->rdr;
229- case A_SCMR:
230- return sci->scmr;
231- case A_SEMR:
232- return sci->semr;
688+ if (fifo8_num_used(&sci->rxfifo) > 0) {
689+ return fifo8_pop(&sci->rxfifo);
690+ } else {
691+ return 0xff;
692+ }
233693 default:
234694 qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX
235- " not implemented.\n", offset);
695+ " not implemented.\n", addr);
236696 }
237697 return UINT64_MAX;
238698 }
239699
240-static const MemoryRegionOps sci_ops = {
241- .write = sci_write,
242- .read = sci_read,
243- .endianness = DEVICE_NATIVE_ENDIAN,
244- .impl.max_access_size = 1,
245- .valid.max_access_size = 1,
246-};
700+static uint64_t sci_read(void *opaque, hwaddr addr, unsigned size)
701+{
702+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
703+ addr = map_address(sci, addr);
704+
705+ if (clock_is_enabled(sci->pck)) {
706+ switch (addr) {
707+ case A_TDR:
708+ return sci->tdr;
709+ case A_SPTR:
710+ return RENESAS_SCI(sci)->sptr;
711+ default:
712+ return sci_common_read(sci, addr, size);
713+ }
714+ } else {
715+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCI %d is stopped.\n",
716+ sci->unit);
717+ }
718+ return UINT64_MAX;
719+}
247720
248-static void rsci_reset(DeviceState *dev)
721+static uint64_t scia_read(void *opaque, hwaddr addr, unsigned size)
249722 {
250- RSCIState *sci = RSCI(dev);
251- sci->smr = sci->scr = 0x00;
252- sci->brr = 0xff;
253- sci->tdr = 0xff;
254- sci->rdr = 0x00;
255- sci->ssr = 0x84;
256- sci->scmr = 0x00;
257- sci->semr = 0x00;
258- sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
723+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
724+ RenesasSCIAState *scia = RENESAS_SCIA(opaque);
725+
726+ if (clock_is_enabled(sci->pck)) {
727+ addr = map_address(sci, addr);
728+ switch (addr) {
729+ case A_TDR:
730+ return sci->tdr;
731+ case A_RDR:
732+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, RDRF, 0);
733+ return fifo8_pop(&sci->rxfifo);
734+ case A_SCMR:
735+ return scia->scmr;
736+ default:
737+ return sci_common_read(sci, addr, size);
738+ }
739+ } else {
740+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCIa %d is stopped.\n",
741+ sci->unit);
742+ }
743+ return UINT64_MAX;
744+}
745+
746+static uint64_t scif_read(void *opaque, hwaddr addr, unsigned size)
747+{
748+ RenesasSCIFState *scif = RENESAS_SCIF(opaque);
749+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
750+ uint64_t ret;
751+
752+ if (clock_is_enabled(sci->pck)) {
753+ addr = map_address(sci, addr);
754+ switch (addr) {
755+ case A_FCR:
756+ return scif->fcr & 0x7ff;
757+ case A_FDR:
758+ ret = 0;
759+ ret = FIELD_DP16(ret, FDR, Rn, fifo8_num_used(&sci->rxfifo));
760+ ret = FIELD_DP16(ret, FDR, Tn, scif->tdcnt - transmit_byte(scif));
761+ return ret;
762+ case A_SPTR:
763+ return scif->sptr;
764+ case A_LSR:
765+ scif->read_lsr = scif->lsr;
766+ return scif->lsr;
767+ default:
768+ return sci_common_read(sci, addr, size);
769+ }
770+ } else {
771+ qemu_log_mask(LOG_GUEST_ERROR, "renesas_sci: SCIF %d is stopped.\n",
772+ sci->unit);
773+ }
774+ return UINT64_MAX;
775+}
776+
777+static void rsci_common_init(Object *obj)
778+{
779+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(obj);
780+ SysBusDevice *d = SYS_BUS_DEVICE(obj);
781+ int i;
782+
783+ for (i = 0; i < SCI_NR_IRQ; i++) {
784+ sysbus_init_irq(d, &sci->irq[i]);
785+ }
786+ fifo8_create(&sci->rxfifo, SCIF_FIFO_DEPTH);
787+ sci->event_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sci_timer_event, sci);
788+ sci->pck = qdev_init_clock_in(DEVICE(d), "pck",
789+ sci_pck_update, sci, ClockUpdate);
259790 }
260791
261792 static void sci_event(void *opaque, QEMUChrEvent event)
262793 {
263- RSCIState *sci = RSCI(opaque);
794+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
795+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
796+ if (clock_is_enabled(sci->pck) && event == CHR_EVENT_BREAK) {
797+ sci->Xsr = FIELD_DP16(sci->Xsr, SSR, FER, 1);
798+ rc->irq_fn(sci, BRI_TEI);
799+ }
800+}
801+
802+static void scif_event(void *opaque, QEMUChrEvent event)
803+{
804+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(opaque);
264805 if (event == CHR_EVENT_BREAK) {
265- sci->ssr = FIELD_DP8(sci->ssr, SSR, FER, 1);
266- if (FIELD_EX8(sci->scr, SCR, RIE)) {
267- qemu_set_irq(sci->irq[ERI], 1);
268- }
806+ sci->Xsr = FIELD_DP16(sci->Xsr, FSR, BRK, 1);
807+ scif_irq(sci, BRI_TEI);
269808 }
270809 }
271810
272-static void rsci_realize(DeviceState *dev, Error **errp)
811+static void rsci_common_realize(DeviceState *dev, Error **errp)
273812 {
274- RSCIState *sci = RSCI(dev);
813+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(dev);
275814
276- if (sci->input_freq == 0) {
815+ if (sci->regshift != 8 && sci->regshift != 16 && sci->regshift != 32) {
277816 qemu_log_mask(LOG_GUEST_ERROR,
278- "renesas_sci: input-freq property must be set.");
817+ "renesas_sci: Invalid register size.");
279818 return;
280819 }
281- qemu_chr_fe_set_handlers(&sci->chr, can_receive, receive,
282- sci_event, NULL, sci, NULL, true);
820+
821+ sci->smr = sci->scr = 0x00;
822+ sci->brr = 0xff;
823+ sci->tdr = 0xff;
824+ sci->Xsr = 0x84;
825+ update_trtime(sci);
826+
283827 }
284828
285-static void rsci_init(Object *obj)
829+static void register_mmio(RenesasSCIBaseState *sci, int size)
286830 {
287- SysBusDevice *d = SYS_BUS_DEVICE(obj);
288- RSCIState *sci = RSCI(obj);
289- int i;
831+ SysBusDevice *d = SYS_BUS_DEVICE(sci);
832+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_GET_CLASS(sci);
290833
291- memory_region_init_io(&sci->memory, OBJECT(sci), &sci_ops,
292- sci, "renesas-sci", 0x8);
834+ memory_region_init_io(&sci->memory, OBJECT(sci), rc->ops,
835+ sci, "renesas-sci", size);
293836 sysbus_init_mmio(d, &sci->memory);
837+ memory_region_init_alias(&sci->memory_p4, NULL, "renesas-sci-p4",
838+ &sci->memory, 0, size);
839+ sysbus_init_mmio(d, &sci->memory_p4);
840+ memory_region_init_alias(&sci->memory_a7, NULL, "renesas-sci-a7",
841+ &sci->memory, 0, size);
842+ sysbus_init_mmio(d, &sci->memory_a7);
843+}
294844
295- for (i = 0; i < SCI_NR_IRQ; i++) {
296- sysbus_init_irq(d, &sci->irq[i]);
297- }
298- timer_init_ns(&sci->timer, QEMU_CLOCK_VIRTUAL, txend, sci);
845+static void rsci_realize(DeviceState *dev, Error **errp)
846+{
847+ RenesasSCIState *sci = RENESAS_SCI(dev);
848+ RenesasSCIBaseState *common = RENESAS_SCI_BASE(dev);
849+
850+ rsci_common_realize(dev, errp);
851+
852+ register_mmio(common, 8 * (1 << common->regshift));
853+ qemu_chr_fe_set_handlers(&common->chr, sci_can_receive, sci_receive,
854+ sci_event, NULL, sci, NULL, true);
855+
856+ sci->sptr = 0x00;
857+}
858+
859+static void rscia_realize(DeviceState *dev, Error **errp)
860+{
861+ RenesasSCIAState *sci = RENESAS_SCIA(dev);
862+ RenesasSCIBaseState *common = RENESAS_SCI_BASE(dev);
863+
864+ rsci_common_realize(dev, errp);
865+
866+ register_mmio(common, 8 * (1 << common->regshift));
867+ qemu_chr_fe_set_handlers(&common->chr, sci_can_receive, sci_receive,
868+ sci_event, NULL, sci, NULL, true);
869+
870+ sci->scmr = 0x00;
871+ sci->semr = 0x00;
872+}
873+
874+static void rscif_realize(DeviceState *dev, Error **errp)
875+{
876+ RenesasSCIFState *sci = RENESAS_SCIF(dev);
877+ RenesasSCIBaseState *common = RENESAS_SCI_BASE(sci);
878+
879+ rsci_common_realize(dev, errp);
880+
881+ register_mmio(common, 10 * (1 << common->regshift));
882+ qemu_chr_fe_set_handlers(&common->chr, scif_can_receive, scif_receive,
883+ scif_event, NULL, sci, NULL, true);
884+ common->Xsr = 0x0060;
885+ sci->fcr = 0x0000;
886+ sci->sptr = 0x0000;
887+ sci->lsr = 0x0000;
299888 }
300889
301890 static const VMStateDescription vmstate_rsci = {
@@ -303,49 +892,141 @@ static const VMStateDescription vmstate_rsci = {
303892 .version_id = 1,
304893 .minimum_version_id = 1,
305894 .fields = (VMStateField[]) {
306- VMSTATE_INT64(trtime, RSCIState),
307- VMSTATE_INT64(rx_next, RSCIState),
308- VMSTATE_UINT8(smr, RSCIState),
309- VMSTATE_UINT8(brr, RSCIState),
310- VMSTATE_UINT8(scr, RSCIState),
311- VMSTATE_UINT8(tdr, RSCIState),
312- VMSTATE_UINT8(ssr, RSCIState),
313- VMSTATE_UINT8(rdr, RSCIState),
314- VMSTATE_UINT8(scmr, RSCIState),
315- VMSTATE_UINT8(semr, RSCIState),
316- VMSTATE_UINT8(read_ssr, RSCIState),
317- VMSTATE_TIMER(timer, RSCIState),
318895 VMSTATE_END_OF_LIST()
319896 }
320897 };
321898
322899 static Property rsci_properties[] = {
323- DEFINE_PROP_UINT64("input-freq", RSCIState, input_freq, 0),
324- DEFINE_PROP_CHR("chardev", RSCIState, chr),
900+ DEFINE_PROP_INT32("register-size", RenesasSCIBaseState,
901+ regshift, SCI_REGSIZE_32),
902+ DEFINE_PROP_UINT32("unit", RenesasSCIBaseState, unit, 0),
903+ DEFINE_PROP_CHR("chardev", RenesasSCIBaseState, chr),
325904 DEFINE_PROP_END_OF_LIST(),
326905 };
327906
328-static void rsci_class_init(ObjectClass *klass, void *data)
907+static void rsci_init(Object *obj)
329908 {
909+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(obj);
910+ sci->event[RXNEXT].handler = sci_rx_next;
911+ sci->event[TXEMPTY].handler = sci_tx_empty;
912+}
913+
914+static void rscif_init(Object *obj)
915+{
916+ RenesasSCIBaseState *sci = RENESAS_SCI_BASE(obj);
917+ sci->event[RXTOUT].handler = scif_rx_timeout;
918+ sci->event[TXEMPTY].handler = scif_tx_empty;
919+ sci->event[TXEND].handler = scif_tx_end;
920+}
921+
922+static void rsci_common_class_init(ObjectClass *klass, void *data)
923+{
924+ RenesasSCIBaseClass *rc = RENESAS_SCI_BASE_CLASS(klass);
330925 DeviceClass *dc = DEVICE_CLASS(klass);
331926
332- dc->realize = rsci_realize;
333927 dc->vmsd = &vmstate_rsci;
334- dc->reset = rsci_reset;
335928 device_class_set_props(dc, rsci_properties);
929+ rc->divrate = static_divrate;
336930 }
337931
338-static const TypeInfo rsci_info = {
339- .name = TYPE_RENESAS_SCI,
340- .parent = TYPE_SYS_BUS_DEVICE,
341- .instance_size = sizeof(RSCIState),
342- .instance_init = rsci_init,
343- .class_init = rsci_class_init,
932+static const MemoryRegionOps sci_ops = {
933+ .read = sci_read,
934+ .write = sci_write,
935+ .endianness = DEVICE_NATIVE_ENDIAN,
936+ .valid = {
937+ .min_access_size = 1,
938+ .max_access_size = 4,
939+ },
344940 };
345941
346-static void rsci_register_types(void)
942+static void rsci_class_init(ObjectClass *klass, void *data)
347943 {
348- type_register_static(&rsci_info);
944+ RenesasSCIBaseClass *comm_rc = RENESAS_SCI_BASE_CLASS(klass);
945+ DeviceClass *dc = DEVICE_CLASS(klass);
946+
947+ comm_rc->ops = &sci_ops;
948+ comm_rc->irq_fn = sci_irq;
949+ dc->realize = rsci_realize;
349950 }
350951
351-type_init(rsci_register_types)
952+static const MemoryRegionOps scia_ops = {
953+ .read = scia_read,
954+ .write = scia_write,
955+ .endianness = DEVICE_NATIVE_ENDIAN,
956+ .valid = {
957+ .min_access_size = 1,
958+ .max_access_size = 4,
959+ },
960+};
961+
962+static void rscia_class_init(ObjectClass *klass, void *data)
963+{
964+ RenesasSCIBaseClass *comm_rc = RENESAS_SCI_BASE_CLASS(klass);
965+ DeviceClass *dc = DEVICE_CLASS(klass);
966+
967+ comm_rc->ops = &scia_ops;
968+ comm_rc->irq_fn = scia_irq;
969+ comm_rc->divrate = scia_divrate;
970+
971+ dc->realize = rscia_realize;
972+}
973+
974+static const MemoryRegionOps scif_ops = {
975+ .read = scif_read,
976+ .write = scif_write,
977+ .endianness = DEVICE_NATIVE_ENDIAN,
978+ .valid = {
979+ .min_access_size = 1,
980+ .max_access_size = 4,
981+ },
982+};
983+
984+static void rscif_class_init(ObjectClass *klass, void *data)
985+{
986+ RenesasSCIBaseClass *comm_rc = RENESAS_SCI_BASE_CLASS(klass);
987+ DeviceClass *dc = DEVICE_CLASS(klass);
988+
989+ comm_rc->ops = &scif_ops;
990+ comm_rc->irq_fn = scif_irq;
991+
992+ dc->realize = rscif_realize;
993+}
994+
995+static const TypeInfo renesas_sci_info[] = {
996+ {
997+ .name = TYPE_RENESAS_SCI_BASE,
998+ .parent = TYPE_SYS_BUS_DEVICE,
999+ .instance_size = sizeof(RenesasSCIBaseState),
1000+ .instance_init = rsci_common_init,
1001+ .class_init = rsci_common_class_init,
1002+ .class_size = sizeof(RenesasSCIBaseClass),
1003+ .abstract = true,
1004+ },
1005+ {
1006+ .name = TYPE_RENESAS_SCI,
1007+ .parent = TYPE_RENESAS_SCI_BASE,
1008+ .instance_size = sizeof(RenesasSCIState),
1009+ .instance_init = rsci_init,
1010+ .class_init = rsci_class_init,
1011+ .class_size = sizeof(RenesasSCIClass),
1012+ },
1013+ {
1014+ .name = TYPE_RENESAS_SCIA,
1015+ .parent = TYPE_RENESAS_SCI_BASE,
1016+ .instance_size = sizeof(RenesasSCIAState),
1017+ /* Initializer same of SCI */
1018+ .instance_init = rsci_init,
1019+ .class_init = rscia_class_init,
1020+ .class_size = sizeof(RenesasSCIAClass),
1021+ },
1022+ {
1023+ .name = TYPE_RENESAS_SCIF,
1024+ .parent = TYPE_RENESAS_SCI_BASE,
1025+ .instance_size = sizeof(RenesasSCIFState),
1026+ .instance_init = rscif_init,
1027+ .class_init = rscif_class_init,
1028+ .class_size = sizeof(RenesasSCIFClass),
1029+ },
1030+};
1031+
1032+DEFINE_TYPES(renesas_sci_info)
--- a/include/hw/char/renesas_sci.h
+++ b/include/hw/char/renesas_sci.h
@@ -1,54 +1,137 @@
11 /*
22 * Renesas Serial Communication Interface
33 *
4- * Copyright (c) 2018 Yoshinori Sato
4+ * Copyright (c) 2020 Yoshinori Sato
5+ *
6+ * This code is licensed under the GPL version 2 or later.
57 *
6- * SPDX-License-Identifier: GPL-2.0-or-later
78 */
89
9-#ifndef HW_CHAR_RENESAS_SCI_H
10-#define HW_CHAR_RENESAS_SCI_H
11-
1210 #include "chardev/char-fe.h"
11+#include "qemu/timer.h"
12+#include "qemu/fifo8.h"
1313 #include "hw/sysbus.h"
1414 #include "qom/object.h"
1515
16+#define TYPE_RENESAS_SCI_BASE "renesas-sci-base"
17+OBJECT_DECLARE_TYPE(RenesasSCIBaseState, RenesasSCIBaseClass,
18+ RENESAS_SCI_BASE)
1619 #define TYPE_RENESAS_SCI "renesas-sci"
17-typedef struct RSCIState RSCIState;
18-DECLARE_INSTANCE_CHECKER(RSCIState, RSCI,
19- TYPE_RENESAS_SCI)
20+OBJECT_DECLARE_TYPE(RenesasSCIState, RenesasSCIClass,
21+ RENESAS_SCI)
22+#define TYPE_RENESAS_SCIA "renesas-scia"
23+OBJECT_DECLARE_TYPE(RenesasSCIAState, RenesasSCIAClass,
24+ RENESAS_SCIA)
25+#define TYPE_RENESAS_SCIF "renesas-scif"
26+OBJECT_DECLARE_TYPE(RenesasSCIFState, RenesasSCIFClass,
27+ RENESAS_SCIF)
2028
2129 enum {
2230 ERI = 0,
2331 RXI = 1,
2432 TXI = 2,
25- TEI = 3,
26- SCI_NR_IRQ = 4
33+ BRI_TEI = 3,
34+ SCI_NR_IRQ = 4,
35+};
36+
37+enum {
38+ RXTOUT,
39+ RXNEXT,
40+ TXEMPTY,
41+ TXEND,
42+ NR_SCI_EVENT,
2743 };
2844
29-struct RSCIState {
45+enum {
46+ SCI_REGSIZE_8 = 0,
47+ SCI_REGSIZE_16 = 1,
48+ SCI_REGSIZE_32 = 2,
49+};
50+
51+typedef struct RenesasSCIBaseState {
3052 /*< private >*/
3153 SysBusDevice parent_obj;
32- /*< public >*/
33-
3454 MemoryRegion memory;
35- QEMUTimer timer;
36- CharBackend chr;
37- qemu_irq irq[SCI_NR_IRQ];
55+ MemoryRegion memory_p4;
56+ MemoryRegion memory_a7;
3857
58+ /* SCI register */
3959 uint8_t smr;
4060 uint8_t brr;
4161 uint8_t scr;
4262 uint8_t tdr;
43- uint8_t ssr;
44- uint8_t rdr;
45- uint8_t scmr;
46- uint8_t semr;
63+ uint16_t Xsr;
4764
48- uint8_t read_ssr;
65+ /* internal use */
66+ uint16_t read_Xsr;
67+ int64_t etu;
4968 int64_t trtime;
50- int64_t rx_next;
69+ int64_t tx_start_time;
70+ struct {
71+ int64_t time;
72+ int64_t (*handler)(struct RenesasSCIBaseState *sci);
73+ } event[NR_SCI_EVENT];
74+ QEMUTimer *event_timer;
75+ CharBackend chr;
5176 uint64_t input_freq;
77+ qemu_irq irq[SCI_NR_IRQ];
78+ Fifo8 rxfifo;
79+ int regshift;
80+ uint32_t unit;
81+ Clock *pck;
82+} RenesasSCIBaseState;
83+
84+struct RenesasSCIState {
85+ RenesasSCIBaseState parent_obj;
86+
87+ /* SCI specific register */
88+ uint8_t sptr;
5289 };
5390
54-#endif
91+struct RenesasSCIAState {
92+ RenesasSCIBaseState parent_obj;
93+
94+ /* SCIa specific register */
95+ uint8_t scmr;
96+ uint8_t semr;
97+};
98+
99+struct RenesasSCIFState {
100+ RenesasSCIBaseState parent_obj;
101+
102+ /* SCIF specific register */
103+ uint16_t fcr;
104+ uint16_t sptr;
105+ uint16_t lsr;
106+
107+ /* private */
108+ uint16_t read_lsr;
109+ int tdcnt;
110+};
111+
112+typedef struct RenesasSCIBaseClass {
113+ SysBusDeviceClass parent;
114+
115+ const struct MemoryRegionOps *ops;
116+ void (*irq_fn)(struct RenesasSCIBaseState *sci, int request);
117+ int (*divrate)(struct RenesasSCIBaseState *sci);
118+} RenesasSCIBaseClass;
119+
120+typedef struct RenesasSCIClass {
121+ RenesasSCIBaseClass parent;
122+
123+ void (*p_irq_fn)(struct RenesasSCIBaseState *sci, int request);
124+} RenesasSCIClass;
125+
126+typedef struct RenesasSCIAClass {
127+ RenesasSCIBaseClass parent;
128+
129+ void (*p_irq_fn)(struct RenesasSCIBaseState *sci, int request);
130+ int (*p_divrate)(struct RenesasSCIBaseState *sci);
131+} RenesasSCIAClass;
132+
133+typedef struct RenesasSCIFClass {
134+ RenesasSCIBaseClass parent;
135+
136+ void (*p_irq_fn)(struct RenesasSCIBaseState *sci, int request);
137+} RenesasSCIFClass;