mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220210' into staging
ppc-7.0 queue * Exception model rework (Fabiano) * Unused CPU models removal (Fabiano and Cédric) * Fix for VOF installation (Alexey) * Misc fixes # gpg: Signature made Thu 10 Feb 2022 12:59:07 GMT # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * remotes/legoater/tags/pull-ppc-20220210: (42 commits) spapr/vof: Install rom and nvram binaries docs: rstfy confidential guest documentation target/ppc: Change VSX instructions behavior to fill with zeros target/ppc: books: Remove excp_model argument from ppc_excp_apply_ail target/ppc: Assert if MSR bits differ from msr_mask during exceptions target/ppc: powerpc_excp: Move common code to the caller function target/ppc: Remove powerpc_excp_legacy target/ppc: 7xx: Set SRRs directly in exception code target/ppc: 7xx: Software TLB cleanup target/ppc: 7xx: System Reset cleanup target/ppc: 7xx: System Call exception cleanup target/ppc: 7xx: Program exception cleanup target/ppc: 7xx: External interrupt cleanup target/ppc: 7xx: Machine Check exception cleanup target/ppc: Simplify powerpc_excp_7xx target/ppc: Introduce powerpc_excp_7xx target/ppc: Merge 7x5 and 7x0 exception model IDs target/ppc: 6xx: Set SRRs directly in exception code target/ppc: 6xx: Software TLB exceptions cleanup target/ppc: 6xx: System Reset interrupt cleanup ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+1
-1
@@ -408,7 +408,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
M: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
F: docs/amd-memory-encryption.txt
|
||||
F: docs/system/i386/amd-memory-encryption.rst
|
||||
F: docs/system/i386/sgx.rst
|
||||
F: target/i386/kvm/
|
||||
F: target/i386/sev*
|
||||
|
||||
@@ -19,10 +19,10 @@ Running a Confidential Guest
|
||||
|
||||
To run a confidential guest you need to add two command line parameters:
|
||||
|
||||
1. Use "-object" to create a "confidential guest support" object. The
|
||||
1. Use ``-object`` to create a "confidential guest support" object. The
|
||||
type and parameters will vary with the specific mechanism to be
|
||||
used
|
||||
2. Set the "confidential-guest-support" machine parameter to the ID of
|
||||
2. Set the ``confidential-guest-support`` machine parameter to the ID of
|
||||
the object from (1).
|
||||
|
||||
Example (for AMD SEV)::
|
||||
@@ -37,13 +37,8 @@ Supported mechanisms
|
||||
|
||||
Currently supported confidential guest mechanisms are:
|
||||
|
||||
AMD Secure Encrypted Virtualization (SEV)
|
||||
docs/amd-memory-encryption.txt
|
||||
|
||||
POWER Protected Execution Facility (PEF)
|
||||
docs/papr-pef.txt
|
||||
|
||||
s390x Protected Virtualization (PV)
|
||||
docs/system/s390x/protvirt.rst
|
||||
* AMD Secure Encrypted Virtualization (SEV) (see :doc:`i386/amd-memory-encryption`)
|
||||
* POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected-execution-facility-pef`)
|
||||
* s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`)
|
||||
|
||||
Other mechanisms may be supported in future.
|
||||
@@ -1,3 +1,6 @@
|
||||
AMD Secure Encrypted Virtualization (SEV)
|
||||
=========================================
|
||||
|
||||
Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
|
||||
|
||||
SEV is an extension to the AMD-V architecture which supports running encrypted
|
||||
@@ -24,17 +27,18 @@ the hypervisor to satisfy the requested function.
|
||||
|
||||
Launching
|
||||
---------
|
||||
|
||||
Boot images (such as bios) must be encrypted before a guest can be booted. The
|
||||
MEMORY_ENCRYPT_OP ioctl provides commands to encrypt the images: LAUNCH_START,
|
||||
LAUNCH_UPDATE_DATA, LAUNCH_MEASURE and LAUNCH_FINISH. These four commands
|
||||
``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images: ``LAUNCH_START``,
|
||||
``LAUNCH_UPDATE_DATA``, ``LAUNCH_MEASURE`` and ``LAUNCH_FINISH``. These four commands
|
||||
together generate a fresh memory encryption key for the VM, encrypt the boot
|
||||
images and provide a measurement than can be used as an attestation of a
|
||||
successful launch.
|
||||
|
||||
For a SEV-ES guest, the LAUNCH_UPDATE_VMSA command is also used to encrypt the
|
||||
For a SEV-ES guest, the ``LAUNCH_UPDATE_VMSA`` command is also used to encrypt the
|
||||
guest register state, or VM save area (VMSA), for all of the guest vCPUs.
|
||||
|
||||
LAUNCH_START is called first to create a cryptographic launch context within
|
||||
``LAUNCH_START`` is called first to create a cryptographic launch context within
|
||||
the firmware. To create this context, guest owner must provide a guest policy,
|
||||
its public Diffie-Hellman key (PDH) and session parameters. These inputs
|
||||
should be treated as a binary blob and must be passed as-is to the SEV firmware.
|
||||
@@ -45,37 +49,37 @@ in bad measurement). The guest policy is a 4-byte data structure containing
|
||||
several flags that restricts what can be done on a running SEV guest.
|
||||
See KM Spec section 3 and 6.2 for more details.
|
||||
|
||||
The guest policy can be provided via the 'policy' property (see below)
|
||||
The guest policy can be provided via the ``policy`` property::
|
||||
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,policy=0x1...\
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,policy=0x1...\
|
||||
|
||||
Setting the "SEV-ES required" policy bit (bit 2) will launch the guest as a
|
||||
SEV-ES guest (see below)
|
||||
SEV-ES guest::
|
||||
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,policy=0x5...\
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,policy=0x5...\
|
||||
|
||||
The guest owner provided DH certificate and session parameters will be used to
|
||||
establish a cryptographic session with the guest owner to negotiate keys used
|
||||
for the attestation.
|
||||
|
||||
The DH certificate and session blob can be provided via the 'dh-cert-file' and
|
||||
'session-file' properties (see below)
|
||||
The DH certificate and session blob can be provided via the ``dh-cert-file`` and
|
||||
``session-file`` properties::
|
||||
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
|
||||
# ${QEMU} \
|
||||
sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
|
||||
|
||||
LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
|
||||
created via the LAUNCH_START command. If required, this command can be called
|
||||
``LAUNCH_UPDATE_DATA`` encrypts the memory region using the cryptographic context
|
||||
created via the ``LAUNCH_START`` command. If required, this command can be called
|
||||
multiple times to encrypt different memory regions. The command also calculates
|
||||
the measurement of the memory contents as it encrypts.
|
||||
|
||||
LAUNCH_UPDATE_VMSA encrypts all the vCPU VMSAs for a SEV-ES guest using the
|
||||
cryptographic context created via the LAUNCH_START command. The command also
|
||||
``LAUNCH_UPDATE_VMSA`` encrypts all the vCPU VMSAs for a SEV-ES guest using the
|
||||
cryptographic context created via the ``LAUNCH_START`` command. The command also
|
||||
calculates the measurement of the VMSAs as it encrypts them.
|
||||
|
||||
LAUNCH_MEASURE can be used to retrieve the measurement of encrypted memory and,
|
||||
``LAUNCH_MEASURE`` can be used to retrieve the measurement of encrypted memory and,
|
||||
for a SEV-ES guest, encrypted VMSAs. This measurement is a signature of the
|
||||
memory contents and, for a SEV-ES guest, the VMSA contents, that can be sent
|
||||
to the guest owner as an attestation that the memory and VMSAs were encrypted
|
||||
@@ -85,27 +89,28 @@ Since the guest owner knows the initial contents of the guest at boot, the
|
||||
attestation measurement can be verified by comparing it to what the guest owner
|
||||
expects.
|
||||
|
||||
LAUNCH_FINISH finalizes the guest launch and destroys the cryptographic
|
||||
``LAUNCH_FINISH`` finalizes the guest launch and destroys the cryptographic
|
||||
context.
|
||||
|
||||
See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
|
||||
See SEV KM API Spec ([SEVKM]_) 'Launching a guest' usage flow (Appendix A) for the
|
||||
complete flow chart.
|
||||
|
||||
To launch a SEV guest
|
||||
To launch a SEV guest::
|
||||
|
||||
# ${QEMU} \
|
||||
-machine ...,confidential-guest-support=sev0 \
|
||||
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
|
||||
# ${QEMU} \
|
||||
-machine ...,confidential-guest-support=sev0 \
|
||||
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
|
||||
|
||||
To launch a SEV-ES guest
|
||||
To launch a SEV-ES guest::
|
||||
|
||||
# ${QEMU} \
|
||||
-machine ...,confidential-guest-support=sev0 \
|
||||
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x5
|
||||
# ${QEMU} \
|
||||
-machine ...,confidential-guest-support=sev0 \
|
||||
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x5
|
||||
|
||||
An SEV-ES guest has some restrictions as compared to a SEV guest. Because the
|
||||
guest register state is encrypted and cannot be updated by the VMM/hypervisor,
|
||||
a SEV-ES guest:
|
||||
|
||||
- Does not support SMM - SMM support requires updating the guest register
|
||||
state.
|
||||
- Does not support reboot - a system reset requires updating the guest register
|
||||
@@ -114,35 +119,42 @@ a SEV-ES guest:
|
||||
manage booting APs.
|
||||
|
||||
Debugging
|
||||
-----------
|
||||
---------
|
||||
|
||||
Since the memory contents of a SEV guest are encrypted, hypervisor access to
|
||||
the guest memory will return cipher text. If the guest policy allows debugging,
|
||||
then a hypervisor can use the DEBUG_DECRYPT and DEBUG_ENCRYPT commands to access
|
||||
the guest memory region for debug purposes. This is not supported in QEMU yet.
|
||||
|
||||
Snapshot/Restore
|
||||
-----------------
|
||||
----------------
|
||||
|
||||
TODO
|
||||
|
||||
Live Migration
|
||||
----------------
|
||||
---------------
|
||||
|
||||
TODO
|
||||
|
||||
References
|
||||
-----------------
|
||||
----------
|
||||
|
||||
AMD Memory Encryption whitepaper:
|
||||
https://developer.amd.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
|
||||
`AMD Memory Encryption whitepaper
|
||||
<https://developer.amd.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf>`_
|
||||
|
||||
Secure Encrypted Virtualization Key Management:
|
||||
[1] http://developer.amd.com/wordpress/media/2017/11/55766_SEV-KM-API_Specification.pdf
|
||||
.. [SEVKM] `Secure Encrypted Virtualization Key Management
|
||||
<http://developer.amd.com/wordpress/media/2017/11/55766_SEV-KM-API_Specification.pdf>`_
|
||||
|
||||
KVM Forum slides:
|
||||
http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
|
||||
https://www.linux-kvm.org/images/9/94/Extending-Secure-Encrypted-Virtualization-with-SEV-ES-Thomas-Lendacky-AMD.pdf
|
||||
|
||||
AMD64 Architecture Programmer's Manual:
|
||||
http://support.amd.com/TechDocs/24593.pdf
|
||||
SME is section 7.10
|
||||
SEV is section 15.34
|
||||
SEV-ES is section 15.35
|
||||
* `AMD’s Virtualization Memory Encryption (2016)
|
||||
<http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf>`_
|
||||
* `Extending Secure Encrypted Virtualization With SEV-ES (2018)
|
||||
<https://www.linux-kvm.org/images/9/94/Extending-Secure-Encrypted-Virtualization-with-SEV-ES-Thomas-Lendacky-AMD.pdf>`_
|
||||
|
||||
`AMD64 Architecture Programmer's Manual:
|
||||
<http://support.amd.com/TechDocs/24593.pdf>`_
|
||||
|
||||
* SME is section 7.10
|
||||
* SEV is section 15.34
|
||||
* SEV-ES is section 15.35
|
||||
@@ -34,3 +34,4 @@ or Hypervisor.Framework.
|
||||
targets
|
||||
security
|
||||
multi-process
|
||||
confidential-guest-support
|
||||
|
||||
@@ -224,6 +224,8 @@ nested. Combinations not shown in the table are not available.
|
||||
.. [3] Introduced on Power10 machines.
|
||||
|
||||
|
||||
.. _power-papr-protected-execution-facility-pef:
|
||||
|
||||
POWER (PAPR) Protected Execution Facility (PEF)
|
||||
-----------------------------------------------
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ Architectural features
|
||||
i386/cpu
|
||||
i386/kvm-pv
|
||||
i386/sgx
|
||||
i386/amd-memory-encryption
|
||||
|
||||
.. _pcsys_005freq:
|
||||
|
||||
|
||||
@@ -1083,27 +1083,6 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
|
||||
return &cpu_ppc_set_tb_clk;
|
||||
}
|
||||
|
||||
/* Specific helpers for POWER & PowerPC 601 RTC */
|
||||
void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value)
|
||||
{
|
||||
_cpu_ppc_store_tbu(env, value);
|
||||
}
|
||||
|
||||
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env)
|
||||
{
|
||||
return _cpu_ppc_load_tbu(env);
|
||||
}
|
||||
|
||||
void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value)
|
||||
{
|
||||
cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
|
||||
}
|
||||
|
||||
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env)
|
||||
{
|
||||
return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PowerPC 40x timers */
|
||||
|
||||
|
||||
+2
-7
@@ -255,13 +255,8 @@ static void ibm_40p_init(MachineState *machine)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (env->flags & POWERPC_FLAG_RTC_CLK) {
|
||||
/* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
|
||||
cpu_ppc_tb_init(env, 7812500UL);
|
||||
} else {
|
||||
/* Set time-base frequency to 100 Mhz */
|
||||
cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
|
||||
}
|
||||
/* Set time-base frequency to 100 Mhz */
|
||||
cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
|
||||
qemu_register_reset(ppc_prep_reset, cpu);
|
||||
|
||||
/* PCI host */
|
||||
|
||||
@@ -54,14 +54,6 @@ uint64_t cpu_ppc_load_vtb(CPUPPCState *env)
|
||||
return cpu_ppc_get_tb(env);
|
||||
}
|
||||
|
||||
uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
|
||||
__attribute__ (( alias ("cpu_ppc_load_tbu") ));
|
||||
|
||||
uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
|
||||
{
|
||||
return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
|
||||
}
|
||||
|
||||
/* XXX: to be fixed */
|
||||
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
|
||||
{
|
||||
@@ -289,14 +281,6 @@ void cpu_loop(CPUPPCState *env)
|
||||
cpu_abort(cs, "Programmable interval timer interrupt "
|
||||
"while in user mode. Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_IO: /* IO error exception */
|
||||
cpu_abort(cs, "IO error exception while in user mode. "
|
||||
"Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_RUNM: /* Run mode exception */
|
||||
cpu_abort(cs, "Run mode exception while in user mode. "
|
||||
"Aborting\n");
|
||||
break;
|
||||
case POWERPC_EXCP_EMUL: /* Emulation trap exception */
|
||||
cpu_abort(cs, "Emulation trap exception not handled\n");
|
||||
break;
|
||||
|
||||
@@ -81,6 +81,8 @@ blobs = files(
|
||||
'opensbi-riscv32-generic-fw_dynamic.bin',
|
||||
'opensbi-riscv64-generic-fw_dynamic.bin',
|
||||
'npcm7xx_bootrom.bin',
|
||||
'vof.bin',
|
||||
'vof-nvram.bin',
|
||||
)
|
||||
|
||||
if get_option('install_blobs')
|
||||
|
||||
@@ -422,12 +422,6 @@
|
||||
CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, e600)
|
||||
/* 32 bits "classic" PowerPC */
|
||||
/* PowerPC 6xx family */
|
||||
POWERPC_DEF("601_v0", CPU_POWERPC_601_v0, 601,
|
||||
"PowerPC 601v0")
|
||||
POWERPC_DEF("601_v1", CPU_POWERPC_601_v1, 601,
|
||||
"PowerPC 601v1")
|
||||
POWERPC_DEF("601_v2", CPU_POWERPC_601_v2, 601v,
|
||||
"PowerPC 601v2")
|
||||
POWERPC_DEF("603", CPU_POWERPC_603, 603,
|
||||
"PowerPC 603")
|
||||
POWERPC_DEF("603e_v1.1", CPU_POWERPC_603E_v11, 603E,
|
||||
@@ -859,8 +853,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "mpc8555", "mpc8555_v11" },
|
||||
{ "mpc8555e", "mpc8555e_v11" },
|
||||
{ "mpc8560", "mpc8560_v21" },
|
||||
{ "601", "601_v2" },
|
||||
{ "601v", "601_v2" },
|
||||
{ "vanilla", "603" },
|
||||
{ "603e", "603e_v4.1" },
|
||||
{ "stretch", "603e_v4.1" },
|
||||
|
||||
@@ -205,9 +205,6 @@ enum {
|
||||
#define CPU_POWERPC_MPC8641 CPU_POWERPC_e600
|
||||
#define CPU_POWERPC_MPC8641D CPU_POWERPC_e600
|
||||
/* PowerPC 6xx cores */
|
||||
CPU_POWERPC_601_v0 = 0x00010001,
|
||||
CPU_POWERPC_601_v1 = 0x00010001,
|
||||
CPU_POWERPC_601_v2 = 0x00010002,
|
||||
CPU_POWERPC_603 = 0x00030100,
|
||||
CPU_POWERPC_603E_v11 = 0x00060101,
|
||||
CPU_POWERPC_603E_v12 = 0x00060102,
|
||||
|
||||
+4
-16
@@ -61,8 +61,6 @@ enum powerpc_mmu_t {
|
||||
POWERPC_MMU_BOOKE = 0x00000008,
|
||||
/* BookE 2.06 MMU model */
|
||||
POWERPC_MMU_BOOKE206 = 0x00000009,
|
||||
/* PowerPC 601 MMU model (specific BATs format) */
|
||||
POWERPC_MMU_601 = 0x0000000A,
|
||||
#define POWERPC_MMU_64 0x00010000
|
||||
/* 64 bits PowerPC MMU */
|
||||
POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
|
||||
@@ -90,20 +88,10 @@ enum powerpc_excp_t {
|
||||
POWERPC_EXCP_STD,
|
||||
/* PowerPC 40x exception model */
|
||||
POWERPC_EXCP_40x,
|
||||
/* PowerPC 601 exception model */
|
||||
POWERPC_EXCP_601,
|
||||
/* PowerPC 602 exception model */
|
||||
POWERPC_EXCP_602,
|
||||
/* PowerPC 603 exception model */
|
||||
POWERPC_EXCP_603,
|
||||
/* PowerPC G2 exception model */
|
||||
POWERPC_EXCP_G2,
|
||||
/* PowerPC 604 exception model */
|
||||
POWERPC_EXCP_604,
|
||||
/* PowerPC 7x0 exception model */
|
||||
POWERPC_EXCP_7x0,
|
||||
/* PowerPC 7x5 exception model */
|
||||
POWERPC_EXCP_7x5,
|
||||
/* PowerPC 603/604/G2 exception model */
|
||||
POWERPC_EXCP_6xx,
|
||||
/* PowerPC 7xx exception model */
|
||||
POWERPC_EXCP_7xx,
|
||||
/* PowerPC 74xx exception model */
|
||||
POWERPC_EXCP_74xx,
|
||||
/* BookE exception model */
|
||||
|
||||
+6
-33
@@ -89,11 +89,9 @@ enum {
|
||||
POWERPC_EXCP_VPU = 73, /* Vector unavailable exception */
|
||||
/* 40x specific exceptions */
|
||||
POWERPC_EXCP_PIT = 74, /* Programmable interval timer interrupt */
|
||||
/* 601 specific exceptions */
|
||||
POWERPC_EXCP_IO = 75, /* IO error exception */
|
||||
POWERPC_EXCP_RUNM = 76, /* Run mode exception */
|
||||
/* Vectors 75-76 are 601 specific exceptions */
|
||||
/* 602 specific exceptions */
|
||||
POWERPC_EXCP_EMUL = 77, /* Emulation trap exception */
|
||||
POWERPC_EXCP_EMUL = 77, /* Emulation trap exception */
|
||||
/* 602/603 specific exceptions */
|
||||
POWERPC_EXCP_IFTLB = 78, /* Instruction fetch TLB miss */
|
||||
POWERPC_EXCP_DLTLB = 79, /* Data load TLB miss */
|
||||
@@ -632,8 +630,7 @@ enum {
|
||||
POWERPC_FLAG_PX = 0x00000200,
|
||||
POWERPC_FLAG_PMM = 0x00000400,
|
||||
/* Flag for special features */
|
||||
/* Decrementer clock: RTC clock (POWER, 601) or bus clock */
|
||||
POWERPC_FLAG_RTC_CLK = 0x00010000,
|
||||
/* Decrementer clock */
|
||||
POWERPC_FLAG_BUS_CLK = 0x00020000,
|
||||
/* Has CFAR */
|
||||
POWERPC_FLAG_CFAR = 0x00040000,
|
||||
@@ -643,8 +640,6 @@ enum {
|
||||
POWERPC_FLAG_TM = 0x00100000,
|
||||
/* Has SCV (ISA 3.00) */
|
||||
POWERPC_FLAG_SCV = 0x00200000,
|
||||
/* Has HID0 for LE bit (601) */
|
||||
POWERPC_FLAG_HID0_LE = 0x00400000,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -655,7 +650,7 @@ enum {
|
||||
* the MSR are validated in hreg_compute_hflags.
|
||||
*/
|
||||
enum {
|
||||
HFLAGS_LE = 0, /* MSR_LE -- comes from elsewhere on 601 */
|
||||
HFLAGS_LE = 0, /* MSR_LE */
|
||||
HFLAGS_HV = 1, /* computed from MSR_HV and other state */
|
||||
HFLAGS_64 = 2, /* computed from MSR_CE and MSR_SF */
|
||||
HFLAGS_GTSE = 3, /* computed from SPR_LPCR[GTSE] */
|
||||
@@ -1389,11 +1384,7 @@ void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
|
||||
void cpu_ppc_store_tbu40(CPUPPCState *env, uint64_t value);
|
||||
uint64_t cpu_ppc_load_purr(CPUPPCState *env);
|
||||
void cpu_ppc_store_purr(CPUPPCState *env, uint64_t value);
|
||||
uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env);
|
||||
uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void cpu_ppc601_store_rtcl(CPUPPCState *env, uint32_t value);
|
||||
void cpu_ppc601_store_rtcu(CPUPPCState *env, uint32_t value);
|
||||
target_ulong load_40x_pit(CPUPPCState *env);
|
||||
void store_40x_pit(CPUPPCState *env, target_ulong val);
|
||||
void store_40x_dbcr0(CPUPPCState *env, uint32_t val);
|
||||
@@ -1516,17 +1507,12 @@ typedef PowerPCCPU ArchCPU;
|
||||
/* SPR definitions */
|
||||
#define SPR_MQ (0x000)
|
||||
#define SPR_XER (0x001)
|
||||
#define SPR_601_VRTCU (0x004)
|
||||
#define SPR_601_VRTCL (0x005)
|
||||
#define SPR_601_UDECR (0x006)
|
||||
#define SPR_LR (0x008)
|
||||
#define SPR_CTR (0x009)
|
||||
#define SPR_UAMR (0x00D)
|
||||
#define SPR_DSCR (0x011)
|
||||
#define SPR_DSISR (0x012)
|
||||
#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
|
||||
#define SPR_601_RTCU (0x014)
|
||||
#define SPR_601_RTCL (0x015)
|
||||
#define SPR_DAR (0x013)
|
||||
#define SPR_DECR (0x016)
|
||||
#define SPR_SDR1 (0x019)
|
||||
#define SPR_SRR0 (0x01A)
|
||||
@@ -2003,7 +1989,6 @@ typedef PowerPCCPU ArchCPU;
|
||||
#define SPR_HID1 (0x3F1)
|
||||
#define SPR_IABR (0x3F2)
|
||||
#define SPR_40x_DBCR0 (0x3F2)
|
||||
#define SPR_601_HID2 (0x3F2)
|
||||
#define SPR_Exxx_L1CSR0 (0x3F2)
|
||||
#define SPR_ICTRL (0x3F3)
|
||||
#define SPR_HID2 (0x3F3)
|
||||
@@ -2019,7 +2004,6 @@ typedef PowerPCCPU ArchCPU;
|
||||
#define DABR_MASK (~(target_ulong)0x7)
|
||||
#define SPR_Exxx_BUCSR (0x3F5)
|
||||
#define SPR_40x_IAC2 (0x3F5)
|
||||
#define SPR_601_HID5 (0x3F5)
|
||||
#define SPR_40x_DAC1 (0x3F6)
|
||||
#define SPR_MSSCR0 (0x3F6)
|
||||
#define SPR_970_HID5 (0x3F6)
|
||||
@@ -2052,7 +2036,6 @@ typedef PowerPCCPU ArchCPU;
|
||||
#define SPR_403_PBL2 (0x3FE)
|
||||
#define SPR_PIR (0x3FF)
|
||||
#define SPR_403_PBU2 (0x3FF)
|
||||
#define SPR_601_HID15 (0x3FF)
|
||||
#define SPR_604_HID15 (0x3FF)
|
||||
#define SPR_E500_SVR (0x3FF)
|
||||
|
||||
@@ -2117,15 +2100,6 @@ enum {
|
||||
#define PPC_RES PPC_INSNS_BASE
|
||||
/* spr/msr access instructions */
|
||||
#define PPC_MISC PPC_INSNS_BASE
|
||||
/* Deprecated instruction sets */
|
||||
/* Original POWER instruction set */
|
||||
PPC_POWER = 0x0000000000000002ULL,
|
||||
/* POWER2 instruction set extension */
|
||||
PPC_POWER2 = 0x0000000000000004ULL,
|
||||
/* Power RTC support */
|
||||
PPC_POWER_RTC = 0x0000000000000008ULL,
|
||||
/* Power-to-PowerPC bridge (601) */
|
||||
PPC_POWER_BR = 0x0000000000000010ULL,
|
||||
/* 64 bits PowerPC instruction set */
|
||||
PPC_64B = 0x0000000000000020ULL,
|
||||
/* New 64 bits extensions (PowerPC 2.0x) */
|
||||
@@ -2236,8 +2210,7 @@ enum {
|
||||
/* popcntw and popcntd instructions */
|
||||
PPC_POPCNTWD = 0x8000000000000000ULL,
|
||||
|
||||
#define PPC_TCG_INSNS (PPC_INSNS_BASE | PPC_POWER | PPC_POWER2 \
|
||||
| PPC_POWER_RTC | PPC_POWER_BR | PPC_64B \
|
||||
#define PPC_TCG_INSNS (PPC_INSNS_BASE | PPC_64B \
|
||||
| PPC_64BX | PPC_64H | PPC_WAIT | PPC_MFTB \
|
||||
| PPC_ISEL | PPC_POPCNTB \
|
||||
| PPC_STRING | PPC_FLOAT | PPC_FLOAT_EXT \
|
||||
|
||||
+18
-313
@@ -749,83 +749,6 @@ static void register_G2_sprs(CPUPPCState *env)
|
||||
0x00000000);
|
||||
}
|
||||
|
||||
/* SPR specific to PowerPC 601 implementation */
|
||||
static void register_601_sprs(CPUPPCState *env)
|
||||
{
|
||||
/* Multiplication/division register */
|
||||
/* MQ */
|
||||
spr_register(env, SPR_MQ, "MQ",
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* RTC registers */
|
||||
spr_register(env, SPR_601_RTCU, "RTCU",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
SPR_NOACCESS, &spr_write_601_rtcu,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_601_VRTCU, "RTCU",
|
||||
&spr_read_601_rtcu, SPR_NOACCESS,
|
||||
&spr_read_601_rtcu, SPR_NOACCESS,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_601_RTCL, "RTCL",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
SPR_NOACCESS, &spr_write_601_rtcl,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_601_VRTCL, "RTCL",
|
||||
&spr_read_601_rtcl, SPR_NOACCESS,
|
||||
&spr_read_601_rtcl, SPR_NOACCESS,
|
||||
0x00000000);
|
||||
/* Timer */
|
||||
#if 0 /* ? */
|
||||
spr_register(env, SPR_601_UDECR, "UDECR",
|
||||
&spr_read_decr, SPR_NOACCESS,
|
||||
&spr_read_decr, SPR_NOACCESS,
|
||||
0x00000000);
|
||||
#endif
|
||||
/* External access control */
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_EAR, "EAR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
spr_register(env, SPR_IBAT0U, "IBAT0U",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatu,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT0L, "IBAT0L",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatl,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT1U, "IBAT1U",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatu,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT1L, "IBAT1L",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatl,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT2U, "IBAT2U",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatu,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT2L, "IBAT2L",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatl,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT3U, "IBAT3U",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatu,
|
||||
0x00000000);
|
||||
spr_register(env, SPR_IBAT3L, "IBAT3L",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_601_ubat, &spr_write_601_ubatl,
|
||||
0x00000000);
|
||||
env->nb_BATs = 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void register_74xx_sprs(CPUPPCState *env)
|
||||
{
|
||||
/* Processor identification */
|
||||
@@ -2060,26 +1983,6 @@ static void init_excp_BookE(CPUPPCState *env)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void init_excp_601(CPUPPCState *env)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
|
||||
env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
|
||||
env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
|
||||
env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
|
||||
env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
|
||||
env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
|
||||
env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
|
||||
env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
|
||||
env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
|
||||
env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
|
||||
env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
|
||||
env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
|
||||
/* Hardware reset vector */
|
||||
env->hreset_vector = 0x00000100UL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void init_excp_603(CPUPPCState *env)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
@@ -2703,89 +2606,6 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
|
||||
POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
|
||||
}
|
||||
|
||||
static void init_proc_440x4(CPUPPCState *env)
|
||||
{
|
||||
/* Time base */
|
||||
register_tbl(env);
|
||||
register_BookE_sprs(env, 0x000000000000FFFFULL);
|
||||
register_440_sprs(env);
|
||||
register_usprgh_sprs(env);
|
||||
/* Processor identification */
|
||||
spr_register(env, SPR_BOOKE_PIR, "PIR",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_pir,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_IAC3, "IAC3",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_IAC4, "IAC4",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_DVC1, "DVC1",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_BOOKE_DVC2, "DVC2",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
env->nb_tlb = 64;
|
||||
env->nb_ways = 1;
|
||||
env->id_tlbs = 0;
|
||||
env->tlb_type = TLB_EMB;
|
||||
#endif
|
||||
init_excp_BookE(env);
|
||||
env->dcache_line_size = 32;
|
||||
env->icache_line_size = 32;
|
||||
/* XXX: TODO: allocate internal IRQ controller */
|
||||
|
||||
SET_FIT_PERIOD(12, 16, 20, 24);
|
||||
SET_WDT_PERIOD(20, 24, 28, 32);
|
||||
}
|
||||
|
||||
POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
|
||||
|
||||
dc->desc = "PowerPC 440x4";
|
||||
pcc->init_proc = init_proc_440x4;
|
||||
pcc->check_pow = check_pow_nocheck;
|
||||
pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
|
||||
PPC_DCR | PPC_WRTEE |
|
||||
PPC_CACHE | PPC_CACHE_ICBI |
|
||||
PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
|
||||
PPC_MEM_TLBSYNC | PPC_MFTB |
|
||||
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
|
||||
PPC_440_SPEC;
|
||||
pcc->msr_mask = (1ull << MSR_POW) |
|
||||
(1ull << MSR_CE) |
|
||||
(1ull << MSR_EE) |
|
||||
(1ull << MSR_PR) |
|
||||
(1ull << MSR_FP) |
|
||||
(1ull << MSR_ME) |
|
||||
(1ull << MSR_FE0) |
|
||||
(1ull << MSR_DWE) |
|
||||
(1ull << MSR_DE) |
|
||||
(1ull << MSR_FE1) |
|
||||
(1ull << MSR_IR) |
|
||||
(1ull << MSR_DR);
|
||||
pcc->mmu_model = POWERPC_MMU_BOOKE;
|
||||
pcc->excp_model = POWERPC_EXCP_BOOKE;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_BookE;
|
||||
pcc->bfd_mach = bfd_mach_ppc_403;
|
||||
pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
|
||||
POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
|
||||
}
|
||||
|
||||
static void init_proc_440x5(CPUPPCState *env)
|
||||
{
|
||||
/* Time base */
|
||||
@@ -2962,7 +2782,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_REAL;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
|
||||
pcc->bfd_mach = bfd_mach_ppc_505;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -3005,7 +2825,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_MPC8xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
|
||||
pcc->bfd_mach = bfd_mach_ppc_860;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -3086,7 +2906,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_DR) |
|
||||
(1ull << MSR_RI);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_G2;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_ec603e;
|
||||
pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
|
||||
@@ -3168,7 +2988,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_G2;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_ec603e;
|
||||
pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
|
||||
@@ -3423,7 +3243,7 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_603;
|
||||
pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
|
||||
@@ -3892,120 +3712,6 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
|
||||
#endif
|
||||
|
||||
/* Non-embedded PowerPC */
|
||||
|
||||
#define POWERPC_MSRR_601 (0x0000000000001040ULL)
|
||||
|
||||
static void init_proc_601(CPUPPCState *env)
|
||||
{
|
||||
register_ne_601_sprs(env);
|
||||
register_sdr1_sprs(env);
|
||||
register_601_sprs(env);
|
||||
/* Hardware implementation registers */
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_HID0, "HID0",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_hid0_601,
|
||||
0x80010080);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_HID1, "HID1",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_601_HID2, "HID2",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_601_HID5, "HID5",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
/* Memory management */
|
||||
init_excp_601(env);
|
||||
/*
|
||||
* XXX: beware that dcache line size is 64
|
||||
* but dcbz uses 32 bytes "sectors"
|
||||
* XXX: this breaks clcs instruction !
|
||||
*/
|
||||
env->dcache_line_size = 32;
|
||||
env->icache_line_size = 64;
|
||||
/* Allocate hardware IRQ controller */
|
||||
ppc6xx_irq_init(env_archcpu(env));
|
||||
}
|
||||
|
||||
POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
|
||||
|
||||
dc->desc = "PowerPC 601";
|
||||
pcc->init_proc = init_proc_601;
|
||||
pcc->check_pow = check_pow_none;
|
||||
pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
|
||||
PPC_FLOAT |
|
||||
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->msr_mask = (1ull << MSR_EE) |
|
||||
(1ull << MSR_PR) |
|
||||
(1ull << MSR_FP) |
|
||||
(1ull << MSR_ME) |
|
||||
(1ull << MSR_FE0) |
|
||||
(1ull << MSR_SE) |
|
||||
(1ull << MSR_FE1) |
|
||||
(1ull << MSR_EP) |
|
||||
(1ull << MSR_IR) |
|
||||
(1ull << MSR_DR);
|
||||
pcc->mmu_model = POWERPC_MMU_601;
|
||||
pcc->excp_model = POWERPC_EXCP_601;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_601;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE;
|
||||
}
|
||||
|
||||
#define POWERPC_MSRR_601v (0x0000000000001040ULL)
|
||||
|
||||
static void init_proc_601v(CPUPPCState *env)
|
||||
{
|
||||
init_proc_601(env);
|
||||
/* XXX : not implemented */
|
||||
spr_register(env, SPR_601_HID15, "HID15",
|
||||
SPR_NOACCESS, SPR_NOACCESS,
|
||||
&spr_read_generic, &spr_write_generic,
|
||||
0x00000000);
|
||||
}
|
||||
|
||||
POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
|
||||
|
||||
dc->desc = "PowerPC 601v";
|
||||
pcc->init_proc = init_proc_601v;
|
||||
pcc->check_pow = check_pow_none;
|
||||
pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
|
||||
PPC_FLOAT |
|
||||
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
|
||||
PPC_SEGMENT | PPC_EXTERN;
|
||||
pcc->msr_mask = (1ull << MSR_EE) |
|
||||
(1ull << MSR_PR) |
|
||||
(1ull << MSR_FP) |
|
||||
(1ull << MSR_ME) |
|
||||
(1ull << MSR_FE0) |
|
||||
(1ull << MSR_SE) |
|
||||
(1ull << MSR_FE1) |
|
||||
(1ull << MSR_EP) |
|
||||
(1ull << MSR_IR) |
|
||||
(1ull << MSR_DR);
|
||||
pcc->mmu_model = POWERPC_MMU_601;
|
||||
pcc->excp_model = POWERPC_EXCP_601;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_601;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE;
|
||||
}
|
||||
|
||||
static void init_proc_603(CPUPPCState *env)
|
||||
{
|
||||
register_ne_601_sprs(env);
|
||||
@@ -4066,7 +3772,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_603;
|
||||
pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
|
||||
@@ -4105,7 +3811,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_603;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_ec603e;
|
||||
pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
|
||||
@@ -4166,7 +3872,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_604;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_604;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4247,7 +3953,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_604;
|
||||
pcc->excp_model = POWERPC_EXCP_6xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_604;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4315,7 +4021,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4392,7 +4098,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4592,7 +4298,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4672,7 +4378,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4757,7 +4463,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4842,7 +4548,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_32B;
|
||||
pcc->excp_model = POWERPC_EXCP_7x0;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -4918,7 +4624,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_7x5;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -5005,7 +4711,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
|
||||
(1ull << MSR_RI) |
|
||||
(1ull << MSR_LE);
|
||||
pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
|
||||
pcc->excp_model = POWERPC_EXCP_7x5;
|
||||
pcc->excp_model = POWERPC_EXCP_7xx;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
|
||||
pcc->bfd_mach = bfd_mach_ppc_750;
|
||||
pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
|
||||
@@ -7760,7 +7466,7 @@ static void init_ppc_proc(PowerPCCPU *cpu)
|
||||
"Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
|
||||
if ((env->flags & POWERPC_FLAG_BUS_CLK) == 0) {
|
||||
fprintf(stderr, "PowerPC flags inconsistency\n"
|
||||
"Should define the time-base and decrementer clock source\n");
|
||||
exit(1);
|
||||
@@ -8574,7 +8280,6 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||
|
||||
switch (env->mmu_model) {
|
||||
case POWERPC_MMU_32B:
|
||||
case POWERPC_MMU_601:
|
||||
case POWERPC_MMU_SOFT_6xx:
|
||||
#if defined(TARGET_PPC64)
|
||||
case POWERPC_MMU_64B:
|
||||
|
||||
+597
-542
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -1696,7 +1696,7 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
|
||||
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -1772,7 +1772,7 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -1843,7 +1843,7 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -1919,7 +1919,7 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
|
||||
#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -1959,7 +1959,7 @@ VSX_RE(xvresp, 4, float32, VsrW(i), 0, 0)
|
||||
#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -2004,7 +2004,7 @@ VSX_SQRT(xvsqrtsp, 4, float32, VsrW(i), 0, 0)
|
||||
#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
helper_reset_fpstatus(env); \
|
||||
@@ -2472,7 +2472,7 @@ void helper_xscmpuqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xa,
|
||||
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < nels; i++) { \
|
||||
@@ -2498,7 +2498,7 @@ VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
|
||||
void helper_##name(CPUPPCState *env, \
|
||||
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
bool vxsnan_flag = false, vex_flag = false; \
|
||||
\
|
||||
if (unlikely(float64_is_any_nan(xa->VsrD(0)) || \
|
||||
@@ -2533,7 +2533,7 @@ VSX_MAX_MINC(xsmincdp, 0);
|
||||
void helper_##name(CPUPPCState *env, \
|
||||
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
bool vxsnan_flag = false, vex_flag = false; \
|
||||
\
|
||||
if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \
|
||||
@@ -2654,7 +2654,7 @@ VSX_CMP(xvcmpnesp, 4, float32, VsrW(i), eq, 0, 0)
|
||||
#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < nels; i++) { \
|
||||
@@ -2833,7 +2833,7 @@ uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
int all_flags = env->fp_status.float_exception_flags, flags; \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < nels; i++) { \
|
||||
@@ -2917,7 +2917,7 @@ VSX_CVT_FP_TO_INT_VECTOR(xscvqpuwz, float128, uint32, f128, VsrD(0), 0x0ULL)
|
||||
#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < nels; i++) { \
|
||||
@@ -2990,7 +2990,7 @@ VSX_CVT_INT_TO_FP_VECTOR(xscvudqp, uint64, float128, VsrD(0), f128)
|
||||
#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
|
||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||
{ \
|
||||
ppc_vsr_t t = *xt; \
|
||||
ppc_vsr_t t = { }; \
|
||||
int i; \
|
||||
FloatRoundMode curr_rounding_mode; \
|
||||
\
|
||||
|
||||
@@ -7,7 +7,6 @@ DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
DEF_HELPER_2(store_msr, void, env, tl)
|
||||
DEF_HELPER_1(rfi, void, env)
|
||||
DEF_HELPER_1(rfsvc, void, env)
|
||||
DEF_HELPER_1(40x_rfci, void, env)
|
||||
DEF_HELPER_1(rfci, void, env)
|
||||
DEF_HELPER_1(rfdi, void, env)
|
||||
@@ -653,14 +652,9 @@ DEF_HELPER_2(book3s_msgclr, void, env, tl)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32)
|
||||
DEF_HELPER_FLAGS_2(clcs, TCG_CALL_NO_RWG_SE, tl, env, i32)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
DEF_HELPER_2(rac, tl, env, tl)
|
||||
#endif
|
||||
DEF_HELPER_3(div, tl, env, tl, tl)
|
||||
DEF_HELPER_3(divo, tl, env, tl, tl)
|
||||
DEF_HELPER_3(divs, tl, env, tl, tl)
|
||||
DEF_HELPER_3(divso, tl, env, tl, tl)
|
||||
|
||||
DEF_HELPER_2(load_dcr, tl, env, tl)
|
||||
DEF_HELPER_3(store_dcr, void, env, tl, tl)
|
||||
@@ -674,8 +668,6 @@ DEF_HELPER_FLAGS_1(load_tbu, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(load_atbl, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(load_atbu, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(load_vtb, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(load_601_rtcl, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#if defined(TARGET_PPC64)
|
||||
DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
|
||||
@@ -693,15 +685,12 @@ DEF_HELPER_FLAGS_2(store_tbl, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_tbu, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_atbl, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_atbu, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_601_rtcl, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_601_rtcu, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_1(load_decr, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_vtb, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_tbu40, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_2(store_hid0_601, void, env, tl)
|
||||
DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
|
||||
DEF_HELPER_FLAGS_2(store_40x_pit, TCG_CALL_NO_RWG, void, env, tl)
|
||||
DEF_HELPER_FLAGS_2(store_40x_tcr, TCG_CALL_NO_RWG, void, env, tl)
|
||||
@@ -715,8 +704,6 @@ 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)
|
||||
DEF_HELPER_3(store_dbatu, void, env, i32, tl)
|
||||
DEF_HELPER_3(store_601_batl, void, env, i32, tl)
|
||||
DEF_HELPER_3(store_601_batu, void, env, i32, tl)
|
||||
#endif
|
||||
|
||||
#define dh_alias_fprp ptr
|
||||
|
||||
@@ -59,15 +59,6 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
|
||||
msr_mask = ((1 << MSR_LE) | (1 << MSR_PR) |
|
||||
(1 << MSR_DR) | (1 << MSR_FP));
|
||||
|
||||
if (ppc_flags & POWERPC_FLAG_HID0_LE) {
|
||||
/*
|
||||
* Note that MSR_LE is not set in env->msr_mask for this cpu,
|
||||
* and so will never be set in msr.
|
||||
*/
|
||||
uint32_t le = extract32(env->spr[SPR_HID0], 3, 1);
|
||||
hflags |= le << MSR_LE;
|
||||
}
|
||||
|
||||
if (ppc_flags & POWERPC_FLAG_DE) {
|
||||
target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
|
||||
if (dbcr0 & DBCR0_ICMP) {
|
||||
@@ -249,7 +240,6 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
|
||||
hreg_swap_gpr_tgpr(env);
|
||||
}
|
||||
if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
|
||||
/* Change the exception prefix on PowerPC 601 */
|
||||
env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -422,72 +422,6 @@ uint64_t helper_PEXTD(uint64_t src, uint64_t mask)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PowerPC 601 specific instructions (POWER bridge) */
|
||||
target_ulong helper_div(CPUPPCState *env, target_ulong arg1, target_ulong arg2)
|
||||
{
|
||||
uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ];
|
||||
|
||||
if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->spr[SPR_MQ] = tmp % arg2;
|
||||
return tmp / (int32_t)arg2;
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong helper_divo(CPUPPCState *env, target_ulong arg1,
|
||||
target_ulong arg2)
|
||||
{
|
||||
uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ];
|
||||
|
||||
if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->so = env->ov = 1;
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->spr[SPR_MQ] = tmp % arg2;
|
||||
tmp /= (int32_t)arg2;
|
||||
if ((int32_t)tmp != tmp) {
|
||||
env->so = env->ov = 1;
|
||||
} else {
|
||||
env->ov = 0;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong helper_divs(CPUPPCState *env, target_ulong arg1,
|
||||
target_ulong arg2)
|
||||
{
|
||||
if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
|
||||
return (int32_t)arg1 / (int32_t)arg2;
|
||||
}
|
||||
}
|
||||
|
||||
target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
|
||||
target_ulong arg2)
|
||||
{
|
||||
if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->so = env->ov = 1;
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->ov = 0;
|
||||
env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
|
||||
return (int32_t)arg1 / (int32_t)arg2;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Altivec extension helpers */
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user