qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/5] lm32 fixes and additions
@ 2012-03-31 18:40 Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target Michael Walle
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Anthony Liguori

Hi Anthony or Blue,

Please pull the following lm32 fixes and additions.

The following changes since commit b7c8e15a146a7b20021b524f41d6b8072ee093b5:

  Merge branch 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm (2012-03-31 12:10:07 +0000)

are available in the git repository at:

  git://github.com/mwalle/qemu.git for-upstream

Michael Walle (5):
      tests: fix out-of-tree building for lm32 target
      target-lm32: init tcg only if available
      milkymist-sysctl: support for new core version
      target-lm32: add simple disassembler
      milkymist-vgafb: add missing register

 Makefile.objs           |    1 +
 configure               |    8 +-
 dis-asm.h               |    3 +
 disas.c                 |    6 +
 hw/milkymist-sysctl.c   |   26 +++--
 hw/milkymist-vgafb.c    |    5 +-
 lm32-dis.c              |  351 +++++++++++++++++++++++++++++++++++++++++++++++
 target-lm32/helper.c    |    2 +-
 tests/tcg/lm32/Makefile |   13 +-
 9 files changed, 398 insertions(+), 17 deletions(-)
 create mode 100644 lm32-dis.c

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target
  2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
@ 2012-03-31 18:40 ` Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 2/5] target-lm32: init tcg only if available Michael Walle
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

Signed-off-by: Michael Walle <michael@walle.cc>
---
 configure               |    4 +++-
 tests/tcg/lm32/Makefile |   13 ++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index b51a749..4ef5ec6 100755
--- a/configure
+++ b/configure
@@ -3876,7 +3876,8 @@ echo "QEMU_INCLUDES+=$includes" >> $config_target_mak
 done # for target in $targets
 
 # build tree in object directory in case the source is not in the current directory
-DIRS="tests tests/tcg tests/tcg/cris slirp audio block net pc-bios/optionrom"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32"
+DIRS="$DIRS slirp audio block net pc-bios/optionrom"
 DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui usb"
@@ -3884,6 +3885,7 @@ DIRS="$DIRS qapi qapi-generated"
 DIRS="$DIRS qga trace qom"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
+FILES="$FILES tests/tcg/lm32/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile
index 03a1abb..9a00ef7 100644
--- a/tests/tcg/lm32/Makefile
+++ b/tests/tcg/lm32/Makefile
@@ -1,4 +1,4 @@
--include ../../config-host.mak
+-include ../../../config-host.mak
 
 CROSS=lm32-elf-
 
@@ -12,7 +12,10 @@ SIZE    = $(CROSS)size
 LD      = $(CC)
 OBJCOPY = $(CROSS)objcopy
 
-LDFLAGS = -Tlinker.ld
+TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32
+
+LDFLAGS = -T$(TSRC_PATH)/linker.ld
+ASFLAGS += -Wa,-I,$(TSRC_PATH)/
 
 CRT        = crt.o
 TESTCASES += test_add.tst
@@ -82,13 +85,13 @@ TESTCASES += test_xori.tst
 
 all: build
 
-%.o: $(SRC_PATH)/tests/lm32/%.c
+%.o: $(TSRC_PATH)/%.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
-%.o: $(SRC_PATH)/tests/lm32/%.S
+%.o: $(TSRC_PATH)/%.S
 	$(AS) $(ASFLAGS) -c $< -o $@
 
-%.tst: %.o macros.inc $(CRT)
+%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT)
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
 
 build: $(CRT) $(TESTCASES)
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 2/5] target-lm32: init tcg only if available
  2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target Michael Walle
@ 2012-03-31 18:40 ` Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 3/5] milkymist-sysctl: support for new core version Michael Walle
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

Once qtest support for target-lm32 arrives, tcg may be disabled.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 target-lm32/helper.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 5db8f8d..78076e4 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -215,7 +215,7 @@ CPULM32State *cpu_lm32_init(const char *cpu_model)
     cpu_state_reset(env);
     qemu_init_vcpu(env);
 
-    if (!tcg_initialized) {
+    if (tcg_enabled() && !tcg_initialized) {
         tcg_initialized = 1;
         lm32_translate_init();
     }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 3/5] milkymist-sysctl: support for new core version
  2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 2/5] target-lm32: init tcg only if available Michael Walle
@ 2012-03-31 18:40 ` Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler Michael Walle
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 5/5] milkymist-vgafb: add missing register Michael Walle
  4 siblings, 0 replies; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

The new version introduces the following new registers:
 - SoC clock frequency: read-only of system clock used on the SoC
 - debug scratchpad: 8 bit scratchpad register
 - debug write lock: write once register, without any function on QEMU

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/milkymist-sysctl.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index a88548e..8878d2b 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -1,7 +1,7 @@
 /*
  *  QEMU model of the Milkymist System Controller.
  *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -39,20 +39,19 @@ enum {
 };
 
 enum {
-    R_GPIO_IN = 0,
+    R_GPIO_IN         = 0,
     R_GPIO_OUT,
     R_GPIO_INTEN,
-    R_RESERVED0,
-    R_TIMER0_CONTROL,
+    R_TIMER0_CONTROL  = 4,
     R_TIMER0_COMPARE,
     R_TIMER0_COUNTER,
-    R_RESERVED1,
-    R_TIMER1_CONTROL,
+    R_TIMER1_CONTROL  = 8,
     R_TIMER1_COMPARE,
     R_TIMER1_COUNTER,
-    R_RESERVED2,
-    R_RESERVED3,
-    R_ICAP,
+    R_ICAP = 16,
+    R_DBG_SCRATCHPAD  = 20,
+    R_DBG_WRITE_LOCK,
+    R_CLK_FREQUENCY   = 29,
     R_CAPABILITIES,
     R_SYSTEM_ID,
     R_MAX
@@ -116,6 +115,9 @@ static uint64_t sysctl_read(void *opaque, target_phys_addr_t addr,
     case R_TIMER1_CONTROL:
     case R_TIMER1_COMPARE:
     case R_ICAP:
+    case R_DBG_SCRATCHPAD:
+    case R_DBG_WRITE_LOCK:
+    case R_CLK_FREQUENCY:
     case R_CAPABILITIES:
     case R_SYSTEM_ID:
         r = s->regs[addr];
@@ -145,6 +147,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_GPIO_INTEN:
     case R_TIMER0_COUNTER:
     case R_TIMER1_COUNTER:
+    case R_DBG_SCRATCHPAD:
         s->regs[addr] = value;
         break;
     case R_TIMER0_COMPARE:
@@ -182,11 +185,15 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_ICAP:
         sysctl_icap_write(s, value);
         break;
+    case R_DBG_WRITE_LOCK:
+        s->regs[addr] = 1;
+        break;
     case R_SYSTEM_ID:
         qemu_system_reset_request();
         break;
 
     case R_GPIO_IN:
+    case R_CLK_FREQUENCY:
     case R_CAPABILITIES:
         error_report("milkymist_sysctl: write to read-only register 0x"
                 TARGET_FMT_plx, addr << 2);
@@ -253,6 +260,7 @@ static void milkymist_sysctl_reset(DeviceState *d)
     /* defaults */
     s->regs[R_ICAP] = ICAP_READY;
     s->regs[R_SYSTEM_ID] = s->systemid;
+    s->regs[R_CLK_FREQUENCY] = s->freq_hz;
     s->regs[R_CAPABILITIES] = s->capabilities;
     s->regs[R_GPIO_IN] = s->strappings;
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler
  2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
                   ` (2 preceding siblings ...)
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 3/5] milkymist-sysctl: support for new core version Michael Walle
@ 2012-03-31 18:40 ` Michael Walle
  2012-04-01 17:17   ` Blue Swirl
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 5/5] milkymist-vgafb: add missing register Michael Walle
  4 siblings, 1 reply; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

