Commit 54ce6f22 authored by Laurent Vivier's avatar Laurent Vivier Committed by David Gibson
Browse files

qtest: ask endianness of the target in qtest_init()



The target endianness is not deduced anymore from
the architecture name but asked directly to the guest,
using a new qtest command: "endianness". As it can't
change (this is the value of TARGET_WORDS_BIGENDIAN),
we store it to not have to ask every time we want to
know if we have to byte-swap a value.

Signed-off-by: default avatarLaurent Vivier <lvivier@redhat.com>
CC: Greg Kurz <groug@kaod.org>
CC: David Gibson <david@gibson.dropbear.id.au>
CC: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 44a3dd9b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -537,6 +537,13 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)

        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "endianness") == 0) {
        qtest_send_prefix(chr);
#if defined(TARGET_WORDS_BIGENDIAN)
        qtest_sendf(chr, "OK big\n");
#else
        qtest_sendf(chr, "OK little\n");
#endif
#ifdef TARGET_PPC64
    } else if (strcmp(words[0], "rtas") == 0) {
        uint64_t res, args, ret;
+1 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t addr)
    int i;
    uint64_t u64 = 0;

    if (qtest_big_endian()) {
    if (target_big_endian()) {
        for (i = 0; i < 8; ++i) {
            u64 |= (uint64_t)qpci_io_readb(dev->pdev,
                                (void *)(uintptr_t)addr + i) << (7 - i) * 8;
+23 −45
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ struct QTestState
    bool irq_level[MAX_IRQ];
    GString *rx;
    pid_t qemu_pid;  /* our child QEMU process */
    bool big_endian;
};

static GHookList abrt_hooks;
@@ -47,6 +48,8 @@ static struct sigaction sigact_old;
    g_assert_cmpint(ret, !=, -1); \
} while (0)

static int qtest_query_target_endianness(QTestState *s);

static int init_socket(const char *socket_path)
{
    struct sockaddr_un addr;
@@ -209,6 +212,10 @@ QTestState *qtest_init(const char *extra_args)
        kill(s->qemu_pid, SIGSTOP);
    }

    /* ask endianness of the target */

    s->big_endian = qtest_query_target_endianness(s);

    return s;
}

@@ -342,6 +349,20 @@ redo:
    return words;
}

static int qtest_query_target_endianness(QTestState *s)
{
    gchar **args;
    int big_endian;

    qtest_sendf(s, "endianness\n");
    args = qtest_rsp(s, 1);
    g_assert(strcmp(args[1], "big") == 0 || strcmp(args[1], "little") == 0);
    big_endian = strcmp(args[1], "big") == 0;
    g_strfreev(args);

    return big_endian;
}

typedef struct {
    JSONMessageParser parser;
    QDict *response;
@@ -886,50 +907,7 @@ char *hmp(const char *fmt, ...)
    return ret;
}

bool qtest_big_endian(void)
bool qtest_big_endian(QTestState *s)
{
    const char *arch = qtest_get_arch();
    int i;

    static const struct {
        const char *arch;
        bool big_endian;
    } endianness[] = {
        { "aarch64", false },
        { "alpha", false },
        { "arm", false },
        { "cris", false },
        { "i386", false },
        { "lm32", true },
        { "m68k", true },
        { "microblaze", true },
        { "microblazeel", false },
        { "mips", true },
        { "mips64", true },
        { "mips64el", false },
        { "mipsel", false },
        { "moxie", true },
        { "or32", true },
        { "ppc", true },
        { "ppc64", true },
        { "ppcemb", true },
        { "s390x", true },
        { "sh4", false },
        { "sh4eb", true },
        { "sparc", true },
        { "sparc64", true },
        { "unicore32", false },
        { "x86_64", false },
        { "xtensa", false },
        { "xtensaeb", true },
        {},
    };

    for (i = 0; endianness[i].arch; i++) {
        if (strcmp(endianness[i].arch, arch) == 0) {
            return endianness[i].big_endian;
        }
    }

    return false;
    return s->big_endian;
}
+13 −3
Original line number Diff line number Diff line
@@ -409,6 +409,14 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
 */
int64_t qtest_clock_set(QTestState *s, int64_t val);

/**
 * qtest_big_endian:
 * @s: QTestState instance to operate on.
 *
 * Returns: True if the architecture under test has a big endian configuration.
 */
bool qtest_big_endian(QTestState *s);

/**
 * qtest_get_arch:
 *
@@ -874,12 +882,14 @@ static inline int64_t clock_set(int64_t val)
}

/**
 * qtest_big_endian:
 * target_big_endian:
 *
 * Returns: True if the architecture under test has a big endian configuration.
 */
bool qtest_big_endian(void);

static inline bool target_big_endian(void)
{
    return qtest_big_endian(global_qtest);
}

QDict *qmp_fd_receive(int fd);
void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
    bool host_endian = false;
#endif

    if (qtest_big_endian() != host_endian) {
    if (target_big_endian() != host_endian) {
        req->type = bswap32(req->type);
        req->ioprio = bswap32(req->ioprio);
        req->sector = bswap64(req->sector);