static void exynos4210_uart_write(void *opaque, target_phys_addr_t offset, uint64_t val, unsigned size) { Exynos4210UartState *s = (Exynos4210UartState *)opaque; uint8_t ch; PRINT_DEBUG_EXTEND("UART%d: <0x%04x> %s <- 0x%08llx\n", s->channel, offset, exynos4210_uart_regname(offset), (long long unsigned int)val); switch (offset) { case ULCON: case UBRDIV: case UFRACVAL: s->reg[I_(offset)] = val; exynos4210_uart_update_parameters(s); break; case UFCON: s->reg[I_(UFCON)] = val; if (val & UFCON_Rx_FIFO_RESET) { fifo_reset(&s->rx); s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET; PRINT_DEBUG("UART%d: Rx FIFO Reset\n", s->channel); } if (val & UFCON_Tx_FIFO_RESET) { fifo_reset(&s->tx); s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET; PRINT_DEBUG("UART%d: Tx FIFO Reset\n", s->channel); } break; case UTXH: if (s->chr) { s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY | UTRSTAT_Tx_BUFFER_EMPTY); ch = (uint8_t)val; qemu_chr_fe_write(s->chr, &ch, 1); #if DEBUG_Tx_DATA fprintf(stderr, "%c", ch); #endif s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY | UTRSTAT_Tx_BUFFER_EMPTY; s->reg[I_(UINTSP)] |= UINTSP_TXD; exynos4210_uart_update_irq(s); } break; case UINTP: s->reg[I_(UINTP)] &= ~val; s->reg[I_(UINTSP)] &= ~val; PRINT_DEBUG("UART%d: UINTP [%04x] have been cleared: %08x\n", s->channel, offset, s->reg[I_(UINTP)]); exynos4210_uart_update_irq(s); break; case UTRSTAT: case UERSTAT: case UFSTAT: case UMSTAT: case URXH: PRINT_DEBUG("UART%d: Trying to write into RO register: %s [%04x]\n", s->channel, exynos4210_uart_regname(offset), offset); break; case UINTSP: s->reg[I_(UINTSP)] &= ~val; break; case UINTM: s->reg[I_(UINTM)] = val; exynos4210_uart_update_irq(s); break; case UCON: case UMCON: default: s->reg[I_(offset)] = val; break; } }