Because binutils disassembler is based on libopcode, this is a rewrite from
scratch.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 Makefile.objs |    1 +
 configure     |    4 +
 dis-asm.h     |    3 +
 disas.c       |    6 +
 lm32-dis.c    |  351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 365 insertions(+), 0 deletions(-)
 create mode 100644 lm32-dis.c

diff --git a/Makefile.objs b/Makefile.objs
index e9842b0..f308b57 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -365,6 +365,7 @@ libdis-$(CONFIG_PPC_DIS) += ppc-dis.o
 libdis-$(CONFIG_S390_DIS) += s390-dis.o
 libdis-$(CONFIG_SH4_DIS) += sh4-dis.o
 libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
+libdis-$(CONFIG_LM32_DIS) += lm32-dis.o
 
 ######################################################################
 # trace
diff --git a/configure b/configure
index 4ef5ec6..4b3adc9 100755
--- a/configure
+++ b/configure
@@ -3770,6 +3770,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
     echo "CONFIG_IA64_DIS=y"  >> $config_target_mak
     echo "CONFIG_IA64_DIS=y"  >> $libdis_config_mak
   ;;
+  lm32)
+    echo "CONFIG_LM32_DIS=y"  >> $config_target_mak
+    echo "CONFIG_LM32_DIS=y"  >> $libdis_config_mak
+  ;;
   m68k)
     echo "CONFIG_M68K_DIS=y"  >> $config_target_mak
     echo "CONFIG_M68K_DIS=y"  >> $libdis_config_mak
diff --git a/dis-asm.h b/dis-asm.h
index 4f15fad..3944b3c 100644
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -221,6 +221,8 @@ enum bfd_architecture
   bfd_arch_ia64,      /* HP/Intel ia64 */
 #define bfd_mach_ia64_elf64    64
 #define bfd_mach_ia64_elf32    32
+  bfd_arch_lm32,       /* Lattice Mico32 */
+#define bfd_mach_lm32 1
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -404,6 +406,7 @@ int print_insn_crisv32          (bfd_vma, disassemble_info*);
 int print_insn_crisv10          (bfd_vma, disassemble_info*);
 int print_insn_microblaze       (bfd_vma, disassemble_info*);
 int print_insn_ia64             (bfd_vma, disassemble_info*);
+int print_insn_lm32             (bfd_vma, disassemble_info*);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/disas.c b/disas.c
index 4945c44..9485824 100644
--- a/disas.c
+++ b/disas.c
@@ -220,6 +220,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
 #elif defined(TARGET_MICROBLAZE)
     disasm_info.mach = bfd_arch_microblaze;
     print_insn = print_insn_microblaze;
+#elif defined(TARGET_LM32)
+    disasm_info.mach = bfd_mach_lm32;
+    print_insn = print_insn_lm32;
 #else
     fprintf(out, "0x" TARGET_FMT_lx
 	    ": Asm output not supported on this arch\n", code);
@@ -421,6 +424,9 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
 #elif defined(TARGET_S390X)
     disasm_info.mach = bfd_mach_s390_64;
     print_insn = print_insn_s390;
+#elif defined(TARGET_LM32)
+    disasm_info.mach = bfd_mach_lm32;
+    print_insn = print_insn_lm32;
 #else
     monitor_printf(mon, "0x" TARGET_FMT_lx
                    ": Asm output not supported on this arch\n", pc);
