Ejemplo n.º 1
0
void cpu_vcpu_dump_user_reg(struct vmm_vcpu * vcpu, arch_regs_t * regs)
{
	u32 ite;
	vmm_printf("  Core Registers\n");
	vmm_printf("    SP=0x%08x       LR=0x%08x       PC=0x%08x\n",
		   regs->sp, regs->lr, regs->pc);
	vmm_printf("    CPSR=0x%08x     \n", 
				cpu_vcpu_cpsr_retrieve(vcpu, regs));
	vmm_printf("  General Purpose Registers");
	for (ite = 0; ite < CPU_GPR_COUNT; ite++) {
		if (ite % 3 == 0)
			vmm_printf("\n");
		vmm_printf("    R%02d=0x%08x  ", ite, regs->gpr[ite]);
	}
	vmm_printf("\n");
}
Ejemplo n.º 2
0
int arch_vcpu_irq_execute(struct vmm_vcpu * vcpu,
			 arch_regs_t * regs, 
			 u32 irq_no, u32 reason)
{
	u32 old_cpsr, new_cpsr, new_mode, new_flags, lr_off;
	virtual_addr_t new_pc;

	old_cpsr = cpu_vcpu_cpsr_retrieve(vcpu, regs);
	new_cpsr = old_cpsr;
	new_flags = 0x0;

	switch(irq_no) {
	case CPU_RESET_IRQ:
		new_mode = CPSR_MODE_SUPERVISOR;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		new_flags |= CPSR_FIQ_DISABLED;
		lr_off = 0;
		break;
	case CPU_UNDEF_INST_IRQ:
		new_mode = CPSR_MODE_UNDEFINED;
		new_flags |= CPSR_IRQ_DISABLED;
		lr_off = 4;
		break;
	case CPU_SOFT_IRQ:
		new_mode = CPSR_MODE_SUPERVISOR;
		new_flags |= CPSR_IRQ_DISABLED;
		lr_off = 4;
		break;
	case CPU_PREFETCH_ABORT_IRQ:
		new_mode = CPSR_MODE_ABORT;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		lr_off = 4;
		break;
	case CPU_DATA_ABORT_IRQ:
		new_mode = CPSR_MODE_ABORT;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		lr_off = 8;
		break;
	case CPU_NOT_USED_IRQ:
		new_mode = CPSR_MODE_SUPERVISOR;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		new_flags |= CPSR_FIQ_DISABLED;
		lr_off = 0;
		break;
	case CPU_EXTERNAL_IRQ:
		if (old_cpsr & CPSR_IRQ_DISABLED) {
			return VMM_EFAIL;
		}
		new_mode = CPSR_MODE_IRQ;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		lr_off = 4;
		break;
	case CPU_EXTERNAL_FIQ:
		if (old_cpsr & CPSR_FIQ_DISABLED) {
			return VMM_EFAIL;
		}
		new_mode = CPSR_MODE_FIQ;
		new_flags |= CPSR_ASYNC_ABORT_DISABLED;
		new_flags |= CPSR_IRQ_DISABLED;
		new_flags |= CPSR_FIQ_DISABLED;
		lr_off = 4;
		break;
	default:
		return VMM_EFAIL;
		break;
	};

	new_pc = cpu_vcpu_cp15_vector_addr(vcpu, irq_no);
	new_cpsr &= ~CPSR_MODE_MASK;
	new_cpsr |= (new_mode | new_flags);
	new_cpsr &= ~(CPSR_IT1_MASK | CPSR_IT2_MASK);
	if (arm_feature(vcpu, ARM_FEATURE_V4T)) {
		if (arm_priv(vcpu)->cp15.c1_sctlr & (1 << 30)) {
			new_cpsr |= CPSR_THUMB_ENABLED;
		} else {
			new_cpsr &= ~CPSR_THUMB_ENABLED;
		}
	}
	cpu_vcpu_cpsr_update(vcpu, regs, new_cpsr, CPSR_ALLBITS_MASK);
	cpu_vcpu_spsr_update(vcpu, old_cpsr, CPSR_ALLBITS_MASK);
	regs->lr = regs->pc + lr_off;
	regs->pc = new_pc;

	return VMM_OK;
}