mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Drop the deprecated lm32 target
Target lm32 was deprecated in commit d849800512, v5.2.0. See there
for rationale.
Some of its code lives on in device models derived from milkymist
ones: hw/char/digic-uart.c and hw/display/bcm2835_fb.c.
Cc: Michael Walle <michael@walle.cc>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210503084034.3804963-2-armbru@redhat.com>
Acked-by: Michael Walle <michael@walle.cc>
[Trivial conflicts resolved, reST markup fixed]
This commit is contained in:
+1
-1
@@ -624,7 +624,7 @@ build-deprecated:
|
||||
IMAGE: debian-all-test-cross
|
||||
CONFIGURE_ARGS: --disable-tools
|
||||
MAKE_CHECK_ARGS: build-tcg
|
||||
TARGETS: ppc64abi32-linux-user lm32-softmmu unicore32-softmmu
|
||||
TARGETS: ppc64abi32-linux-user unicore32-softmmu
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
|
||||
-25
@@ -207,19 +207,6 @@ F: disas/hppa.c
|
||||
F: hw/net/*i82596*
|
||||
F: include/hw/net/lasi_82596.h
|
||||
|
||||
LM32 TCG CPUs
|
||||
R: Michael Walle <michael@walle.cc>
|
||||
S: Orphan
|
||||
F: target/lm32/
|
||||
F: disas/lm32.c
|
||||
F: hw/lm32/
|
||||
F: hw/*/lm32_*
|
||||
F: hw/*/milkymist-*
|
||||
F: include/hw/display/milkymist_tmu2.h
|
||||
F: include/hw/char/lm32_juart.h
|
||||
F: include/hw/lm32/
|
||||
F: tests/tcg/lm32/
|
||||
|
||||
M68K TCG CPUs
|
||||
M: Laurent Vivier <laurent@vivier.eu>
|
||||
S: Maintained
|
||||
@@ -1081,18 +1068,6 @@ F: default-configs/*/hppa-softmmu.mak
|
||||
F: hw/hppa/
|
||||
F: pc-bios/hppa-firmware.img
|
||||
|
||||
LM32 Machines
|
||||
-------------
|
||||
EVR32 and uclinux BSP
|
||||
R: Michael Walle <michael@walle.cc>
|
||||
S: Orphan
|
||||
F: hw/lm32/lm32_boards.c
|
||||
|
||||
milkymist
|
||||
R: Michael Walle <michael@walle.cc>
|
||||
S: Orphan
|
||||
F: hw/lm32/milkymist.c
|
||||
|
||||
M68K Machines
|
||||
-------------
|
||||
an5206
|
||||
|
||||
@@ -1663,7 +1663,7 @@ if [ "$ARCH" = "unknown" ]; then
|
||||
fi
|
||||
|
||||
default_target_list=""
|
||||
deprecated_targets_list=ppc64abi32-linux-user,lm32-softmmu,unicore32-softmmu
|
||||
deprecated_targets_list=ppc64abi32-linux-user,unicore32-softmmu
|
||||
deprecated_features=""
|
||||
mak_wilds=""
|
||||
|
||||
@@ -3617,7 +3617,7 @@ case "$fdt" in
|
||||
esac
|
||||
|
||||
##########################################
|
||||
# opengl probe (for sdl2, gtk, milkymist-tmu2)
|
||||
# opengl probe (for sdl2, gtk)
|
||||
|
||||
gbm="no"
|
||||
if $pkg_config gbm; then
|
||||
@@ -6274,14 +6274,13 @@ fi
|
||||
# UNLINK is used to remove symlinks from older development versions
|
||||
# that might get into the way when doing "git update" without doing
|
||||
# a "make distclean" in between.
|
||||
DIRS="tests tests/tcg tests/tcg/lm32 tests/qapi-schema tests/qtest/libqos"
|
||||
DIRS="tests tests/tcg tests/qapi-schema tests/qtest/libqos"
|
||||
DIRS="$DIRS tests/qtest tests/qemu-iotests tests/vm tests/fp tests/qgraph"
|
||||
DIRS="$DIRS docs docs/interop fsdev scsi"
|
||||
DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
|
||||
DIRS="$DIRS roms/seabios"
|
||||
DIRS="$DIRS contrib/plugins/"
|
||||
LINKS="Makefile"
|
||||
LINKS="$LINKS tests/tcg/lm32/Makefile"
|
||||
LINKS="$LINKS tests/tcg/Makefile.target"
|
||||
LINKS="$LINKS pc-bios/optionrom/Makefile"
|
||||
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# Default configuration for lm32-softmmu
|
||||
|
||||
# Uncomment the following lines to disable these optional devices:
|
||||
#
|
||||
#CONFIG_MILKYMIST_TMU2=n # disabling it actually causes compile-time failures
|
||||
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_LM32_EVR=y
|
||||
CONFIG_MILKYMIST=y
|
||||
@@ -1,2 +0,0 @@
|
||||
TARGET_ARCH=lm32
|
||||
TARGET_WORDS_BIGENDIAN=y
|
||||
-361
@@ -1,361 +0,0 @@
|
||||
/*
|
||||
* 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.1 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 "qemu/osdep.h"
|
||||
#include "disas/dis-asm.h"
|
||||
|
||||
typedef enum {
|
||||
LM32_OP_SRUI = 0, LM32_OP_NORI, LM32_OP_MULI, LM32_OP_SH, LM32_OP_LB,
|
||||
LM32_OP_SRI, LM32_OP_XORI, LM32_OP_LH, LM32_OP_ANDI, LM32_OP_XNORI,
|
||||
LM32_OP_LW, LM32_OP_LHU, LM32_OP_SB, LM32_OP_ADDI, LM32_OP_ORI,
|
||||
LM32_OP_SLI, LM32_OP_LBU, LM32_OP_BE, LM32_OP_BG, LM32_OP_BGE,
|
||||
LM32_OP_BGEU, LM32_OP_BGU, LM32_OP_SW, LM32_OP_BNE, LM32_OP_ANDHI,
|
||||
LM32_OP_CMPEI, LM32_OP_CMPGI, LM32_OP_CMPGEI, LM32_OP_CMPGEUI,
|
||||
LM32_OP_CMPGUI, LM32_OP_ORHI, LM32_OP_CMPNEI, LM32_OP_SRU, LM32_OP_NOR,
|
||||
LM32_OP_MUL, LM32_OP_DIVU, LM32_OP_RCSR, LM32_OP_SR, LM32_OP_XOR,
|
||||
LM32_OP_ILL0, LM32_OP_AND, LM32_OP_XNOR, LM32_OP_ILL1, LM32_OP_SCALL,
|
||||
LM32_OP_SEXTB, LM32_OP_ADD, LM32_OP_OR, LM32_OP_SL, LM32_OP_B,
|
||||
LM32_OP_MODU, LM32_OP_SUB, LM32_OP_ILL2, LM32_OP_WCSR, LM32_OP_ILL3,
|
||||
LM32_OP_CALL, LM32_OP_SEXTH, LM32_OP_BI, LM32_OP_CMPE, LM32_OP_CMPG,
|
||||
LM32_OP_CMPGE, LM32_OP_CMPGEU, LM32_OP_CMPGU, LM32_OP_CALLI, LM32_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 {
|
||||
LM32_CSR_IE = 0, LM32_CSR_IM, LM32_CSR_IP, LM32_CSR_ICC, LM32_CSR_DCC,
|
||||
LM32_CSR_CC, LM32_CSR_CFG, LM32_CSR_EBA, LM32_CSR_DC, LM32_CSR_DEBA,
|
||||
LM32_CSR_CFG2, LM32_CSR_JTX = 0xe, LM32_CSR_JRX, LM32_CSR_BP0,
|
||||
LM32_CSR_BP1, LM32_CSR_BP2, LM32_CSR_BP3, LM32_CSR_WP0 = 0x18,
|
||||
LM32_CSR_WP1, LM32_CSR_WP2, LM32_CSR_WP3,
|
||||
} Lm32CsrNum;
|
||||
|
||||
typedef struct {
|
||||
int csr;
|
||||
const char *name;
|
||||
} Lm32CsrInfo;
|
||||
|
||||
static const Lm32CsrInfo lm32_csr_info[] = {
|
||||
{LM32_CSR_IE, "ie", },
|
||||
{LM32_CSR_IM, "im", },
|
||||
{LM32_CSR_IP, "ip", },
|
||||
{LM32_CSR_ICC, "icc", },
|
||||
{LM32_CSR_DCC, "dcc", },
|
||||
{LM32_CSR_CC, "cc", },
|
||||
{LM32_CSR_CFG, "cfg", },
|
||||
{LM32_CSR_EBA, "eba", },
|
||||
{LM32_CSR_DC, "dc", },
|
||||
{LM32_CSR_DEBA, "deba", },
|
||||
{LM32_CSR_CFG2, "cfg2", },
|
||||
{LM32_CSR_JTX, "jtx", },
|
||||
{LM32_CSR_JRX, "jrx", },
|
||||
{LM32_CSR_BP0, "bp0", },
|
||||
{LM32_CSR_BP1, "bp1", },
|
||||
{LM32_CSR_BP2, "bp2", },
|
||||
{LM32_CSR_BP3, "bp3", },
|
||||
{LM32_CSR_WP0, "wp0", },
|
||||
{LM32_CSR_WP1, "wp1", },
|
||||
{LM32_CSR_WP2, "wp2", },
|
||||
{LM32_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 {
|
||||
LM32_REG_R0 = 0, LM32_REG_R1, LM32_REG_R2, LM32_REG_R3, LM32_REG_R4,
|
||||
LM32_REG_R5, LM32_REG_R6, LM32_REG_R7, LM32_REG_R8, LM32_REG_R9,
|
||||
LM32_REG_R10, LM32_REG_R11, LM32_REG_R12, LM32_REG_R13, LM32_REG_R14,
|
||||
LM32_REG_R15, LM32_REG_R16, LM32_REG_R17, LM32_REG_R18, LM32_REG_R19,
|
||||
LM32_REG_R20, LM32_REG_R21, LM32_REG_R22, LM32_REG_R23, LM32_REG_R24,
|
||||
LM32_REG_R25, LM32_REG_GP, LM32_REG_FP, LM32_REG_SP, LM32_REG_RA,
|
||||
LM32_REG_EA, LM32_REG_BA,
|
||||
} Lm32RegNum;
|
||||
|
||||
static const Lm32RegInfo lm32_reg_info[] = {
|
||||
{LM32_REG_R0, "r0", },
|
||||
{LM32_REG_R1, "r1", },
|
||||
{LM32_REG_R2, "r2", },
|
||||
{LM32_REG_R3, "r3", },
|
||||
{LM32_REG_R4, "r4", },
|
||||
{LM32_REG_R5, "r5", },
|
||||
{LM32_REG_R6, "r6", },
|
||||
{LM32_REG_R7, "r7", },
|
||||
{LM32_REG_R8, "r8", },
|
||||
{LM32_REG_R9, "r9", },
|
||||
{LM32_REG_R10, "r10", },
|
||||
{LM32_REG_R11, "r11", },
|
||||
{LM32_REG_R12, "r12", },
|
||||
{LM32_REG_R13, "r13", },
|
||||
{LM32_REG_R14, "r14", },
|
||||
{LM32_REG_R15, "r15", },
|
||||
{LM32_REG_R16, "r16", },
|
||||
{LM32_REG_R17, "r17", },
|
||||
{LM32_REG_R18, "r18", },
|
||||
{LM32_REG_R19, "r19", },
|
||||
{LM32_REG_R20, "r20", },
|
||||
{LM32_REG_R21, "r21", },
|
||||
{LM32_REG_R22, "r22", },
|
||||
{LM32_REG_R23, "r23", },
|
||||
{LM32_REG_R24, "r24", },
|
||||
{LM32_REG_R25, "r25", },
|
||||
{LM32_REG_GP, "gp", },
|
||||
{LM32_REG_FP, "fp", },
|
||||
{LM32_REG_SP, "sp", },
|
||||
{LM32_REG_RA, "ra", },
|
||||
{LM32_REG_EA, "ea", },
|
||||
{LM32_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(LM32_OP_ADD), "add", "%2, %0, %1" },
|
||||
{_O(LM32_OP_ADDI), "addi", "%1, %0, %s" },
|
||||
{_O(LM32_OP_AND), "and", "%2, %0, %1" },
|
||||
{_O(LM32_OP_ANDHI), "andhi", "%1, %0, %u" },
|
||||
{_O(LM32_OP_ANDI), "andi", "%1, %0, %u" },
|
||||
{_O(LM32_OP_B), "b", "%0", },
|
||||
{_O(LM32_OP_BE), "be", "%1, %0, %r" },
|
||||
{_O(LM32_OP_BG), "bg", "%1, %0, %r" },
|
||||
{_O(LM32_OP_BGE), "bge", "%1, %0, %r" },
|
||||
{_O(LM32_OP_BGEU), "bgeu", "%1, %0, %r" },
|
||||
{_O(LM32_OP_BGU), "bgu", "%1, %0, %r" },
|
||||
{_O(LM32_OP_BI), "bi", "%R", },
|
||||
{_O(LM32_OP_BNE), "bne", "%1, %0, %r" },
|
||||
{_O(LM32_OP_CALL), "call", "%0", },
|
||||
{_O(LM32_OP_CALLI), "calli", "%R", },
|
||||
{_O(LM32_OP_CMPE), "cmpe", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPEI), "cmpei", "%1, %0, %s" },
|
||||
{_O(LM32_OP_CMPG), "cmpg", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPGE), "cmpge", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPGEI), "cmpgei", "%1, %0, %s" },
|
||||
{_O(LM32_OP_CMPGEU), "cmpgeu", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPGEUI), "cmpgeui", "%1, %0, %s" },
|
||||
{_O(LM32_OP_CMPGI), "cmpgi", "%1, %0, %s" },
|
||||
{_O(LM32_OP_CMPGU), "cmpgu", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPGUI), "cmpgui", "%1, %0, %s" },
|
||||
{_O(LM32_OP_CMPNE), "cmpne", "%2, %0, %1" },
|
||||
{_O(LM32_OP_CMPNEI), "cmpnei", "%1, %0, %s" },
|
||||
{_O(LM32_OP_DIVU), "divu", "%2, %0, %1" },
|
||||
{_O(LM32_OP_LB), "lb", "%1, (%0+%s)" },
|
||||
{_O(LM32_OP_LBU), "lbu", "%1, (%0+%s)" },
|
||||
{_O(LM32_OP_LH), "lh", "%1, (%0+%s)" },
|
||||
{_O(LM32_OP_LHU), "lhu", "%1, (%0+%s)" },
|
||||
{_O(LM32_OP_LW), "lw", "%1, (%0+%s)" },
|
||||
{_O(LM32_OP_MODU), "modu", "%2, %0, %1" },
|
||||
{_O(LM32_OP_MULI), "muli", "%1, %0, %s" },
|
||||
{_O(LM32_OP_MUL), "mul", "%2, %0, %1" },
|
||||
{_O(LM32_OP_NORI), "nori", "%1, %0, %u" },
|
||||
{_O(LM32_OP_NOR), "nor", "%2, %0, %1" },
|
||||
{_O(LM32_OP_ORHI), "orhi", "%1, %0, %u" },
|
||||
{_O(LM32_OP_ORI), "ori", "%1, %0, %u" },
|
||||
{_O(LM32_OP_OR), "or", "%2, %0, %1" },
|
||||
{_O(LM32_OP_RCSR), "rcsr", "%2, %c", },
|
||||
{_O(LM32_OP_SB), "sb", "(%0+%s), %1" },
|
||||
{_O(LM32_OP_SEXTB), "sextb", "%2, %0", },
|
||||
{_O(LM32_OP_SEXTH), "sexth", "%2, %0", },
|
||||
{_O(LM32_OP_SH), "sh", "(%0+%s), %1" },
|
||||
{_O(LM32_OP_SLI), "sli", "%1, %0, %h" },
|
||||
{_O(LM32_OP_SL), "sl", "%2, %0, %1" },
|
||||
{_O(LM32_OP_SRI), "sri", "%1, %0, %h" },
|
||||
{_O(LM32_OP_SR), "sr", "%2, %0, %1" },
|
||||
{_O(LM32_OP_SRUI), "srui", "%1, %0, %d" },
|
||||
{_O(LM32_OP_SRU), "sru", "%2, %0, %s" },
|
||||
{_O(LM32_OP_SUB), "sub", "%2, %0, %s" },
|
||||
{_O(LM32_OP_SW), "sw", "(%0+%s), %1" },
|
||||
{_O(LM32_OP_WCSR), "wcsr", "%c, %1", },
|
||||
{_O(LM32_OP_XNORI), "xnori", "%1, %0, %u" },
|
||||
{_O(LM32_OP_XNOR), "xnor", "%2, %0, %1" },
|
||||
{_O(LM32_OP_XORI), "xori", "%1, %0, %u" },
|
||||
{_O(LM32_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 Lm32CsrInfo *info;
|
||||
csr = (op >> 21) & 0x1f;
|
||||
info = find_csr_info(csr);
|
||||
if (info) {
|
||||
fprintf_fn(stream, "%s", info->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;
|
||||
}
|
||||
@@ -9,7 +9,6 @@ common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c'))
|
||||
common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c'))
|
||||
common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
|
||||
common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c'))
|
||||
common_ss.add(when: 'CONFIG_LM32_DIS', if_true: files('lm32.c'))
|
||||
common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
|
||||
common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
|
||||
common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c'))
|
||||
|
||||
@@ -198,14 +198,6 @@ from Linux upstream kernel, declare it deprecated.
|
||||
System emulator CPUS
|
||||
--------------------
|
||||
|
||||
``lm32`` CPUs (since 5.2.0)
|
||||
'''''''''''''''''''''''''''
|
||||
|
||||
The ``lm32`` guest CPU support is deprecated and will be removed in
|
||||
a future version of QEMU. The only public user of this architecture
|
||||
was the milkymist project, which has been dead for years; there was
|
||||
never an upstream Linux port.
|
||||
|
||||
``unicore32`` CPUs (since 5.2.0)
|
||||
''''''''''''''''''''''''''''''''
|
||||
|
||||
|
||||
@@ -298,6 +298,13 @@ Nobody was using this CPU emulation in QEMU, and there were no test images
|
||||
available to make sure that the code is still working, so it has been removed
|
||||
without replacement.
|
||||
|
||||
``lm32`` CPUs (removed in 6.1.0)
|
||||
''''''''''''''''''''''''''''''''
|
||||
|
||||
The only public user of this architecture was the milkymist project,
|
||||
which has been dead for years; there was never an upstream Linux
|
||||
port. Removed without replacement.
|
||||
|
||||
System emulator machines
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ static FloatParts parts_default_nan(float_status *status)
|
||||
/* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
|
||||
* S390, SH4, TriCore, and Xtensa. I cannot find documentation
|
||||
* for Unicore32; the choice from the original commit is unchanged.
|
||||
* Our other supported targets, CRIS, LM32, and Nios2,
|
||||
* Our other supported targets, CRIS, Nios2, and Tile,
|
||||
* do not have floating-point.
|
||||
*/
|
||||
if (snan_bit_is_one(status)) {
|
||||
|
||||
@@ -47,7 +47,6 @@ source avr/Kconfig
|
||||
source cris/Kconfig
|
||||
source hppa/Kconfig
|
||||
source i386/Kconfig
|
||||
source lm32/Kconfig
|
||||
source m68k/Kconfig
|
||||
source microblaze/Kconfig
|
||||
source mips/Kconfig
|
||||
|
||||
@@ -7,7 +7,6 @@ softmmu_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_GUS', if_true: files('gus.c', 'gusemu_hal.c', 'gusemu_mixer.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_HDA', if_true: files('intel-hda.c', 'hda-codec.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_MARVELL_88W8618', if_true: files('marvell_88w8618.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-ac97.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c'))
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
/*
|
||||
* QEMU model of the Milkymist System Controller.
|
||||
*
|
||||
* Copyright (c) 2010 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.1 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/>.
|
||||
*
|
||||
*
|
||||
* Specification available at:
|
||||
* http://milkymist.walle.cc/socdoc/ac97.pdf
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
#include "audio/audio.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
enum {
|
||||
R_AC97_CTRL = 0,
|
||||
R_AC97_ADDR,
|
||||
R_AC97_DATAOUT,
|
||||
R_AC97_DATAIN,
|
||||
R_D_CTRL,
|
||||
R_D_ADDR,
|
||||
R_D_REMAINING,
|
||||
R_RESERVED,
|
||||
R_U_CTRL,
|
||||
R_U_ADDR,
|
||||
R_U_REMAINING,
|
||||
R_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
AC97_CTRL_RQEN = (1<<0),
|
||||
AC97_CTRL_WRITE = (1<<1),
|
||||
};
|
||||
|
||||
enum {
|
||||
CTRL_EN = (1<<0),
|
||||
};
|
||||
|
||||
#define TYPE_MILKYMIST_AC97 "milkymist-ac97"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(MilkymistAC97State, MILKYMIST_AC97)
|
||||
|
||||
struct MilkymistAC97State {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
MemoryRegion regs_region;
|
||||
|
||||
QEMUSoundCard card;
|
||||
SWVoiceIn *voice_in;
|
||||
SWVoiceOut *voice_out;
|
||||
|
||||
uint32_t regs[R_MAX];
|
||||
|
||||
qemu_irq crrequest_irq;
|
||||
qemu_irq crreply_irq;
|
||||
qemu_irq dmar_irq;
|
||||
qemu_irq dmaw_irq;
|
||||
};
|
||||
|
||||
static void update_voices(MilkymistAC97State *s)
|
||||
{
|
||||
if (s->regs[R_D_CTRL] & CTRL_EN) {
|
||||
AUD_set_active_out(s->voice_out, 1);
|
||||
} else {
|
||||
AUD_set_active_out(s->voice_out, 0);
|
||||
}
|
||||
|
||||
if (s->regs[R_U_CTRL] & CTRL_EN) {
|
||||
AUD_set_active_in(s->voice_in, 1);
|
||||
} else {
|
||||
AUD_set_active_in(s->voice_in, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t ac97_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
MilkymistAC97State *s = opaque;
|
||||
uint32_t r = 0;
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_AC97_CTRL:
|
||||
case R_AC97_ADDR:
|
||||
case R_AC97_DATAOUT:
|
||||
case R_AC97_DATAIN:
|
||||
case R_D_CTRL:
|
||||
case R_D_ADDR:
|
||||
case R_D_REMAINING:
|
||||
case R_U_CTRL:
|
||||
case R_U_ADDR:
|
||||
case R_U_REMAINING:
|
||||
r = s->regs[addr];
|
||||
break;
|
||||
|
||||
default:
|
||||
error_report("milkymist_ac97: read access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_milkymist_ac97_memory_read(addr << 2, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void ac97_write(void *opaque, hwaddr addr, uint64_t value,
|
||||
unsigned size)
|
||||
{
|
||||
MilkymistAC97State *s = opaque;
|
||||
|
||||
trace_milkymist_ac97_memory_write(addr, value);
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_AC97_CTRL:
|
||||
/* always raise an IRQ according to the direction */
|
||||
if (value & AC97_CTRL_RQEN) {
|
||||
if (value & AC97_CTRL_WRITE) {
|
||||
trace_milkymist_ac97_pulse_irq_crrequest();
|
||||
qemu_irq_pulse(s->crrequest_irq);
|
||||
} else {
|
||||
trace_milkymist_ac97_pulse_irq_crreply();
|
||||
qemu_irq_pulse(s->crreply_irq);
|
||||
}
|
||||
}
|
||||
|
||||
/* RQEN is self clearing */
|
||||
s->regs[addr] = value & ~AC97_CTRL_RQEN;
|
||||
break;
|
||||
case R_D_CTRL:
|
||||
case R_U_CTRL:
|
||||
s->regs[addr] = value;
|
||||
update_voices(s);
|
||||
break;
|
||||
case R_AC97_ADDR:
|
||||
case R_AC97_DATAOUT:
|
||||
case R_AC97_DATAIN:
|
||||
case R_D_ADDR:
|
||||
case R_D_REMAINING:
|
||||
case R_U_ADDR:
|
||||
case R_U_REMAINING:
|
||||
s->regs[addr] = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
error_report("milkymist_ac97: write access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const MemoryRegionOps ac97_mmio_ops = {
|
||||
.read = ac97_read,
|
||||
.write = ac97_write,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void ac97_in_cb(void *opaque, int avail_b)
|
||||
{
|
||||
MilkymistAC97State *s = opaque;
|
||||
uint8_t buf[4096];
|
||||
uint32_t remaining = s->regs[R_U_REMAINING];
|
||||
int temp = MIN(remaining, avail_b);
|
||||
uint32_t addr = s->regs[R_U_ADDR];
|
||||
int transferred = 0;
|
||||
|
||||
trace_milkymist_ac97_in_cb(avail_b, remaining);
|
||||
|
||||
/* prevent from raising an IRQ */
|
||||
if (temp == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (temp) {
|
||||
int acquired, to_copy;
|
||||
|
||||
to_copy = MIN(temp, sizeof(buf));
|
||||
acquired = AUD_read(s->voice_in, buf, to_copy);
|
||||
if (!acquired) {
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_physical_memory_write(addr, buf, acquired);
|
||||
|
||||
temp -= acquired;
|
||||
addr += acquired;
|
||||
transferred += acquired;
|
||||
}
|
||||
|
||||
trace_milkymist_ac97_in_cb_transferred(transferred);
|
||||
|
||||
s->regs[R_U_ADDR] = addr;
|
||||
s->regs[R_U_REMAINING] -= transferred;
|
||||
|
||||
if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) {
|
||||
trace_milkymist_ac97_pulse_irq_dmaw();
|
||||
qemu_irq_pulse(s->dmaw_irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void ac97_out_cb(void *opaque, int free_b)
|
||||
{
|
||||
MilkymistAC97State *s = opaque;
|
||||
uint8_t buf[4096];
|
||||
uint32_t remaining = s->regs[R_D_REMAINING];
|
||||
int temp = MIN(remaining, free_b);
|
||||
uint32_t addr = s->regs[R_D_ADDR];
|
||||
int transferred = 0;
|
||||
|
||||
trace_milkymist_ac97_out_cb(free_b, remaining);
|
||||
|
||||
/* prevent from raising an IRQ */
|
||||
if (temp == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (temp) {
|
||||
int copied, to_copy;
|
||||
|
||||
to_copy = MIN(temp, sizeof(buf));
|
||||
cpu_physical_memory_read(addr, buf, to_copy);
|
||||
copied = AUD_write(s->voice_out, buf, to_copy);
|
||||
if (!copied) {
|
||||
break;
|
||||
}
|
||||
temp -= copied;
|
||||
addr += copied;
|
||||
transferred += copied;
|
||||
}
|
||||
|
||||
trace_milkymist_ac97_out_cb_transferred(transferred);
|
||||
|
||||
s->regs[R_D_ADDR] = addr;
|
||||
s->regs[R_D_REMAINING] -= transferred;
|
||||
|
||||
if ((s->regs[R_D_CTRL] & CTRL_EN) && (s->regs[R_D_REMAINING] == 0)) {
|
||||
trace_milkymist_ac97_pulse_irq_dmar();
|
||||
qemu_irq_pulse(s->dmar_irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void milkymist_ac97_reset(DeviceState *d)
|
||||
{
|
||||
MilkymistAC97State *s = MILKYMIST_AC97(d);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < R_MAX; i++) {
|
||||
s->regs[i] = 0;
|
||||
}
|
||||
|
||||
AUD_set_active_in(s->voice_in, 0);
|
||||
AUD_set_active_out(s->voice_out, 0);
|
||||
}
|
||||
|
||||
static int ac97_post_load(void *opaque, int version_id)
|
||||
{
|
||||
MilkymistAC97State *s = opaque;
|
||||
|
||||
update_voices(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void milkymist_ac97_init(Object *obj)
|
||||
{
|
||||
MilkymistAC97State *s = MILKYMIST_AC97(obj);
|
||||
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
||||
|
||||
sysbus_init_irq(dev, &s->crrequest_irq);
|
||||
sysbus_init_irq(dev, &s->crreply_irq);
|
||||
sysbus_init_irq(dev, &s->dmar_irq);
|
||||
sysbus_init_irq(dev, &s->dmaw_irq);
|
||||
|
||||
memory_region_init_io(&s->regs_region, obj, &ac97_mmio_ops, s,
|
||||
"milkymist-ac97", R_MAX * 4);
|
||||
sysbus_init_mmio(dev, &s->regs_region);
|
||||
}
|
||||
|
||||
static void milkymist_ac97_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MilkymistAC97State *s = MILKYMIST_AC97(dev);
|
||||
struct audsettings as;
|
||||
|
||||
AUD_register_card("Milkymist AC'97", &s->card);
|
||||
|
||||
as.freq = 48000;
|
||||
as.nchannels = 2;
|
||||
as.fmt = AUDIO_FORMAT_S16;
|
||||
as.endianness = 1;
|
||||
|
||||
s->voice_in = AUD_open_in(&s->card, s->voice_in,
|
||||
"mm_ac97.in", s, ac97_in_cb, &as);
|
||||
s->voice_out = AUD_open_out(&s->card, s->voice_out,
|
||||
"mm_ac97.out", s, ac97_out_cb, &as);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_milkymist_ac97 = {
|
||||
.name = "milkymist-ac97",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.post_load = ac97_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property milkymist_ac97_properties[] = {
|
||||
DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = milkymist_ac97_realize;
|
||||
dc->reset = milkymist_ac97_reset;
|
||||
dc->vmsd = &vmstate_milkymist_ac97;
|
||||
device_class_set_props(dc, milkymist_ac97_properties);
|
||||
}
|
||||
|
||||
static const TypeInfo milkymist_ac97_info = {
|
||||
.name = TYPE_MILKYMIST_AC97,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MilkymistAC97State),
|
||||
.instance_init = milkymist_ac97_init,
|
||||
.class_init = milkymist_ac97_class_init,
|
||||
};
|
||||
|
||||
static void milkymist_ac97_register_types(void)
|
||||
{
|
||||
type_register_static(&milkymist_ac97_info);
|
||||
}
|
||||
|
||||
type_init(milkymist_ac97_register_types)
|
||||
@@ -6,18 +6,6 @@ cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
|
||||
cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
|
||||
cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
|
||||
|
||||
# milkymist-ac97.c
|
||||
milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
|
||||
milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
|
||||
milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
|
||||
milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
|
||||
milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
|
||||
milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
|
||||
milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
|
||||
milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
|
||||
|
||||
# hda-codec.c
|
||||
hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run %d"
|
||||
hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st %s, %d x %s @ %d Hz"
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* LatticeMico32 JTAG UART model.
|
||||
*
|
||||
* Copyright (c) 2010 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.1 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 "qemu/osdep.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "trace.h"
|
||||
#include "chardev/char-fe.h"
|
||||
|
||||
#include "hw/char/lm32_juart.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
enum {
|
||||
LM32_JUART_MIN_SAVE_VERSION = 0,
|
||||
LM32_JUART_CURRENT_SAVE_VERSION = 0,
|
||||
LM32_JUART_MAX_SAVE_VERSION = 0,
|
||||
};
|
||||
|
||||
enum {
|
||||
JTX_FULL = (1<<8),
|
||||
};
|
||||
|
||||
enum {
|
||||
JRX_FULL = (1<<8),
|
||||
};
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LM32JuartState, LM32_JUART)
|
||||
|
||||
struct LM32JuartState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
CharBackend chr;
|
||||
|
||||
uint32_t jtx;
|
||||
uint32_t jrx;
|
||||
};
|
||||
|
||||
uint32_t lm32_juart_get_jtx(DeviceState *d)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(d);
|
||||
|
||||
trace_lm32_juart_get_jtx(s->jtx);
|
||||
return s->jtx;
|
||||
}
|
||||
|
||||
uint32_t lm32_juart_get_jrx(DeviceState *d)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(d);
|
||||
|
||||
trace_lm32_juart_get_jrx(s->jrx);
|
||||
return s->jrx;
|
||||
}
|
||||
|
||||
void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(d);
|
||||
unsigned char ch = jtx & 0xff;
|
||||
|
||||
trace_lm32_juart_set_jtx(s->jtx);
|
||||
|
||||
s->jtx = jtx;
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(&s->chr, &ch, 1);
|
||||
}
|
||||
|
||||
void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(d);
|
||||
|
||||
trace_lm32_juart_set_jrx(s->jrx);
|
||||
s->jrx &= ~JRX_FULL;
|
||||
}
|
||||
|
||||
static void juart_rx(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
LM32JuartState *s = opaque;
|
||||
|
||||
s->jrx = *buf | JRX_FULL;
|
||||
}
|
||||
|
||||
static int juart_can_rx(void *opaque)
|
||||
{
|
||||
LM32JuartState *s = opaque;
|
||||
|
||||
return !(s->jrx & JRX_FULL);
|
||||
}
|
||||
|
||||
static void juart_event(void *opaque, QEMUChrEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
static void juart_reset(DeviceState *d)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(d);
|
||||
|
||||
s->jtx = 0;
|
||||
s->jrx = 0;
|
||||
}
|
||||
|
||||
static void lm32_juart_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
LM32JuartState *s = LM32_JUART(dev);
|
||||
|
||||
qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx,
|
||||
juart_event, NULL, s, NULL, true);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_lm32_juart = {
|
||||
.name = "lm32-juart",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(jtx, LM32JuartState),
|
||||
VMSTATE_UINT32(jrx, LM32JuartState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property lm32_juart_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", LM32JuartState, chr),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void lm32_juart_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = juart_reset;
|
||||
dc->vmsd = &vmstate_lm32_juart;
|
||||
device_class_set_props(dc, lm32_juart_properties);
|
||||
dc->realize = lm32_juart_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo lm32_juart_info = {
|
||||
.name = TYPE_LM32_JUART,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(LM32JuartState),
|
||||
.class_init = lm32_juart_class_init,
|
||||
};
|
||||
|
||||
static void lm32_juart_register_types(void)
|
||||
{
|
||||
type_register_static(&lm32_juart_info);
|
||||
}
|
||||
|
||||
type_init(lm32_juart_register_types)
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
* QEMU model of the LatticeMico32 UART block.
|
||||
*
|
||||
* Copyright (c) 2010 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.1 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/>.
|
||||
*
|
||||
*
|
||||
* Specification available at:
|
||||
* http://www.latticesemi.com/documents/mico32uart.pdf
|
||||
*/
|
||||
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
enum {
|
||||
R_RXTX = 0,
|
||||
R_IER,
|
||||
R_IIR,
|
||||
R_LCR,
|
||||
R_MCR,
|
||||
R_LSR,
|
||||
R_MSR,
|
||||
R_DIV,
|
||||
R_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
IER_RBRI = (1<<0),
|
||||
IER_THRI = (1<<1),
|
||||
IER_RLSI = (1<<2),
|
||||
IER_MSI = (1<<3),
|
||||
};
|
||||
|
||||
enum {
|
||||
IIR_STAT = (1<<0),
|
||||
IIR_ID0 = (1<<1),
|
||||
IIR_ID1 = (1<<2),
|
||||
};
|
||||
|
||||
enum {
|
||||
LCR_WLS0 = (1<<0),
|
||||
LCR_WLS1 = (1<<1),
|
||||
LCR_STB = (1<<2),
|
||||
LCR_PEN = (1<<3),
|
||||
LCR_EPS = (1<<4),
|
||||
LCR_SP = (1<<5),
|
||||
LCR_SB = (1<<6),
|
||||
};
|
||||
|
||||
enum {
|
||||
MCR_DTR = (1<<0),
|
||||
MCR_RTS = (1<<1),
|
||||
};
|
||||
|
||||
enum {
|
||||
LSR_DR = (1<<0),
|
||||
LSR_OE = (1<<1),
|
||||
LSR_PE = (1<<2),
|
||||
LSR_FE = (1<<3),
|
||||
LSR_BI = (1<<4),
|
||||
LSR_THRE = (1<<5),
|
||||
LSR_TEMT = (1<<6),
|
||||
};
|
||||
|
||||
enum {
|
||||
MSR_DCTS = (1<<0),
|
||||
MSR_DDSR = (1<<1),
|
||||
MSR_TERI = (1<<2),
|
||||
MSR_DDCD = (1<<3),
|
||||
MSR_CTS = (1<<4),
|
||||
MSR_DSR = (1<<5),
|
||||
MSR_RI = (1<<6),
|
||||
MSR_DCD = (1<<7),
|
||||
};
|
||||
|
||||
#define TYPE_LM32_UART "lm32-uart"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LM32UartState, LM32_UART)
|
||||
|
||||
struct LM32UartState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
MemoryRegion iomem;
|
||||
CharBackend chr;
|
||||
qemu_irq irq;
|
||||
|
||||
uint32_t regs[R_MAX];
|
||||
};
|
||||
|
||||
static void uart_update_irq(LM32UartState *s)
|
||||
{
|
||||
unsigned int irq;
|
||||
|
||||
if ((s->regs[R_LSR] & (LSR_OE | LSR_PE | LSR_FE | LSR_BI))
|
||||
&& (s->regs[R_IER] & IER_RLSI)) {
|
||||
irq = 1;
|
||||
s->regs[R_IIR] = IIR_ID1 | IIR_ID0;
|
||||
} else if ((s->regs[R_LSR] & LSR_DR) && (s->regs[R_IER] & IER_RBRI)) {
|
||||
irq = 1;
|
||||
s->regs[R_IIR] = IIR_ID1;
|
||||
} else if ((s->regs[R_LSR] & LSR_THRE) && (s->regs[R_IER] & IER_THRI)) {
|
||||
irq = 1;
|
||||
s->regs[R_IIR] = IIR_ID0;
|
||||
} else if ((s->regs[R_MSR] & 0x0f) && (s->regs[R_IER] & IER_MSI)) {
|
||||
irq = 1;
|
||||
s->regs[R_IIR] = 0;
|
||||
} else {
|
||||
irq = 0;
|
||||
s->regs[R_IIR] = IIR_STAT;
|
||||
}
|
||||
|
||||
trace_lm32_uart_irq_state(irq);
|
||||
qemu_set_irq(s->irq, irq);
|
||||
}
|
||||
|
||||
static uint64_t uart_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
LM32UartState *s = opaque;
|
||||
uint32_t r = 0;
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_RXTX:
|
||||
r = s->regs[R_RXTX];
|
||||
s->regs[R_LSR] &= ~LSR_DR;
|
||||
uart_update_irq(s);
|
||||
qemu_chr_fe_accept_input(&s->chr);
|
||||
break;
|
||||
case R_IIR:
|
||||
case R_LSR:
|
||||
case R_MSR:
|
||||
r = s->regs[addr];
|
||||
break;
|
||||
case R_IER:
|
||||
case R_LCR:
|
||||
case R_MCR:
|
||||
case R_DIV:
|
||||
error_report("lm32_uart: read access to write only register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
default:
|
||||
error_report("lm32_uart: read access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_lm32_uart_memory_read(addr << 2, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void uart_write(void *opaque, hwaddr addr,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
LM32UartState *s = opaque;
|
||||
unsigned char ch = value;
|
||||
|
||||
trace_lm32_uart_memory_write(addr, value);
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_RXTX:
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(&s->chr, &ch, 1);
|
||||
break;
|
||||
case R_IER:
|
||||
case R_LCR:
|
||||
case R_MCR:
|
||||
case R_DIV:
|
||||
s->regs[addr] = value;
|
||||
break;
|
||||
case R_IIR:
|
||||
case R_LSR:
|
||||
case R_MSR:
|
||||
error_report("lm32_uart: write access to read only register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
default:
|
||||
error_report("lm32_uart: write access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
}
|
||||
uart_update_irq(s);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps uart_ops = {
|
||||
.read = uart_read,
|
||||
.write = uart_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static void uart_rx(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
LM32UartState *s = opaque;
|
||||
|
||||
if (s->regs[R_LSR] & LSR_DR) {
|
||||
s->regs[R_LSR] |= LSR_OE;
|
||||
}
|
||||
|
||||
s->regs[R_LSR] |= LSR_DR;
|
||||
s->regs[R_RXTX] = *buf;
|
||||
|
||||
uart_update_irq(s);
|
||||
}
|
||||
|
||||
static int uart_can_rx(void *opaque)
|
||||
{
|
||||
LM32UartState *s = opaque;
|
||||
|
||||
return !(s->regs[R_LSR] & LSR_DR);
|
||||
}
|
||||
|
||||
static void uart_event(void *opaque, QEMUChrEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
static void uart_reset(DeviceState *d)
|
||||
{
|
||||
LM32UartState *s = LM32_UART(d);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < R_MAX; i++) {
|
||||
s->regs[i] = 0;
|
||||
}
|
||||
|
||||
/* defaults */
|
||||
s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
|
||||
}
|
||||
|
||||
static void lm32_uart_init(Object *obj)
|
||||
{
|
||||
LM32UartState *s = LM32_UART(obj);
|
||||
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
|
||||
memory_region_init_io(&s->iomem, obj, &uart_ops, s,
|
||||
"uart", R_MAX * 4);
|
||||
sysbus_init_mmio(dev, &s->iomem);
|
||||
}
|
||||
|
||||
static void lm32_uart_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
LM32UartState *s = LM32_UART(dev);
|
||||
|
||||
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
|
||||
uart_event, NULL, s, NULL, true);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_lm32_uart = {
|
||||
.name = "lm32-uart",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, LM32UartState, R_MAX),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property lm32_uart_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", LM32UartState, chr),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void lm32_uart_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = uart_reset;
|
||||
dc->vmsd = &vmstate_lm32_uart;
|
||||
device_class_set_props(dc, lm32_uart_properties);
|
||||
dc->realize = lm32_uart_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo lm32_uart_info = {
|
||||
.name = TYPE_LM32_UART,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(LM32UartState),
|
||||
.instance_init = lm32_uart_init,
|
||||
.class_init = lm32_uart_class_init,
|
||||
};
|
||||
|
||||
static void lm32_uart_register_types(void)
|
||||
{
|
||||
type_register_static(&lm32_uart_info);
|
||||
}
|
||||
|
||||
type_init(lm32_uart_register_types)
|
||||
@@ -8,9 +8,6 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_serial.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_IPACK', if_true: files('ipoctal232.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_ISA_BUS', if_true: files('parallel-isa.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugcon.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_juart.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_uart.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-uart.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_uart.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_PARALLEL', if_true: files('parallel.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_PL011', if_true: files('pl011.c'))
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* QEMU model of the Milkymist UART block.
|
||||
*
|
||||
* Copyright (c) 2010 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.1 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/>.
|
||||
*
|
||||
*
|
||||
* Specification available at:
|
||||
* http://milkymist.walle.cc/socdoc/uart.pdf
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
enum {
|
||||
R_RXTX = 0,
|
||||
R_DIV,
|
||||
R_STAT,
|
||||
R_CTRL,
|
||||
R_DBG,
|
||||
R_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
STAT_THRE = (1<<0),
|
||||
STAT_RX_EVT = (1<<1),
|
||||
STAT_TX_EVT = (1<<2),
|
||||
};
|
||||
|
||||
enum {
|
||||
CTRL_RX_IRQ_EN = (1<<0),
|
||||
CTRL_TX_IRQ_EN = (1<<1),
|
||||
CTRL_THRU_EN = (1<<2),
|
||||
};
|
||||
|
||||
enum {
|
||||
DBG_BREAK_EN = (1<<0),
|
||||
};
|
||||
|
||||
#define TYPE_MILKYMIST_UART "milkymist-uart"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(MilkymistUartState, MILKYMIST_UART)
|
||||
|
||||
struct MilkymistUartState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
MemoryRegion regs_region;
|
||||
CharBackend chr;
|
||||
qemu_irq irq;
|
||||
|
||||
uint32_t regs[R_MAX];
|
||||
};
|
||||
|
||||
static void uart_update_irq(MilkymistUartState *s)
|
||||
{
|
||||
int rx_event = s->regs[R_STAT] & STAT_RX_EVT;
|
||||
int tx_event = s->regs[R_STAT] & STAT_TX_EVT;
|
||||
int rx_irq_en = s->regs[R_CTRL] & CTRL_RX_IRQ_EN;
|
||||
int tx_irq_en = s->regs[R_CTRL] & CTRL_TX_IRQ_EN;
|
||||
|
||||
if ((rx_irq_en && rx_event) || (tx_irq_en && tx_event)) {
|
||||
trace_milkymist_uart_raise_irq();
|
||||
qemu_irq_raise(s->irq);
|
||||
} else {
|
||||
trace_milkymist_uart_lower_irq();
|
||||
qemu_irq_lower(s->irq);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t uart_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
MilkymistUartState *s = opaque;
|
||||
uint32_t r = 0;
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_RXTX:
|
||||
r = s->regs[addr];
|
||||
break;
|
||||
case R_DIV:
|
||||
case R_STAT:
|
||||
case R_CTRL:
|
||||
case R_DBG:
|
||||
r = s->regs[addr];
|
||||
break;
|
||||
|
||||
default:
|
||||
error_report("milkymist_uart: read access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_milkymist_uart_memory_read(addr << 2, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void uart_write(void *opaque, hwaddr addr, uint64_t value,
|
||||
unsigned size)
|
||||
{
|
||||
MilkymistUartState *s = opaque;
|
||||
unsigned char ch = value;
|
||||
|
||||
trace_milkymist_uart_memory_write(addr, value);
|
||||
|
||||
addr >>= 2;
|
||||
switch (addr) {
|
||||
case R_RXTX:
|
||||
qemu_chr_fe_write_all(&s->chr, &ch, 1);
|
||||
s->regs[R_STAT] |= STAT_TX_EVT;
|
||||
break;
|
||||
case R_DIV:
|
||||
case R_CTRL:
|
||||
case R_DBG:
|
||||
s->regs[addr] = value;
|
||||
break;
|
||||
|
||||
case R_STAT:
|
||||
/* write one to clear bits */
|
||||
s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT));
|
||||
qemu_chr_fe_accept_input(&s->chr);
|
||||
break;
|
||||
|
||||
default:
|
||||
error_report("milkymist_uart: write access to unknown register 0x"
|
||||
TARGET_FMT_plx, addr << 2);
|
||||
break;
|
||||
}
|
||||
|
||||
uart_update_irq(s);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps uart_mmio_ops = {
|
||||
.read = uart_read,
|
||||
.write = uart_write,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void uart_rx(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
MilkymistUartState *s = opaque;
|
||||
|
||||
assert(!(s->regs[R_STAT] & STAT_RX_EVT));
|
||||
|
||||
s->regs[R_STAT] |= STAT_RX_EVT;
|
||||
s->regs[R_RXTX] = *buf;
|
||||
|
||||
uart_update_irq(s);
|
||||
}
|
||||
|
||||
static int uart_can_rx(void *opaque)
|
||||
{
|
||||
MilkymistUartState *s = opaque;
|
||||
|
||||
return !(s->regs[R_STAT] & STAT_RX_EVT);
|
||||
}
|
||||
|
||||
static void uart_event(void *opaque, QEMUChrEvent event)
|
||||
{
|
||||
}
|
||||
|
||||
static void milkymist_uart_reset(DeviceState *d)
|
||||
{
|
||||
MilkymistUartState *s = MILKYMIST_UART(d);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < R_MAX; i++) {
|
||||
s->regs[i] = 0;
|
||||
}
|
||||
|
||||
/* THRE is always set */
|
||||
s->regs[R_STAT] = STAT_THRE;
|
||||
}
|
||||
|
||||
static void milkymist_uart_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MilkymistUartState *s = MILKYMIST_UART(dev);
|
||||
|
||||
qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
|
||||
uart_event, NULL, s, NULL, true);
|
||||
}
|
||||
|
||||
static void milkymist_uart_init(Object *obj)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
MilkymistUartState *s = MILKYMIST_UART(obj);
|
||||
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
|
||||
memory_region_init_io(&s->regs_region, OBJECT(s), &uart_mmio_ops, s,
|
||||
"milkymist-uart", R_MAX * 4);
|
||||
sysbus_init_mmio(sbd, &s->regs_region);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_milkymist_uart = {
|
||||
.name = "milkymist-uart",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, MilkymistUartState, R_MAX),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property milkymist_uart_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", MilkymistUartState, chr),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void milkymist_uart_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = milkymist_uart_realize;
|
||||
dc->reset = milkymist_uart_reset;
|
||||
dc->vmsd = &vmstate_milkymist_uart;
|
||||
device_class_set_props(dc, milkymist_uart_properties);
|
||||
}
|
||||
|
||||
static const TypeInfo milkymist_uart_info = {
|
||||
.name = TYPE_MILKYMIST_UART,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MilkymistUartState),
|
||||
.instance_init = milkymist_uart_init,
|
||||
.class_init = milkymist_uart_class_init,
|
||||
};
|
||||
|
||||
static void milkymist_uart_register_types(void)
|
||||
{
|
||||
type_register_static(&milkymist_uart_info);
|
||||
}
|
||||
|
||||
type_init(milkymist_uart_register_types)
|
||||
@@ -35,23 +35,6 @@ grlib_apbuart_event(int event) "event:%d"
|
||||
grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
|
||||
grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
|
||||
|
||||
# lm32_juart.c
|
||||
lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
|
||||
lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
|
||||
lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
|
||||
lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
|
||||
|
||||
# lm32_uart.c
|
||||
lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
lm32_uart_irq_state(int level) "irq state %d"
|
||||
|
||||
# milkymist-uart.c
|
||||
milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
|
||||
milkymist_uart_raise_irq(void) "Raise IRQ"
|
||||
milkymist_uart_lower_irq(void) "Lower IRQ"
|
||||
|
||||
# escc.c
|
||||
escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
|
||||
escc_get_queue(char channel, int val) "channel %c get 0x%02x"
|
||||
|
||||
@@ -72,10 +72,6 @@ config BLIZZARD
|
||||
config FRAMEBUFFER
|
||||
bool
|
||||
|
||||
config MILKYMIST_TMU2
|
||||
bool
|
||||
depends on OPENGL && X11
|
||||
|
||||
config SM501
|
||||
bool
|
||||
select I2C
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user