Commit 205e3e78 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180222' into staging



 * New "raspi3" machine emulating RaspberryPi 3
 * Fix bad register definitions for VMIDR and VMPIDR (which caused
   assertions for 64-bit guest CPUs with EL2 on big-endian hosts)
 * hw/char/stm32f2xx_usart: fix TXE/TC bit handling
 * Fix ast2500 protection register emulation
 * Lots of SD card emulation cleanups and bugfixes

# gpg: Signature made Thu 22 Feb 2018 15:18:53 GMT
# gpg:                using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20180222: (32 commits)
  sdcard: simplify SD_SEND_OP_COND (ACMD41)
  sdcard: simplify SEND_IF_COND (CMD8)
  sdcard: warn if host uses an incorrect address for APP CMD (CMD55)
  sdcard: check the card is in correct state for APP CMD (CMD55)
  sdcard: handles more commands in SPI mode
  sdcard: use a more descriptive label 'unimplemented_spi_cmd'
  sdcard: handle the Security Specification commands
  sdcard: handle CMD54 (SDIO)
  sdcard: use the registerfields API for the CARD_STATUS register masks
  sdcard: use the correct masked OCR in the R3 reply
  sdcard: simplify using the ldst API
  sdcard: remove commands from unsupported old MMC specification
  sdcard: clean the SCR register and add few comments
  sdcard: fix the 'maximum data transfer rate' to 25MHz
  sdcard: update the CSD CRC register regardless the CSD structure version
  sdcard: Don't always set the high capacity bit
  sdcard: use the registerfields API to access the OCR register
  sdcard: use G_BYTE from cutils
  sdcard: define SDMMC_CMD_MAX instead of using the magic '64'
  sdcard: add more trace events
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 0ce9cb91 4e5cc675
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -187,3 +187,26 @@ static void raspi2_machine_init(MachineClass *mc)
    mc->ignore_memory_transaction_failures = true;
};
DEFINE_MACHINE("raspi2", raspi2_machine_init)

#ifdef TARGET_AARCH64
static void raspi3_init(MachineState *machine)
{
    raspi_init(machine, 3);
}

static void raspi3_machine_init(MachineClass *mc)
{
    mc->desc = "Raspberry Pi 3";
    mc->init = raspi3_init;
    mc->block_default_type = IF_SD;
    mc->no_parallel = 1;
    mc->no_floppy = 1;
    mc->no_cdrom = 1;
    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
    mc->max_cpus = BCM2836_NCPUS;
    mc->min_cpus = BCM2836_NCPUS;
    mc->default_cpus = BCM2836_NCPUS;
    mc->default_ram_size = 1024 * 1024 * 1024;
}
DEFINE_MACHINE("raspi3", raspi3_machine_init)
#endif
+8 −4
Original line number Diff line number Diff line
@@ -96,12 +96,10 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
    switch (addr) {
    case USART_SR:
        retvalue = s->usart_sr;
        s->usart_sr &= ~USART_SR_TC;
        qemu_chr_fe_accept_input(&s->chr);
        return retvalue;
    case USART_DR:
        DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
        s->usart_sr |= USART_SR_TXE;
        s->usart_sr &= ~USART_SR_RXNE;
        qemu_chr_fe_accept_input(&s->chr);
        qemu_set_irq(s->irq, 0);
@@ -137,7 +135,9 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
    switch (addr) {
    case USART_SR:
        if (value <= 0x3FF) {
            s->usart_sr = value;
            /* I/O being synchronous, TXE is always set. In addition, it may
               only be set by hardware, so keep it set here. */
            s->usart_sr = value | USART_SR_TXE;
        } else {
            s->usart_sr &= value;
        }
@@ -151,8 +151,12 @@ static void stm32f2xx_usart_write(void *opaque, hwaddr addr,
            /* XXX this blocks entire thread. Rewrite to use
             * qemu_chr_fe_write and background I/O callbacks */
            qemu_chr_fe_write_all(&s->chr, &ch, 1);
            /* XXX I/O are currently synchronous, making it impossible for
               software to observe transient states where TXE or TC aren't
               set. Unlike TXE however, which is read-only, software may
               clear TC by writing 0 to the SR register, so set it again
               on each write. */
            s->usart_sr |= USART_SR_TC;
            s->usart_sr &= ~USART_SR_TXE;
        }
        return;
    case USART_BRR:
+5 −1
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
    }

    if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
            s->regs[PROT_KEY] != ASPEED_SCU_PROT_KEY) {
            !s->regs[PROT_KEY]) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
        return;
    }
@@ -199,6 +199,10 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
    trace_aspeed_scu_write(offset, size, data);

    switch (reg) {
    case PROT_KEY:
        s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
        return;

    case FREQ_CNTR_EVAL:
    case VGA_SCRATCH1 ... VGA_SCRATCH8:
    case RNG_DATA:
+7 −1
Original line number Diff line number Diff line
@@ -110,7 +110,12 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
        return;
    }

    if (addr != R_PROT && s->regs[R_PROT] != PROT_KEY_UNLOCK) {
    if (addr == R_PROT) {
        s->regs[addr] = (data == PROT_KEY_UNLOCK) ? 1 : 0;
        return;
    }

    if (!s->regs[R_PROT]) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
        return;
    }
@@ -123,6 +128,7 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
            data &= ~ASPEED_SDMC_READONLY_MASK;
            break;
        case AST2500_A0_SILICON_REV:
        case AST2500_A1_SILICON_REV:
            data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
            break;
        default:
