]> xenbits.xensource.com Git - qemu-xen-4.0-testing.git/commitdiff
Embedded PowerPC Device Control Registers infrastructure.
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 12 Apr 2007 21:11:03 +0000 (21:11 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 12 Apr 2007 21:11:03 +0000 (21:11 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2653 c046a42c-6fe2-441c-8c8c-71466251a162

hw/ppc.c
target-ppc/cpu.h
target-ppc/op_helper.c
vl.h

index f5c45001bbf2184386087aebd1895c31599b2ded..f502271bca24e734e29231a7dc3e510887183283 100644 (file)
--- a/hw/ppc.c
+++ b/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) */
index 0560a38a1ee643a96562acdd86647ce47a2908b6..2a2c4409d380cbc0683515383e09a5907c10da3f 100644 (file)
@@ -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"
 
index e1fff7f497428635dd35e161490d8ee6bf56bd18..a65da36b7b346c7b62c827457087d6ac3ddd21f9 100644 (file)
@@ -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)
diff --git a/vl.h b/vl.h
index b40ff3747530d275181ff071c9cc9cff1d5ba02d..df76a9fbcc47d524b61b2cfb903a6035e692dd66 100644 (file)
--- a/vl.h
+++ b/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);