19944d320SPaolo Bonzini /* 29944d320SPaolo Bonzini * QEMU SCI/SCIF serial port emulation 39944d320SPaolo Bonzini * 49944d320SPaolo Bonzini * Copyright (c) 2007 Magnus Damm 59944d320SPaolo Bonzini * 69944d320SPaolo Bonzini * Based on serial.c - QEMU 16450 UART emulation 79944d320SPaolo Bonzini * Copyright (c) 2003-2004 Fabrice Bellard 89944d320SPaolo Bonzini * 99944d320SPaolo Bonzini * Permission is hereby granted, free of charge, to any person obtaining a copy 109944d320SPaolo Bonzini * of this software and associated documentation files (the "Software"), to deal 119944d320SPaolo Bonzini * in the Software without restriction, including without limitation the rights 129944d320SPaolo Bonzini * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 139944d320SPaolo Bonzini * copies of the Software, and to permit persons to whom the Software is 149944d320SPaolo Bonzini * furnished to do so, subject to the following conditions: 159944d320SPaolo Bonzini * 169944d320SPaolo Bonzini * The above copyright notice and this permission notice shall be included in 179944d320SPaolo Bonzini * all copies or substantial portions of the Software. 189944d320SPaolo Bonzini * 199944d320SPaolo Bonzini * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 209944d320SPaolo Bonzini * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 219944d320SPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 229944d320SPaolo Bonzini * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 239944d320SPaolo Bonzini * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 249944d320SPaolo Bonzini * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 259944d320SPaolo Bonzini * THE SOFTWARE. 269944d320SPaolo Bonzini */ 270430891cSPeter Maydell #include "qemu/osdep.h" 289944d320SPaolo Bonzini #include "hw/hw.h" 299944d320SPaolo Bonzini #include "hw/sh4/sh.h" 30dccfcd0eSPaolo Bonzini #include "sysemu/char.h" 319944d320SPaolo Bonzini #include "exec/address-spaces.h" 32*32a6ebecSMarc-André Lureau #include "qapi/error.h" 339944d320SPaolo Bonzini 349944d320SPaolo Bonzini //#define DEBUG_SERIAL 359944d320SPaolo Bonzini 369944d320SPaolo Bonzini #define SH_SERIAL_FLAG_TEND (1 << 0) 379944d320SPaolo Bonzini #define SH_SERIAL_FLAG_TDE (1 << 1) 389944d320SPaolo Bonzini #define SH_SERIAL_FLAG_RDF (1 << 2) 399944d320SPaolo Bonzini #define SH_SERIAL_FLAG_BRK (1 << 3) 409944d320SPaolo Bonzini #define SH_SERIAL_FLAG_DR (1 << 4) 419944d320SPaolo Bonzini 429944d320SPaolo Bonzini #define SH_RX_FIFO_LENGTH (16) 439944d320SPaolo Bonzini 449944d320SPaolo Bonzini typedef struct { 459944d320SPaolo Bonzini MemoryRegion iomem; 469944d320SPaolo Bonzini MemoryRegion iomem_p4; 479944d320SPaolo Bonzini MemoryRegion iomem_a7; 489944d320SPaolo Bonzini uint8_t smr; 499944d320SPaolo Bonzini uint8_t brr; 509944d320SPaolo Bonzini uint8_t scr; 519944d320SPaolo Bonzini uint8_t dr; /* ftdr / tdr */ 529944d320SPaolo Bonzini uint8_t sr; /* fsr / ssr */ 539944d320SPaolo Bonzini uint16_t fcr; 549944d320SPaolo Bonzini uint8_t sptr; 559944d320SPaolo Bonzini 569944d320SPaolo Bonzini uint8_t rx_fifo[SH_RX_FIFO_LENGTH]; /* frdr / rdr */ 579944d320SPaolo Bonzini uint8_t rx_cnt; 589944d320SPaolo Bonzini uint8_t rx_tail; 599944d320SPaolo Bonzini uint8_t rx_head; 609944d320SPaolo Bonzini 619944d320SPaolo Bonzini int freq; 629944d320SPaolo Bonzini int feat; 639944d320SPaolo Bonzini int flags; 649944d320SPaolo Bonzini int rtrg; 659944d320SPaolo Bonzini 66*32a6ebecSMarc-André Lureau CharBackend chr; 679944d320SPaolo Bonzini 689944d320SPaolo Bonzini qemu_irq eri; 699944d320SPaolo Bonzini qemu_irq rxi; 709944d320SPaolo Bonzini qemu_irq txi; 719944d320SPaolo Bonzini qemu_irq tei; 729944d320SPaolo Bonzini qemu_irq bri; 739944d320SPaolo Bonzini } sh_serial_state; 749944d320SPaolo Bonzini 759944d320SPaolo Bonzini static void sh_serial_clear_fifo(sh_serial_state * s) 769944d320SPaolo Bonzini { 779944d320SPaolo Bonzini memset(s->rx_fifo, 0, SH_RX_FIFO_LENGTH); 789944d320SPaolo Bonzini s->rx_cnt = 0; 799944d320SPaolo Bonzini s->rx_head = 0; 809944d320SPaolo Bonzini s->rx_tail = 0; 819944d320SPaolo Bonzini } 829944d320SPaolo Bonzini 839944d320SPaolo Bonzini static void sh_serial_write(void *opaque, hwaddr offs, 849944d320SPaolo Bonzini uint64_t val, unsigned size) 859944d320SPaolo Bonzini { 869944d320SPaolo Bonzini sh_serial_state *s = opaque; 879944d320SPaolo Bonzini unsigned char ch; 889944d320SPaolo Bonzini 899944d320SPaolo Bonzini #ifdef DEBUG_SERIAL 909944d320SPaolo Bonzini printf("sh_serial: write offs=0x%02x val=0x%02x\n", 919944d320SPaolo Bonzini offs, val); 929944d320SPaolo Bonzini #endif 939944d320SPaolo Bonzini switch(offs) { 949944d320SPaolo Bonzini case 0x00: /* SMR */ 959944d320SPaolo Bonzini s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff); 969944d320SPaolo Bonzini return; 979944d320SPaolo Bonzini case 0x04: /* BRR */ 989944d320SPaolo Bonzini s->brr = val; 999944d320SPaolo Bonzini return; 1009944d320SPaolo Bonzini case 0x08: /* SCR */ 1019944d320SPaolo Bonzini /* TODO : For SH7751, SCIF mask should be 0xfb. */ 1029944d320SPaolo Bonzini s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff); 1039944d320SPaolo Bonzini if (!(val & (1 << 5))) 1049944d320SPaolo Bonzini s->flags |= SH_SERIAL_FLAG_TEND; 1059944d320SPaolo Bonzini if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) { 1069944d320SPaolo Bonzini qemu_set_irq(s->txi, val & (1 << 7)); 1079944d320SPaolo Bonzini } 1089944d320SPaolo Bonzini if (!(val & (1 << 6))) { 1099944d320SPaolo Bonzini qemu_set_irq(s->rxi, 0); 1109944d320SPaolo Bonzini } 1119944d320SPaolo Bonzini return; 1129944d320SPaolo Bonzini case 0x0c: /* FTDR / TDR */ 113*32a6ebecSMarc-André Lureau if (s->chr.chr) { 1149944d320SPaolo Bonzini ch = val; 1156ab3fc32SDaniel P. Berrange /* XXX this blocks entire thread. Rewrite to use 1166ab3fc32SDaniel P. Berrange * qemu_chr_fe_write and background I/O callbacks */ 117*32a6ebecSMarc-André Lureau qemu_chr_fe_write_all(s->chr.chr, &ch, 1); 1189944d320SPaolo Bonzini } 1199944d320SPaolo Bonzini s->dr = val; 1209944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_TDE; 1219944d320SPaolo Bonzini return; 1229944d320SPaolo Bonzini #if 0 1239944d320SPaolo Bonzini case 0x14: /* FRDR / RDR */ 1249944d320SPaolo Bonzini ret = 0; 1259944d320SPaolo Bonzini break; 1269944d320SPaolo Bonzini #endif 1279944d320SPaolo Bonzini } 1289944d320SPaolo Bonzini if (s->feat & SH_SERIAL_FEAT_SCIF) { 1299944d320SPaolo Bonzini switch(offs) { 1309944d320SPaolo Bonzini case 0x10: /* FSR */ 1319944d320SPaolo Bonzini if (!(val & (1 << 6))) 1329944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_TEND; 1339944d320SPaolo Bonzini if (!(val & (1 << 5))) 1349944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_TDE; 1359944d320SPaolo Bonzini if (!(val & (1 << 4))) 1369944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_BRK; 1379944d320SPaolo Bonzini if (!(val & (1 << 1))) 1389944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_RDF; 1399944d320SPaolo Bonzini if (!(val & (1 << 0))) 1409944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_DR; 1419944d320SPaolo Bonzini 1429944d320SPaolo Bonzini if (!(val & (1 << 1)) || !(val & (1 << 0))) { 1439944d320SPaolo Bonzini if (s->rxi) { 1449944d320SPaolo Bonzini qemu_set_irq(s->rxi, 0); 1459944d320SPaolo Bonzini } 1469944d320SPaolo Bonzini } 1479944d320SPaolo Bonzini return; 1489944d320SPaolo Bonzini case 0x18: /* FCR */ 1499944d320SPaolo Bonzini s->fcr = val; 1509944d320SPaolo Bonzini switch ((val >> 6) & 3) { 1519944d320SPaolo Bonzini case 0: 1529944d320SPaolo Bonzini s->rtrg = 1; 1539944d320SPaolo Bonzini break; 1549944d320SPaolo Bonzini case 1: 1559944d320SPaolo Bonzini s->rtrg = 4; 1569944d320SPaolo Bonzini break; 1579944d320SPaolo Bonzini case 2: 1589944d320SPaolo Bonzini s->rtrg = 8; 1599944d320SPaolo Bonzini break; 1609944d320SPaolo Bonzini case 3: 1619944d320SPaolo Bonzini s->rtrg = 14; 1629944d320SPaolo Bonzini break; 1639944d320SPaolo Bonzini } 1649944d320SPaolo Bonzini if (val & (1 << 1)) { 1659944d320SPaolo Bonzini sh_serial_clear_fifo(s); 1669944d320SPaolo Bonzini s->sr &= ~(1 << 1); 1679944d320SPaolo Bonzini } 1689944d320SPaolo Bonzini 1699944d320SPaolo Bonzini return; 1709944d320SPaolo Bonzini case 0x20: /* SPTR */ 1719944d320SPaolo Bonzini s->sptr = val & 0xf3; 1729944d320SPaolo Bonzini return; 1739944d320SPaolo Bonzini case 0x24: /* LSR */ 1749944d320SPaolo Bonzini return; 1759944d320SPaolo Bonzini } 1769944d320SPaolo Bonzini } 1779944d320SPaolo Bonzini else { 1789944d320SPaolo Bonzini switch(offs) { 1799944d320SPaolo Bonzini #if 0 1809944d320SPaolo Bonzini case 0x0c: 1819944d320SPaolo Bonzini ret = s->dr; 1829944d320SPaolo Bonzini break; 1839944d320SPaolo Bonzini case 0x10: 1849944d320SPaolo Bonzini ret = 0; 1859944d320SPaolo Bonzini break; 1869944d320SPaolo Bonzini #endif 1879944d320SPaolo Bonzini case 0x1c: 1889944d320SPaolo Bonzini s->sptr = val & 0x8f; 1899944d320SPaolo Bonzini return; 1909944d320SPaolo Bonzini } 1919944d320SPaolo Bonzini } 1929944d320SPaolo Bonzini 1939944d320SPaolo Bonzini fprintf(stderr, "sh_serial: unsupported write to 0x%02" 1949944d320SPaolo Bonzini HWADDR_PRIx "\n", offs); 1959944d320SPaolo Bonzini abort(); 1969944d320SPaolo Bonzini } 1979944d320SPaolo Bonzini 1989944d320SPaolo Bonzini static uint64_t sh_serial_read(void *opaque, hwaddr offs, 1999944d320SPaolo Bonzini unsigned size) 2009944d320SPaolo Bonzini { 2019944d320SPaolo Bonzini sh_serial_state *s = opaque; 2029944d320SPaolo Bonzini uint32_t ret = ~0; 2039944d320SPaolo Bonzini 2049944d320SPaolo Bonzini #if 0 2059944d320SPaolo Bonzini switch(offs) { 2069944d320SPaolo Bonzini case 0x00: 2079944d320SPaolo Bonzini ret = s->smr; 2089944d320SPaolo Bonzini break; 2099944d320SPaolo Bonzini case 0x04: 2109944d320SPaolo Bonzini ret = s->brr; 2119944d320SPaolo Bonzini break; 2129944d320SPaolo Bonzini case 0x08: 2139944d320SPaolo Bonzini ret = s->scr; 2149944d320SPaolo Bonzini break; 2159944d320SPaolo Bonzini case 0x14: 2169944d320SPaolo Bonzini ret = 0; 2179944d320SPaolo Bonzini break; 2189944d320SPaolo Bonzini } 2199944d320SPaolo Bonzini #endif 2209944d320SPaolo Bonzini if (s->feat & SH_SERIAL_FEAT_SCIF) { 2219944d320SPaolo Bonzini switch(offs) { 2229944d320SPaolo Bonzini case 0x00: /* SMR */ 2239944d320SPaolo Bonzini ret = s->smr; 2249944d320SPaolo Bonzini break; 2259944d320SPaolo Bonzini case 0x08: /* SCR */ 2269944d320SPaolo Bonzini ret = s->scr; 2279944d320SPaolo Bonzini break; 2289944d320SPaolo Bonzini case 0x10: /* FSR */ 2299944d320SPaolo Bonzini ret = 0; 2309944d320SPaolo Bonzini if (s->flags & SH_SERIAL_FLAG_TEND) 2319944d320SPaolo Bonzini ret |= (1 << 6); 2329944d320SPaolo Bonzini if (s->flags & SH_SERIAL_FLAG_TDE) 2339944d320SPaolo Bonzini ret |= (1 << 5); 2349944d320SPaolo Bonzini if (s->flags & SH_SERIAL_FLAG_BRK) 2359944d320SPaolo Bonzini ret |= (1 << 4); 2369944d320SPaolo Bonzini if (s->flags & SH_SERIAL_FLAG_RDF) 2379944d320SPaolo Bonzini ret |= (1 << 1); 2389944d320SPaolo Bonzini if (s->flags & SH_SERIAL_FLAG_DR) 2399944d320SPaolo Bonzini ret |= (1 << 0); 2409944d320SPaolo Bonzini 2419944d320SPaolo Bonzini if (s->scr & (1 << 5)) 2429944d320SPaolo Bonzini s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND; 2439944d320SPaolo Bonzini 2449944d320SPaolo Bonzini break; 2459944d320SPaolo Bonzini case 0x14: 2469944d320SPaolo Bonzini if (s->rx_cnt > 0) { 2479944d320SPaolo Bonzini ret = s->rx_fifo[s->rx_tail++]; 2489944d320SPaolo Bonzini s->rx_cnt--; 2499944d320SPaolo Bonzini if (s->rx_tail == SH_RX_FIFO_LENGTH) 2509944d320SPaolo Bonzini s->rx_tail = 0; 2519944d320SPaolo Bonzini if (s->rx_cnt < s->rtrg) 2529944d320SPaolo Bonzini s->flags &= ~SH_SERIAL_FLAG_RDF; 2539944d320SPaolo Bonzini } 2549944d320SPaolo Bonzini break; 2559944d320SPaolo Bonzini case 0x18: 2569944d320SPaolo Bonzini ret = s->fcr; 2579944d320SPaolo Bonzini break; 2589944d320SPaolo Bonzini case 0x1c: 2599944d320SPaolo Bonzini ret = s->rx_cnt; 2609944d320SPaolo Bonzini break; 2619944d320SPaolo Bonzini case 0x20: 2629944d320SPaolo Bonzini ret = s->sptr; 2639944d320SPaolo Bonzini break; 2649944d320SPaolo Bonzini case 0x24: 2659944d320SPaolo Bonzini ret = 0; 2669944d320SPaolo Bonzini break; 2679944d320SPaolo Bonzini } 2689944d320SPaolo Bonzini } 2699944d320SPaolo Bonzini else { 2709944d320SPaolo Bonzini switch(offs) { 2719944d320SPaolo Bonzini #if 0 2729944d320SPaolo Bonzini case 0x0c: 2739944d320SPaolo Bonzini ret = s->dr; 2749944d320SPaolo Bonzini break; 2759944d320SPaolo Bonzini case 0x10: 2769944d320SPaolo Bonzini ret = 0; 2779944d320SPaolo Bonzini break; 2789944d320SPaolo Bonzini case 0x14: 2799944d320SPaolo Bonzini ret = s->rx_fifo[0]; 2809944d320SPaolo Bonzini break; 2819944d320SPaolo Bonzini #endif 2829944d320SPaolo Bonzini case 0x1c: 2839944d320SPaolo Bonzini ret = s->sptr; 2849944d320SPaolo Bonzini break; 2859944d320SPaolo Bonzini } 2869944d320SPaolo Bonzini } 2879944d320SPaolo Bonzini #ifdef DEBUG_SERIAL 2889944d320SPaolo Bonzini printf("sh_serial: read offs=0x%02x val=0x%x\n", 2899944d320SPaolo Bonzini offs, ret); 2909944d320SPaolo Bonzini #endif 2919944d320SPaolo Bonzini 2929944d320SPaolo Bonzini if (ret & ~((1 << 16) - 1)) { 2939944d320SPaolo Bonzini fprintf(stderr, "sh_serial: unsupported read from 0x%02" 2949944d320SPaolo Bonzini HWADDR_PRIx "\n", offs); 2959944d320SPaolo Bonzini abort(); 2969944d320SPaolo Bonzini } 2979944d320SPaolo Bonzini 2989944d320SPaolo Bonzini return ret; 2999944d320SPaolo Bonzini } 3009944d320SPaolo Bonzini 3019944d320SPaolo Bonzini static int sh_serial_can_receive(sh_serial_state *s) 3029944d320SPaolo Bonzini { 3039944d320SPaolo Bonzini return s->scr & (1 << 4); 3049944d320SPaolo Bonzini } 3059944d320SPaolo Bonzini 3069944d320SPaolo Bonzini static void sh_serial_receive_break(sh_serial_state *s) 3079944d320SPaolo Bonzini { 3089944d320SPaolo Bonzini if (s->feat & SH_SERIAL_FEAT_SCIF) 3099944d320SPaolo Bonzini s->sr |= (1 << 4); 3109944d320SPaolo Bonzini } 3119944d320SPaolo Bonzini 3129944d320SPaolo Bonzini static int sh_serial_can_receive1(void *opaque) 3139944d320SPaolo Bonzini { 3149944d320SPaolo Bonzini sh_serial_state *s = opaque; 3159944d320SPaolo Bonzini return sh_serial_can_receive(s); 3169944d320SPaolo Bonzini } 3179944d320SPaolo Bonzini 3189944d320SPaolo Bonzini static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size) 3199944d320SPaolo Bonzini { 3209944d320SPaolo Bonzini sh_serial_state *s = opaque; 3219944d320SPaolo Bonzini 3229944d320SPaolo Bonzini if (s->feat & SH_SERIAL_FEAT_SCIF) { 3239944d320SPaolo Bonzini int i; 3249944d320SPaolo Bonzini for (i = 0; i < size; i++) { 3259944d320SPaolo Bonzini if (s->rx_cnt < SH_RX_FIFO_LENGTH) { 3269944d320SPaolo Bonzini s->rx_fifo[s->rx_head++] = buf[i]; 3279944d320SPaolo Bonzini if (s->rx_head == SH_RX_FIFO_LENGTH) { 3289944d320SPaolo Bonzini s->rx_head = 0; 3299944d320SPaolo Bonzini } 3309944d320SPaolo Bonzini s->rx_cnt++; 3319944d320SPaolo Bonzini if (s->rx_cnt >= s->rtrg) { 3329944d320SPaolo Bonzini s->flags |= SH_SERIAL_FLAG_RDF; 3339944d320SPaolo Bonzini if (s->scr & (1 << 6) && s->rxi) { 3349944d320SPaolo Bonzini qemu_set_irq(s->rxi, 1); 3359944d320SPaolo Bonzini } 3369944d320SPaolo Bonzini } 3379944d320SPaolo Bonzini } 3389944d320SPaolo Bonzini } 3399944d320SPaolo Bonzini } else { 3409944d320SPaolo Bonzini s->rx_fifo[0] = buf[0]; 3419944d320SPaolo Bonzini } 3429944d320SPaolo Bonzini } 3439944d320SPaolo Bonzini 3449944d320SPaolo Bonzini static void sh_serial_event(void *opaque, int event) 3459944d320SPaolo Bonzini { 3469944d320SPaolo Bonzini sh_serial_state *s = opaque; 3479944d320SPaolo Bonzini if (event == CHR_EVENT_BREAK) 3489944d320SPaolo Bonzini sh_serial_receive_break(s); 3499944d320SPaolo Bonzini } 3509944d320SPaolo Bonzini 3519944d320SPaolo Bonzini static const MemoryRegionOps sh_serial_ops = { 3529944d320SPaolo Bonzini .read = sh_serial_read, 3539944d320SPaolo Bonzini .write = sh_serial_write, 3549944d320SPaolo Bonzini .endianness = DEVICE_NATIVE_ENDIAN, 3559944d320SPaolo Bonzini }; 3569944d320SPaolo Bonzini 3579944d320SPaolo Bonzini void sh_serial_init(MemoryRegion *sysmem, 3589944d320SPaolo Bonzini hwaddr base, int feat, 3599944d320SPaolo Bonzini uint32_t freq, CharDriverState *chr, 3609944d320SPaolo Bonzini qemu_irq eri_source, 3619944d320SPaolo Bonzini qemu_irq rxi_source, 3629944d320SPaolo Bonzini qemu_irq txi_source, 3639944d320SPaolo Bonzini qemu_irq tei_source, 3649944d320SPaolo Bonzini qemu_irq bri_source) 3659944d320SPaolo Bonzini { 3669944d320SPaolo Bonzini sh_serial_state *s; 3679944d320SPaolo Bonzini 3689944d320SPaolo Bonzini s = g_malloc0(sizeof(sh_serial_state)); 3699944d320SPaolo Bonzini 3709944d320SPaolo Bonzini s->feat = feat; 3719944d320SPaolo Bonzini s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE; 3729944d320SPaolo Bonzini s->rtrg = 1; 3739944d320SPaolo Bonzini 3749944d320SPaolo Bonzini s->smr = 0; 3759944d320SPaolo Bonzini s->brr = 0xff; 3769944d320SPaolo Bonzini s->scr = 1 << 5; /* pretend that TX is enabled so early printk works */ 3779944d320SPaolo Bonzini s->sptr = 0; 3789944d320SPaolo Bonzini 3799944d320SPaolo Bonzini if (feat & SH_SERIAL_FEAT_SCIF) { 3809944d320SPaolo Bonzini s->fcr = 0; 3819944d320SPaolo Bonzini } 3829944d320SPaolo Bonzini else { 3839944d320SPaolo Bonzini s->dr = 0xff; 3849944d320SPaolo Bonzini } 3859944d320SPaolo Bonzini 3869944d320SPaolo Bonzini sh_serial_clear_fifo(s); 3879944d320SPaolo Bonzini 3882c9b15caSPaolo Bonzini memory_region_init_io(&s->iomem, NULL, &sh_serial_ops, s, 3899944d320SPaolo Bonzini "serial", 0x100000000ULL); 3909944d320SPaolo Bonzini 3912c9b15caSPaolo Bonzini memory_region_init_alias(&s->iomem_p4, NULL, "serial-p4", &s->iomem, 3929944d320SPaolo Bonzini 0, 0x28); 3939944d320SPaolo Bonzini memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4); 3949944d320SPaolo Bonzini 3952c9b15caSPaolo Bonzini memory_region_init_alias(&s->iomem_a7, NULL, "serial-a7", &s->iomem, 3969944d320SPaolo Bonzini 0, 0x28); 3979944d320SPaolo Bonzini memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7); 3989944d320SPaolo Bonzini 3999944d320SPaolo Bonzini if (chr) { 4009944d320SPaolo Bonzini qemu_chr_fe_claim_no_fail(chr); 401*32a6ebecSMarc-André Lureau qemu_chr_fe_init(&s->chr, chr, &error_abort); 4029944d320SPaolo Bonzini qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, 4039944d320SPaolo Bonzini sh_serial_event, s); 4049944d320SPaolo Bonzini } 4059944d320SPaolo Bonzini 4069944d320SPaolo Bonzini s->eri = eri_source; 4079944d320SPaolo Bonzini s->rxi = rxi_source; 4089944d320SPaolo Bonzini s->txi = txi_source; 4099944d320SPaolo Bonzini s->tei = tei_source; 4109944d320SPaolo Bonzini s->bri = bri_source; 4119944d320SPaolo Bonzini } 412