12f062c72Sths /* 22f062c72Sths * QEMU SCI/SCIF serial port emulation 32f062c72Sths * 42f062c72Sths * Copyright (c) 2007 Magnus Damm 52f062c72Sths * 62f062c72Sths * Based on serial.c - QEMU 16450 UART emulation 72f062c72Sths * Copyright (c) 2003-2004 Fabrice Bellard 82f062c72Sths * 92f062c72Sths * Permission is hereby granted, free of charge, to any person obtaining a copy 102f062c72Sths * of this software and associated documentation files (the "Software"), to deal 112f062c72Sths * in the Software without restriction, including without limitation the rights 122f062c72Sths * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 132f062c72Sths * copies of the Software, and to permit persons to whom the Software is 142f062c72Sths * furnished to do so, subject to the following conditions: 152f062c72Sths * 162f062c72Sths * The above copyright notice and this permission notice shall be included in 172f062c72Sths * all copies or substantial portions of the Software. 182f062c72Sths * 192f062c72Sths * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 202f062c72Sths * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 212f062c72Sths * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 222f062c72Sths * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 232f062c72Sths * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 242f062c72Sths * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 252f062c72Sths * THE SOFTWARE. 262f062c72Sths */ 2764552b6bSMarkus Armbruster 280430891cSPeter Maydell #include "qemu/osdep.h" 2964552b6bSMarkus Armbruster #include "hw/irq.h" 300d09e41aSPaolo Bonzini #include "hw/sh4/sh.h" 314d43a603SMarc-André Lureau #include "chardev/char-fe.h" 3232a6ebecSMarc-André Lureau #include "qapi/error.h" 3371bb4ce1SGeert Uytterhoeven #include "qemu/timer.h" 343cf7ce43SBALATON Zoltan #include "qemu/log.h" 35ad52cfc1SBALATON Zoltan #include "trace.h" 362f062c72Sths 372f062c72Sths #define SH_SERIAL_FLAG_TEND (1 << 0) 382f062c72Sths #define SH_SERIAL_FLAG_TDE (1 << 1) 392f062c72Sths #define SH_SERIAL_FLAG_RDF (1 << 2) 402f062c72Sths #define SH_SERIAL_FLAG_BRK (1 << 3) 412f062c72Sths #define SH_SERIAL_FLAG_DR (1 << 4) 422f062c72Sths 4363242a00Saurel32 #define SH_RX_FIFO_LENGTH (16) 4463242a00Saurel32 452f062c72Sths typedef struct { 469a9d0b81SBenoît Canet MemoryRegion iomem; 479a9d0b81SBenoît Canet MemoryRegion iomem_p4; 489a9d0b81SBenoît Canet MemoryRegion iomem_a7; 492f062c72Sths uint8_t smr; 502f062c72Sths uint8_t brr; 512f062c72Sths uint8_t scr; 522f062c72Sths uint8_t dr; /* ftdr / tdr */ 532f062c72Sths uint8_t sr; /* fsr / ssr */ 542f062c72Sths uint16_t fcr; 552f062c72Sths uint8_t sptr; 562f062c72Sths 5763242a00Saurel32 uint8_t rx_fifo[SH_RX_FIFO_LENGTH]; /* frdr / rdr */ 582f062c72Sths uint8_t rx_cnt; 5963242a00Saurel32 uint8_t rx_tail; 6063242a00Saurel32 uint8_t rx_head; 612f062c72Sths 622f062c72Sths int freq; 632f062c72Sths int feat; 642f062c72Sths int flags; 6563242a00Saurel32 int rtrg; 662f062c72Sths 6732a6ebecSMarc-André Lureau CharBackend chr; 685b344b02SBALATON Zoltan QEMUTimer fifo_timeout_timer; 6971bb4ce1SGeert Uytterhoeven uint64_t etu; /* Elementary Time Unit (ns) */ 70bf5b7423Saurel32 714e7ed2d1Saurel32 qemu_irq eri; 724e7ed2d1Saurel32 qemu_irq rxi; 734e7ed2d1Saurel32 qemu_irq txi; 744e7ed2d1Saurel32 qemu_irq tei; 754e7ed2d1Saurel32 qemu_irq bri; 762f6df137SBALATON Zoltan } SHSerialState; 772f062c72Sths 782f6df137SBALATON Zoltan static void sh_serial_clear_fifo(SHSerialState *s) 7963242a00Saurel32 { 8063242a00Saurel32 memset(s->rx_fifo, 0, SH_RX_FIFO_LENGTH); 8163242a00Saurel32 s->rx_cnt = 0; 8263242a00Saurel32 s->rx_head = 0; 8363242a00Saurel32 s->rx_tail = 0; 8463242a00Saurel32 } 8563242a00Saurel32 86a8170e5eSAvi Kivity static void sh_serial_write(void *opaque, hwaddr offs, 879a9d0b81SBenoît Canet uint64_t val, unsigned size) 882f062c72Sths { 892f6df137SBALATON Zoltan SHSerialState *s = opaque; 902f062c72Sths unsigned char ch; 912f062c72Sths 92ad52cfc1SBALATON Zoltan trace_sh_serial_write(size, offs, val); 932f062c72Sths switch (offs) { 942f062c72Sths case 0x00: /* SMR */ 952f062c72Sths s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff); 962f062c72Sths return; 972f062c72Sths case 0x04: /* BRR */ 982f062c72Sths s->brr = val; 992f062c72Sths return; 1002f062c72Sths case 0x08: /* SCR */ 10163242a00Saurel32 /* TODO : For SH7751, SCIF mask should be 0xfb. */ 102bf5b7423Saurel32 s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff); 103ac3c9e74SBALATON Zoltan if (!(val & (1 << 5))) { 1042f062c72Sths s->flags |= SH_SERIAL_FLAG_TEND; 105ac3c9e74SBALATON Zoltan } 106bf5b7423Saurel32 if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) { 1074e7ed2d1Saurel32 qemu_set_irq(s->txi, val & (1 << 7)); 108bf5b7423Saurel32 } 1094e7ed2d1Saurel32 if (!(val & (1 << 6))) { 1104e7ed2d1Saurel32 qemu_set_irq(s->rxi, 0); 11163242a00Saurel32 } 1122f062c72Sths return; 1132f062c72Sths case 0x0c: /* FTDR / TDR */ 11430650701SAnton Nefedov if (qemu_chr_fe_backend_connected(&s->chr)) { 1152f062c72Sths ch = val; 11622138965SBALATON Zoltan /* 11722138965SBALATON Zoltan * XXX this blocks entire thread. Rewrite to use 11822138965SBALATON Zoltan * qemu_chr_fe_write and background I/O callbacks 11922138965SBALATON Zoltan */ 1205345fdb4SMarc-André Lureau qemu_chr_fe_write_all(&s->chr, &ch, 1); 1212f062c72Sths } 1222f062c72Sths s->dr = val; 1232f062c72Sths s->flags &= ~SH_SERIAL_FLAG_TDE; 1242f062c72Sths return; 1252f062c72Sths #if 0 1262f062c72Sths case 0x14: /* FRDR / RDR */ 1272f062c72Sths ret = 0; 1282f062c72Sths break; 1292f062c72Sths #endif 1302f062c72Sths } 1312f062c72Sths if (s->feat & SH_SERIAL_FEAT_SCIF) { 1322f062c72Sths switch (offs) { 1332f062c72Sths case 0x10: /* FSR */ 134ac3c9e74SBALATON Zoltan if (!(val & (1 << 6))) { 1352f062c72Sths s->flags &= ~SH_SERIAL_FLAG_TEND; 136ac3c9e74SBALATON Zoltan } 137ac3c9e74SBALATON Zoltan if (!(val & (1 << 5))) { 1382f062c72Sths s->flags &= ~SH_SERIAL_FLAG_TDE; 139ac3c9e74SBALATON Zoltan } 140ac3c9e74SBALATON Zoltan if (!(val & (1 << 4))) { 1412f062c72Sths s->flags &= ~SH_SERIAL_FLAG_BRK; 142ac3c9e74SBALATON Zoltan } 143ac3c9e74SBALATON Zoltan if (!(val & (1 << 1))) { 1442f062c72Sths s->flags &= ~SH_SERIAL_FLAG_RDF; 145ac3c9e74SBALATON Zoltan } 146ac3c9e74SBALATON Zoltan if (!(val & (1 << 0))) { 1472f062c72Sths s->flags &= ~SH_SERIAL_FLAG_DR; 148ac3c9e74SBALATON Zoltan } 14963242a00Saurel32 15063242a00Saurel32 if (!(val & (1 << 1)) || !(val & (1 << 0))) { 1514e7ed2d1Saurel32 if (s->rxi) { 1524e7ed2d1Saurel32 qemu_set_irq(s->rxi, 0); 15363242a00Saurel32 } 15463242a00Saurel32 } 1552f062c72Sths return; 1562f062c72Sths case 0x18: /* FCR */ 1572f062c72Sths s->fcr = val; 15863242a00Saurel32 switch ((val >> 6) & 3) { 15963242a00Saurel32 case 0: 16063242a00Saurel32 s->rtrg = 1; 16163242a00Saurel32 break; 16263242a00Saurel32 case 1: 16363242a00Saurel32 s->rtrg = 4; 16463242a00Saurel32 break; 16563242a00Saurel32 case 2: 16663242a00Saurel32 s->rtrg = 8; 16763242a00Saurel32 break; 16863242a00Saurel32 case 3: 16963242a00Saurel32 s->rtrg = 14; 17063242a00Saurel32 break; 17163242a00Saurel32 } 17263242a00Saurel32 if (val & (1 << 1)) { 17363242a00Saurel32 sh_serial_clear_fifo(s); 17463242a00Saurel32 s->sr &= ~(1 << 1); 17563242a00Saurel32 } 17663242a00Saurel32 1772f062c72Sths return; 1782f062c72Sths case 0x20: /* SPTR */ 17963242a00Saurel32 s->sptr = val & 0xf3; 1802f062c72Sths return; 1812f062c72Sths case 0x24: /* LSR */ 1822f062c72Sths return; 1832f062c72Sths } 184f94bff13SBALATON Zoltan } else { 1852f062c72Sths switch (offs) { 186d1f193b0Saurel32 #if 0 1872f062c72Sths case 0x0c: 1882f062c72Sths ret = s->dr; 1892f062c72Sths break; 1902f062c72Sths case 0x10: 1912f062c72Sths ret = 0; 1922f062c72Sths break; 1932f062c72Sths #endif 194d1f193b0Saurel32 case 0x1c: 195d1f193b0Saurel32 s->sptr = val & 0x8f; 196d1f193b0Saurel32 return; 197d1f193b0Saurel32 } 1982f062c72Sths } 1993cf7ce43SBALATON Zoltan qemu_log_mask(LOG_GUEST_ERROR, 2003cf7ce43SBALATON Zoltan "%s: unsupported write to 0x%02" HWADDR_PRIx "\n", 2013cf7ce43SBALATON Zoltan __func__, offs); 2022f062c72Sths } 2032f062c72Sths 204a8170e5eSAvi Kivity static uint64_t sh_serial_read(void *opaque, hwaddr offs, 2059a9d0b81SBenoît Canet unsigned size) 2062f062c72Sths { 2072f6df137SBALATON Zoltan SHSerialState *s = opaque; 2083cf7ce43SBALATON Zoltan uint32_t ret = UINT32_MAX; 2092f062c72Sths 2102f062c72Sths #if 0 2112f062c72Sths switch (offs) { 2122f062c72Sths case 0x00: 2132f062c72Sths ret = s->smr; 2142f062c72Sths break; 2152f062c72Sths case 0x04: 2162f062c72Sths ret = s->brr; 2172f062c72Sths break; 2182f062c72Sths case 0x08: 2192f062c72Sths ret = s->scr; 2202f062c72Sths break; 2212f062c72Sths case 0x14: 2222f062c72Sths ret = 0; 2232f062c72Sths break; 2242f062c72Sths } 2252f062c72Sths #endif 2262f062c72Sths if (s->feat & SH_SERIAL_FEAT_SCIF) { 2272f062c72Sths switch (offs) { 228bf5b7423Saurel32 case 0x00: /* SMR */ 229bf5b7423Saurel32 ret = s->smr; 230bf5b7423Saurel32 break; 231bf5b7423Saurel32 case 0x08: /* SCR */ 232bf5b7423Saurel32 ret = s->scr; 233bf5b7423Saurel32 break; 2342f062c72Sths case 0x10: /* FSR */ 2352f062c72Sths ret = 0; 236ac3c9e74SBALATON Zoltan if (s->flags & SH_SERIAL_FLAG_TEND) { 2372f062c72Sths ret |= (1 << 6); 238ac3c9e74SBALATON Zoltan } 239ac3c9e74SBALATON Zoltan if (s->flags & SH_SERIAL_FLAG_TDE) { 2402f062c72Sths ret |= (1 << 5); 241ac3c9e74SBALATON Zoltan } 242ac3c9e74SBALATON Zoltan if (s->flags & SH_SERIAL_FLAG_BRK) { 2432f062c72Sths ret |= (1 << 4); 244ac3c9e74SBALATON Zoltan } 245ac3c9e74SBALATON Zoltan if (s->flags & SH_SERIAL_FLAG_RDF) { 2462f062c72Sths ret |= (1 << 1); 247ac3c9e74SBALATON Zoltan } 248ac3c9e74SBALATON Zoltan if (s->flags & SH_SERIAL_FLAG_DR) { 2492f062c72Sths ret |= (1 << 0); 250ac3c9e74SBALATON Zoltan } 2512f062c72Sths 252ac3c9e74SBALATON Zoltan if (s->scr & (1 << 5)) { 2532f062c72Sths s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND; 254ac3c9e74SBALATON Zoltan } 2552f062c72Sths 2562f062c72Sths break; 25763242a00Saurel32 case 0x14: 25863242a00Saurel32 if (s->rx_cnt > 0) { 25963242a00Saurel32 ret = s->rx_fifo[s->rx_tail++]; 26063242a00Saurel32 s->rx_cnt--; 261ac3c9e74SBALATON Zoltan if (s->rx_tail == SH_RX_FIFO_LENGTH) { 26263242a00Saurel32 s->rx_tail = 0; 263ac3c9e74SBALATON Zoltan } 264ac3c9e74SBALATON Zoltan if (s->rx_cnt < s->rtrg) { 26563242a00Saurel32 s->flags &= ~SH_SERIAL_FLAG_RDF; 26663242a00Saurel32 } 267ac3c9e74SBALATON Zoltan } 26863242a00Saurel32 break; 2692f062c72Sths case 0x18: 2702f062c72Sths ret = s->fcr; 2712f062c72Sths break; 2722f062c72Sths case 0x1c: 2732f062c72Sths ret = s->rx_cnt; 2742f062c72Sths break; 2752f062c72Sths case 0x20: 2762f062c72Sths ret = s->sptr; 2772f062c72Sths break; 2782f062c72Sths case 0x24: 2792f062c72Sths ret = 0; 2802f062c72Sths break; 2812f062c72Sths } 282f94bff13SBALATON Zoltan } else { 2832f062c72Sths switch (offs) { 284d1f193b0Saurel32 #if 0 2852f062c72Sths case 0x0c: 2862f062c72Sths ret = s->dr; 2872f062c72Sths break; 2882f062c72Sths case 0x10: 2892f062c72Sths ret = 0; 2902f062c72Sths break; 29163242a00Saurel32 case 0x14: 29263242a00Saurel32 ret = s->rx_fifo[0]; 29363242a00Saurel32 break; 294d1f193b0Saurel32 #endif 2952f062c72Sths case 0x1c: 2962f062c72Sths ret = s->sptr; 2972f062c72Sths break; 2982f062c72Sths } 2992f062c72Sths } 300ad52cfc1SBALATON Zoltan trace_sh_serial_read(size, offs, ret); 3012f062c72Sths 3023cf7ce43SBALATON Zoltan if (ret > UINT16_MAX) { 3033cf7ce43SBALATON Zoltan qemu_log_mask(LOG_GUEST_ERROR, 3043cf7ce43SBALATON Zoltan "%s: unsupported read from 0x%02" HWADDR_PRIx "\n", 3053cf7ce43SBALATON Zoltan __func__, offs); 3063cf7ce43SBALATON Zoltan ret = 0; 3072f062c72Sths } 3082f062c72Sths 3092f062c72Sths return ret; 3102f062c72Sths } 3112f062c72Sths 3122f6df137SBALATON Zoltan static int sh_serial_can_receive(SHSerialState *s) 3132f062c72Sths { 31463242a00Saurel32 return s->scr & (1 << 4); 3152f062c72Sths } 3162f062c72Sths 3172f6df137SBALATON Zoltan static void sh_serial_receive_break(SHSerialState *s) 3182f062c72Sths { 319ac3c9e74SBALATON Zoltan if (s->feat & SH_SERIAL_FEAT_SCIF) { 32063242a00Saurel32 s->sr |= (1 << 4); 3212f062c72Sths } 322ac3c9e74SBALATON Zoltan } 3232f062c72Sths 3242f062c72Sths static int sh_serial_can_receive1(void *opaque) 3252f062c72Sths { 3262f6df137SBALATON Zoltan SHSerialState *s = opaque; 3272f062c72Sths return sh_serial_can_receive(s); 3282f062c72Sths } 3292f062c72Sths 33071bb4ce1SGeert Uytterhoeven static void sh_serial_timeout_int(void *opaque) 33171bb4ce1SGeert Uytterhoeven { 3322f6df137SBALATON Zoltan SHSerialState *s = opaque; 33371bb4ce1SGeert Uytterhoeven 33471bb4ce1SGeert Uytterhoeven s->flags |= SH_SERIAL_FLAG_RDF; 33571bb4ce1SGeert Uytterhoeven if (s->scr & (1 << 6) && s->rxi) { 33671bb4ce1SGeert Uytterhoeven qemu_set_irq(s->rxi, 1); 33771bb4ce1SGeert Uytterhoeven } 33871bb4ce1SGeert Uytterhoeven } 33971bb4ce1SGeert Uytterhoeven 3402f062c72Sths static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size) 3412f062c72Sths { 3422f6df137SBALATON Zoltan SHSerialState *s = opaque; 343b7d2b020SAurelien Jarno 344b7d2b020SAurelien Jarno if (s->feat & SH_SERIAL_FEAT_SCIF) { 345b7d2b020SAurelien Jarno int i; 346b7d2b020SAurelien Jarno for (i = 0; i < size; i++) { 347b7d2b020SAurelien Jarno if (s->rx_cnt < SH_RX_FIFO_LENGTH) { 348b7d2b020SAurelien Jarno s->rx_fifo[s->rx_head++] = buf[i]; 349b7d2b020SAurelien Jarno if (s->rx_head == SH_RX_FIFO_LENGTH) { 350b7d2b020SAurelien Jarno s->rx_head = 0; 351b7d2b020SAurelien Jarno } 352b7d2b020SAurelien Jarno s->rx_cnt++; 353b7d2b020SAurelien Jarno if (s->rx_cnt >= s->rtrg) { 354b7d2b020SAurelien Jarno s->flags |= SH_SERIAL_FLAG_RDF; 355b7d2b020SAurelien Jarno if (s->scr & (1 << 6) && s->rxi) { 3565b344b02SBALATON Zoltan timer_del(&s->fifo_timeout_timer); 357b7d2b020SAurelien Jarno qemu_set_irq(s->rxi, 1); 358b7d2b020SAurelien Jarno } 35971bb4ce1SGeert Uytterhoeven } else { 3605b344b02SBALATON Zoltan timer_mod(&s->fifo_timeout_timer, 36171bb4ce1SGeert Uytterhoeven qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu); 362b7d2b020SAurelien Jarno } 363b7d2b020SAurelien Jarno } 364b7d2b020SAurelien Jarno } 365b7d2b020SAurelien Jarno } else { 366b7d2b020SAurelien Jarno s->rx_fifo[0] = buf[0]; 367b7d2b020SAurelien Jarno } 3682f062c72Sths } 3692f062c72Sths 370083b266fSPhilippe Mathieu-Daudé static void sh_serial_event(void *opaque, QEMUChrEvent event) 3712f062c72Sths { 3722f6df137SBALATON Zoltan SHSerialState *s = opaque; 373ac3c9e74SBALATON Zoltan if (event == CHR_EVENT_BREAK) { 3742f062c72Sths sh_serial_receive_break(s); 3752f062c72Sths } 376ac3c9e74SBALATON Zoltan } 3772f062c72Sths 3789a9d0b81SBenoît Canet static const MemoryRegionOps sh_serial_ops = { 3799a9d0b81SBenoît Canet .read = sh_serial_read, 3809a9d0b81SBenoît Canet .write = sh_serial_write, 3819a9d0b81SBenoît Canet .endianness = DEVICE_NATIVE_ENDIAN, 3822f062c72Sths }; 3832f062c72Sths 384*017f77bbSBALATON Zoltan static void sh_serial_reset(SHSerialState *s) 385*017f77bbSBALATON Zoltan { 386*017f77bbSBALATON Zoltan s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE; 387*017f77bbSBALATON Zoltan s->rtrg = 1; 388*017f77bbSBALATON Zoltan 389*017f77bbSBALATON Zoltan s->smr = 0; 390*017f77bbSBALATON Zoltan s->brr = 0xff; 391*017f77bbSBALATON Zoltan s->scr = 1 << 5; /* pretend that TX is enabled so early printk works */ 392*017f77bbSBALATON Zoltan s->sptr = 0; 393*017f77bbSBALATON Zoltan 394*017f77bbSBALATON Zoltan if (s->feat & SH_SERIAL_FEAT_SCIF) { 395*017f77bbSBALATON Zoltan s->fcr = 0; 396*017f77bbSBALATON Zoltan } else { 397*017f77bbSBALATON Zoltan s->dr = 0xff; 398*017f77bbSBALATON Zoltan } 399*017f77bbSBALATON Zoltan 400*017f77bbSBALATON Zoltan sh_serial_clear_fifo(s); 401*017f77bbSBALATON Zoltan } 402*017f77bbSBALATON Zoltan 4039a9d0b81SBenoît Canet void sh_serial_init(MemoryRegion *sysmem, 404a8170e5eSAvi Kivity hwaddr base, int feat, 4050ec7b3e7SMarc-André Lureau uint32_t freq, Chardev *chr, 4064e7ed2d1Saurel32 qemu_irq eri_source, 4074e7ed2d1Saurel32 qemu_irq rxi_source, 4084e7ed2d1Saurel32 qemu_irq txi_source, 4094e7ed2d1Saurel32 qemu_irq tei_source, 4104e7ed2d1Saurel32 qemu_irq bri_source) 4112f062c72Sths { 4122f6df137SBALATON Zoltan SHSerialState *s = g_malloc0(sizeof(*s)); 4132f062c72Sths 4142f062c72Sths s->feat = feat; 415*017f77bbSBALATON Zoltan sh_serial_reset(s); 4162f062c72Sths 4172c9b15caSPaolo Bonzini memory_region_init_io(&s->iomem, NULL, &sh_serial_ops, s, 4189a9d0b81SBenoît Canet "serial", 0x100000000ULL); 4199a9d0b81SBenoît Canet 4202c9b15caSPaolo Bonzini memory_region_init_alias(&s->iomem_p4, NULL, "serial-p4", &s->iomem, 4219a9d0b81SBenoît Canet 0, 0x28); 4229a9d0b81SBenoît Canet memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4); 4239a9d0b81SBenoît Canet 4242c9b15caSPaolo Bonzini memory_region_init_alias(&s->iomem_a7, NULL, "serial-a7", &s->iomem, 4259a9d0b81SBenoît Canet 0, 0x28); 4269a9d0b81SBenoît Canet memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7); 4272f062c72Sths 428456d6069SHans de Goede if (chr) { 42932a6ebecSMarc-André Lureau qemu_chr_fe_init(&s->chr, chr, &error_abort); 4305345fdb4SMarc-André Lureau qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1, 4315345fdb4SMarc-André Lureau sh_serial_receive1, 43281517ba3SAnton Nefedov sh_serial_event, NULL, s, NULL, true); 433456d6069SHans de Goede } 434bf5b7423Saurel32 4355b344b02SBALATON Zoltan timer_init_ns(&s->fifo_timeout_timer, QEMU_CLOCK_VIRTUAL, 43671bb4ce1SGeert Uytterhoeven sh_serial_timeout_int, s); 43771bb4ce1SGeert Uytterhoeven s->etu = NANOSECONDS_PER_SECOND / 9600; 438bf5b7423Saurel32 s->eri = eri_source; 439bf5b7423Saurel32 s->rxi = rxi_source; 440bf5b7423Saurel32 s->txi = txi_source; 441bf5b7423Saurel32 s->tei = tei_source; 442bf5b7423Saurel32 s->bri = bri_source; 4432f062c72Sths } 444