+46 −35
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
#include "trace.h"
#include "qemu/error-report.h"
#include "include/qapi/error.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/sd/sd.h"
@@ -68,7 +69,7 @@ struct MilkymistMemcardState {
    SysBusDevice parent_obj;

    MemoryRegion regs_region;
    SDState *card;
    SDBus sdbus;

    int command_write_ptr;
    int response_read_ptr;
@@ -104,7 +105,7 @@ static void memcard_sd_command(MilkymistMemcardState *s)
    req.crc = s->command[5];

    s->response[0] = req.cmd;
    s->response_len = sd_do_command(s->card, &req, s->response+1);
    s->response_len = sdbus_do_command(&s->sdbus, &req, s->response + 1);
    s->response_read_ptr = 0;

    if (s->response_len == 16) {
@@ -138,7 +139,7 @@ static uint64_t memcard_read(void *opaque, hwaddr addr,
        } else {
            r = s->response[s->response_read_ptr++];
            if (s->response_read_ptr > s->response_len) {
                error_report("milkymist_memcard: "
                qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: "
                              "read more cmd bytes than available. Clipping.");
                s->response_read_ptr = 0;
            }
@@ -149,10 +150,10 @@ static uint64_t memcard_read(void *opaque, hwaddr addr,
            r = 0xffffffff;
        } else {
            r = 0;
            r |= sd_read_data(s->card) << 24;
            r |= sd_read_data(s->card) << 16;
            r |= sd_read_data(s->card) << 8;
            r |= sd_read_data(s->card);
            r |= sdbus_read_data(&s->sdbus) << 24;
            r |= sdbus_read_data(&s->sdbus) << 16;
            r |= sdbus_read_data(&s->sdbus) << 8;
            r |= sdbus_read_data(&s->sdbus);
        }
        break;
    case R_CLK2XDIV:
@@ -163,8 +164,9 @@ static uint64_t memcard_read(void *opaque, hwaddr addr,
        break;

    default:
        error_report("milkymist_memcard: read access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        qemu_log_mask(LOG_UNIMP, "milkymist_memcard: "
                      "read access to unknown register 0x%" HWADDR_PRIx "\n",
                      addr << 2);
        break;
    }

@@ -205,10 +207,10 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value,
        if (!s->enabled) {
            break;
        }
        sd_write_data(s->card, (value >> 24) & 0xff);
        sd_write_data(s->card, (value >> 16) & 0xff);
        sd_write_data(s->card, (value >> 8) & 0xff);
        sd_write_data(s->card, value & 0xff);
        sdbus_write_data(&s->sdbus, (value >> 24) & 0xff);
        sdbus_write_data(&s->sdbus, (value >> 16) & 0xff);
        sdbus_write_data(&s->sdbus, (value >> 8) & 0xff);
        sdbus_write_data(&s->sdbus, value & 0xff);
        break;
    case R_ENABLE:
        s->regs[addr] = value;
@@ -220,8 +222,9 @@ static void memcard_write(void *opaque, hwaddr addr, uint64_t value,
        break;

    default:
        error_report("milkymist_memcard: write access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        qemu_log_mask(LOG_UNIMP, "milkymist_memcard: "
                      "write access to unknown register 0x%" HWADDR_PRIx " "
                      "(value 0x%" PRIx64 ")\n", addr << 2, value);
        break;
    }
}
@@ -248,33 +251,41 @@ static void milkymist_memcard_reset(DeviceState *d)
    for (i = 0; i < R_MAX; i++) {
        s->regs[i] = 0;
    }
    /* Since we're still using the legacy SD API the card is not plugged
     * into any bus, and we must reset it manually.
     */
    device_reset(DEVICE(s->card));
}

static int milkymist_memcard_init(SysBusDevice *dev)
static void milkymist_memcard_init(Object *obj)
{
    MilkymistMemcardState *s = MILKYMIST_MEMCARD(obj);
    SysBusDevice *dev = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
            "milkymist-memcard", R_MAX * 4);
    sysbus_init_mmio(dev, &s->regs_region);
}

static void milkymist_memcard_realize(DeviceState *dev, Error **errp)
{
    MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev);
    DriveInfo *dinfo;
    DeviceState *carddev;
    BlockBackend *blk;
    DriveInfo *dinfo;
    Error *err = NULL;

    qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
                        dev, "sd-bus");

    /* Create and plug in the sd card */
    /* FIXME use a qdev drive property instead of drive_get_next() */
    dinfo = drive_get_next(IF_SD);
    blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
    s->card = sd_init(blk, false);
    if (s->card == NULL) {
        return -1;
    carddev = qdev_create(&s->sdbus.qbus, TYPE_SD_CARD);
    qdev_prop_set_drive(carddev, "drive", blk, &err);
    object_property_set_bool(OBJECT(carddev), true, "realized", &err);
    if (err) {
        error_setg(errp, "failed to init SD card: %s", error_get_pretty(err));
        return;
    }

    s->enabled = blk && blk_is_inserted(blk);

    memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
            "milkymist-memcard", R_MAX * 4);
    sysbus_init_mmio(dev, &s->regs_region);

    return 0;
}

static const VMStateDescription vmstate_milkymist_memcard = {
@@ -297,9 +308,8 @@ static const VMStateDescription vmstate_milkymist_memcard = {
static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = milkymist_memcard_init;
    dc->realize = milkymist_memcard_realize;
    dc->reset = milkymist_memcard_reset;
    dc->vmsd = &vmstate_milkymist_memcard;
    /* Reason: init() method uses drive_get_next() */
@@ -310,6 +320,7 @@ static const TypeInfo milkymist_memcard_info = {
    .name          = TYPE_MILKYMIST_MEMCARD,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MilkymistMemcardState),
    .instance_init = milkymist_memcard_init,
    .class_init    = milkymist_memcard_class_init,
};

Loading