Commit d6d549b2 authored by Alexander Graf's avatar Alexander Graf Committed by Avi Kivity
Browse files

KVM: PPC: Add Gekko SPRs



The Gekko has some SPR values that differ from other PPC core values and
also some additional ones.

Let's add support for them in our mfspr/mtspr emulator.

Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 3c402a75
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ struct kvmppc_vcpu_book3s {
	struct kvmppc_bat ibat[8];
	struct kvmppc_bat dbat[8];
	u64 hid[6];
	u64 gqr[8];
	int slb_nr;
	u64 sdr1;
	u64 dsisr;
+10 −0
Original line number Diff line number Diff line
@@ -293,10 +293,12 @@
#define HID1_ABE	(1<<10)		/* 7450 Address Broadcast Enable */
#define HID1_PS		(1<<16)		/* 750FX PLL selection */
#define SPRN_HID2	0x3F8		/* Hardware Implementation Register 2 */
#define SPRN_HID2_GEKKO	0x398		/* Gekko HID2 Register */
#define SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
#define SPRN_IABR2	0x3FA		/* 83xx */
#define SPRN_IBCR	0x135		/* 83xx Insn Breakpoint Control Reg */
#define SPRN_HID4	0x3F4		/* 970 HID4 */
#define SPRN_HID4_GEKKO	0x3F3		/* Gekko HID4 */
#define SPRN_HID5	0x3F6		/* 970 HID5 */
#define SPRN_HID6	0x3F9	/* BE HID 6 */
#define   HID6_LB	(0x0F<<12) /* Concurrent Large Page Modes */
@@ -465,6 +467,14 @@
#define SPRN_VRSAVE	0x100	/* Vector Register Save Register */
#define SPRN_XER	0x001	/* Fixed Point Exception Register */

#define SPRN_MMCR0_GEKKO 0x3B8 /* Gekko Monitor Mode Control Register 0 */
#define SPRN_MMCR1_GEKKO 0x3BC /* Gekko Monitor Mode Control Register 1 */
#define SPRN_PMC1_GEKKO  0x3B9 /* Gekko Performance Monitor Control 1 */
#define SPRN_PMC2_GEKKO  0x3BA /* Gekko Performance Monitor Control 2 */
#define SPRN_PMC3_GEKKO  0x3BD /* Gekko Performance Monitor Control 3 */
#define SPRN_PMC4_GEKKO  0x3BE /* Gekko Performance Monitor Control 4 */
#define SPRN_WPAR_GEKKO  0x399 /* Gekko Write Pipe Address Register */

#define SPRN_SCOMC	0x114	/* SCOM Access Control */
#define SPRN_SCOMD	0x115	/* SCOM Access DATA */

+70 −0
Original line number Diff line number Diff line
@@ -42,6 +42,15 @@
/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */
#define OP_31_XOP_DCBZ		1010

#define SPRN_GQR0		912
#define SPRN_GQR1		913
#define SPRN_GQR2		914
#define SPRN_GQR3		915
#define SPRN_GQR4		916
#define SPRN_GQR5		917
#define SPRN_GQR6		918
#define SPRN_GQR7		919

int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                           unsigned int inst, int *advance)
{
@@ -268,7 +277,29 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
	case SPRN_HID2:
		to_book3s(vcpu)->hid[2] = spr_val;
		break;
	case SPRN_HID2_GEKKO:
		to_book3s(vcpu)->hid[2] = spr_val;
		/* HID2.PSE controls paired single on gekko */
		switch (vcpu->arch.pvr) {
		case 0x00080200:	/* lonestar 2.0 */
		case 0x00088202:	/* lonestar 2.2 */
		case 0x70000100:	/* gekko 1.0 */
		case 0x00080100:	/* gekko 2.0 */
		case 0x00083203:	/* gekko 2.3a */
		case 0x00083213:	/* gekko 2.3b */
		case 0x00083204:	/* gekko 2.4 */
		case 0x00083214:	/* gekko 2.4e (8SE) - retail HW2 */
			if (spr_val & (1 << 29)) { /* HID2.PSE */
				vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE;
				kvmppc_giveup_ext(vcpu, MSR_FP);
			} else {
				vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE;
			}
			break;
		}
		break;
	case SPRN_HID4:
	case SPRN_HID4_GEKKO:
		to_book3s(vcpu)->hid[4] = spr_val;
		break;
	case SPRN_HID5:
@@ -278,12 +309,30 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
		    (mfmsr() & MSR_HV))
			vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
		break;
	case SPRN_GQR0:
	case SPRN_GQR1:
	case SPRN_GQR2:
	case SPRN_GQR3:
	case SPRN_GQR4:
	case SPRN_GQR5:
	case SPRN_GQR6:
	case SPRN_GQR7:
		to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val;
		break;
	case SPRN_ICTC:
	case SPRN_THRM1:
	case SPRN_THRM2:
	case SPRN_THRM3:
	case SPRN_CTRLF:
	case SPRN_CTRLT:
	case SPRN_L2CR:
	case SPRN_MMCR0_GEKKO:
	case SPRN_MMCR1_GEKKO:
	case SPRN_PMC1_GEKKO:
	case SPRN_PMC2_GEKKO:
	case SPRN_PMC3_GEKKO:
	case SPRN_PMC4_GEKKO:
	case SPRN_WPAR_GEKKO:
		break;
	default:
		printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
@@ -320,19 +369,40 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]);
		break;
	case SPRN_HID2:
	case SPRN_HID2_GEKKO:
		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]);
		break;
	case SPRN_HID4:
	case SPRN_HID4_GEKKO:
		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]);
		break;
	case SPRN_HID5:
		kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]);
		break;
	case SPRN_GQR0:
	case SPRN_GQR1:
	case SPRN_GQR2:
	case SPRN_GQR3:
	case SPRN_GQR4:
	case SPRN_GQR5:
	case SPRN_GQR6:
	case SPRN_GQR7:
		kvmppc_set_gpr(vcpu, rt,
			       to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]);
		break;
	case SPRN_THRM1:
	case SPRN_THRM2:
	case SPRN_THRM3:
	case SPRN_CTRLF:
	case SPRN_CTRLT:
	case SPRN_L2CR:
	case SPRN_MMCR0_GEKKO:
	case SPRN_MMCR1_GEKKO:
	case SPRN_PMC1_GEKKO:
	case SPRN_PMC2_GEKKO:
	case SPRN_PMC3_GEKKO:
	case SPRN_PMC4_GEKKO:
	case SPRN_WPAR_GEKKO:
		kvmppc_set_gpr(vcpu, rt, 0);
		break;
	default: