Esempio n. 1
0
/* external write */
static void amdvi_writew(AMDVIState *s, hwaddr addr, uint16_t val)
{
    uint16_t romask = lduw_le_p(&s->romask[addr]);
    uint16_t w1cmask = lduw_le_p(&s->w1cmask[addr]);
    uint16_t oldval = lduw_le_p(&s->mmior[addr]);
    stw_le_p(&s->mmior[addr],
            ((oldval & romask) | (val & ~romask)) & ~(val & w1cmask));
}
Esempio n. 2
0
static char *read_splashfile(char *filename, gsize *file_sizep,
                             int *file_typep)
{
    GError *err = NULL;
    gchar *content;
    int file_type;
    unsigned int filehead;
    int bmp_bpp;

    if (!g_file_get_contents(filename, &content, file_sizep, &err)) {
        error_report("failed to read splash file '%s': %s",
                     filename, err->message);
        g_error_free(err);
        return NULL;
    }

    /* check file size */
    if (*file_sizep < 30) {
        goto error;
    }

    /* check magic ID */
    filehead = lduw_le_p(content);
    if (filehead == 0xd8ff) {
        file_type = JPG_FILE;
    } else if (filehead == 0x4d42) {
        file_type = BMP_FILE;
    } else {
        goto error;
    }

    /* check BMP bpp */
    if (file_type == BMP_FILE) {
        bmp_bpp = lduw_le_p(&content[28]);
        if (bmp_bpp != 24) {
            goto error;
        }
    }

    /* return values */
    *file_typep = file_type;

    return content;

error:
    error_report("splash file '%s' format not recognized; must be JPEG "
                 "or 24 bit BMP", filename);
    g_free(content);
    return NULL;
}
Esempio n. 3
0
static void v9fs_req_recv(P9Req *req, uint8_t id)
{
    QVirtIO9P *v9p = req->v9p;
    P9Hdr hdr;
    int i;

    for (i = 0; i < 10; i++) {
        qvirtio_wait_queue_isr(v9p->dev, v9p->vq, 1000 * 1000);

        v9fs_memread(req, &hdr, 7);
        hdr.size = ldl_le_p(&hdr.size);
        hdr.tag = lduw_le_p(&hdr.tag);
        if (hdr.size >= 7) {
            break;
        }
        v9fs_memrewind(req, 7);
    }

    g_assert_cmpint(hdr.size, >=, 7);
    g_assert_cmpint(hdr.size, <=, P9_MAX_SIZE);
    g_assert_cmpint(hdr.tag, ==, req->tag);

    if (hdr.id != id) {
        g_printerr("Received response %d (%s) instead of %d (%s)\n",
                   hdr.id, rmessage_name(hdr.id), id, rmessage_name(id));

        if (hdr.id == P9_RLERROR) {
            uint32_t err;
            v9fs_uint32_read(req, &err);
            g_printerr("Rlerror has errno %d (%s)\n", err, strerror(err));
        }
    }
    g_assert_cmpint(hdr.id, ==, id);
}
Esempio n. 4
0
/* warning: addr must be aligned */
static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
    hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
    enum device_endian endian)
{
    uint8_t *ptr;
    uint64_t val;
    MemoryRegion *mr;
    hwaddr l = 2;
    hwaddr addr1;
    MemTxResult r;
    bool release_lock = false;

    RCU_READ_LOCK();
    mr = TRANSLATE(addr, &addr1, &l, false);
    if (l < 2 || !IS_DIRECT(mr, false)) {
        release_lock |= prepare_mmio_access(mr);

        /* I/O case */
        r = memory_region_dispatch_read(mr, addr1, &val, 2, attrs);
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap16(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap16(val);
        }
#endif
    } else {
        /* RAM case */
        ptr = MAP_RAM(mr, addr1);
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            val = lduw_le_p(ptr);
            break;
        case DEVICE_BIG_ENDIAN:
            val = lduw_be_p(ptr);
            break;
        default:
            val = lduw_p(ptr);
            break;
        }
        r = MEMTX_OK;
    }
    if (result) {
        *result = r;
    }
    if (release_lock) {
        qemu_mutex_unlock_iothread();
    }
    RCU_READ_UNLOCK();
    return val;
}
Esempio n. 5
0
static uint16_t amdvi_readw(AMDVIState *s, hwaddr addr)
{
    return lduw_le_p(&s->mmior[addr]);
}
Esempio n. 6
0
/* Install a copy of the ACPI table specified in @blob.
 *
 * If @has_header is set, @blob starts with the System Description Table Header
 * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
 * is optionally overwritten from @hdrs.
 *
 * It is valid to call this function with
 * (@blob == NULL && bloblen == 0 && !has_header).
 *
 * @hdrs->file and @hdrs->data are ignored.
 *
 * SIZE_MAX is considered "infinity" in this function.
 *
 * The number of tables that can be installed is not limited, but the 16-bit
 * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
 */
static void acpi_table_install(const char unsigned *blob, size_t bloblen,
                               bool has_header,
                               const struct AcpiTableOptions *hdrs,
                               Error **errp)
{
    size_t body_start;
    const char unsigned *hdr_src;
    size_t body_size, acpi_payload_size;
    struct acpi_table_header *ext_hdr;
    unsigned changed_fields;

    /* Calculate where the ACPI table body starts within the blob, plus where
     * to copy the ACPI table header from.
     */
    if (has_header) {
        /*   _length             | ACPI header in blob | blob body
         *   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^
         *   ACPI_TABLE_PFX_SIZE     sizeof dfl_hdr      body_size
         *                           == body_start
         *
         *                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *                           acpi_payload_size == bloblen
         */
        body_start = sizeof dfl_hdr;

        if (bloblen < body_start) {
            error_setg(errp, "ACPI table claiming to have header is too "
                       "short, available: %zu, expected: %zu", bloblen,
                       body_start);
            return;
        }
        hdr_src = blob;
    } else {
        /*   _length             | ACPI header in template | blob body
         *   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^
         *   ACPI_TABLE_PFX_SIZE       sizeof dfl_hdr        body_size
         *                                                   == bloblen
         *
         *                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *                                  acpi_payload_size
         */
        body_start = 0;
        hdr_src = dfl_hdr;
    }
    body_size = bloblen - body_start;
    acpi_payload_size = sizeof dfl_hdr + body_size;

    if (acpi_payload_size > UINT16_MAX) {
        error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
                   acpi_payload_size, (unsigned)UINT16_MAX);
        return;
    }

    /* We won't fail from here on. Initialize / extend the globals. */
    if (acpi_tables == NULL) {
        acpi_tables_len = sizeof(uint16_t);
        acpi_tables = g_malloc0(acpi_tables_len);
    }

    acpi_tables = g_realloc(acpi_tables, acpi_tables_len +
                                         ACPI_TABLE_PFX_SIZE +
                                         sizeof dfl_hdr + body_size);

    ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len);
    acpi_tables_len += ACPI_TABLE_PFX_SIZE;

    memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr);
    acpi_tables_len += sizeof dfl_hdr;

    if (blob != NULL) {
        memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size);
        acpi_tables_len += body_size;
    }

    /* increase number of tables */
    stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);

    /* Update the header fields. The strings need not be NUL-terminated. */
    changed_fields = 0;
    ext_hdr->_length = cpu_to_le16(acpi_payload_size);

    if (hdrs->has_sig) {
        strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
        ++changed_fields;
    }

    if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
        warn_report("ACPI table has wrong length, header says "
                    "%" PRIu32 ", actual size %zu bytes",
                    le32_to_cpu(ext_hdr->length), acpi_payload_size);
    }
    ext_hdr->length = cpu_to_le32(acpi_payload_size);

    if (hdrs->has_rev) {
        ext_hdr->revision = hdrs->rev;
        ++changed_fields;
    }

    ext_hdr->checksum = 0;

    if (hdrs->has_oem_id) {
        strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
        ++changed_fields;
    }
    if (hdrs->has_oem_table_id) {
        strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id,
                sizeof ext_hdr->oem_table_id);
        ++changed_fields;
    }
    if (hdrs->has_oem_rev) {
        ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev);
        ++changed_fields;
    }
    if (hdrs->has_asl_compiler_id) {
        strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id,
                sizeof ext_hdr->asl_compiler_id);
        ++changed_fields;
    }
    if (hdrs->has_asl_compiler_rev) {
        ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev);
        ++changed_fields;
    }

    if (!has_header && changed_fields == 0) {
        warn_report("ACPI table: no headers are specified");
    }

    /* recalculate checksum */
    ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
                                      ACPI_TABLE_PFX_SIZE, acpi_payload_size);
}