m68k pull request 20201212

Fix for Coverity CID 1421883
 Fix some comment spelling errors
 Add m68k vmstate
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAl/VA9QSHGxhdXJlbnRA
 dml2aWVyLmV1AAoJEPMMOL0/L748Mh0P/j8JukKO0H57zx57h9r4A/1uGzZN/Sdl
 ejlHYDMK/DnHTgtUpZl8kWm/OwHDGrQkh0trunVyEbgNXmwad+4Vi1yQO8yMbP41
 DENriBHag5ceh5lPZXMFrMu9w90bpBbxQGqpvr/rgCp5PCqAzlEIxQEVDlY9lCzy
 4dvQsKEnjy10OA0g5bC9R6StErwFKrzuh2QxrPF7QL8O1JOhwwKjdaoNDDSQQP4P
 pCQO4L0YbMGOdXrSEifg549j9C1uxPavm/r8c5V2OP65aLf0pSQFlj8sHc3kV/2X
 tfPlUJkNmU8xub2+1+vtZ4MRhcsE8LS0nYzXDWaC2KQPNQLJ1kZfq8ZtVlV2QVip
 Scg6NTniFdYlHNwAQaAadilYrLBrLQJWvOhYpQ3uU569b3EpqoFIn+Sq41Fxsh5h
 9itAPQRCR77igQG9myOjah0VGr7pwm5arGpdIWhJbOcTUAPMZtKKDikAgV+SBUPC
 tgPr6fVcyDby7IG6RyO+9Peab/cWVxdfCOEYgtqZAvui70v2d0+v7LZwdzwKSX/Y
 F5E+kSS8lip5DW26ul8f5XvEezR+4ybzIUsX1+SPtdKijo/xhlHiiEW3iV1cRi7c
 G6RqGBwH6Y+efiSPHCoIdpCodWuWXlJykIsuKiEdc3Z37kQAcb/lWIbT/3/yzWfJ
 WraG+L2fh0Jw
 =czfA
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-6.0-pull-request' into staging

m68k pull request 20201212

Fix for Coverity CID 1421883
Fix some comment spelling errors
Add m68k vmstate

# gpg: Signature made Sat 12 Dec 2020 17:54:28 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/m68k-for-6.0-pull-request:
  m68k: fix some comment spelling errors
  target/m68k: Add vmstate definition for M68kCPU
  target/m68k: remove useless qregs array
  hw/m68k/q800.c: Make the GLUE chip an actual QOM device
  hw/m68k/q800: Don't connect two qemu_irqs directly to the same input

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-12-12 18:33:46 +00:00
commit 17584289af
6 changed files with 286 additions and 31 deletions

View File

@ -22,3 +22,4 @@ config Q800
select ESCC
select ESP
select DP8393X
select OR_IRQ

View File

