e600 core for MPC86xx processors

MPC86xx processors are based on the e600 core, which is not the case
in qemu where it is based on the 7400 processor.

This patch creates the e600 core and instantiates the MPC86xx
processors based on it. Therefore, adding the high BATs, the SPRG
4..7 registers, which are e600-specific [1], and a HW MMU model (as 7400).
This allows to define the MPC8610 processor too.

Tested with a kernel using the HW TLB misses.

[1] http://cache.freescale.com/files/32bit/doc/ref_manual/E600CORERM.pdf

Signed-off-by: Julio Guerra <guerr@julio.in>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Julio Guerra 2013-06-24 23:15:54 +02:00 committed by Alexander Graf
parent c170a23ca0
commit 7162bdea75
3 changed files with 130 additions and 9 deletions

View File

@ -792,17 +792,15 @@
POWERPC_DEF_SVR("MPC8572E", "MPC8572E",
CPU_POWERPC_MPC8572E, POWERPC_SVR_8572E, e500v2)
/* e600 family */
POWERPC_DEF("e600", CPU_POWERPC_e600, 7400,
POWERPC_DEF("e600", CPU_POWERPC_e600, e600,
"PowerPC e600 core")
/* PowerPC e600 microcontrollers */
#if defined(TODO)
POWERPC_DEF_SVR("MPC8610", "MPC8610",
CPU_POWERPC_MPC8610, POWERPC_SVR_8610, 7400)
#endif
CPU_POWERPC_MPC8610, POWERPC_SVR_8610, e600)
POWERPC_DEF_SVR("MPC8641", "MPC8641",
CPU_POWERPC_MPC8641, POWERPC_SVR_8641, 7400)
CPU_POWERPC_MPC8641, POWERPC_SVR_8641, e600)
POWERPC_DEF_SVR("MPC8641D", "MPC8641D",
CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, 7400)
CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, e600)
/* 32 bits "classic" PowerPC */
/* PowerPC 6xx family */
POWERPC_DEF("601_v0", CPU_POWERPC_601_v0, 601,

View File

@ -732,9 +732,7 @@ enum {
POWERPC_SVR_8568E = 0x807D0011 | POWERPC_SVR_E500,
POWERPC_SVR_8572 = 0x80E00010 | POWERPC_SVR_E500,
POWERPC_SVR_8572E = 0x80E80010 | POWERPC_SVR_E500,
#if 0
POWERPC_SVR_8610 = xxx,
#endif
POWERPC_SVR_8610 = 0x80A00011,
POWERPC_SVR_8641 = 0x80900021,
POWERPC_SVR_8641D = 0x80900121,
};

View File

@ -6479,6 +6479,131 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
POWERPC_FLAG_BUS_CLK;
}
static void init_proc_e600 (CPUPPCState *env)
{
gen_spr_ne_601(env);
gen_spr_7xx(env);
/* Time base */
gen_tbl(env);
/* 74xx specific SPR */
gen_spr_74xx(env);
/* XXX : not implemented */
spr_register(env, SPR_UBAMR, "UBAMR",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_LDSTCR, "LDSTCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_ICTRL, "ICTRL",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_MSSSR0, "MSSSR0",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_PMC5, "PMC5",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_UPMC5, "UPMC5",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_PMC6, "PMC6",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_UPMC6, "UPMC6",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
/* SPRGs */
spr_register(env, SPR_SPRG4, "SPRG4",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
spr_register(env, SPR_USPRG4, "USPRG4",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
spr_register(env, SPR_SPRG5, "SPRG5",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
spr_register(env, SPR_USPRG5, "USPRG5",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
spr_register(env, SPR_SPRG6, "SPRG6",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
spr_register(env, SPR_USPRG6, "USPRG6",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
spr_register(env, SPR_SPRG7, "SPRG7",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
spr_register(env, SPR_USPRG7, "USPRG7",
&spr_read_ureg, SPR_NOACCESS,
&spr_read_ureg, SPR_NOACCESS,
0x00000000);
/* Memory management */
gen_low_BATs(env);
gen_high_BATs(env);
gen_74xx_soft_tlb(env, 128, 2);
init_excp_7450(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
/* Allocate hardware IRQ controller */
ppc6xx_irq_init(env);
}
POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
dc->desc = "PowerPC e600";
pcc->init_proc = init_proc_e600;
pcc->check_pow = check_pow_hid0_74xx;
pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
PPC_FLOAT_STFIWX |
PPC_CACHE | PPC_CACHE_ICBI |
PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
PPC_MEM_SYNC | PPC_MEM_EIEIO |
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
PPC_MEM_TLBIA | PPC_74xx_TLB |
PPC_SEGMENT | PPC_EXTERN |
PPC_ALTIVEC;
pcc->insns_flags2 = PPC_NONE;
pcc->msr_mask = 0x000000000205FF77ULL;
pcc->mmu_model = POWERPC_MMU_32B;
#if defined(CONFIG_SOFTMMU)
pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
#endif
pcc->excp_model = POWERPC_EXCP_74xx;
pcc->bus_model = PPC_FLAGS_INPUT_6xx;
pcc->bfd_mach = bfd_mach_ppc_7400;
pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
POWERPC_FLAG_BUS_CLK;
}
#if defined (TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080