Commit 2e719ba3476fcf1c7c74649d9e16f486eb8c02fc

Authored by j_mayer
1 parent 83b1fb88

Embedded PowerPC Device Control Registers infrastructure.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2653 c046a42c-6fe2-441c-8c8c-71466251a162
hw/ppc.c
... ... @@ -547,6 +547,101 @@ void ppc_emb_timers_init (CPUState *env)
547 547 }
548 548 }
549 549  
  550 +/*****************************************************************************/
  551 +/* Embedded PowerPC Device Control Registers */
  552 +typedef struct ppc_dcrn_t ppc_dcrn_t;
  553 +struct ppc_dcrn_t {
  554 + dcr_read_cb dcr_read;
  555 + dcr_write_cb dcr_write;
  556 + void *opaque;
  557 +};
  558 +
  559 +#define DCRN_NB 1024
  560 +struct ppc_dcr_t {
  561 + ppc_dcrn_t dcrn[DCRN_NB];
  562 + int (*read_error)(int dcrn);
  563 + int (*write_error)(int dcrn);
  564 +};
  565 +
  566 +int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
  567 +{
  568 + ppc_dcrn_t *dcr;
  569 +
  570 + if (dcrn < 0 || dcrn >= DCRN_NB)
  571 + goto error;
  572 + dcr = &dcr_env->dcrn[dcrn];
  573 + if (dcr->dcr_read == NULL)
  574 + goto error;
  575 + *valp = (*dcr->dcr_read)(dcr->opaque, dcrn);
  576 +
  577 + return 0;
  578 +
  579 + error:
  580 + if (dcr_env->read_error != NULL)
  581 + return (*dcr_env->read_error)(dcrn);
  582 +
  583 + return -1;
  584 +}
  585 +
  586 +int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
  587 +{
  588 + ppc_dcrn_t *dcr;
  589 +
  590 + if (dcrn < 0 || dcrn >= DCRN_NB)
  591 + goto error;
  592 + dcr = &dcr_env->dcrn[dcrn];
  593 + if (dcr->dcr_write == NULL)
  594 + goto error;
  595 + (*dcr->dcr_write)(dcr->opaque, dcrn, val);
  596 +
  597 + return 0;
  598 +
  599 + error:
  600 + if (dcr_env->write_error != NULL)
  601 + return (*dcr_env->write_error)(dcrn);
  602 +
  603 + return -1;
  604 +}
  605 +
  606 +int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
  607 + dcr_read_cb dcr_read, dcr_write_cb dcr_write)
  608 +{
  609 + ppc_dcr_t *dcr_env;
  610 + ppc_dcrn_t *dcr;
  611 +
  612 + dcr_env = env->dcr_env;
  613 + if (dcr_env == NULL)
  614 + return -1;
  615 + if (dcrn < 0 || dcrn >= DCRN_NB)
  616 + return -1;
  617 + dcr = &dcr_env->dcrn[dcrn];
  618 + if (dcr->opaque != NULL ||
  619 + dcr->dcr_read != NULL ||
  620 + dcr->dcr_write != NULL)
  621 + return -1;
  622 + dcr->opaque = opaque;
  623 + dcr->dcr_read = dcr_read;
  624 + dcr->dcr_write = dcr_write;
  625 +
  626 + return 0;
  627 +}
  628 +
  629 +int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
  630 + int (*write_error)(int dcrn))
  631 +{
  632 + ppc_dcr_t *dcr_env;
  633 +
  634 + dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
  635 + if (dcr_env == NULL)
  636 + return -1;
  637 + dcr_env->read_error = read_error;
  638 + dcr_env->write_error = write_error;
  639 + env->dcr_env = dcr_env;
  640 +
  641 + return 0;
  642 +}
  643 +
  644 +
550 645 #if 0
551 646 /*****************************************************************************/
552 647 /* Handle system reset (for now, just stop emulation) */
... ...
target-ppc/cpu.h
... ... @@ -730,8 +730,6 @@ struct CPUPPCState {
730 730 /* Time base and decrementer */
731 731 ppc_tb_t *tb_env;
732 732 /* Device control registers */
733   - int (*dcr_read)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong *val);
734   - int (*dcr_write)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong val);
735 733 ppc_dcr_t *dcr_env;
736 734  
737 735 /* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */
... ... @@ -863,6 +861,10 @@ void store_booke_tsr (CPUPPCState *env, target_ulong val);
863 861 #endif
864 862 #endif
865 863  
  864 +/* Device control registers */
  865 +int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp);
  866 +int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
  867 +
866 868 #define TARGET_PAGE_BITS 12
867 869 #include "cpu-all.h"
868 870  
... ...
target-ppc/op_helper.c
... ... @@ -1249,20 +1249,26 @@ void do_load_dcr (void)
1249 1249 {
1250 1250 target_ulong val;
1251 1251  
1252   - if (unlikely(env->dcr_read == NULL))
  1252 + if (unlikely(env->dcr_env == NULL)) {
  1253 + printf("No DCR environment\n");
1253 1254 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
1254   - else if (unlikely((*env->dcr_read)(env->dcr_env, T0, &val) != 0))
  1255 + } else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
  1256 + printf("DCR read error\n");
1255 1257 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
1256   - else
  1258 + } else {
1257 1259 T0 = val;
  1260 + }
1258 1261 }
1259 1262  
1260 1263 void do_store_dcr (void)
1261 1264 {
1262   - if (unlikely(env->dcr_write == NULL))
  1265 + if (unlikely(env->dcr_env == NULL)) {
  1266 + printf("No DCR environment\n");
1263 1267 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
1264   - else if (unlikely((*env->dcr_write)(env->dcr_env, T0, T1) != 0))
  1268 + } else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
  1269 + printf("DCR write error\n");
1265 1270 do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
  1271 + }
1266 1272 }
1267 1273  
1268 1274 void do_load_403_pb (int num)
... ...
... ... @@ -1147,6 +1147,13 @@ extern QEMUMachine shix_machine;
1147 1147 #ifdef TARGET_PPC
1148 1148 /* PowerPC hardware exceptions management helpers */
1149 1149 ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
  1150 +/* Embedded PowerPC DCR management */
  1151 +typedef target_ulong (*dcr_read_cb)(void *opaque, int dcrn);
  1152 +typedef void (*dcr_write_cb)(void *opaque, int dcrn, target_ulong val);
  1153 +int ppc_dcr_init (CPUState *env, int (*dcr_read_error)(int dcrn),
  1154 + int (*dcr_write_error)(int dcrn));
  1155 +int ppc_dcr_register (CPUState *env, int dcrn, void *opaque,
  1156 + dcr_read_cb drc_read, dcr_write_cb dcr_write);
1150 1157 #endif
1151 1158 void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
1152 1159  
... ...