Cortex-A8: stop using CP15 ops
authorDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 1 Dec 2009 08:48:40 +0000 (00:48 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 1 Dec 2009 08:48:40 +0000 (00:48 -0800)
There were two chunks of Cortex-A8 code which called the
ARMv7-A CP15 operations; get rid of them, helping prepare
to remove those methods completely:

 - post_debug_entry() can use the mrc() method to read
   its two registers.

 - write_memory() can use dpm->instr_write_data_r0() to
   flush the ICache and DCache ... doing it this way is
   actually faster since it reduces per-write overhead.

Note that the mrc() method parameters are re-ordered with
respect to the ARM instruction documentation, so that part
can be confusing.

Cleaned up the layout and comments in those areas a bit.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/target/cortex_a8.c

index 8402081dfc947a2b20caa2e18b7ad6c0e407a38e..652efa9353ac5036076516e62bc8a233c7b17165 100644 (file)
@@ -933,19 +933,26 @@ static void cortex_a8_post_debug_entry(struct target *target)
 {
        struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
        struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
+       int retval;
 
-//     cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
-       /* examine cp15 control reg */
-       armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
-       jtag_execute_queue();
+       /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
+       retval = target->type->mrc(target, 15,
+                       0, 0,   /* op1, op2 */
+                       1, 0,   /* CRn, CRm */
+                       &cortex_a8->cp15_control_reg);
        LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
 
        if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
        {
                uint32_t cache_type_reg;
-               /* identify caches */
-               armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
-               jtag_execute_queue();
+
+               /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
+               retval = target->type->mrc(target, 15,
+                               0, 1,   /* op1, op2 */
+                               0, 0,   /* CRn, CRm */
+                               &cache_type_reg);
+               LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg);
+
                /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
                armv4_5_identify_cache(cache_type_reg,
                                &armv7a->armv4_5_mmu.armv4_5_cache);
@@ -1350,25 +1357,55 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address,
                }
        }
 
+       /* REVISIT this op is generic ARMv7-A/R stuff */
        if (retval == ERROR_OK && target->state == TARGET_HALTED)
        {
-               /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
+               struct arm_dpm *dpm = armv7a->armv4_5_common.dpm;
+
+               retval = dpm->prepare(dpm);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               /* The Cache handling will NOT work with MMU active, the
+                * wrong addresses will be invalidated!
+                *
+                * For both ICache and DCache, walk all cache lines in the
+                * address range. Cortex-A8 has fixed 64 byte line length.
+                */
+
                /* invalidate I-Cache */
                if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
                {
-                       /* Invalidate ICache single entry with MVA, repeat this for all cache
-                          lines in the address range, Cortex-A8 has fixed 64 byte line length */
-                       /* Invalidate Cache single entry with MVA to PoU */
-                       for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
-                               armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
+                       /* ICIMVAU - Invalidate Cache single entry
+                        * with MVA to PoU
+                        *      MCR p15, 0, r0, c7, c5, 1
+                        */
+                       for (uint32_t cacheline = address;
+                                       cacheline < address + size * count;
+                                       cacheline += 64) {
+                               retval = dpm->instr_write_data_r0(dpm,
+                                       ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
+                                       cacheline);
+                       }
                }
+
                /* invalidate D-Cache */
                if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
                {
-                       /* Invalidate Cache single entry with MVA to PoC */
-                       for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
-                               armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
+                       /* DCIMVAC - Invalidate data Cache line
+                        * with MVA to PoC
+                        *      MCR p15, 0, r0, c7, c6, 1
+                        */
+                       for (uint32_t cacheline = address;
+                                       cacheline < address + size * count;
+                                       cacheline += 64) {
+                               retval = dpm->instr_write_data_r0(dpm,
+                                       ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
+                                       cacheline);
+                       }
                }
+
+               /* (void) */ dpm->finish(dpm);
        }
 
        return retval;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)