mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (31 commits) PPC: linux-user: Calculate context pointer explicitly target-ppc: Error out for -cpu host on unknown PVR target-ppc: Slim conversion of model definitions to QOM subclasses PPC: Bring EPR support closer to reality PPC: KVM: set has-idle in guest device tree kvm: Update kernel headers openpic: fix CTPR and de-assertion of interrupts openpic: move IACK to its own function openpic: IRQ_check: search the queue a word at a time openpic: fix sense and priority bits openpic: add some bounds checking for IRQ numbers openpic: use standard bitmap operations Revert "openpic: Accelerate pending irq search" openpic: always call IRQ_check from IRQ_get_next openpic/fsl: critical interrupts ignore mask before v4.1 openpic: make ctpr signed openpic: rework critical interrupt support openpic: make register names correspond better with hw docs ppc/booke: fix crit/mcheck/debug exceptions openpic: lower interrupt when reading the MSI register ...
This commit is contained in:
+640
-392
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -225,6 +225,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
|
||||
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
|
||||
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
|
||||
hypercall, sizeof(hypercall));
|
||||
/* if KVM supports the idle hcall, set property indicating this */
|
||||
if (kvmppc_get_hasidle(env)) {
|
||||
qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create CPU nodes */
|
||||
@@ -493,8 +497,8 @@ void ppce500_init(PPCE500Params *params)
|
||||
irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
|
||||
irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
|
||||
env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
|
||||
env->mpic_cpu_base = MPC8544_CCSRBAR_BASE +
|
||||
MPC8544_MPIC_REGS_OFFSET + 0x20000;
|
||||
env->mpic_iack = MPC8544_CCSRBAR_BASE +
|
||||
MPC8544_MPIC_REGS_OFFSET + 0x200A0;
|
||||
|
||||
ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
|
||||
|
||||
|
||||
@@ -237,6 +237,17 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val)
|
||||
|
||||
}
|
||||
|
||||
static void ppc_booke_timer_reset_handle(void *opaque)
|
||||
{
|
||||
PowerPCCPU *cpu = opaque;
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
env->spr[SPR_BOOKE_TSR] = 0;
|
||||
env->spr[SPR_BOOKE_TCR] = 0;
|
||||
|
||||
booke_update_irq(cpu);
|
||||
}
|
||||
|
||||
void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
|
||||
{
|
||||
ppc_tb_t *tb_env;
|
||||
@@ -257,4 +268,6 @@ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
|
||||
qemu_new_timer_ns(vm_clock, &booke_fit_cb, cpu);
|
||||
booke_timer->wdt_timer =
|
||||
qemu_new_timer_ns(vm_clock, &booke_wdt_cb, cpu);
|
||||
|
||||
qemu_register_reset(ppc_booke_timer_reset_handle, cpu);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* ePAPR hcall interface
|
||||
*
|
||||
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Author: Timur Tabi <timur@freescale.com>
|
||||
*
|
||||
* This file is provided under a dual BSD/GPL license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Freescale Semiconductor nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") as published by the Free Software
|
||||
* Foundation, either version 2 of that License or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_POWERPC_EPAPR_HCALLS_H
|
||||
#define _ASM_POWERPC_EPAPR_HCALLS_H
|
||||
|
||||
#define EV_BYTE_CHANNEL_SEND 1
|
||||
#define EV_BYTE_CHANNEL_RECEIVE 2
|
||||
#define EV_BYTE_CHANNEL_POLL 3
|
||||
#define EV_INT_SET_CONFIG 4
|
||||
#define EV_INT_GET_CONFIG 5
|
||||
#define EV_INT_SET_MASK 6
|
||||
#define EV_INT_GET_MASK 7
|
||||
#define EV_INT_IACK 9
|
||||
#define EV_INT_EOI 10
|
||||
#define EV_INT_SEND_IPI 11
|
||||
#define EV_INT_SET_TASK_PRIORITY 12
|
||||
#define EV_INT_GET_TASK_PRIORITY 13
|
||||
#define EV_DOORBELL_SEND 14
|
||||
#define EV_MSGSND 15
|
||||
#define EV_IDLE 16
|
||||
|
||||
/* vendor ID: epapr */
|
||||
#define EV_LOCAL_VENDOR_ID 0 /* for private use */
|
||||
#define EV_EPAPR_VENDOR_ID 1
|
||||
#define EV_FSL_VENDOR_ID 2 /* Freescale Semiconductor */
|
||||
#define EV_IBM_VENDOR_ID 3 /* IBM */
|
||||
#define EV_GHS_VENDOR_ID 4 /* Green Hills Software */
|
||||
#define EV_ENEA_VENDOR_ID 5 /* Enea */
|
||||
#define EV_WR_VENDOR_ID 6 /* Wind River Systems */
|
||||
#define EV_AMCC_VENDOR_ID 7 /* Applied Micro Circuits */
|
||||
#define EV_KVM_VENDOR_ID 42 /* KVM */
|
||||
|
||||
/* The max number of bytes that a byte channel can send or receive per call */
|
||||
#define EV_BYTE_CHANNEL_MAX_BYTES 16
|
||||
|
||||
|
||||
#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
|
||||
#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num)
|
||||
|
||||
/* epapr return codes */
|
||||
#define EV_SUCCESS 0
|
||||
#define EV_EPERM 1 /* Operation not permitted */
|
||||
#define EV_ENOENT 2 /* Entry Not Found */
|
||||
#define EV_EIO 3 /* I/O error occured */
|
||||
#define EV_EAGAIN 4 /* The operation had insufficient
|
||||
* resources to complete and should be
|
||||
* retried
|
||||
*/
|
||||
#define EV_ENOMEM 5 /* There was insufficient memory to
|
||||
* complete the operation */
|
||||
#define EV_EFAULT 6 /* Bad guest address */
|
||||
#define EV_ENODEV 7 /* No such device */
|
||||
#define EV_EINVAL 8 /* An argument supplied to the hcall
|
||||
was out of range or invalid */
|
||||
#define EV_INTERNAL 9 /* An internal error occured */
|
||||
#define EV_CONFIG 10 /* A configuration error was detected */
|
||||
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
|
||||
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
|
||||
#define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */
|
||||
|
||||
#endif /* _ASM_POWERPC_EPAPR_HCALLS_H */
|
||||
@@ -221,6 +221,12 @@ struct kvm_sregs {
|
||||
|
||||
__u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */
|
||||
__u32 dbcr[3];
|
||||
/*
|
||||
* iac/dac registers are 64bit wide, while this API
|
||||
* interface provides only lower 32 bits on 64 bit
|
||||
* processors. ONE_REG interface is added for 64bit
|
||||
* iac/dac registers.
|
||||
*/
|
||||
__u32 iac[4];
|
||||
__u32 dac[2];
|
||||
__u32 dvc[2];
|
||||
@@ -325,6 +331,86 @@ struct kvm_book3e_206_tlb_params {
|
||||
__u32 reserved[8];
|
||||
};
|
||||
|
||||
/* For KVM_PPC_GET_HTAB_FD */
|
||||
struct kvm_get_htab_fd {
|
||||
__u64 flags;
|
||||
__u64 start_index;
|
||||
__u64 reserved[2];
|
||||
};
|
||||
|
||||
/* Values for kvm_get_htab_fd.flags */
|
||||
#define KVM_GET_HTAB_BOLTED_ONLY ((__u64)0x1)
|
||||
#define KVM_GET_HTAB_WRITE ((__u64)0x2)
|
||||
|
||||
/*
|
||||
* Data read on the file descriptor is formatted as a series of
|
||||
* records, each consisting of a header followed by a series of
|
||||
* `n_valid' HPTEs (16 bytes each), which are all valid. Following
|
||||
* those valid HPTEs there are `n_invalid' invalid HPTEs, which
|
||||
* are not represented explicitly in the stream. The same format
|
||||
* is used for writing.
|
||||
*/
|
||||
struct kvm_get_htab_header {
|
||||
__u32 index;
|
||||
__u16 n_valid;
|
||||
__u16 n_invalid;
|
||||
};
|
||||
|
||||
#define KVM_REG_PPC_HIOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1)
|
||||
#define KVM_REG_PPC_IAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2)
|
||||
#define KVM_REG_PPC_IAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3)
|
||||
#define KVM_REG_PPC_IAC3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4)
|
||||
#define KVM_REG_PPC_IAC4 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5)
|
||||
#define KVM_REG_PPC_DAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6)
|
||||
#define KVM_REG_PPC_DAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7)
|
||||
#define KVM_REG_PPC_DABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8)
|
||||
#define KVM_REG_PPC_DSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9)
|
||||
#define KVM_REG_PPC_PURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa)
|
||||
#define KVM_REG_PPC_SPURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb)
|
||||
#define KVM_REG_PPC_DAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc)
|
||||
#define KVM_REG_PPC_DSISR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd)
|
||||
#define KVM_REG_PPC_AMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xe)
|
||||
#define KVM_REG_PPC_UAMOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xf)
|
||||
|
||||
#define KVM_REG_PPC_MMCR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10)
|
||||
#define KVM_REG_PPC_MMCR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11)
|
||||
#define KVM_REG_PPC_MMCRA (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12)
|
||||
|
||||
#define KVM_REG_PPC_PMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18)
|
||||
#define KVM_REG_PPC_PMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19)
|
||||
#define KVM_REG_PPC_PMC3 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1a)
|
||||
#define KVM_REG_PPC_PMC4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1b)
|
||||
#define KVM_REG_PPC_PMC5 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1c)
|
||||
#define KVM_REG_PPC_PMC6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1d)
|
||||
#define KVM_REG_PPC_PMC7 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e)
|
||||
#define KVM_REG_PPC_PMC8 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f)
|
||||
|
||||
/* 32 floating-point registers */
|
||||
#define KVM_REG_PPC_FPR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20)
|
||||
#define KVM_REG_PPC_FPR(n) (KVM_REG_PPC_FPR0 + (n))
|
||||
#define KVM_REG_PPC_FPR31 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f)
|
||||
|
||||
/* 32 VMX/Altivec vector registers */
|
||||
#define KVM_REG_PPC_VR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40)
|
||||
#define KVM_REG_PPC_VR(n) (KVM_REG_PPC_VR0 + (n))
|
||||
#define KVM_REG_PPC_VR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f)
|
||||
|
||||
/* 32 double-width FP registers for VSX */
|
||||
/* High-order halves overlap with FP regs */
|
||||
#define KVM_REG_PPC_VSR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60)
|
||||
#define KVM_REG_PPC_VSR(n) (KVM_REG_PPC_VSR0 + (n))
|
||||
#define KVM_REG_PPC_VSR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f)
|
||||
|
||||
/* FP and vector status/control registers */
|
||||
#define KVM_REG_PPC_FPSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80)
|
||||
#define KVM_REG_PPC_VSCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81)
|
||||
|
||||
/* Virtual processor areas */
|
||||
/* For SLB & DTL, address in high (first) half, length in low half */
|
||||
#define KVM_REG_PPC_VPA_ADDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82)
|
||||
#define KVM_REG_PPC_VPA_SLB (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83)
|
||||
#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
|
||||
|
||||
#define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
|
||||
|
||||
#endif /* __LINUX_KVM_POWERPC_H */
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
* Authors: Hollis Blanchard <hollisb@us.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _UAPI__POWERPC_KVM_PARA_H__
|
||||
#define _UAPI__POWERPC_KVM_PARA_H__
|
||||
#ifndef __POWERPC_KVM_PARA_H__
|
||||
#define __POWERPC_KVM_PARA_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -75,9 +75,10 @@ struct kvm_vcpu_arch_shared {
|
||||
};
|
||||
|
||||
#define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */
|
||||
#define HC_VENDOR_KVM (42 << 16)
|
||||
#define HC_EV_SUCCESS 0
|
||||
#define HC_EV_UNIMPLEMENTED 12
|
||||
|
||||
#define KVM_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num)
|
||||
|
||||
#include <asm/epapr_hcalls.h>
|
||||
|
||||
#define KVM_FEATURE_MAGIC_PAGE 1
|
||||
|
||||
@@ -87,4 +88,4 @@ struct kvm_vcpu_arch_shared {
|
||||
#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1)
|
||||
|
||||
|
||||
#endif /* _UAPI__POWERPC_KVM_PARA_H__ */
|
||||
#endif /* __POWERPC_KVM_PARA_H__ */
|
||||
|
||||
@@ -167,10 +167,15 @@ struct kvm_pit_config {
|
||||
#define KVM_EXIT_OSI 18
|
||||
#define KVM_EXIT_PAPR_HCALL 19
|
||||
#define KVM_EXIT_S390_UCONTROL 20
|
||||
#define KVM_EXIT_WATCHDOG 21
|
||||
|
||||
/* For KVM_EXIT_INTERNAL_ERROR */
|
||||
#define KVM_INTERNAL_ERROR_EMULATION 1
|
||||
#define KVM_INTERNAL_ERROR_SIMUL_EX 2
|
||||
/* Emulate instruction failed. */
|
||||
#define KVM_INTERNAL_ERROR_EMULATION 1
|
||||
/* Encounter unexpected simultaneous exceptions. */
|
||||
#define KVM_INTERNAL_ERROR_SIMUL_EX 2
|
||||
/* Encounter unexpected vm-exit due to delivery event. */
|
||||
#define KVM_INTERNAL_ERROR_DELIVERY_EV 3
|
||||
|
||||
/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
|
||||
struct kvm_run {
|
||||
@@ -477,6 +482,8 @@ struct kvm_ppc_smmu_info {
|
||||
struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
|
||||
};
|
||||
|
||||
#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0)
|
||||
|
||||
#define KVMIO 0xAE
|
||||
|
||||
/* machine type bits, to be used as argument to KVM_CREATE_VM */
|
||||
@@ -626,6 +633,8 @@ struct kvm_ppc_smmu_info {
|
||||
#define KVM_CAP_READONLY_MEM 81
|
||||
#endif
|
||||
#define KVM_CAP_IRQFD_RESAMPLE 82
|
||||
#define KVM_CAP_PPC_BOOKE_WATCHDOG 83
|
||||
#define KVM_CAP_PPC_HTAB_FD 84
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
@@ -848,6 +857,11 @@ struct kvm_s390_ucas_mapping {
|
||||
#define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info)
|
||||
/* Available with KVM_CAP_PPC_ALLOC_HTAB */
|
||||
#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
|
||||
#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
|
||||
/* Available with KVM_CAP_RMA */
|
||||
#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
|
||||
/* Available with KVM_CAP_PPC_HTAB_FD */
|
||||
#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd)
|
||||
|
||||
/*
|
||||
* ioctls for vcpu fds
|
||||
@@ -911,9 +925,6 @@ struct kvm_s390_ucas_mapping {
|
||||
/* Available with KVM_CAP_XCRS */
|
||||
#define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs)
|
||||
#define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs)
|
||||
#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
|
||||
/* Available with KVM_CAP_RMA */
|
||||
#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
|
||||
/* Available with KVM_CAP_SW_TLB */
|
||||
#define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb)
|
||||
/* Available with KVM_CAP_ONE_REG */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _UAPI__LINUX_KVM_PARA_H
|
||||
#define _UAPI__LINUX_KVM_PARA_H
|
||||
#ifndef __LINUX_KVM_PARA_H
|
||||
#define __LINUX_KVM_PARA_H
|
||||
|
||||
/*
|
||||
* This header file provides a method for making a hypercall to the host
|
||||
@@ -25,4 +25,4 @@
|
||||
*/
|
||||
#include <asm/kvm_para.h>
|
||||
|
||||
#endif /* _UAPI__LINUX_KVM_PARA_H */
|
||||
#endif /* __LINUX_KVM_PARA_H */
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _UAPIVFIO_H
|
||||
#define _UAPIVFIO_H
|
||||
#ifndef VFIO_H
|
||||
#define VFIO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
@@ -365,4 +365,4 @@ struct vfio_iommu_type1_dma_unmap {
|
||||
|
||||
#define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
|
||||
|
||||
#endif /* _UAPIVFIO_H */
|
||||
#endif /* VFIO_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _UAPI_LINUX_VIRTIO_CONFIG_H
|
||||
#define _UAPI_LINUX_VIRTIO_CONFIG_H
|
||||
#ifndef _LINUX_VIRTIO_CONFIG_H
|
||||
#define _LINUX_VIRTIO_CONFIG_H
|
||||
/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
|
||||
* anyone can use the definitions to implement compatible drivers/servers.
|
||||
*
|
||||
@@ -51,4 +51,4 @@
|
||||
* suppressed them? */
|
||||
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
|
||||
|
||||
#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */
|
||||
#endif /* _LINUX_VIRTIO_CONFIG_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _UAPI_LINUX_VIRTIO_RING_H
|
||||
#define _UAPI_LINUX_VIRTIO_RING_H
|
||||
#ifndef _LINUX_VIRTIO_RING_H
|
||||
#define _LINUX_VIRTIO_RING_H
|
||||
/* An interface for efficient virtio implementation, currently for use by KVM
|
||||
* and lguest, but hopefully others soon. Do NOT change this since it will
|
||||
* break existing servers and clients.
|
||||
@@ -160,4 +160,4 @@ static __inline__ int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old
|
||||
return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
|
||||
}
|
||||
|
||||
#endif /* _UAPI_LINUX_VIRTIO_RING_H */
|
||||
#endif /* _LINUX_VIRTIO_RING_H */
|
||||
|
||||
+3
-3
@@ -4578,7 +4578,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
signal = current_exec_domain_sig(sig);
|
||||
|
||||
err |= __put_user(h2g(ka->_sa_handler), &sc->handler);
|
||||
err |= __put_user(ka->_sa_handler, &sc->handler);
|
||||
err |= __put_user(set->sig[0], &sc->oldmask);
|
||||
#if defined(TARGET_PPC64)
|
||||
err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]);
|
||||
@@ -4600,7 +4600,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
/* Create a stack frame for the caller of the handler. */
|
||||
newsp = frame_addr - SIGNAL_FRAMESIZE;
|
||||
err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp);
|
||||
err |= put_user(env->gpr[1], newsp, target_ulong);
|
||||
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
@@ -4608,7 +4608,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
|
||||
/* Set up registers for signal handler. */
|
||||
env->gpr[1] = newsp;
|
||||
env->gpr[3] = signal;
|
||||
env->gpr[4] = (target_ulong) h2g(sc);
|
||||
env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx);
|
||||
env->nip = (target_ulong) ka->_sa_handler;
|
||||
/* Signal handlers are entered in big-endian mode. */
|
||||
env->msr &= ~MSR_LE;
|
||||
|
||||
@@ -54,6 +54,9 @@ for arch in $ARCHLIST; do
|
||||
if [ $arch = x86 ]; then
|
||||
cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86"
|
||||
fi
|
||||
if [ $arch = powerpc ]; then
|
||||
cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/"
|
||||
fi
|
||||
done
|
||||
|
||||
rm -rf "$output/linux-headers/linux"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
obj-y += translate.o helper.o
|
||||
obj-y += translate.o
|
||||
obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
|
||||
obj-y += helper.o
|
||||
obj-y += excp_helper.o
|
||||
obj-y += fpu_helper.o
|
||||
obj-y += int_helper.o
|
||||
@@ -9,4 +8,3 @@ obj-y += mmu_helper.o
|
||||
obj-y += timebase_helper.o
|
||||
obj-y += misc_helper.o
|
||||
obj-y += mem_helper.o
|
||||
obj-y += mpic_helper.o
|
||||
|
||||
@@ -50,6 +50,9 @@ typedef struct PowerPCCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
|
||||
/* TODO inline fields here */
|
||||
ppc_def_t *info;
|
||||
} PowerPCCPUClass;
|
||||
|
||||
/**
|
||||
@@ -73,5 +76,7 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
|
||||
|
||||
#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
|
||||
|
||||
PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+3
-5
@@ -1067,7 +1067,9 @@ struct CPUPPCState {
|
||||
target_ulong ivor_mask;
|
||||
target_ulong ivpr_mask;
|
||||
target_ulong hreset_vector;
|
||||
hwaddr mpic_cpu_base;
|
||||
hwaddr mpic_iack;
|
||||
/* true when the external proxy facility mode is enabled */
|
||||
bool mpic_proxy;
|
||||
#endif
|
||||
|
||||
/* Those resources are used only during code translation */
|
||||
@@ -1156,10 +1158,6 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
|
||||
|
||||
void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
|
||||
|
||||
const ppc_def_t *ppc_find_by_pvr(uint32_t pvr);
|
||||
const ppc_def_t *cpu_ppc_find_by_name (const char *name);
|
||||
int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
|
||||
|
||||
/* Time-base and decrementer management */
|
||||
#ifndef NO_CPU_IO_DEFS
|
||||
uint64_t cpu_ppc_load_tbl (CPUPPCState *env);
|
||||
|
||||
@@ -84,7 +84,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
" => %08x (%02x)\n", env->nip, excp, env->error_code);
|
||||
|
||||
/* new srr1 value excluding must-be-zero bits */
|
||||
msr = env->msr & ~0x783f0000ULL;
|
||||
if (excp_model == POWERPC_EXCP_BOOKE) {
|
||||
msr = env->msr;
|
||||
} else {
|
||||
msr = env->msr & ~0x783f0000ULL;
|
||||
}
|
||||
|
||||
/* new interrupt handler msr */
|
||||
new_msr = env->msr & ((target_ulong)1 << MSR_ME);
|
||||
@@ -145,6 +149,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
srr1 = SPR_40x_SRR3;
|
||||
break;
|
||||
case POWERPC_EXCP_BOOKE:
|
||||
/* FIXME: choose one or the other based on CPU type */
|
||||
srr0 = SPR_BOOKE_MCSRR0;
|
||||
srr1 = SPR_BOOKE_MCSRR1;
|
||||
asrr0 = SPR_BOOKE_CSRR0;
|
||||
@@ -173,6 +178,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
if (lpes0 == 1) {
|
||||
new_msr |= (target_ulong)MSR_HVB;
|
||||
}
|
||||
if (env->mpic_proxy) {
|
||||
/* IACK the IRQ on delivery */
|
||||
env->spr[SPR_BOOKE_EPR] = ldl_phys(env->mpic_iack);
|
||||
}
|
||||
goto store_next;
|
||||
case POWERPC_EXCP_ALIGN: /* Alignment exception */
|
||||
if (lpes1 == 0) {
|
||||
@@ -275,6 +284,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
case POWERPC_EXCP_DEBUG: /* Debug interrupt */
|
||||
switch (excp_model) {
|
||||
case POWERPC_EXCP_BOOKE:
|
||||
/* FIXME: choose one or the other based on CPU type */
|
||||
srr0 = SPR_BOOKE_DSRR0;
|
||||
srr1 = SPR_BOOKE_DSRR1;
|
||||
asrr0 = SPR_BOOKE_CSRR0;
|
||||
@@ -836,8 +846,13 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
|
||||
|
||||
void helper_rfi(CPUPPCState *env)
|
||||
{
|
||||
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
|
||||
~((target_ulong)0x783F0000), 1);
|
||||
if (env->excp_model == POWERPC_EXCP_BOOKE) {
|
||||
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
|
||||
~((target_ulong)0), 0);
|
||||
} else {
|
||||
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
|
||||
~((target_ulong)0x783F0000), 1);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
@@ -864,20 +879,22 @@ void helper_40x_rfci(CPUPPCState *env)
|
||||
|
||||
void helper_rfci(CPUPPCState *env)
|
||||
{
|
||||
do_rfi(env, env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1,
|
||||
~((target_ulong)0x3FFF0000), 0);
|
||||
do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
|
||||
~((target_ulong)0), 0);
|
||||
}
|
||||
|
||||
void helper_rfdi(CPUPPCState *env)
|
||||
{
|
||||
do_rfi(env, env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1,
|
||||
~((target_ulong)0x3FFF0000), 0);
|
||||
/* FIXME: choose CSRR1 or DSRR1 based on cpu type */
|
||||
do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
|
||||
~((target_ulong)0), 0);
|
||||
}
|
||||
|
||||
void helper_rfmci(CPUPPCState *env)
|
||||
{
|
||||
do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
|
||||
~((target_ulong)0x3FFF0000), 0);
|
||||
/* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
|
||||
do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
|
||||
~((target_ulong)0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* PowerPC emulation helpers for QEMU.
|
||||
*
|
||||
* Copyright (c) 2003-2007 Jocelyn Mayer
|
||||
*
|
||||
* 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 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 "cpu.h"
|
||||
#include "helper_regs.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "kvm_ppc.h"
|
||||
#include "sysemu/cpus.h"
|
||||
|
||||
PowerPCCPU *cpu_ppc_init(const char *cpu_model)
|
||||
{
|
||||
PowerPCCPU *cpu;
|
||||
CPUPPCState *env;
|
||||
const ppc_def_t *def;
|
||||
|
||||
def = cpu_ppc_find_by_name(cpu_model);
|
||||
if (!def) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
|
||||
env = &cpu->env;
|
||||
|
||||
if (tcg_enabled()) {
|
||||
ppc_translate_init();
|
||||
}
|
||||
|
||||
env->cpu_model_str = cpu_model;
|
||||
cpu_ppc_register_internal(env, def);
|
||||
|
||||
qemu_init_vcpu(env);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
@@ -405,7 +405,6 @@ DEF_HELPER_2(store_40x_dbcr0, void, env, tl)
|
||||
DEF_HELPER_2(store_40x_sler, void, env, tl)
|
||||
DEF_HELPER_2(store_booke_tcr, void, env, tl)
|
||||
DEF_HELPER_2(store_booke_tsr, void, env, tl)
|
||||
DEF_HELPER_1(load_epr, tl, env)
|
||||
DEF_HELPER_3(store_ibatl, void, env, i32, tl)
|
||||
DEF_HELPER_3(store_ibatu, void, env, i32, tl)
|
||||
DEF_HELPER_3(store_dbatl, void, env, i32, tl)
|
||||
|
||||
+67
-16
@@ -989,18 +989,38 @@ uint32_t kvmppc_get_dfp(void)
|
||||
return kvmppc_read_int_cpu_dt("ibm,dfp");
|
||||
}
|
||||
|
||||
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
uint32_t *hc = (uint32_t*)buf;
|
||||
|
||||
struct kvm_ppc_pvinfo pvinfo;
|
||||
static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
|
||||
!kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) {
|
||||
memcpy(buf, pvinfo.hcall, buf_len);
|
||||
!kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvmppc_get_hasidle(CPUPPCState *env)
|
||||
{
|
||||
struct kvm_ppc_pvinfo pvinfo;
|
||||
|
||||
if (!kvmppc_get_pvinfo(env, &pvinfo) &&
|
||||
(pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
|
||||
{
|
||||
uint32_t *hc = (uint32_t*)buf;
|
||||
struct kvm_ppc_pvinfo pvinfo;
|
||||
|
||||
if (!kvmppc_get_pvinfo(env, &pvinfo)) {
|
||||
memcpy(buf, pvinfo.hcall, buf_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1210,18 +1230,37 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)
|
||||
}
|
||||
}
|
||||
|
||||
const ppc_def_t *kvmppc_host_cpu_def(void)
|
||||
static void kvmppc_host_cpu_initfn(Object *obj)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(obj);
|
||||
|
||||
assert(kvm_enabled());
|
||||
|
||||
if (pcc->info->pvr != mfpvr()) {
|
||||
fprintf(stderr, "Your host CPU is unsupported.\n"
|
||||
"Please choose a supported model instead, see -cpu ?.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
|
||||
uint32_t host_pvr = mfpvr();
|
||||
const ppc_def_t *base_spec;
|
||||
PowerPCCPUClass *pvr_pcc;
|
||||
ppc_def_t *spec;
|
||||
uint32_t vmx = kvmppc_get_vmx();
|
||||
uint32_t dfp = kvmppc_get_dfp();
|
||||
|
||||
base_spec = ppc_find_by_pvr(host_pvr);
|
||||
|
||||
spec = g_malloc0(sizeof(*spec));
|
||||
memcpy(spec, base_spec, sizeof(*spec));
|
||||
|
||||
pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
|
||||
if (pvr_pcc != NULL) {
|
||||
memcpy(spec, pvr_pcc->info, sizeof(*spec));
|
||||
}
|
||||
pcc->info = spec;
|
||||
/* Override the display name for -cpu ? and QMP */
|
||||
pcc->info->name = "host";
|
||||
|
||||
/* Now fix up the spec with information we can query from the host */
|
||||
|
||||
@@ -1234,8 +1273,6 @@ const ppc_def_t *kvmppc_host_cpu_def(void)
|
||||
/* Only override when we know what the host supports */
|
||||
alter_insns(&spec->insns_flags2, PPC2_DFP, dfp);
|
||||
}
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
int kvmppc_fixup_cpu(CPUPPCState *env)
|
||||
@@ -1265,3 +1302,17 @@ int kvm_arch_on_sigbus(int code, void *addr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const TypeInfo kvm_host_cpu_type_info = {
|
||||
.name = TYPE_HOST_POWERPC_CPU,
|
||||
.parent = TYPE_POWERPC_CPU,
|
||||
.instance_init = kvmppc_host_cpu_initfn,
|
||||
.class_init = kvmppc_host_cpu_class_init,
|
||||
};
|
||||
|
||||
static void kvm_ppc_register_types(void)
|
||||
{
|
||||
type_register_static(&kvm_host_cpu_type_info);
|
||||
}
|
||||
|
||||
type_init(kvm_ppc_register_types)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user