diff --git a/lm32-dis.c b/lm32-dis.c
new file mode 100644
index 0000000..84a264a
--- /dev/null
+++ b/lm32-dis.c
@@ -0,0 +1,351 @@
+/*
+ *  Simple LatticeMico32 disassembler.
+ *
+ *  Copyright (c) 2012 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include "dis-asm.h"
+
+typedef enum {
+    OP_SRUI = 0, OP_NORI, OP_MULI, OP_SH, OP_LB, OP_SRI, OP_XORI, OP_LH,
+    OP_ANDI, OP_XNORI, OP_LW, OP_LHU, OP_SB, OP_ADDI, OP_ORI, OP_SLI, OP_LBU,
+    OP_BE, OP_BG, OP_BGE, OP_BGEU, OP_BGU, OP_SW, OP_BNE, OP_ANDHI, OP_CMPEI,
+    OP_CMPGI, OP_CMPGEI, OP_CMPGEUI, OP_CMPGUI, OP_ORHI, OP_CMPNEI, OP_SRU,
+    OP_NOR, OP_MUL, OP_DIVU, OP_RCSR, OP_SR, OP_XOR, OP_ILL0, OP_AND, OP_XNOR,
+    OP_ILL1, OP_SCALL, OP_SEXTB, OP_ADD, OP_OR, OP_SL, OP_B, OP_MODU, OP_SUB,
+    OP_ILL2, OP_WCSR, OP_ILL3, OP_CALL, OP_SEXTH, OP_BI, OP_CMPE, OP_CMPG,
+    OP_CMPGE, OP_CMPGEU, OP_CMPGU, OP_CALLI, OP_CMPNE,
+} Lm32Opcode;
+
+typedef enum {
+    FMT_INVALID = 0, FMT_RRI5, FMT_RRI16, FMT_IMM26, FMT_LOAD, FMT_STORE,
+    FMT_RRR, FMT_R, FMT_RNR, FMT_CRN, FMT_CNR, FMT_BREAK,
+} Lm32OpcodeFmt;
+
+typedef enum {
+    CSR_IE = 0, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
+    CSR_DC, CSR_DEBA, CSR_CFG2, CSR_JTX = 0xe, CSR_JRX, CSR_BP0, CSR_BP1,
+    CSR_BP2, CSR_BP3, CSR_WP0 = 0x18, CSR_WP1, CSR_WP2, CSR_WP3,
+} Lm32CsrNum;
+
+typedef struct {
+    int csr;
+    const char *name;
+} Lm32CsrInfo;
+
+static const Lm32CsrInfo lm32_csr_info[] = {
+    {CSR_IE,   "ie", },
+    {CSR_IM,   "im", },
+    {CSR_IP,   "ip", },
+    {CSR_ICC,  "icc", },
+    {CSR_DCC,  "dcc", },
+    {CSR_CC,   "cc", },
+    {CSR_CFG,  "cfg", },
+    {CSR_EBA,  "eba", },
+    {CSR_DC,   "dc", },
+    {CSR_DEBA, "deba", },
+    {CSR_CFG2, "cfg2", },
+    {CSR_JTX,  "jtx", },
+    {CSR_JRX,  "jrx", },
+    {CSR_BP0,  "bp0", },
+    {CSR_BP1,  "bp1", },
+    {CSR_BP2,  "bp2", },
+    {CSR_BP3,  "bp3", },
+    {CSR_WP0,  "wp0", },
+    {CSR_WP1,  "wp1", },
+    {CSR_WP2,  "wp2", },
+    {CSR_WP3,  "wp3", },
+};
+
+static const Lm32CsrInfo *find_csr_info(int csr)
+{
+    const Lm32CsrInfo *info;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(lm32_csr_info); i++) {
+        info = &lm32_csr_info[i];
+        if (csr == info->csr) {
+            return info;
+        }
+    }
+
+    return NULL;
+}
+
+typedef struct {
+    int reg;
+    const char *name;
+} Lm32RegInfo;
+
+typedef enum {
+    REG_R0 = 0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8,
+    REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_R16,
+    REG_R17, REG_R18, REG_R19, REG_R20, REG_R21, REG_R22, REG_R23, REG_R24,
+    REG_R25, REG_GP, REG_FP, REG_SP, REG_RA, REG_EA, REG_BA,
+} Lm32RegNum;
+
+static const Lm32RegInfo lm32_reg_info[] = {
+    {REG_R0,  "r0", },
+    {REG_R1,  "r1", },
+    {REG_R2,  "r2", },
+    {REG_R3,  "r3", },
+    {REG_R4,  "r4", },
+    {REG_R5,  "r5", },
+    {REG_R6,  "r6", },
+    {REG_R7,  "r7", },
+    {REG_R8,  "r8", },
+    {REG_R9,  "r9", },
+    {REG_R10, "r10", },
+    {REG_R11, "r11", },
+    {REG_R12, "r12", },
+    {REG_R13, "r13", },
+    {REG_R14, "r14", },
+    {REG_R15, "r15", },
+    {REG_R16, "r16", },
+    {REG_R17, "r17", },
+    {REG_R18, "r18", },
+    {REG_R19, "r19", },
+    {REG_R20, "r20", },
+    {REG_R21, "r21", },
+    {REG_R22, "r22", },
+    {REG_R23, "r23", },
+    {REG_R24, "r24", },
+    {REG_R25, "r25", },
+    {REG_GP,  "gp", },
+    {REG_FP,  "fp", },
+    {REG_SP,  "sp", },
+    {REG_RA,  "ra", },
+    {REG_EA,  "ea", },
+    {REG_BA,  "ba", },
+};
+
+static const Lm32RegInfo *find_reg_info(int reg)
+{
+    assert(ARRAY_SIZE(lm32_reg_info) == 32);
+    return &lm32_reg_info[reg & 0x1f];
+}
+
+typedef struct {
+    struct {
+        uint32_t code;
+        uint32_t mask;
+    } op;
+    const char *name;
+    const char *args_fmt;
+} Lm32OpcodeInfo;
+
+static const Lm32OpcodeInfo lm32_opcode_info[] = {
+    /* pseudo instructions */
+    {{0x34000000, 0xffffffff}, "nop",   NULL},
+    {{0xac000002, 0xffffffff}, "break", NULL},
+    {{0xac000003, 0xffffffff}, "scall", NULL},
+    {{0xc3e00000, 0xffffffff}, "bret",  NULL},
+    {{0xc3c00000, 0xffffffff}, "eret",  NULL},
+    {{0xc3a00000, 0xffffffff}, "ret",   NULL},
+    {{0xa4000000, 0xfc1f07ff}, "not",   "%2, %0"},
+    {{0xb8000000, 0xfc1f07ff}, "mv",    "%2, %0"},
+    {{0x71e00000, 0xffe00000}, "mvhi",  "%1, %u"},
+    {{0x34000000, 0xffe00000}, "mvi",   "%1, %s"},
+
+#define _O(op) {op << 26, 0x3f << 26}
+    /* regular opcodes */
+    {_O(OP_ADD),     "add",     "%2, %0, %1"  },
+    {_O(OP_ADDI),    "addi",    "%1, %0, %s"  },
+    {_O(OP_AND),     "and",     "%2, %0, %1"  },
+    {_O(OP_ANDHI),   "andhi",   "%1, %0, %u"  },
+    {_O(OP_ANDI),    "andi",    "%1, %0, %u"  },
+    {_O(OP_B),       "b",       "%0",         },
+    {_O(OP_BE),      "be",      "%1, %0, %r"  },
+    {_O(OP_BG),      "bg",      "%1, %0, %r"  },
+    {_O(OP_BGE),     "bge",     "%1, %0, %r"  },
+    {_O(OP_BGEU),    "bgeu",    "%1, %0, %r"  },
+    {_O(OP_BGU),     "bgu",     "%1, %0, %r"  },
+    {_O(OP_BI),      "bi",      "%R",         },
+    {_O(OP_BNE),     "bne",     "%1, %0, %r"  },
+    {_O(OP_CALL),    "call",    "%0",         },
+    {_O(OP_CALLI),   "calli",   "%R",         },
+    {_O(OP_CMPE),    "cmpe",    "%2, %0, %1"  },
+    {_O(OP_CMPEI),   "cmpei",   "%1, %0, %s"  },
+    {_O(OP_CMPG),    "cmpg",    "%2, %0, %1"  },
+    {_O(OP_CMPGE),   "cmpge",   "%2, %0, %1"  },
+    {_O(OP_CMPGEI),  "cmpgei",  "%1, %0, %s"  },
+    {_O(OP_CMPGEU),  "cmpgeu",  "%2, %0, %1"  },
+    {_O(OP_CMPGEUI), "cmpgeui", "%1, %0, %s"  },
+    {_O(OP_CMPGI),   "cmpgi",   "%1, %0, %s"  },
+    {_O(OP_CMPGU),   "cmpgu",   "%2, %0, %1"  },
+    {_O(OP_CMPGUI),  "cmpgui",  "%1, %0, %s"  },
+    {_O(OP_CMPNE),   "cmpne",   "%2, %0, %1"  },
+    {_O(OP_CMPNEI),  "cmpnei",  "%1, %0, %s"  },
+    {_O(OP_DIVU),    "divu",    "%2, %0, %1"  },
+    {_O(OP_LB),      "lb",      "%1, (%0+%s)" },
+    {_O(OP_LBU),     "lbu",     "%1, (%0+%s)" },
+    {_O(OP_LH),      "lh",      "%1, (%0+%s)" },
+    {_O(OP_LHU),     "lhu",     "%1, (%0+%s)" },
+    {_O(OP_LW),      "lw",      "%1, (%0+%s)" },
+    {_O(OP_MODU),    "modu",    "%2, %0, %1"  },
+    {_O(OP_MULI),    "muli",    "%1, %0, %s"  },
+    {_O(OP_MUL),     "mul",     "%2, %0, %1"  },
+    {_O(OP_NORI),    "nori",    "%1, %0, %u"  },
+    {_O(OP_NOR),     "nor",     "%2, %0, %1"  },
+    {_O(OP_ORHI),    "orhi",    "%1, %0, %u"  },
+    {_O(OP_ORI),     "ori",     "%1, %0, %u"  },
+    {_O(OP_OR),      "or",      "%2, %0, %1"  },
+    {_O(OP_RCSR),    "rcsr",    "%2, %c",     },
+    {_O(OP_SB),      "sb",      "(%0+%s), %1" },
+    {_O(OP_SEXTB),   "sextb",   "%2, %0",     },
+    {_O(OP_SEXTH),   "sexth",   "%2, %0",     },
+    {_O(OP_SH),      "sh",      "(%0+%s), %1" },
+    {_O(OP_SLI),     "sli",     "%1, %0, %h"  },
+    {_O(OP_SL),      "sl",      "%2, %0, %1"  },
+    {_O(OP_SRI),     "sri",     "%1, %0, %h"  },
+    {_O(OP_SR),      "sr",      "%2, %0, %1"  },
+    {_O(OP_SRUI),    "srui",    "%1, %0, %d"  },
+    {_O(OP_SRU),     "sru",     "%2, %0, %s"  },
+    {_O(OP_SUB),     "sub",     "%2, %0, %s"  },
+    {_O(OP_SW),      "sw",      "(%0+%s), %1" },
+    {_O(OP_WCSR),    "wcsr",    "%c, %1",     },
+    {_O(OP_XNORI),   "xnori",   "%1, %0, %u"  },
+    {_O(OP_XNOR),    "xnor",    "%2, %0, %1"  },
+    {_O(OP_XORI),    "xori",    "%1, %0, %u"  },
+    {_O(OP_XOR),     "xor",     "%2, %0, %1"  },
+#undef _O
+};
+
+static const Lm32OpcodeInfo *find_opcode_info(uint32_t opcode)
+{
+    const Lm32OpcodeInfo *info;
+    int i;
+    for (i = 0; i < ARRAY_SIZE(lm32_opcode_info); i++) {
+        info = &lm32_opcode_info[i];
+        if ((opcode & info->op.mask) == info->op.code) {
+            return info;
+        }
+    }
+
+    return NULL;
+}
+
+int print_insn_lm32(bfd_vma memaddr, struct disassemble_info *info)
+{
+    fprintf_function fprintf_fn = info->fprintf_func;
+    void *stream = info->stream;
+    int rc;
+    uint8_t insn[4];
+    const Lm32OpcodeInfo *opc_info;
+    uint32_t op;
+    const char *args_fmt;
+
+    rc = info->read_memory_func(memaddr, insn, 4, info);
+    if (rc != 0) {
+        info->memory_error_func(rc, memaddr, info);
+        return -1;
+    }
+
+    fprintf_fn(stream, "%02x %02x %02x %02x    ",
+            insn[0], insn[1], insn[2], insn[3]);
+
+    op = bfd_getb32(insn);
+    opc_info = find_opcode_info(op);
+    if (opc_info) {
+        fprintf_fn(stream, "%-8s ", opc_info->name);
+        args_fmt = opc_info->args_fmt;
+        while (args_fmt && *args_fmt) {
+            if (*args_fmt == '%') {
+                switch (*(++args_fmt)) {
+                case '0': {
+                    uint8_t r0;
+                    const char *r0_name;
+                    r0 = (op >> 21) & 0x1f;
+                    r0_name = find_reg_info(r0)->name;
+                    fprintf_fn(stream, "%s", r0_name);
+                    break;
+                }
+                case '1': {
+                    uint8_t r1;
+                    const char *r1_name;
+                    r1 = (op >> 16) & 0x1f;
+                    r1_name = find_reg_info(r1)->name;
+                    fprintf_fn(stream, "%s", r1_name);
+                    break;
+                }
+                case '2': {
+                    uint8_t r2;
+                    const char *r2_name;
+                    r2 = (op >> 11) & 0x1f;
+                    r2_name = find_reg_info(r2)->name;
+                    fprintf_fn(stream, "%s", r2_name);
+                    break;
+                }
+                case 'c': {
+                    uint8_t csr;
+                    const char *csr_name;
+                    csr = (op >> 21) & 0x1f;
+                    csr_name = find_csr_info(csr)->name;
+                    if (csr_name) {
+                        fprintf_fn(stream, "%s", csr_name);
+                    } else {
+                        fprintf_fn(stream, "0x%x", csr);
+                    }
+                    break;
+                }
+                case 'u': {
+                    uint16_t u16;
+                    u16 = op & 0xffff;
+                    fprintf_fn(stream, "0x%x", u16);
+                    break;
+                }
+                case 's': {
+                    int16_t s16;
+                    s16 = (int16_t)(op & 0xffff);
+                    fprintf_fn(stream, "%d", s16);
+                    break;
+                }
+                case 'r': {
+                    uint32_t rela;
+                    rela = memaddr + (((int16_t)(op & 0xffff)) << 2);
+                    fprintf_fn(stream, "%x", rela);
+                    break;
+                }
+                case 'R': {
+                    uint32_t rela;
+                    int32_t imm26;
+                    imm26 = (int32_t)((op & 0x3ffffff) << 6) >> 4;
+                    rela = memaddr + imm26;
+                    fprintf_fn(stream, "%x", rela);
+                    break;
+                }
+                case 'h': {
+                    uint8_t u5;
+                    u5 = (op & 0x1f);
+                    fprintf_fn(stream, "%d", u5);
+                    break;
+                }
+                default:
+                    break;
+                }
+            } else {
+                fprintf_fn(stream, "%c", *args_fmt);
+            }
+            args_fmt++;
+        }
+    } else {
+        fprintf_fn(stream, ".word 0x%x", op);
+    }
+
+    return 4;
+}
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 5/5] milkymist-vgafb: add missing register
  2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
                   ` (3 preceding siblings ...)
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler Michael Walle
@ 2012-03-31 18:40 ` Michael Walle
  4 siblings, 0 replies; 8+ messages in thread
