mirror of https://github.com/xemu-project/xemu.git
Embedded PowerPC Device Control Registers infrastructure.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2653 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
83b1fb88f8
commit
2e719ba347
95
hw/ppc.c
95
hw/ppc.c
|
@ -547,6 +547,101 @@ void ppc_emb_timers_init (CPUState *env)
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Embedded PowerPC Device Control Registers */
|
||||
typedef struct ppc_dcrn_t ppc_dcrn_t;
|
||||
struct ppc_dcrn_t {
|
||||
dcr_read_cb dcr_read;
|
||||
dcr_write_cb dcr_write;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
#define DCRN_NB 1024
|
||||
struct ppc_dcr_t {
|
||||
ppc_dcrn_t dcrn[DCRN_NB];
|
||||
int (*read_error)(int dcrn);
|
||||
int (*write_error)(int dcrn);
|
||||
};
|
||||
|
||||
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
|
||||
{
|
||||
ppc_dcrn_t *dcr;
|
||||
|
||||
if (dcrn < 0 || dcrn >= DCRN_NB)
|
||||
goto error;
|
||||
dcr = &dcr_env->dcrn[dcrn];
|
||||
if (dcr->dcr_read == NULL)
|
||||
goto error;
|
||||
*valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (dcr_env->read_error != NULL)
|
||||
return (*dcr_env->read_error)(dcrn);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
|
||||
{
|
||||
ppc_dcrn_t *dcr;
|
||||
|
||||
if (dcrn < 0 || dcrn >= DCRN_NB)
|
||||
goto error;
|
||||
dcr = &dcr_env->dcrn[dcrn];
|
||||
if (dcr->dcr_write == NULL)
|
||||
goto error;
|
||||
(*dcr->dcr_write)(dcr->opaque, dcrn, val);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (dcr_env->write_error != NULL)
|
||||
return (*dcr_env->write_error)(dcrn);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
|
||||
dcr_read_cb dcr_read, dcr_write_cb dcr_write)
|
||||
{
|
||||
ppc_dcr_t *dcr_env;
|
||||
ppc_dcrn_t *dcr;
|
||||
|
||||
dcr_env = env->dcr_env;
|
||||
if (dcr_env == NULL)
|
||||
return -1;
|
||||
if (dcrn < 0 || dcrn >= DCRN_NB)
|
||||
return -1;
|
||||
dcr = &dcr_env->dcrn[dcrn];
|
||||
if (dcr->opaque != NULL ||
|
||||
dcr->dcr_read != NULL ||
|
||||
dcr->dcr_write != NULL)
|
||||
return -1;
|
||||
dcr->opaque = opaque;
|
||||
dcr->dcr_read = dcr_read;
|
||||
dcr->dcr_write = dcr_write;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
|
||||
int (*write_error)(int dcrn))
|
||||
{
|
||||
ppc_dcr_t *dcr_env;
|
||||
|
||||
dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
|
||||
if (dcr_env == NULL)
|
||||
return -1;
|
||||
dcr_env->read_error = read_error;
|
||||
dcr_env->write_error = write_error;
|
||||
env->dcr_env = dcr_env;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*****************************************************************************/
|
||||
/* Handle system reset (for now, just stop emulation) */
|
||||
|
|
|
@ -730,8 +730,6 @@ struct CPUPPCState {
|
|||
/* Time base and decrementer */
|
||||
ppc_tb_t *tb_env;
|
||||
/* Device control registers */
|
||||
int (*dcr_read)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong *val);
|
||||
int (*dcr_write)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong val);
|
||||
ppc_dcr_t *dcr_env;
|
||||
|
||||
/* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */
|
||||
|
@ -863,6 +861,10 @@ void store_booke_tsr (CPUPPCState *env, target_ulong val);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* Device control registers */
|
||||
int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp);
|
||||
int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
|
||||
|
||||
#define TARGET_PAGE_BITS 12
|
||||
#include "cpu-all.h"
|
||||
|
||||
|
|
|
@ -1249,20 +1249,26 @@ void do_load_dcr (void)
|
|||
{
|
||||
target_ulong val;
|
||||
|
||||
if (unlikely(env->dcr_read == NULL))
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
printf("No DCR environment\n");
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
else if (unlikely((*env->dcr_read)(env->dcr_env, T0, &val) != 0))
|
||||
} else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
|
||||
printf("DCR read error\n");
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
else
|
||||
} else {
|
||||
T0 = val;
|
||||
}
|
||||
}
|
||||
|
||||
void do_store_dcr (void)
|
||||
{
|
||||
if (unlikely(env->dcr_write == NULL))
|
||||
if (unlikely(env->dcr_env == NULL)) {
|
||||
printf("No DCR environment\n");
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
|
||||
else if (unlikely((*env->dcr_write)(env->dcr_env, T0, T1) != 0))
|
||||
} else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
|
||||
printf("DCR write error\n");
|
||||
do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
|
||||
}
|
||||
}
|
||||
|
||||
void do_load_403_pb (int num)
|
||||
|
|
7
vl.h
7
vl.h
|
@ -1147,6 +1147,13 @@ extern QEMUMachine shix_machine;
|
|||
#ifdef TARGET_PPC
|
||||
/* PowerPC hardware exceptions management helpers */
|
||||
ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
|
||||
/* Embedded PowerPC DCR management */
|
||||
typedef target_ulong (*dcr_read_cb)(void *opaque, int dcrn);
|
||||
typedef void (*dcr_write_cb)(void *opaque, int dcrn, target_ulong val);
|
||||
int ppc_dcr_init (CPUState *env, int (*dcr_read_error)(int dcrn),
|
||||
int (*dcr_write_error)(int dcrn));
|
||||
int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
|
||||
dcr_read_cb drc_read, dcr_write_cb dcr_write);
|
||||
#endif
|
||||
void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
|
||||
|
||||
|
|
Loading…
Reference in New Issue