@ -29,6 +29,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/irq.h"
#include "hw/or-irq.h"
#include "elf.h"
#include "hw/loader.h"
#include "ui/console.h"
@ -47,6 +48,7 @@
#include "sysemu/qtest.h"
#include "sysemu/runstate.h"
#include "sysemu/reset.h"
#include "migration/vmstate.h"
#define MACROM_ADDR 0x40800000
#define MACROM_SIZE 0x00100000
@ -94,10 +96,14 @@
* CPU.
*/
typedef struct {
#define TYPE_GLUE "q800-glue"
OBJECT_DECLARE_SIMPLE_TYPE(GLUEState, GLUE)
struct GLUEState {
SysBusDevice parent_obj;
M68kCPU *cpu;
uint8_t ipr;
} GLUEState;
};
static void GLUE_set_irq(void *opaque, int irq, int level)
{
@ -119,6 +125,58 @@ static void GLUE_set_irq(void *opaque, int irq, int level)
m68k_set_irq_level(s->cpu, 0, 0);
}
static void glue_reset(DeviceState *dev)
{
GLUEState *s = GLUE(dev);
s->ipr = 0;
}
static const VMStateDescription vmstate_glue = {
.name = "q800-glue",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT8(ipr, GLUEState),
VMSTATE_END_OF_LIST(),
},
};
/*
* If the m68k CPU implemented its inbound irq lines as GPIO lines
* rather than via the m68k_set_irq_level() function we would not need
* this cpu link property and could instead provide outbound IRQ lines
* that the board could wire up to the CPU.
*/
static Property glue_properties[] = {
DEFINE_PROP_LINK("cpu", GLUEState, cpu, TYPE_M68K_CPU, M68kCPU *),
DEFINE_PROP_END_OF_LIST(),
};
static void glue_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
qdev_init_gpio_in(dev, GLUE_set_irq, 8);
}
static void glue_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_glue;
dc->reset = glue_reset;
device_class_set_props(dc, glue_properties);
}
static const TypeInfo glue_info = {
.name = TYPE_GLUE,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GLUEState),
.instance_init = glue_init,
.class_init = glue_class_init,
};
static void main_cpu_reset(void *opaque)
{
M68kCPU *cpu = opaque;
@ -173,13 +231,13 @@ static void q800_init(MachineState *machine)
CPUState *cs;
DeviceState *dev;
DeviceState *via_dev;
DeviceState *escc_orgate;
SysBusESPState *sysbus_esp;
ESPState *esp;
SysBusDevice *sysbus;
BusState *adb_bus;
NubusBus *nubus;
GLUEState *irq;
qemu_irq *pic;
DeviceState *glue;
DriveInfo *dinfo;
linux_boot = (kernel_filename != NULL);
@ -213,10 +271,9 @@ static void q800_init(MachineState *machine)
}
/* IRQ Glue */
irq = g_new0(GLUEState, 1);
irq->cpu = cpu;
pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
glue = qdev_new(TYPE_GLUE);
object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort);
sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal);
/* VIA */
@ -228,8 +285,10 @@ static void q800_init(MachineState *machine)
sysbus = SYS_BUS_DEVICE(via_dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_mmio_map(sysbus, 0, VIA_BASE);
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0, pic[0]);
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1, pic[1]);
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
qdev_get_gpio_in(glue, 0));
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1,
qdev_get_gpio_in(glue, 1));
adb_bus = qdev_get_child_bus(via_dev, "adb.0");
@ -270,7 +329,7 @@ static void q800_init(MachineState *machine)
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_mmio_map(sysbus, 0, SONIC_BASE);
sysbus_mmio_map(sysbus, 1, SONIC_PROM_BASE);
sysbus_connect_irq(sysbus, 0, pic[2]);
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 2));
/* SCC */
@ -285,8 +344,14 @@ static void q800_init(MachineState *machine)
qdev_prop_set_uint32(dev, "chnAtype", 0);
sysbus = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_connect_irq(sysbus, 0, pic[3]);
sysbus_connect_irq(sysbus, 1, pic[3]);
/* Logically OR both its IRQs together */
escc_orgate = DEVICE(object_new(TYPE_OR_IRQ));
object_property_set_int(OBJECT(escc_orgate), "num-lines", 2, &error_fatal);
qdev_realize_and_unref(escc_orgate, NULL, &error_fatal);
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
qdev_connect_gpio_out(DEVICE(escc_orgate), 0, qdev_get_gpio_in(glue, 3));
sysbus_mmio_map(sysbus, 0, SCC_BASE);
/* SCSI */
@ -448,6 +513,7 @@ static const TypeInfo q800_machine_typeinfo = {
static void q800_machine_register_types(void)
{
type_register_static(&q800_machine_typeinfo);
type_register_static(&glue_info);
}
type_init(q800_machine_register_types)

View File

@ -260,10 +260,198 @@ static void m68k_cpu_initfn(Object *obj)
cpu_set_cpustate_pointers(cpu);
}
#if defined(CONFIG_SOFTMMU)
static bool fpu_needed(void *opaque)
{
M68kCPU *s = opaque;
return m68k_feature(&s->env, M68K_FEATURE_CF_FPU) ||
m68k_feature(&s->env, M68K_FEATURE_FPU);
}
typedef struct m68k_FPReg_tmp {
FPReg *parent;
uint64_t tmp_mant;
uint16_t tmp_exp;
} m68k_FPReg_tmp;
static void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f)
{
CPU_LDoubleU temp;
temp.d = f;
*pmant = temp.l.lower;
*pexp = temp.l.upper;
}
static floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper)
{
CPU_LDoubleU temp;
temp.l.upper = upper;
temp.l.lower = mant;
return temp.d;
}
static int freg_pre_save(void *opaque)
{
m68k_FPReg_tmp *tmp = opaque;
cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d);
return 0;
}
static int freg_post_load(void *opaque, int version)
{
m68k_FPReg_tmp *tmp = opaque;
tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp);
return 0;
}
static const VMStateDescription vmstate_freg_tmp = {
.name = "freg_tmp",
.post_load = freg_post_load,
.pre_save = freg_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT64(tmp_mant, m68k_FPReg_tmp),
VMSTATE_UINT16(tmp_exp, m68k_FPReg_tmp),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_freg = {
.name = "freg",
.fields = (VMStateField[]) {
VMSTATE_WITH_TMP(FPReg, m68k_FPReg_tmp, vmstate_freg_tmp),
VMSTATE_END_OF_LIST()
}
};
static int fpu_post_load(void *opaque, int version)
{
M68kCPU *s = opaque;
cpu_m68k_restore_fp_status(&s->env);
return 0;
}
const VMStateDescription vmmstate_fpu = {
.name = "cpu/fpu",
.version_id = 1,
.minimum_version_id = 1,
.needed = fpu_needed,
.post_load = fpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(env.fpcr, M68kCPU),
VMSTATE_UINT32(env.fpsr, M68kCPU),
VMSTATE_STRUCT_ARRAY(env.fregs, M68kCPU, 8, 0, vmstate_freg, FPReg),
VMSTATE_STRUCT(env.fp_result, M68kCPU, 0, vmstate_freg, FPReg),
VMSTATE_END_OF_LIST()
}
};
static bool cf_spregs_needed(void *opaque)
{
M68kCPU *s = opaque;
return m68k_feature(&s->env, M68K_FEATURE_CF_ISA_A);
}
const VMStateDescription vmstate_cf_spregs = {
.name = "cpu/cf_spregs",
.version_id = 1,
.minimum_version_id = 1,
.needed = cf_spregs_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT64_ARRAY(env.macc, M68kCPU, 4),
VMSTATE_UINT32(env.macsr, M68kCPU),
VMSTATE_UINT32(env.mac_mask, M68kCPU),
VMSTATE_UINT32(env.rambar0, M68kCPU),
VMSTATE_UINT32(env.mbar, M68kCPU),
VMSTATE_END_OF_LIST()
}
};
static bool cpu_68040_mmu_needed(void *opaque)
{
M68kCPU *s = opaque;
return m68k_feature(&s->env, M68K_FEATURE_M68040);
}
const VMStateDescription vmstate_68040_mmu = {
.name = "cpu/68040_mmu",
.version_id = 1,
.minimum_version_id = 1,
.needed = cpu_68040_mmu_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(env.mmu.ar, M68kCPU),
VMSTATE_UINT32(env.mmu.ssw, M68kCPU),
VMSTATE_UINT16(env.mmu.tcr, M68kCPU),
VMSTATE_UINT32(env.mmu.urp, M68kCPU),
VMSTATE_UINT32(env.mmu.srp, M68kCPU),
VMSTATE_BOOL(env.mmu.fault, M68kCPU),
VMSTATE_UINT32_ARRAY(env.mmu.ttr, M68kCPU, 4),
VMSTATE_UINT32(env.mmu.mmusr, M68kCPU),
VMSTATE_END_OF_LIST()
}
};
static bool cpu_68040_spregs_needed(void *opaque)
{
M68kCPU *s = opaque;
return m68k_feature(&s->env, M68K_FEATURE_M68040);
}
const VMStateDescription vmstate_68040_spregs = {
.name = "cpu/68040_spregs",
.version_id = 1,
.minimum_version_id = 1,
.needed = cpu_68040_spregs_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(env.vbr, M68kCPU),
VMSTATE_UINT32(env.cacr, M68kCPU),
VMSTATE_UINT32(env.sfc, M68kCPU),
VMSTATE_UINT32(env.dfc, M68kCPU),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_m68k_cpu = {
.name = "cpu",
.unmigratable = 1,
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.dregs, M68kCPU, 8),
VMSTATE_UINT32_ARRAY(env.aregs, M68kCPU, 8),
VMSTATE_UINT32(env.pc, M68kCPU),
VMSTATE_UINT32(env.sr, M68kCPU),
VMSTATE_INT32(env.current_sp, M68kCPU),
VMSTATE_UINT32_ARRAY(env.sp, M68kCPU, 3),
VMSTATE_UINT32(env.cc_op, M68kCPU),
VMSTATE_UINT32(env.cc_x, M68kCPU),
VMSTATE_UINT32(env.cc_n, M68kCPU),
VMSTATE_UINT32(env.cc_v, M68kCPU),
VMSTATE_UINT32(env.cc_c, M68kCPU),
VMSTATE_UINT32(env.cc_z, M68kCPU),
VMSTATE_INT32(env.pending_vector, M68kCPU),
VMSTATE_INT32(env.pending_level, M68kCPU),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmmstate_fpu,
&vmstate_cf_spregs,
&vmstate_68040_mmu,
&vmstate_68040_spregs,
NULL
},
};
#endif
static void m68k_cpu_class_init(ObjectClass *c, void *data)
{
@ -287,13 +475,12 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
#if defined(CONFIG_SOFTMMU)
cc->do_transaction_failed = m68k_cpu_transaction_failed;
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_m68k_cpu;
#endif
cc->disas_set_info = m68k_cpu_disas_set_info;
cc->tcg_initialize = m68k_tcg_init;
cc->gdb_num_core_regs = 18;
dc->vmsd = &vmstate_m68k_cpu;
}
static void m68k_cpu_class_init_cf_core(ObjectClass *c, void *data)

