mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Great rework and cleanups to ease PowerPC implementations definitions.
* cleanup cpu.h, removing definitions used only in translate.c/translate_init.c * add new flags to define instructions sets more precisely * various changes in MMU models definitions * add definitions for PowerPC 440/460 support (insns and SPRs). * add definitions for PowerPC 401/403 and 620 input pins model * Fix definitions for most PowerPC 401, 403, 405, 440, 601, 602, 603 and 7x0 * Preliminary support for PowerPC 74xx (aka G4) without altivec. * Code provision for other PowerPC support (7x5, 970, ...). * New SPR and PVR defined, from PowerPC 2.04 specification and other sources * Misc code bugs, error messages and styles fixes. * Update status files for PowerPC cores support. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3244 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -376,11 +376,11 @@ static void ppc405_set_irq (void *opaque, int pin, int level)
|
||||
/* Level sensitive - active high */
|
||||
#if defined(PPC_DEBUG_IRQ)
|
||||
if (loglevel & CPU_LOG_INT) {
|
||||
fprintf(logfile, "%s: set the external IRQ state to %d\n",
|
||||
fprintf(logfile, "%s: set the debug pin state to %d\n",
|
||||
__func__, level);
|
||||
}
|
||||
#endif
|
||||
ppc_set_irq(env, EXCP_40x_DEBUG, level);
|
||||
ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
|
||||
break;
|
||||
default:
|
||||
/* Unknown pin - do nothing */
|
||||
@@ -904,6 +904,9 @@ struct ppc_dcrn_t {
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
/* XXX: on 460, DCR addresses are 32 bits wide,
|
||||
* using DCRIPR to get the 22 upper bits of the DCR address
|
||||
*/
|
||||
#define DCRN_NB 1024
|
||||
struct ppc_dcr_t {
|
||||
ppc_dcrn_t dcrn[DCRN_NB];
|
||||
|
||||
+14
-3
@@ -712,6 +712,17 @@ uint32_t cpu_ppc601_load_rtcl (CPUState *env)
|
||||
return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
|
||||
}
|
||||
|
||||
/* XXX: to be fixed */
|
||||
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void cpu_loop(CPUPPCState *env)
|
||||
{
|
||||
target_siginfo_t info;
|
||||
@@ -761,7 +772,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
case EXCP_MACHINE_CHECK:
|
||||
fprintf(stderr, "Machine check exeption... Stop emulation\n");
|
||||
if (loglevel)
|
||||
fprintf(logfile, "RESET asked... Stop emulation\n");
|
||||
fprintf(logfile, "Machine check exception. Stop emulation\n");
|
||||
info.si_signo = TARGET_SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_BUS_OBJERR;
|
||||
@@ -914,7 +925,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
info.si_code = TARGET_ILL_ILLOPC;
|
||||
break;
|
||||
case EXCP_INVAL_LSWX:
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
break;
|
||||
case EXCP_INVAL_SPR:
|
||||
info.si_code = TARGET_ILL_PRVREG;
|
||||
@@ -1003,7 +1014,7 @@ void cpu_loop(CPUPPCState *env)
|
||||
if (loglevel)
|
||||
fprintf(logfile, "Tried to go into supervisor mode !\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXCP_BRANCH:
|
||||
/* We stopped because of a jump... */
|
||||
|
||||
+428
-233
File diff suppressed because it is too large
Load Diff
+140
-503
File diff suppressed because it is too large
Load Diff
@@ -106,6 +106,8 @@ void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
|
||||
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
|
||||
target_ulong pte0, target_ulong pte1);
|
||||
void ppc4xx_tlb_invalidate_all (CPUState *env);
|
||||
void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
|
||||
uint32_t pid);
|
||||
|
||||
static inline void env_to_regs (void)
|
||||
{
|
||||
|
||||
+161
-126
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -2319,7 +2319,6 @@ void OPPROTO op_405_check_satu (void)
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void OPPROTO op_load_dcr (void)
|
||||
{
|
||||
do_load_dcr();
|
||||
@@ -2332,6 +2331,7 @@ void OPPROTO op_store_dcr (void)
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* Return from critical interrupt :
|
||||
* same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
|
||||
*/
|
||||
|
||||
+46
-47
@@ -1206,6 +1206,41 @@ void do_405_check_sat (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: to be improved to check access rights when in user-mode */
|
||||
void do_load_dcr (void)
|
||||
{
|
||||
target_ulong val;
|
||||
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "No DCR environment\n");
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
} else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
} else {
|
||||
T0 = val;
|
||||
}
|
||||
}
|
||||
|
||||
void do_store_dcr (void)
|
||||
{
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "No DCR environment\n");
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
} else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_40x_rfci (void)
|
||||
{
|
||||
@@ -1268,40 +1303,6 @@ void do_rfmci (void)
|
||||
env->interrupt_request = CPU_INTERRUPT_EXITTB;
|
||||
}
|
||||
|
||||
void do_load_dcr (void)
|
||||
{
|
||||
target_ulong val;
|
||||
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "No DCR environment\n");
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
} else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
} else {
|
||||
T0 = val;
|
||||
}
|
||||
}
|
||||
|
||||
void do_store_dcr (void)
|
||||
{
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "No DCR environment\n");
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
} else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
|
||||
if (loglevel != 0) {
|
||||
fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
|
||||
}
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
}
|
||||
}
|
||||
|
||||
void do_load_403_pb (int num)
|
||||
{
|
||||
T0 = env->pb[num];
|
||||
@@ -2238,7 +2239,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
|
||||
if (unlikely(ret != 0)) {
|
||||
if (likely(retaddr)) {
|
||||
/* now we have a real cpu fault */
|
||||
pc = (target_phys_addr_t)retaddr;
|
||||
pc = (target_phys_addr_t)(unsigned long)retaddr;
|
||||
tb = tb_find_pc(pc);
|
||||
if (likely(tb)) {
|
||||
/* the PC is inside the translated code. It means that we have
|
||||
@@ -2261,16 +2262,14 @@ void do_tlbie (void)
|
||||
{
|
||||
T0 = (uint32_t)T0;
|
||||
#if !defined(FLUSH_ALL_TLBS)
|
||||
if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
|
||||
/* XXX: Remove thoses tests */
|
||||
if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
|
||||
ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
|
||||
if (env->id_tlbs == 1)
|
||||
ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
|
||||
} else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
|
||||
/* XXX: TODO */
|
||||
#if 0
|
||||
ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
|
||||
env->spr[SPR_BOOKE_PID]);
|
||||
#endif
|
||||
} else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
|
||||
ppc4xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
|
||||
env->spr[SPR_40x_PID]);
|
||||
} else {
|
||||
/* tlbie invalidate TLBs for all segments */
|
||||
T0 &= TARGET_PAGE_MASK;
|
||||
@@ -2305,11 +2304,11 @@ void do_tlbie_64 (void)
|
||||
{
|
||||
T0 = (uint64_t)T0;
|
||||
#if !defined(FLUSH_ALL_TLBS)
|
||||
if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
|
||||
if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
|
||||
ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
|
||||
if (env->id_tlbs == 1)
|
||||
ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
|
||||
} else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
|
||||
} else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
|
||||
/* XXX: TODO */
|
||||
#if 0
|
||||
ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
|
||||
@@ -2541,7 +2540,7 @@ void do_4xx_tlbwe_hi (void)
|
||||
"are not supported (%d)\n",
|
||||
tlb->size, TARGET_PAGE_SIZE, (int)((T1 >> 7) & 0x7));
|
||||
}
|
||||
tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1);
|
||||
tlb->EPN = T1 & ~(tlb->size - 1);
|
||||
if (T1 & 0x40)
|
||||
tlb->prot |= PAGE_VALID;
|
||||
else
|
||||
@@ -2676,14 +2675,14 @@ void do_440_tlbwe (int word)
|
||||
|
||||
void do_440_tlbsx (void)
|
||||
{
|
||||
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
|
||||
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
|
||||
}
|
||||
|
||||
void do_440_tlbsx_ (void)
|
||||
{
|
||||
int tmp = xer_so;
|
||||
|
||||
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
|
||||
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
|
||||
if (T0 != -1)
|
||||
tmp |= 0x02;
|
||||
env->crf[0] = tmp;
|
||||
|
||||
@@ -167,9 +167,9 @@ void do_440_tlbwe (int word);
|
||||
/* PowerPC 4xx specific helpers */
|
||||
void do_405_check_ov (void);
|
||||
void do_405_check_sat (void);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_load_dcr (void);
|
||||
void do_store_dcr (void);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_40x_rfci (void);
|
||||
void do_rfci (void);
|
||||
void do_rfdi (void);
|
||||
|
||||
+224
-99
File diff suppressed because it is too large
Load Diff
+3324
-2174
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user