All of lore.kernel.org
 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 3/5] milkymist-sysctl: support for new core version
  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

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

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
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 3/5] milkymist-sysctl: support for new core version Michael Walle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.