cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

avr_usart.c (9099B)


      1/*
      2 * AVR USART
      3 *
      4 * Copyright (c) 2018 University of Kent
      5 * Author: Sarah Harris
      6 *
      7 * This library is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, see
     19 * <http://www.gnu.org/licenses/lgpl-2.1.html>
     20 */
     21
     22#include "qemu/osdep.h"
     23#include "hw/char/avr_usart.h"
     24#include "qemu/log.h"
     25#include "hw/irq.h"
     26#include "hw/qdev-properties.h"
     27#include "hw/qdev-properties-system.h"
     28
     29static int avr_usart_can_receive(void *opaque)
     30{
     31    AVRUsartState *usart = opaque;
     32
     33    if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) {
     34        return 0;
     35    }
     36    return 1;
     37}
     38
     39static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size)
     40{
     41    AVRUsartState *usart = opaque;
     42    assert(size == 1);
     43    assert(!usart->data_valid);
     44    usart->data = buffer[0];
     45    usart->data_valid = true;
     46    usart->csra |= USART_CSRA_RXC;
     47    if (usart->csrb & USART_CSRB_RXCIE) {
     48        qemu_set_irq(usart->rxc_irq, 1);
     49    }
     50}
     51
     52static void update_char_mask(AVRUsartState *usart)
     53{
     54    uint8_t mode = ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) |
     55        ((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) |
     56        ((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0);
     57    switch (mode) {
     58    case 0:
     59        usart->char_mask = 0b11111;
     60        break;
     61    case 1:
     62        usart->char_mask = 0b111111;
     63        break;
     64    case 2:
     65        usart->char_mask = 0b1111111;
     66        break;
     67    case 3:
     68        usart->char_mask = 0b11111111;
     69        break;
     70    case 4:
     71        /* Fallthrough. */
     72    case 5:
     73        /* Fallthrough. */
     74    case 6:
     75        qemu_log_mask(
     76            LOG_GUEST_ERROR,
     77            "%s: Reserved character size 0x%x\n",
     78            __func__,
     79            mode);
     80        break;
     81    case 7:
     82        qemu_log_mask(
     83            LOG_GUEST_ERROR,
     84            "%s: Nine bit character size not supported (forcing eight)\n",
     85            __func__);
     86        usart->char_mask = 0b11111111;
     87        break;
     88    default:
     89        assert(0);
     90    }
     91}
     92
     93static void avr_usart_reset(DeviceState *dev)
     94{
     95    AVRUsartState *usart = AVR_USART(dev);
     96    usart->data_valid = false;
     97    usart->csra = 0b00100000;
     98    usart->csrb = 0b00000000;
     99    usart->csrc = 0b00000110;
    100    usart->brrl = 0;
    101    usart->brrh = 0;
    102    update_char_mask(usart);
    103    qemu_set_irq(usart->rxc_irq, 0);
    104    qemu_set_irq(usart->txc_irq, 0);
    105    qemu_set_irq(usart->dre_irq, 0);
    106}
    107
    108static uint64_t avr_usart_read(void *opaque, hwaddr addr, unsigned int size)
    109{
    110    AVRUsartState *usart = opaque;
    111    uint8_t data;
    112    assert(size == 1);
    113
    114    if (!usart->enabled) {
    115        return 0;
    116    }
    117
    118    switch (addr) {
    119    case USART_DR:
    120        if (!(usart->csrb & USART_CSRB_RXEN)) {
    121            /* Receiver disabled, ignore. */
    122            return 0;
    123        }
    124        if (usart->data_valid) {
    125            data = usart->data & usart->char_mask;
    126            usart->data_valid = false;
    127        } else {
    128            data = 0;
    129        }
    130        usart->csra &= 0xff ^ USART_CSRA_RXC;
    131        qemu_set_irq(usart->rxc_irq, 0);
    132        qemu_chr_fe_accept_input(&usart->chr);
    133        return data;
    134    case USART_CSRA:
    135        return usart->csra;
    136    case USART_CSRB:
    137        return usart->csrb;
    138    case USART_CSRC:
    139        return usart->csrc;
    140    case USART_BRRL:
    141        return usart->brrl;
    142    case USART_BRRH:
    143        return usart->brrh;
    144    default:
    145        qemu_log_mask(
    146            LOG_GUEST_ERROR,
    147            "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    148            __func__,
    149            addr);
    150    }
    151    return 0;
    152}
    153
    154static void avr_usart_write(void *opaque, hwaddr addr, uint64_t value,
    155                                unsigned int size)
    156{
    157    AVRUsartState *usart = opaque;
    158    uint8_t mask;
    159    uint8_t data;
    160    assert((value & 0xff) == value);
    161    assert(size == 1);
    162
    163    if (!usart->enabled) {
    164        return;
    165    }
    166
    167    switch (addr) {
    168    case USART_DR:
    169        if (!(usart->csrb & USART_CSRB_TXEN)) {
    170            /* Transmitter disabled, ignore. */
    171            return;
    172        }
    173        usart->csra |= USART_CSRA_TXC;
    174        usart->csra |= USART_CSRA_DRE;
    175        if (usart->csrb & USART_CSRB_TXCIE) {
    176            qemu_set_irq(usart->txc_irq, 1);
    177            usart->csra &= 0xff ^ USART_CSRA_TXC;
    178        }
    179        if (usart->csrb & USART_CSRB_DREIE) {
    180            qemu_set_irq(usart->dre_irq, 1);
    181        }
    182        data = value;
    183        qemu_chr_fe_write_all(&usart->chr, &data, 1);
    184        break;
    185    case USART_CSRA:
    186        mask = 0b01000011;
    187        /* Mask read-only bits. */
    188        value = (value & mask) | (usart->csra & (0xff ^ mask));
    189        usart->csra = value;
    190        if (value & USART_CSRA_TXC) {
    191            usart->csra ^= USART_CSRA_TXC;
    192            qemu_set_irq(usart->txc_irq, 0);
    193        }
    194        if (value & USART_CSRA_MPCM) {
    195            qemu_log_mask(
    196                LOG_GUEST_ERROR,
    197                "%s: MPCM not supported by USART\n",
    198                __func__);
    199        }
    200        break;
    201    case USART_CSRB:
    202        mask = 0b11111101;
    203        /* Mask read-only bits. */
    204        value = (value & mask) | (usart->csrb & (0xff ^ mask));
    205        usart->csrb = value;
    206        if (!(value & USART_CSRB_RXEN)) {
    207            /* Receiver disabled, flush input buffer. */
    208            usart->data_valid = false;
    209        }
    210        qemu_set_irq(usart->rxc_irq,
    211            ((value & USART_CSRB_RXCIE) &&
    212            (usart->csra & USART_CSRA_RXC)) ? 1 : 0);
    213        qemu_set_irq(usart->txc_irq,
    214            ((value & USART_CSRB_TXCIE) &&
    215            (usart->csra & USART_CSRA_TXC)) ? 1 : 0);
    216        qemu_set_irq(usart->dre_irq,
    217            ((value & USART_CSRB_DREIE) &&
    218            (usart->csra & USART_CSRA_DRE)) ? 1 : 0);
    219        update_char_mask(usart);
    220        break;
    221    case USART_CSRC:
    222        usart->csrc = value;
    223        if ((value & USART_CSRC_MSEL1) && (value & USART_CSRC_MSEL0)) {
    224            qemu_log_mask(
    225                LOG_GUEST_ERROR,
    226                "%s: SPI mode not supported by USART\n",
    227                __func__);
    228        }
    229        if ((value & USART_CSRC_MSEL1) && !(value & USART_CSRC_MSEL0)) {
    230            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad USART mode\n", __func__);
    231        }
    232        if (!(value & USART_CSRC_PM1) && (value & USART_CSRC_PM0)) {
    233            qemu_log_mask(
    234                LOG_GUEST_ERROR,
    235                "%s: Bad USART parity mode\n",
    236                __func__);
    237        }
    238        update_char_mask(usart);
    239        break;
    240    case USART_BRRL:
    241        usart->brrl = value;
    242        break;
    243    case USART_BRRH:
    244        usart->brrh = value & 0b00001111;
    245        break;
    246    default:
    247        qemu_log_mask(
    248            LOG_GUEST_ERROR,
    249            "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    250            __func__,
    251            addr);
    252    }
    253}
    254
    255static const MemoryRegionOps avr_usart_ops = {
    256    .read = avr_usart_read,
    257    .write = avr_usart_write,
    258    .endianness = DEVICE_NATIVE_ENDIAN,
    259    .impl = {.min_access_size = 1, .max_access_size = 1}
    260};
    261
    262static Property avr_usart_properties[] = {
    263    DEFINE_PROP_CHR("chardev", AVRUsartState, chr),
    264    DEFINE_PROP_END_OF_LIST(),
    265};
    266
    267static void avr_usart_pr(void *opaque, int irq, int level)
    268{
    269    AVRUsartState *s = AVR_USART(opaque);
    270
    271    s->enabled = !level;
    272
    273    if (!s->enabled) {
    274        avr_usart_reset(DEVICE(s));
    275    }
    276}
    277
    278static void avr_usart_init(Object *obj)
    279{
    280    AVRUsartState *s = AVR_USART(obj);
    281    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rxc_irq);
    282    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->dre_irq);
    283    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->txc_irq);
    284    memory_region_init_io(&s->mmio, obj, &avr_usart_ops, s, TYPE_AVR_USART, 7);
    285    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
    286    qdev_init_gpio_in(DEVICE(s), avr_usart_pr, 1);
    287    s->enabled = true;
    288}
    289
    290static void avr_usart_realize(DeviceState *dev, Error **errp)
    291{
    292    AVRUsartState *s = AVR_USART(dev);
    293    qemu_chr_fe_set_handlers(&s->chr, avr_usart_can_receive,
    294                             avr_usart_receive, NULL, NULL,
    295                             s, NULL, true);
    296    avr_usart_reset(dev);
    297}
    298
    299static void avr_usart_class_init(ObjectClass *klass, void *data)
    300{
    301    DeviceClass *dc = DEVICE_CLASS(klass);
    302
    303    dc->reset = avr_usart_reset;
    304    device_class_set_props(dc, avr_usart_properties);
    305    dc->realize = avr_usart_realize;
    306}
    307
    308static const TypeInfo avr_usart_info = {
    309    .name          = TYPE_AVR_USART,
    310    .parent        = TYPE_SYS_BUS_DEVICE,
    311    .instance_size = sizeof(AVRUsartState),
    312    .instance_init = avr_usart_init,
    313    .class_init    = avr_usart_class_init,
    314};
    315
    316static void avr_usart_register_types(void)
    317{
    318    type_register_static(&avr_usart_info);
    319}
    320
    321type_init(avr_usart_register_types)