View File

@ -33,8 +33,6 @@
#define OS_PACKED 6
#define OS_UNSIZED 7
#define MAX_QREGS 32
#define EXCP_ACCESS 2 /* Access (MMU) error. */
#define EXCP_ADDRESS 3 /* Address error. */
#define EXCP_ILLEGAL 4 /* Illegal instruction. */
@ -139,8 +137,6 @@ typedef struct CPUM68KState {
int pending_vector;
int pending_level;
uint32_t qregs[MAX_QREGS];
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
@ -183,6 +179,7 @@ int cpu_m68k_signal_handler(int host_signum, void *pinfo,
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
void cpu_m68k_set_sr(CPUM68KState *env, uint32_t);
void cpu_m68k_restore_fp_status(CPUM68KState *env);
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);

View File

@ -135,10 +135,8 @@ static void restore_rounding_mode(CPUM68KState *env)
}
}
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val)
void cpu_m68k_restore_fp_status(CPUM68KState *env)
{
env->fpcr = val & 0xffff;
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
cf_restore_precision_mode(env);
} else {
@ -147,6 +145,12 @@ void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val)
restore_rounding_mode(env);
}
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val)
{
env->fpcr = val & 0xffff;
cpu_m68k_restore_fp_status(env);
}
void HELPER(fitrunc)(CPUM68KState *env, FPReg *res, FPReg *val)
{
FloatRoundMode rounding_mode = get_float_rounding_mode(&env->fp_status);

View File

@ -438,7 +438,7 @@ static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp)
}
/*
* Handle a base + index + displacement effective addresss.
* Handle a base + index + displacement effective address.
* A NULL_QREG base means pc-relative.
*/
static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
@ -1696,7 +1696,7 @@ static void bcd_add(TCGv dest, TCGv src)
/*
* t1 = (src + 0x066) + dest + X
* = result with some possible exceding 0x6
* = result with some possible exceeding 0x6
*/
t0 = tcg_const_i32(0x066);
@ -1706,7 +1706,7 @@ static void bcd_add(TCGv dest, TCGv src)
tcg_gen_add_i32(t1, t0, dest);
tcg_gen_add_i32(t1, t1, QREG_CC_X);
/* we will remove exceding 0x6 where there is no carry */
/* we will remove exceeding 0x6 where there is no carry */
/*
* t0 = (src + 0x0066) ^ dest
@ -1736,7 +1736,7 @@ static void bcd_add(TCGv dest, TCGv src)
tcg_temp_free(t0);
/*
* remove the exceding 0x6
* remove the exceeding 0x6
* for digits that have not generated a carry
*/
@ -2638,7 +2638,7 @@ DISAS_INSN(negx)
gen_flush_flags(s); /* compute old Z */
/*
* Perform substract with borrow.
* Perform subtract with borrow.
* (X, N) = -(src + X);
*/
@ -2653,7 +2653,7 @@ DISAS_INSN(negx)
/*
* Compute signed-overflow for negation. The normal formula for
* subtraction is (res ^ src) & (src ^ dest), but with dest==0
* this simplies to res & src.
* this simplifies to res & src.
*/
tcg_gen_and_i32(QREG_CC_V, QREG_CC_N, src);
@ -3159,7 +3159,7 @@ static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize)
gen_flush_flags(s); /* compute old Z */
/*
* Perform substract with borrow.
* Perform subtract with borrow.
* (X, N) = dest - (src + X);
*/
@ -3169,7 +3169,7 @@ static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize)
gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
/* Compute signed-overflow for substract. */
/* Compute signed-overflow for subtract. */
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, dest);
tcg_gen_xor_i32(tmp, dest, src);