Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/arch/rh850/inc/arch/emul.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,24 @@ static inline bool emul_arch_is_bwop(struct emul_access_arch* acc)
static inline uint8_t emul_arch_bwop_emul_acc(struct emul_access_arch* acc, uint8_t cur_val)
{
unsigned long psw = srs_gmpsw_read();
if (cur_val & acc->bit) {
uint8_t bitmask = (uint8_t)(1UL << acc->bit);
if (cur_val & bitmask) {
srs_gmpsw_write(psw & ~PSW_Z);
} else {
srs_gmpsw_write(psw | PSW_Z);
}
uint8_t val = 0;
switch (acc->bwop) {
case EMUL_ARCH_BWOP_SET1:
val = (uint8_t)(cur_val | acc->bit);
val = (uint8_t)(cur_val | bitmask);
;
break;
case EMUL_ARCH_BWOP_NOT1:
val = (uint8_t)(cur_val ^ acc->bit);
val = (uint8_t)(cur_val ^ bitmask);
;
break;
case EMUL_ARCH_BWOP_CLR1:
val = (uint8_t)(cur_val & (uint8_t)~acc->bit);
val = (uint8_t)(cur_val & (uint8_t)~bitmask);
;
break;
/* TST1 only modifies the PSW.Z flag */
Expand Down
26 changes: 8 additions & 18 deletions src/arch/rh850/vipir.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,17 @@ static bool vipir_emul_handler(struct emul_access* acc)
}

if ((chan_idx != IPI_HYP_IRQ_ID) && (tgt_reg != NULL)) {
if (acc->write) {
unsigned long val;
if (emul_arch_is_bwop(&acc->arch)) {
val = (uint8_t)emul_arch_bwop_emul_acc(&acc->arch, *tgt_reg);
} else {
val = (uint8_t)vcpu_readreg(vcpu, acc->reg);
}
val = (uint8_t)vm_translate_to_pcpu_mask(vm, val, vm->cpu_num);
if (emul_arch_is_bwop(&acc->arch)) {
acc->arch.bit = (uint8_t)vm_translate_to_pcpuid(vm, acc->arch.bit);
*tgt_reg = emul_arch_bwop_emul_acc(&acc->arch, *tgt_reg);
} else if (acc->write) {
unsigned long val = (uint8_t)vcpu_readreg(vcpu, acc->reg);
val = (uint8_t)vm_translate_to_pcpu_mask(vm, val, PLAT_CPU_NUM);
*tgt_reg = (uint8_t)((*tgt_reg & ~vm->cpus) | (val & vm->cpus));
} else {
uint8_t val = *tgt_reg;
if (emul_arch_is_bwop(&acc->arch)) {
/* translate vcpu_id bit to pcpu_id bit */
acc->arch.bit =
(uint8_t)vm_translate_to_pcpu_mask(vm, val & acc->arch.bit, vm->cpu_num);
/* invoke emul to update gmpsw.z */
(void)emul_arch_bwop_emul_acc(&acc->arch, val);
} else {
val = (uint8_t)vm_translate_to_pcpu_mask(vm, val, vm->cpu_num);
vcpu_writereg(vcpu, acc->reg, val);
}
val = (uint8_t)vm_translate_to_vcpu_mask(vm, val, PLAT_CPU_NUM);
vcpu_writereg(vcpu, acc->reg, val);
}
}

Expand Down
Loading