qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test


From: Yongbok Kim
Subject: Re: [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test
Date: Wed, 10 Sep 2014 15:13:05 +0000

Tested-by: Yongbok Kim <address@hidden>


-----Original Message-----
From: address@hidden [mailto:address@hidden On Behalf Of Dongxue Zhang
Sent: Tuesday, July 29, 2014 2:48 PM
To: address@hidden
Cc: address@hidden; Dongxue Zhang; address@hidden
Subject: [Qemu-devel] [PATCH 1/2] target-mips: Add synci instruction test

Save code with sw and raise synci. The saved code should be raise.

If the code raised, log 'test passed'.
If the code not raised, log 'test failed, the copied instruction not run'.
Other cases, log 'unhandled'.

The test should log 'test passed'.

Signed-off-by: Dongxue Zhang <address@hidden>
---
 tests/tcg/mips/mips64/Makefile      |  54 ++++++++
 tests/tcg/mips/mips64/head.S        |  16 +++
 tests/tcg/mips/mips64/io.h          |  22 +++
 tests/tcg/mips/mips64/mips_boot.lds |  31 +++++
 tests/tcg/mips/mips64/printf.c      | 266 ++++++++++++++++++++++++++++++++++++
 tests/tcg/mips/mips64/synci.c       |  32 +++++
 6 files changed, 421 insertions(+)
 create mode 100644 tests/tcg/mips/mips64/Makefile
 create mode 100644 tests/tcg/mips/mips64/head.S
 create mode 100644 tests/tcg/mips/mips64/io.h
 create mode 100644 tests/tcg/mips/mips64/mips_boot.lds
 create mode 100644 tests/tcg/mips/mips64/printf.c
 create mode 100644 tests/tcg/mips/mips64/synci.c

diff --git a/tests/tcg/mips/mips64/Makefile b/tests/tcg/mips/mips64/Makefile
new file mode 100644
index 0000000..9a222f7
--- /dev/null
+++ b/tests/tcg/mips/mips64/Makefile
@@ -0,0 +1,54 @@
+CROSS_COMPILE  ?= mips64el-unknown-linux-gnu-
+
+SIM = qemu-system-mips64el
+SIMFLAGS = -nographic -cpu mips64r2-generic -kernel
+
+AS      = $(CROSS_COMPILE)as
+LD      = $(CROSS_COMPILE)ld
+CC      = $(CROSS_COMPILE)gcc
+AR      = $(CROSS_COMPILE)ar
+NM      = $(CROSS_COMPILE)nm
+STRIP       = $(CROSS_COMPILE)strip
+RANLIB      = $(CROSS_COMPILE)ranlib
+OBJCOPY     = $(CROSS_COMPILE)objcopy
+OBJDUMP     = $(CROSS_COMPILE)objdump
+
+VECTORS_OBJ ?= ./head.o ./printf.o
+
+HEAD_FLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe \
+              -msoft-float -march=mips64 -Wa,-mips64 -Wa,--trap \
+              -msym32 -DKBUILD_64BIT_SYM32 -I./
+
+CFLAGS ?= -nostdinc -mabi=64 -G 0 -mno-abicalls -fno-pic -fno-builtin  \
+          -pipe -march=mips64r2 -mgp64 -mdspr2 -static -Wa,--trap -msym32 \
+          -DKBUILD_64BIT_SYM32 -I./
+
+LDFLAGS = -T./mips_boot.lds -L./
+FLAGS = -nostdlib -mabi=64 -march=mips64r2 -mgp64 -mdspr2
+
+TESTCASES = synci.tst
+
+all: build
+
+head.o : head.S
+       $(Q)$(CC) $(HEAD_FLAGS) -D"STACK_TOP=0xffffffff80200000" -c $< -o $@
+
+%.o  : %.S
+       $(CC) $(CFLAGS) -c $< -o $@
+
+%.o  : %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+%.tst: %.o $(VECTORS_OBJ)
+       $(CC) $(VECTORS_OBJ) $(FLAGS) $(LDFLAGS) $< -o $@
+
+build: $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+
+check:  $(VECTORS_OBJ) $(MIPSSOC_LIB) $(TESTCASES)
+       @for case in $(TESTCASES); do \
+               echo $(SIM) $(SIMFLAGS) ./$$case; \
+               $(SIM) $(SIMFLAGS) ./$$case & (sleep 1; killall $(SIM)); \
+       done
+
+clean:
+       $(Q)rm -f *.o *.tst *.a
diff --git a/tests/tcg/mips/mips64/head.S b/tests/tcg/mips/mips64/head.S
new file mode 100644
index 0000000..9a099ae
--- /dev/null
+++ b/tests/tcg/mips/mips64/head.S
@@ -0,0 +1,16 @@
+/*
+ *  Startup Code for MIPS64 CPU-core
+ *
+ */
+.text
+.globl _start
+.align 4
+_start:
+    ori    $2, $2, 0xffff
+    sll    $2, $2, 16
+    ori    $2, $2, 0xffff
+    mtc0   $2, $12, 0
+    jal    main
+
+end:
+    b end
diff --git a/tests/tcg/mips/mips64/io.h b/tests/tcg/mips/mips64/io.h
new file mode 100644
index 0000000..b7db61d
--- /dev/null
+++ b/tests/tcg/mips/mips64/io.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+extern int printf(const char *fmt, ...);
+extern unsigned long get_ticks(void);
+
+#define _read(source)                \
+({ unsigned long __res;                \
+    __asm__ __volatile__(            \
+        "mfc0\t%0, " #source "\n\t"    \
+        : "=r" (__res));        \
+    __res;                    \
+})
+
+#define __read(source)                \
+({ unsigned long __res;                \
+    __asm__ __volatile__(            \
+        "move\t%0, " #source "\n\t"    \
+        : "=r" (__res));        \
+    __res;                    \
+})
+
+#endif
diff --git a/tests/tcg/mips/mips64/mips_boot.lds 
b/tests/tcg/mips/mips64/mips_boot.lds
new file mode 100644
index 0000000..bd7c0c0
--- /dev/null
+++ b/tests/tcg/mips/mips64/mips_boot.lds
@@ -0,0 +1,31 @@
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+    . = 0xffffffff80100000;
+    . = ALIGN((1 << 13));
+    .text :
+    {
+        *(.text)
+        *(.rodata)
+        *(.rodata.*)
+    }
+
+    __init_begin = .;
+    . = ALIGN((1 << 12));
+    .init.text : AT(ADDR(.init.text) - 0)
+    {
+        *(.init.text)
+    }
+    .init.data : AT(ADDR(.init.data) - 0)
+    {
+        *(.init.data)
+    }
+    . = ALIGN((1 << 12));
+    __init_end = .;
+
+    . = ALIGN((1 << 13));
+    .data :
+    {
+        *(.data)
+    }
+}
diff --git a/tests/tcg/mips/mips64/printf.c b/tests/tcg/mips/mips64/printf.c
new file mode 100644
index 0000000..cf8676d
--- /dev/null
+++ b/tests/tcg/mips/mips64/printf.c
@@ -0,0 +1,266 @@
+
+typedef unsigned long va_list;
+
+#define ACC    4
+#define __read(source)                    \
+({ va_list __res;                    \
+    __asm__ __volatile__(                \
+        "move\t%0, " #source "\n\t"        \
+        : "=r" (__res));            \
+    __res;                        \
+})
+
+enum format_type {
+    FORMAT_TYPE_NONE,
+    FORMAT_TYPE_HEX,
+    FORMAT_TYPE_ULONG,
+    FORMAT_TYPE_FLOAT
+};
+
+struct printf_spec {
+    char    type;
+};
+
+static int format_decode(char *fmt, struct printf_spec *spec)
+{
+    char *start = fmt;
+
+    for (; *fmt ; ++fmt) {
+        if (*fmt == '%') {
+            break;
+        }
+    }
+
+    switch (*++fmt) {
+    case 'x':
+        spec->type = FORMAT_TYPE_HEX;
+        break;
+
+    case 'd':
+        spec->type = FORMAT_TYPE_ULONG;
+        break;
+
+    case 'f':
+        spec->type = FORMAT_TYPE_FLOAT;
+        break;
+
+    default:
+        spec->type = FORMAT_TYPE_NONE;
+    }
+
+    return ++fmt - start;
+}
+
+void *memcpy(void *dest, void *src, int n)
+{
+    int i;
+    char *s = src;
+    char *d = dest;
+
+    for (i = 0; i < n; i++) {
+        d[i] = s[i];
+    }
+    return dest;
+}
+
+char *number(char *buf, va_list num)
+{
+    int i;
+    char *str = buf;
+    static char digits[16] = "0123456789abcdef";
+    str = str + sizeof(num) * 2;
+
+    for (i = 0; i < sizeof(num) * 2; i++) {
+        *--str = digits[num & 15];
+        num >>= 4;
+    }
+
+    return buf + sizeof(num) * 2;
+}
+
+char *__number(char *buf, va_list num)
+{
+    int i;
+    va_list mm = num;
+    char *str = buf;
+
+    if (!num) {
+        *str++ = '0';
+        return str;
+    }
+
+    for (i = 0; mm; mm = mm/10, i++) {
+        /* Do nothing. */
+    }
+
+    str = str + i;
+
+    while (num) {
+        *--str = num % 10 + 48;
+        num = num / 10;
+    }
+
+    return str + i;
+}
+
+va_list modf(va_list args, va_list *integer, va_list *num)
+{
+    int i;
+    double dot_v = 0;
+    va_list E, DOT, DOT_V;
+
+    if (!args) {
+        return 0;
+    }
+
+    for (i = 0, args = args << 1 >> 1; i < 52; i++) {
+        if ((args >> i) & 0x1) {
+            break;
+        }
+    }
+
+    *integer = 0;
+
+    if ((args >> 56 != 0x3f) || (args >> 52 == 0x3ff)) {
+        E = (args >> 52) - 1023;
+        DOT = 52 - E - i;
+        DOT_V = args << (12 + E) >> (12 + E) >> i;
+        *integer = ((args << 12 >> 12) >> (i + DOT)) | (1 << E);
+    } else {
+        E = ~((args >> 52) - 1023) + 1;
+        DOT_V = args << 12 >> 12;
+
+        dot_v += 1.0 / (1 << E);
+
+        for (i = 1; i <= 16; i++) {
+            if ((DOT_V >> (52 - i)) & 0x1) {
+                dot_v += 1.0 / (1 << E + i);
+            }
+        }
+
+        for (i = 1, E = 0; i <= ACC; i++) {
+            dot_v *= 10;
+            if (!(va_list)dot_v) {
+                E++;
+            }
+    }
+
+    *num = E;
+
+    return dot_v;
+    }
+
+    if (args & 0xf) {
+        for (i = 1; i <= 16; i++) {
+            if ((DOT_V >> (DOT - i)) & 0x1) {
+                dot_v += 1.0 / (1 << i);
+            }
+        }
+
+        for (i = 1, E = 0; i <= ACC; i++) {
+            dot_v *= 10;
+            if (!(va_list)dot_v) {
+                E++;
+            }
+        }
+
+        *num = E;
+
+        return dot_v;
+    } else if (DOT) {
+        for (i = 1; i <= DOT; i++) {
+            if ((DOT_V >> (DOT - i)) & 0x1) {
+                dot_v += 1.0 / (1 << i);
+            }
+        }
+
+        for (i = 1; i <= ACC; i++) {
+            dot_v = dot_v * 10;
+        }
+
+    return dot_v;
+    }
+
+    return 0;
+}
+
+int vsnprintf(char *buf, int size, char *fmt, va_list args)
+{
+    char *str, *mm;
+    struct printf_spec spec = {0};
+
+    str = mm = buf;
+
+    while (*fmt) {
+        char *old_fmt = fmt;
+        int read = format_decode(fmt, &spec);
+
+        fmt += read;
+
+        switch (spec.type) {
+        case FORMAT_TYPE_NONE: {
+            memcpy(str, old_fmt, read);
+            str += read;
+            break;
+        }
+        case FORMAT_TYPE_HEX: {
+            memcpy(str, old_fmt, read);
+            str = number(str + read, args);
+            for (; *mm ; ++mm) {
+                if (*mm == '%') {
+                    *mm = '0';
+                break;
+                }
+            }
+        break;
+        }
+        case FORMAT_TYPE_ULONG: {
+            memcpy(str, old_fmt, read - 2);
+            str = __number(str + read - 2, args);
+            break;
+        }
+        case FORMAT_TYPE_FLOAT: {
+            va_list integer, dot_v, num;
+            dot_v = modf(args, &integer, &num);
+            memcpy(str, old_fmt, read - 2);
+            str += read - 2;
+            if ((args >> 63 & 0x1)) {
+                *str++ = '-';
+            }
+            str = __number(str, integer);
+            if (dot_v) {
+                *str++ = '.';
+                while (num--) {
+                    *str++ = '0';
+                }
+                str = __number(str, dot_v);
+            }
+            break;
+        }
+        }
+    }
+    *str = '\0';
+
+    return str - buf;
+}
+
+static void serial_out(char *str)
+{
+    while (*str) {
+        *(char *)0xffffffffb80003f8 = *str++;
+    }
+}
+
+int vprintf(char *fmt, va_list args)
+{
+    int printed_len = 0;
+    static char printf_buf[512];
+    printed_len = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
+    serial_out(printf_buf);
+    return printed_len;
+}
+
+int printf(char *fmt, ...)
+{
+    return vprintf(fmt, __read($5));
+}
diff --git a/tests/tcg/mips/mips64/synci.c b/tests/tcg/mips/mips64/synci.c
new file mode 100644
index 0000000..a737f0d
--- /dev/null
+++ b/tests/tcg/mips/mips64/synci.c
@@ -0,0 +1,32 @@
+#include "io.h"
+
+int main()
+{
+    unsigned long addr, tmp, result = 0;
+    unsigned int addi = 0x21ef0001; /* addi $15, $15, 1 */
+
+    __asm
+        ("move %1, $15\n\t"
+         "move $15, $0\n\t"
+         "dla %0, 1f\n\t"
+         "sw %3, 0(%0)\n\t"
+         "synci 0(%0)\n\t"
+         "nop\n\t"
+         "1:\n\t"
+         "nop\n\t"
+         "move %2, $15\n\t"
+         "move $15, %1\n\t"
+         : "+r"(addr), "+r"(tmp), "=r"(result)
+         : "r"(addi)
+         );
+
+    if (result == 0) {
+        printf("test failed, the copied instruction not run.\n");
+    } else if (result == 1) {
+        printf("test passed\n");
+    } else {
+        printf("unhandled\n");
+    }
+
+    return 0;
+}
-- 
1.8.1.2



reply via email to

[Prev in Thread] Current Thread [Next in Thread]