renesas_sci.c (9849B)
1/* 2 * Renesas Serial Communication Interface 3 * 4 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware 5 * (Rev.1.40 R01UH0033EJ0140) 6 * 7 * Copyright (c) 2019 Yoshinori Sato 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms and conditions of the GNU General Public License, 13 * version 2 or later, as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * more details. 19 * 20 * You should have received a copy of the GNU General Public License along with 21 * this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24#include "qemu/osdep.h" 25#include "qemu/log.h" 26#include "hw/irq.h" 27#include "hw/registerfields.h" 28#include "hw/qdev-properties.h" 29#include "hw/qdev-properties-system.h" 30#include "hw/char/renesas_sci.h" 31#include "migration/vmstate.h" 32 33/* SCI register map */ 34REG8(SMR, 0) 35 FIELD(SMR, CKS, 0, 2) 36 FIELD(SMR, MP, 2, 1) 37 FIELD(SMR, STOP, 3, 1) 38 FIELD(SMR, PM, 4, 1) 39 FIELD(SMR, PE, 5, 1) 40 FIELD(SMR, CHR, 6, 1) 41 FIELD(SMR, CM, 7, 1) 42REG8(BRR, 1) 43REG8(SCR, 2) 44 FIELD(SCR, CKE, 0, 2) 45 FIELD(SCR, TEIE, 2, 1) 46 FIELD(SCR, MPIE, 3, 1) 47 FIELD(SCR, RE, 4, 1) 48 FIELD(SCR, TE, 5, 1) 49 FIELD(SCR, RIE, 6, 1) 50 FIELD(SCR, TIE, 7, 1) 51REG8(TDR, 3) 52REG8(SSR, 4) 53 FIELD(SSR, MPBT, 0, 1) 54 FIELD(SSR, MPB, 1, 1) 55 FIELD(SSR, TEND, 2, 1) 56 FIELD(SSR, ERR, 3, 3) 57 FIELD(SSR, PER, 3, 1) 58 FIELD(SSR, FER, 4, 1) 59 FIELD(SSR, ORER, 5, 1) 60 FIELD(SSR, RDRF, 6, 1) 61 FIELD(SSR, TDRE, 7, 1) 62REG8(RDR, 5) 63REG8(SCMR, 6) 64 FIELD(SCMR, SMIF, 0, 1) 65 FIELD(SCMR, SINV, 2, 1) 66 FIELD(SCMR, SDIR, 3, 1) 67 FIELD(SCMR, BCP2, 7, 1) 68REG8(SEMR, 7) 69 FIELD(SEMR, ACS0, 0, 1) 70 FIELD(SEMR, ABCS, 4, 1) 71 72static int can_receive(void *opaque) 73{ 74 RSCIState *sci = RSCI(opaque); 75 if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { 76 return 0; 77 } else { 78 return FIELD_EX8(sci->scr, SCR, RE); 79 } 80} 81 82static void receive(void *opaque, const uint8_t *buf, int size) 83{ 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); 90 } 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]); 96 } 97 } 98} 99 100static void send_byte(RSCIState *sci) 101{ 102 if (qemu_chr_fe_backend_connected(&sci->chr)) { 103 qemu_chr_fe_write_all(&sci->chr, &sci->tdr, 1); 104 } 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]); 111 } 112} 113 114static void txend(void *opaque) 115{ 116 RSCIState *sci = RSCI(opaque); 117 if (!FIELD_EX8(sci->ssr, SSR, TDRE)) { 118 send_byte(sci); 119 } 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); 123 } 124 } 125} 126 127static void update_trtime(RSCIState *sci) 128{ 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; 138} 139 140static bool sci_is_tr_enabled(RSCIState *sci) 141{ 142 return FIELD_EX8(sci->scr, SCR, TE) || FIELD_EX8(sci->scr, SCR, RE); 143} 144 145static void sci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) 146{ 147 RSCIState *sci = RSCI(opaque); 148 149 switch (offset) { 150 case A_SMR: 151 if (!sci_is_tr_enabled(sci)) { 152 sci->smr = val; 153 update_trtime(sci); 154 } 155 break; 156 case A_BRR: 157 if (!sci_is_tr_enabled(sci)) { 158 sci->brr = val; 159 update_trtime(sci); 160 } 161 break; 162 case A_SCR: 163 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 } 170 } 171 if (!FIELD_EX8(sci->scr, SCR, TEIE)) { 172 qemu_set_irq(sci->irq[TEI], 0); 173 } 174 if (!FIELD_EX8(sci->scr, SCR, RIE)) { 175 qemu_set_irq(sci->irq[ERI], 0); 176 } 177 break; 178 case A_TDR: 179 sci->tdr = val; 180 if (FIELD_EX8(sci->ssr, SSR, TEND)) { 181 send_byte(sci); 182 } else { 183 sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0); 184 } 185 break; 186 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"); 198 break; 199 case A_SCMR: 200 sci->scmr = val; break; 201 case A_SEMR: /* SEMR */ 202 sci->semr = val; break; 203 default: 204 qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX " " 205 "not implemented\n", 206 offset); 207 } 208} 209 210static uint64_t sci_read(void *opaque, hwaddr offset, unsigned size) 211{ 212 RSCIState *sci = RSCI(opaque); 213 214 switch (offset) { 215 case A_SMR: 216 return sci->smr; 217 case A_BRR: 218 return sci->brr; 219 case A_SCR: 220 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; 226 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; 233 default: 234 qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX 235 " not implemented.\n", offset); 236 } 237 return UINT64_MAX; 238} 239 240static 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}; 247 248static void rsci_reset(DeviceState *dev) 249{ 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); 259} 260 261static void sci_event(void *opaque, QEMUChrEvent event) 262{ 263 RSCIState *sci = RSCI(opaque); 264 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 } 269 } 270} 271 272static void rsci_realize(DeviceState *dev, Error **errp) 273{ 274 RSCIState *sci = RSCI(dev); 275 276 if (sci->input_freq == 0) { 277 qemu_log_mask(LOG_GUEST_ERROR, 278 "renesas_sci: input-freq property must be set."); 279 return; 280 } 281 qemu_chr_fe_set_handlers(&sci->chr, can_receive, receive, 282 sci_event, NULL, sci, NULL, true); 283} 284 285static void rsci_init(Object *obj) 286{ 287 SysBusDevice *d = SYS_BUS_DEVICE(obj); 288 RSCIState *sci = RSCI(obj); 289 int i; 290 291 memory_region_init_io(&sci->memory, OBJECT(sci), &sci_ops, 292 sci, "renesas-sci", 0x8); 293 sysbus_init_mmio(d, &sci->memory); 294 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); 299} 300 301static const VMStateDescription vmstate_rsci = { 302 .name = "renesas-sci", 303 .version_id = 1, 304 .minimum_version_id = 1, 305 .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), 318 VMSTATE_END_OF_LIST() 319 } 320}; 321 322static Property rsci_properties[] = { 323 DEFINE_PROP_UINT64("input-freq", RSCIState, input_freq, 0), 324 DEFINE_PROP_CHR("chardev", RSCIState, chr), 325 DEFINE_PROP_END_OF_LIST(), 326}; 327 328static void rsci_class_init(ObjectClass *klass, void *data) 329{ 330 DeviceClass *dc = DEVICE_CLASS(klass); 331 332 dc->realize = rsci_realize; 333 dc->vmsd = &vmstate_rsci; 334 dc->reset = rsci_reset; 335 device_class_set_props(dc, rsci_properties); 336} 337 338static 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, 344}; 345 346static void rsci_register_types(void) 347{ 348 type_register_static(&rsci_info); 349} 350 351type_init(rsci_register_types)