From: Michael Walle @ 2012-03-31 18:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

This bug existed since the first commit. Fortunately, the affected
registers have no functionality in qemu. This will only prevent the
following warning:
  milkymist_vgafb: write access to unknown register 0x00000034

Signed-off-by: Michael Walle <michael@walle.cc>
---
 hw/milkymist-vgafb.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 69afd72..cd4365d 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -2,7 +2,7 @@
 /*
  *  QEMU model of the Milkymist VGA framebuffer.
  *
- *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
+ *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -54,6 +54,7 @@ enum {
     R_BASEADDRESS,
     R_BASEADDRESS_ACT,
     R_BURST_COUNT,
+    R_DDC,
     R_SOURCE_CLOCK,
     R_MAX
 };
@@ -173,6 +174,7 @@ static uint64_t vgafb_read(void *opaque, target_phys_addr_t addr,
     case R_VSCAN:
     case R_BASEADDRESS:
     case R_BURST_COUNT:
+    case R_DDC:
     case R_SOURCE_CLOCK:
         r = s->regs[addr];
     break;
@@ -211,6 +213,7 @@ static void vgafb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     case R_VSYNC_END:
     case R_VSCAN:
     case R_BURST_COUNT:
+    case R_DDC:
     case R_SOURCE_CLOCK:
         s->regs[addr] = value;
         break;
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler
  2012-03-31 18:40 ` [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler Michael Walle
@ 2012-04-01 17:17   ` Blue Swirl
  0 siblings, 0 replies; 8+ messages in thread
From: Blue Swirl @ 2012-04-01 17:17 UTC (permalink / raw)
  To: Michael Walle; +Cc: qemu-devel, Anthony Liguori

On Sat, Mar 31, 2012 at 18:40, Michael Walle <michael@walle.cc> wrote:
> Because binutils disassembler is based on libopcode, this is a rewrite from
> scratch.
>
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  Makefile.objs |    1 +
>  configure     |    4 +
>  dis-asm.h     |    3 +
>  disas.c       |    6 +
>  lm32-dis.c    |  351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 365 insertions(+), 0 deletions(-)
>  create mode 100644 lm32-dis.c
>
> diff --git a/Makefile.objs b/Makefile.objs
> index e9842b0..f308b57 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -365,6 +365,7 @@ libdis-$(CONFIG_PPC_DIS) += ppc-dis.o
>  libdis-$(CONFIG_S390_DIS) += s390-dis.o
>  libdis-$(CONFIG_SH4_DIS) += sh4-dis.o
>  libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
> +libdis-$(CONFIG_LM32_DIS) += lm32-dis.o
>
>  ######################################################################
>  # trace
> diff --git a/configure b/configure
> index 4ef5ec6..4b3adc9 100755
> --- a/configure
> +++ b/configure
> @@ -3770,6 +3770,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
>     echo "CONFIG_IA64_DIS=y"  >> $config_target_mak
>     echo "CONFIG_IA64_DIS=y"  >> $libdis_config_mak
>   ;;
> +  lm32)
> +    echo "CONFIG_LM32_DIS=y"  >> $config_target_mak
> +    echo "CONFIG_LM32_DIS=y"  >> $libdis_config_mak
> +  ;;
>   m68k)
>     echo "CONFIG_M68K_DIS=y"  >> $config_target_mak
>     echo "CONFIG_M68K_DIS=y"  >> $libdis_config_mak
> diff --git a/dis-asm.h b/dis-asm.h
> index 4f15fad..3944b3c 100644
> --- a/dis-asm.h
> +++ b/dis-asm.h
> @@ -221,6 +221,8 @@ enum bfd_architecture
>   bfd_arch_ia64,      /* HP/Intel ia64 */
>  #define bfd_mach_ia64_elf64    64
>  #define bfd_mach_ia64_elf32    32
> +  bfd_arch_lm32,       /* Lattice Mico32 */
> +#define bfd_mach_lm32 1
>   bfd_arch_last
>   };
>  #define bfd_mach_s390_31 31
> @@ -404,6 +406,7 @@ int print_insn_crisv32          (bfd_vma, disassemble_info*);
>  int print_insn_crisv10          (bfd_vma, disassemble_info*);
>  int print_insn_microblaze       (bfd_vma, disassemble_info*);
>  int print_insn_ia64             (bfd_vma, disassemble_info*);
> +int print_insn_lm32             (bfd_vma, disassemble_info*);
>
>  #if 0
>  /* Fetch the disassembler for a given BFD, if that support is available.  */
> diff --git a/disas.c b/disas.c
> index 4945c44..9485824 100644
> --- a/disas.c
> +++ b/disas.c
> @@ -220,6 +220,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
>  #elif defined(TARGET_MICROBLAZE)
>     disasm_info.mach = bfd_arch_microblaze;
>     print_insn = print_insn_microblaze;
> +#elif defined(TARGET_LM32)
> +    disasm_info.mach = bfd_mach_lm32;
> +    print_insn = print_insn_lm32;
>  #else
>     fprintf(out, "0x" TARGET_FMT_lx
>            ": Asm output not supported on this arch\n", code);
> @@ -421,6 +424,9 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
>  #elif defined(TARGET_S390X)
>     disasm_info.mach = bfd_mach_s390_64;
>     print_insn = print_insn_s390;
> +#elif defined(TARGET_LM32)
> +    disasm_info.mach = bfd_mach_lm32;
> +    print_insn = print_insn_lm32;
>  #else
>     monitor_printf(mon, "0x" TARGET_FMT_lx
>                    ": Asm output not supported on this arch\n", pc);
> diff --git a/lm32-dis.c b/lm32-dis.c
> new file mode 100644
> index 0000000..84a264a
> --- /dev/null
> +++ b/lm32-dis.c
> @@ -0,0 +1,351 @@
> +/*
> + *  Simple LatticeMico32 disassembler.
> + *
> + *  Copyright (c) 2012 Michael Walle <michael@walle.cc>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include <stdio.h>
> +#include "dis-asm.h"
> +
> +typedef enum {
> +    OP_SRUI = 0, OP_NORI, OP_MULI, OP_SH, OP_LB, OP_SRI, OP_XORI, OP_LH,
> +    OP_ANDI, OP_XNORI, OP_LW, OP_LHU, OP_SB, OP_ADDI, OP_ORI, OP_SLI, OP_LBU,
> +    OP_BE, OP_BG, OP_BGE, OP_BGEU, OP_BGU, OP_SW, OP_BNE, OP_ANDHI, OP_CMPEI,
> +    OP_CMPGI, OP_CMPGEI, OP_CMPGEUI, OP_CMPGUI, OP_ORHI, OP_CMPNEI, OP_SRU,
> +    OP_NOR, OP_MUL, OP_DIVU, OP_RCSR, OP_SR, OP_XOR, OP_ILL0, OP_AND, OP_XNOR,
> +    OP_ILL1, OP_SCALL, OP_SEXTB, OP_ADD, OP_OR, OP_SL, OP_B, OP_MODU, OP_SUB,
> +    OP_ILL2, OP_WCSR, OP_ILL3, OP_CALL, OP_SEXTH, OP_BI, OP_CMPE, OP_CMPG,
> +    OP_CMPGE, OP_CMPGEU, OP_CMPGU, OP_CALLI, OP_CMPNE,
> +} Lm32Opcode;
> +
> +typedef enum {
> +    FMT_INVALID = 0, FMT_RRI5, FMT_RRI16, FMT_IMM26, FMT_LOAD, FMT_STORE,
> +    FMT_RRR, FMT_R, FMT_RNR, FMT_CRN, FMT_CNR, FMT_BREAK,
> +} Lm32OpcodeFmt;
> +
> +typedef enum {
> +    CSR_IE = 0, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
> +    CSR_DC, CSR_DEBA, CSR_CFG2, CSR_JTX = 0xe, CSR_JRX, CSR_BP0, CSR_BP1,
> +    CSR_BP2, CSR_BP3, CSR_WP0 = 0x18, CSR_WP1, CSR_WP2, CSR_WP3,
> +} Lm32CsrNum;
> +
> +typedef struct {
> +    int csr;
> +    const char *name;
> +} Lm32CsrInfo;
> +
> +static const Lm32CsrInfo lm32_csr_info[] = {
> +    {CSR_IE,   "ie", },
> +    {CSR_IM,   "im", },
> +    {CSR_IP,   "ip", },
> +    {CSR_ICC,  "icc", },
> +    {CSR_DCC,  "dcc", },
> +    {CSR_CC,   "cc", },
> +    {CSR_CFG,  "cfg", },
> +    {CSR_EBA,  "eba", },
> +    {CSR_DC,   "dc", },
> +    {CSR_DEBA, "deba", },
> +    {CSR_CFG2, "cfg2", },
> +    {CSR_JTX,  "jtx", },
> +    {CSR_JRX,  "jrx", },
> +    {CSR_BP0,  "bp0", },
> +    {CSR_BP1,  "bp1", },
> +    {CSR_BP2,  "bp2", },
> +    {CSR_BP3,  "bp3", },
> +    {CSR_WP0,  "wp0", },
> +    {CSR_WP1,  "wp1", },
> +    {CSR_WP2,  "wp2", },
> +    {CSR_WP3,  "wp3", },
> +};
> +
> +static const Lm32CsrInfo *find_csr_info(int csr)
> +{
> +    const Lm32CsrInfo *info;
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(lm32_csr_info); i++) {
> +        info = &lm32_csr_info[i];
> +        if (csr == info->csr) {
> +            return info;
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
> +typedef struct {
> +    int reg;
> +    const char *name;
> +} Lm32RegInfo;
> +
> +typedef enum {
> +    REG_R0 = 0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8,
> +    REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_R16,
> +    REG_R17, REG_R18, REG_R19, REG_R20, REG_R21, REG_R22, REG_R23, REG_R24,
> +    REG_R25, REG_GP, REG_FP, REG_SP, REG_RA, REG_EA, REG_BA,
> +} Lm32RegNum;
> +
> +static const Lm32RegInfo lm32_reg_info[] = {
> +    {REG_R0,  "r0", },
> +    {REG_R1,  "r1", },
> +    {REG_R2,  "r2", },
> +    {REG_R3,  "r3", },
> +    {REG_R4,  "r4", },
> +    {REG_R5,  "r5", },
> +    {REG_R6,  "r6", },
> +    {REG_R7,  "r7", },
> +    {REG_R8,  "r8", },
> +    {REG_R9,  "r9", },
> +    {REG_R10, "r10", },
> +    {REG_R11, "r11", },
> +    {REG_R12, "r12", },
> +    {REG_R13, "r13", },
> +    {REG_R14, "r14", },
> +    {REG_R15, "r15", },

Unfortunately these conflict with x86_64 system headers:
  CC    libdis/lm32-dis.o
/src/qemu/lm32-dis.c:96: error: redeclaration of enumerator 'REG_R8'
/usr/include/sys/ucontext.h:45: note: previous definition of 'REG_R8' was here
/src/qemu/lm32-dis.c:97: error: redeclaration of enumerator 'REG_R9'
/usr/include/sys/ucontext.h:47: note: previous definition of 'REG_R9' was here
etc.

> +    {REG_R16, "r16", },
> +    {REG_R17, "r17", },
> +    {REG_R18, "r18", },
> +    {REG_R19, "r19", },
> +    {REG_R20, "r20", },
> +    {REG_R21, "r21", },
> +    {REG_R22, "r22", },
> +    {REG_R23, "r23", },
> +    {REG_R24, "r24", },
> +    {REG_R25, "r25", },
> +    {REG_GP,  "gp", },
> +    {REG_FP,  "fp", },
> +    {REG_SP,  "sp", },
> +    {REG_RA,  "ra", },
> +    {REG_EA,  "ea", },
> +    {REG_BA,  "ba", },
> +};
> +
> +static const Lm32RegInfo *find_reg_info(int reg)
> +{
> +    assert(ARRAY_SIZE(lm32_reg_info) == 32);
> +    return &lm32_reg_info[reg & 0x1f];
> +}
> +
> +typedef struct {
> +    struct {
> +        uint32_t code;
> +        uint32_t mask;
> +    } op;
> +    const char *name;
> +    const char *args_fmt;
> +} Lm32OpcodeInfo;
> +
> +static const Lm32OpcodeInfo lm32_opcode_info[] = {
> +    /* pseudo instructions */
> +    {{0x34000000, 0xffffffff}, "nop",   NULL},
> +    {{0xac000002, 0xffffffff}, "break", NULL},
> +    {{0xac000003, 0xffffffff}, "scall", NULL},
> +    {{0xc3e00000, 0xffffffff}, "bret",  NULL},
> +    {{0xc3c00000, 0xffffffff}, "eret",  NULL},
> +    {{0xc3a00000, 0xffffffff}, "ret",   NULL},
> +    {{0xa4000000, 0xfc1f07ff}, "not",   "%2, %0"},
> +    {{0xb8000000, 0xfc1f07ff}, "mv",    "%2, %0"},
> +    {{0x71e00000, 0xffe00000}, "mvhi",  "%1, %u"},
> +    {{0x34000000, 0xffe00000}, "mvi",   "%1, %s"},
> +
> +#define _O(op) {op << 26, 0x3f << 26}
> +    /* regular opcodes */
> +    {_O(OP_ADD),     "add",     "%2, %0, %1"  },
> +    {_O(OP_ADDI),    "addi",    "%1, %0, %s"  },
> +    {_O(OP_AND),     "and",     "%2, %0, %1"  },
> +    {_O(OP_ANDHI),   "andhi",   "%1, %0, %u"  },
> +    {_O(OP_ANDI),    "andi",    "%1, %0, %u"  },
> +    {_O(OP_B),       "b",       "%0",         },
> +    {_O(OP_BE),      "be",      "%1, %0, %r"  },
> +    {_O(OP_BG),      "bg",      "%1, %0, %r"  },
> +    {_O(OP_BGE),     "bge",     "%1, %0, %r"  },
> +    {_O(OP_BGEU),    "bgeu",    "%1, %0, %r"  },
> +    {_O(OP_BGU),     "bgu",     "%1, %0, %r"  },
> +    {_O(OP_BI),      "bi",      "%R",         },
> +    {_O(OP_BNE),     "bne",     "%1, %0, %r"  },
> +    {_O(OP_CALL),    "call",    "%0",         },
> +    {_O(OP_CALLI),   "calli",   "%R",         },
> +    {_O(OP_CMPE),    "cmpe",    "%2, %0, %1"  },
> +    {_O(OP_CMPEI),   "cmpei",   "%1, %0, %s"  },
> +    {_O(OP_CMPG),    "cmpg",    "%2, %0, %1"  },
> +    {_O(OP_CMPGE),   "cmpge",   "%2, %0, %1"  },
> +    {_O(OP_CMPGEI),  "cmpgei",  "%1, %0, %s"  },
> +    {_O(OP_CMPGEU),  "cmpgeu",  "%2, %0, %1"  },
> +    {_O(OP_CMPGEUI), "cmpgeui", "%1, %0, %s"  },
> +    {_O(OP_CMPGI),   "cmpgi",   "%1, %0, %s"  },
> +    {_O(OP_CMPGU),   "cmpgu",   "%2, %0, %1"  },
> +    {_O(OP_CMPGUI),  "cmpgui",  "%1, %0, %s"  },
> +    {_O(OP_CMPNE),   "cmpne",   "%2, %0, %1"  },
> +    {_O(OP_CMPNEI),  "cmpnei",  "%1, %0, %s"  },
> +    {_O(OP_DIVU),    "divu",    "%2, %0, %1"  },
> +    {_O(OP_LB),      "lb",      "%1, (%0+%s)" },
> +    {_O(OP_LBU),     "lbu",     "%1, (%0+%s)" },
> +    {_O(OP_LH),      "lh",      "%1, (%0+%s)" },
> +    {_O(OP_LHU),     "lhu",     "%1, (%0+%s)" },
> +    {_O(OP_LW),      "lw",      "%1, (%0+%s)" },
> +    {_O(OP_MODU),    "modu",    "%2, %0, %1"  },
> +    {_O(OP_MULI),    "muli",    "%1, %0, %s"  },
> +    {_O(OP_MUL),     "mul",     "%2, %0, %1"  },
> +    {_O(OP_NORI),    "nori",    "%1, %0, %u"  },
> +    {_O(OP_NOR),     "nor",     "%2, %0, %1"  },
> +    {_O(OP_ORHI),    "orhi",    "%1, %0, %u"  },
> +    {_O(OP_ORI),     "ori",     "%1, %0, %u"  },
> +    {_O(OP_OR),      "or",      "%2, %0, %1"  },
> +    {_O(OP_RCSR),    "rcsr",    "%2, %c",     },
> +    {_O(OP_SB),      "sb",      "(%0+%s), %1" },
> +    {_O(OP_SEXTB),   "sextb",   "%2, %0",     },
> +    {_O(OP_SEXTH),   "sexth",   "%2, %0",     },
> +    {_O(OP_SH),      "sh",      "(%0+%s), %1" },
> +    {_O(OP_SLI),     "sli",     "%1, %0, %h"  },
> +    {_O(OP_SL),      "sl",      "%2, %0, %1"  },
> +    {_O(OP_SRI),     "sri",     "%1, %0, %h"  },
> +    {_O(OP_SR),      "sr",      "%2, %0, %1"  },
> +    {_O(OP_SRUI),    "srui",    "%1, %0, %d"  },
> +    {_O(OP_SRU),     "sru",     "%2, %0, %s"  },
> +    {_O(OP_SUB),     "sub",     "%2, %0, %s"  },
> +    {_O(OP_SW),      "sw",      "(%0+%s), %1" },
> +    {_O(OP_WCSR),    "wcsr",    "%c, %1",     },
> +    {_O(OP_XNORI),   "xnori",   "%1, %0, %u"  },
> +    {_O(OP_XNOR),    "xnor",    "%2, %0, %1"  },
> +    {_O(OP_XORI),    "xori",    "%1, %0, %u"  },
> +    {_O(OP_XOR),     "xor",     "%2, %0, %1"  },
> +#undef _O
> +};
> +
> +static const Lm32OpcodeInfo *find_opcode_info(uint32_t opcode)
> +{
> +    const Lm32OpcodeInfo *info;
> +    int i;
> +    for (i = 0; i < ARRAY_SIZE(lm32_opcode_info); i++) {
> +        info = &lm32_opcode_info[i];
> +        if ((opcode & info->op.mask) == info->op.code) {
> +            return info;
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
> +int print_insn_lm32(bfd_vma memaddr, struct disassemble_info *info)
> +{
> +    fprintf_function fprintf_fn = info->fprintf_func;
> +    void *stream = info->stream;
> +    int rc;
> +    uint8_t insn[4];
> +    const Lm32OpcodeInfo *opc_info;
> +    uint32_t op;
> +    const char *args_fmt;
> +
> +    rc = info->read_memory_func(memaddr, insn, 4, info);
> +    if (rc != 0) {
> +        info->memory_error_func(rc, memaddr, info);
> +        return -1;
> +    }
> +
> +    fprintf_fn(stream, "%02x %02x %02x %02x    ",
> +            insn[0], insn[1], insn[2], insn[3]);
> +
> +    op = bfd_getb32(insn);
> +    opc_info = find_opcode_info(op);
> +    if (opc_info) {
> +        fprintf_fn(stream, "%-8s ", opc_info->name);
> +        args_fmt = opc_info->args_fmt;
> +        while (args_fmt && *args_fmt) {
> +            if (*args_fmt == '%') {
> +                switch (*(++args_fmt)) {
> +                case '0': {
> +                    uint8_t r0;
> +                    const char *r0_name;
> +                    r0 = (op >> 21) & 0x1f;
> +                    r0_name = find_reg_info(r0)->name;
> +                    fprintf_fn(stream, "%s", r0_name);
> +                    break;
> +                }
> +                case '1': {
> +                    uint8_t r1;
> +                    const char *r1_name;
> +                    r1 = (op >> 16) & 0x1f;
> +                    r1_name = find_reg_info(r1)->name;
> +                    fprintf_fn(stream, "%s", r1_name);
> +                    break;
> +                }
> +                case '2': {
> +                    uint8_t r2;
> +                    const char *r2_name;
> +                    r2 = (op >> 11) & 0x1f;
> +                    r2_name = find_reg_info(r2)->name;
> +                    fprintf_fn(stream, "%s", r2_name);
> +                    break;
> +                }
> +                case 'c': {
> +                    uint8_t csr;
> +                    const char *csr_name;
> +                    csr = (op >> 21) & 0x1f;
> +                    csr_name = find_csr_info(csr)->name;
> +                    if (csr_name) {
> +                        fprintf_fn(stream, "%s", csr_name);
> +                    } else {
> +                        fprintf_fn(stream, "0x%x", csr);
> +                    }
> +                    break;
> +                }
> +                case 'u': {
> +                    uint16_t u16;
> +                    u16 = op & 0xffff;
> +                    fprintf_fn(stream, "0x%x", u16);
> +                    break;
> +                }
> +                case 's': {
> +                    int16_t s16;
> +                    s16 = (int16_t)(op & 0xffff);
> +                    fprintf_fn(stream, "%d", s16);
> +                    break;
> +                }
> +                case 'r': {
> +                    uint32_t rela;
> +                    rela = memaddr + (((int16_t)(op & 0xffff)) << 2);
> +                    fprintf_fn(stream, "%x", rela);
> +                    break;
> +                }
> +                case 'R': {
> +                    uint32_t rela;
> +                    int32_t imm26;
> +                    imm26 = (int32_t)((op & 0x3ffffff) << 6) >> 4;
> +                    rela = memaddr + imm26;
> +                    fprintf_fn(stream, "%x", rela);
> +                    break;
> +                }
> +                case 'h': {
> +                    uint8_t u5;
> +                    u5 = (op & 0x1f);
> +                    fprintf_fn(stream, "%d", u5);
> +                    break;
> +                }
> +                default:
> +                    break;
> +                }
> +            } else {
> +                fprintf_fn(stream, "%c", *args_fmt);
> +            }
> +            args_fmt++;
> +        }
> +    } else {
> +        fprintf_fn(stream, ".word 0x%x", op);
> +    }
> +
> +    return 4;
> +}
> --
> 1.7.2.5
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target
  2012-04-01 18:37 [Qemu-devel] [PULL v2 0/5] lm32 fixes and additions Michael Walle
@ 2012-04-01 18:37 ` Michael Walle
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Walle @ 2012-04-01 18:37 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Michael Walle, Anthony Liguori

Signed-off-by: Michael Walle <michael@walle.cc>
---
 configure               |    4 +++-
 tests/tcg/lm32/Makefile |   13 ++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index b51a749..4ef5ec6 100755
--- a/configure
+++ b/configure
@@ -3876,7 +3876,8 @@ echo "QEMU_INCLUDES+=$includes" >> $config_target_mak
 done # for target in $targets
 
 # build tree in object directory in case the source is not in the current directory
-DIRS="tests tests/tcg tests/tcg/cris slirp audio block net pc-bios/optionrom"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32"
+DIRS="$DIRS slirp audio block net pc-bios/optionrom"
 DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui usb"
@@ -3884,6 +3885,7 @@ DIRS="$DIRS qapi qapi-generated"
 DIRS="$DIRS qga trace qom"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
+FILES="$FILES tests/tcg/lm32/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile
index 03a1abb..9a00ef7 100644
--- a/tests/tcg/lm32/Makefile
+++ b/tests/tcg/lm32/Makefile
@@ -1,4 +1,4 @@
--include ../../config-host.mak
+-include ../../../config-host.mak
 
 CROSS=lm32-elf-
 
@@ -12,7 +12,10 @@ SIZE    = $(CROSS)size
 LD      = $(CC)
 OBJCOPY = $(CROSS)objcopy
 
-LDFLAGS = -Tlinker.ld
+TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32
+
+LDFLAGS = -T$(TSRC_PATH)/linker.ld
+ASFLAGS += -Wa,-I,$(TSRC_PATH)/
 
 CRT        = crt.o
 TESTCASES += test_add.tst
@@ -82,13 +85,13 @@ TESTCASES += test_xori.tst
 
 all: build
 
-%.o: $(SRC_PATH)/tests/lm32/%.c
+%.o: $(TSRC_PATH)/%.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
-%.o: $(SRC_PATH)/tests/lm32/%.S
+%.o: $(TSRC_PATH)/%.S
 	$(AS) $(ASFLAGS) -c $< -o $@
 
-%.tst: %.o macros.inc $(CRT)
+%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT)
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
 
 build: $(CRT) $(TESTCASES)
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-04-01 18:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-31 18:40 [Qemu-devel] [PULL 0/5] lm32 fixes and additions Michael Walle
2012-03-31 18:40 ` [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target Michael Walle
2012-03-31 18:40 ` [Qemu-devel] [PATCH 2/5] target-lm32: init tcg only if available Michael Walle
2012-03-31 18:40 ` [Qemu-devel] [PATCH 3/5] milkymist-sysctl: support for new core version Michael Walle
2012-03-31 18:40 ` [Qemu-devel] [PATCH 4/5] target-lm32: add simple disassembler Michael Walle
2012-04-01 17:17   ` Blue Swirl
2012-03-31 18:40 ` [Qemu-devel] [PATCH 5/5] milkymist-vgafb: add missing register Michael Walle
  -- strict thread matches above, loose matches on Subject: below --
2012-04-01 18:37 [Qemu-devel] [PULL v2 0/5] lm32 fixes and additions Michael Walle
2012-04-01 18:37 ` [Qemu-devel] [PATCH 1/5] tests: fix out-of-tree building for lm32 target Michael Walle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).