This is an automated email from Gerrit. Kent Brinkley (jkbrinkley.img...@gmail.com) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/2410
-- gerrit commit 6b63589428ac48ec91c6aa0f90717d88facc4c8d Author: Kent Brinkley <jkbrinkley.img...@gmail.com> Date: Wed Nov 26 16:56:02 2014 -0700 New "Invalidate" cache command Added new command to allow user to invalidate either or both of the instruction and data caches. The MIPS core does not update the instruction cache if new code is written to memory. Typically, invalidate should be issued after writing to an instruction region of memory. The allnowb and datanowb options will step through the data cache clearing the cache tags. This is useful for initializing the cache before the memory controller is set up. Change-Id: I71e7d2d893b74f69e6a5b861d1f756417076af8d Signed-off-by: Kent Brinkley <jkbrinkley.img...@gmail.com> Cleaned up patch formatting issues Cleaned up patch formatting issues Change-Id: I1767b6e4189fdbd60fecf08b83a3d833591a31a9 Signed-off-by: Kent Brinkley <jkbrinkley.img...@gmail.com> Fixed checkpatch warning Fixed checkpatch warning Change-Id: I594e6c40ddecf785dd6672106fa28ebef44debd2 Signed-off-by: Kent Brinkley <jkbrinkley.img...@gmail.com> diff --git a/src/target/mips32.c b/src/target/mips32.c index a2d30b8..2dc7d48 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -10,6 +10,9 @@ * Copyright (C) 2011 by Drasko DRASKOVIC * * drasko.drasko...@gmail.com * * * + * Copyright (C) 2014 by Kent Brinkley * + * jkbrinkley.img...@gmail.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -40,41 +43,52 @@ static const char *mips_isa_strings[] = { }; static const struct { + unsigned option; + const char *arg; +} invalidate_cmd[5] = { + { ALL, "all", }, + { INST, "inst", }, + { DATA, "data", }, + { ALLNOWB, "allnowb", }, + { DATANOWB, "datanowb", }, +}; + +static const struct { unsigned id; const char *name; } mips32_regs[MIPS32NUMCOREREGS] = { - { 0, "zero", }, - { 1, "at", }, - { 2, "v0", }, - { 3, "v1", }, - { 4, "a0", }, - { 5, "a1", }, - { 6, "a2", }, - { 7, "a3", }, - { 8, "t0", }, - { 9, "t1", }, - { 10, "t2", }, - { 11, "t3", }, - { 12, "t4", }, - { 13, "t5", }, - { 14, "t6", }, - { 15, "t7", }, - { 16, "s0", }, - { 17, "s1", }, - { 18, "s2", }, - { 19, "s3", }, - { 20, "s4", }, - { 21, "s5", }, - { 22, "s6", }, - { 23, "s7", }, - { 24, "t8", }, - { 25, "t9", }, - { 26, "k0", }, - { 27, "k1", }, - { 28, "gp", }, - { 29, "sp", }, - { 30, "fp", }, - { 31, "ra", }, + { zero, "zero", }, + { AT, "at", }, + { v0, "v0", }, + { v1, "v1", }, + { a0, "a0", }, + { a1, "a1", }, + { a2, "a2", }, + { a3, "a3", }, + { t0, "t0", }, + { t1, "t1", }, + { t2, "t2", }, + { t3, "t3", }, + { t4, "t4", }, + { t5, "t5", }, + { t6, "t6", }, + { t7, "t7", }, + { s0, "s0", }, + { s1, "s1", }, + { s2, "s2", }, + { s3, "s3", }, + { s4, "s4", }, + { s5, "s5", }, + { s6, "s6", }, + { s7, "s7", }, + { t8, "t8", }, + { t9, "t9", }, + { k0, "k0", }, + { k1, "k1", }, + { gp, "gp", }, + { sp, "sp", }, + { fp, "fp", }, + { ra, "ra", }, { 32, "status", }, { 33, "lo", }, @@ -984,7 +998,7 @@ COMMAND_HANDLER(mips32_handle_dsp_command) /* find register name */ if (strcmp(mips32_dsp_regs[i].name, CMD_ARGV[0]) == 0) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - retval = mips32_pracc_write_dsp_regs (ejtag_info, value, mips32_dsp_regs[i].reg); + retval = mips32_pracc_write_dsp_regs(ejtag_info, value, mips32_dsp_regs[i].reg); return retval; } } @@ -1000,6 +1014,132 @@ COMMAND_HANDLER(mips32_handle_dsp_command) return ERROR_OK; } +COMMAND_HANDLER(mips32_handle_invalidate_cache_command) +{ + int retval = -1; + struct target *target = get_current_target(CMD_CTX); + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + int i = 0; + + char *cache_msg[] = {"all", "instr", "data", "L23", NULL, NULL, NULL}; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (CMD_ARGC >= 2) { + LOG_DEBUG("ERROR_COMMAND_SYNTAX_ERROR"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (CMD_ARGC == 1) { + /* PARSE command options - all/inst/data/allnowb/datanowb */ + for (i = 0; i < 5 ; i++) { + if (strcmp(CMD_ARGV[0], invalidate_cmd[i].arg) == 0) { + switch (invalidate_cmd[i].option) { + case ALL: + LOG_INFO("clearing %s cache", cache_msg[1]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[1].option); + if (retval != ERROR_OK) + return retval; + + /* TODO: Add L2 code */ + /* LOG_INFO("clearing %s cache", cache_msg[3]); */ + /* retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, L2); */ + /* if (retval != ERROR_OK) */ + /* return retval; */ + + LOG_INFO("clearing %s cache", cache_msg[0]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[i].option); + if (retval != ERROR_OK) + return retval; + + break; + + case INST: + LOG_INFO("clearing %s cache", cache_msg[invalidate_cmd[i].option]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[i].option); + if (retval != ERROR_OK) + return retval; + + break; + + case DATA: + LOG_INFO("clearing %s cache", cache_msg[invalidate_cmd[i].option]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[i].option); + if (retval != ERROR_OK) + return retval; + + break; + + case ALLNOWB: + LOG_INFO("clearing %s cache no writeback", cache_msg[invalidate_cmd[i].option]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[i].option); + if (retval != ERROR_OK) + return retval; + + /* TODO: Add L2 code */ + /* LOG_INFO("clearing %s cache no writeback", cache_msg[3]); */ + /* retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, L2); */ + /* if (retval != ERROR_OK) */ + /* return retval; */ + + LOG_INFO("clearing %s cache", cache_msg[0]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[0].option); + if (retval != ERROR_OK) + return retval; + + break; + + case DATANOWB: + LOG_INFO("clearing %s cache no writeback", cache_msg[2]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[i].option); + if (retval != ERROR_OK) + return retval; + break; + + default: + LOG_ERROR("Invalid command argument '%s' not found", CMD_ARGV[0]); + return ERROR_COMMAND_SYNTAX_ERROR; + break; + } + + if (retval == ERROR_FAIL) + return ERROR_FAIL; + else + break; + } else { + if (i >= DATANOWB) { + LOG_ERROR("Invalid command argument '%s' not found", CMD_ARGV[0]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + } + + } + } else { + /* default is All */ + LOG_INFO("clearing %s cache", cache_msg[1]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[1].option); + if (retval != ERROR_OK) + return retval; + + /* TODO: Add L2 code */ + /* LOG_INFO("clearing %s cache", cache_msg[2]); */ + /* retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, L2); */ + /* if (retval != ERROR_OK) */ + /* return retval; */ + + LOG_INFO("clearing %s cache", cache_msg[0]); + retval = mips32_pracc_invalidate_cache(target, ejtag_info, 0, 0, 0, invalidate_cmd[0].option); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + COMMAND_HANDLER(mips32_handle_scan_delay_command) { return mips32_scan_delay_command(cmd); @@ -1014,6 +1154,13 @@ static const struct command_registration mips32_exec_command_handlers[] = { .usage = "[[reg_name|regnum select] [value]]", }, { + .name = "invalidate", + .handler = mips32_handle_invalidate_cache_command, + .mode = COMMAND_EXEC, + .help = "Invalidate either or both the instruction and data caches.", + .usage = "[all|inst|data|allnowb|datanowb]", + }, + { .name = "scan_delay", .handler = mips32_handle_scan_delay_command, .mode = COMMAND_ANY, diff --git a/src/target/mips32.h b/src/target/mips32.h index de7b423..6ce8071 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -190,6 +190,142 @@ struct mips32_algorithm { enum mips32_isa_mode isa_mode; }; +#define zero 0 + +#define AT 1 + +#define v0 2 +#define v1 3 + +#define a0 4 +#define a1 5 +#define a2 6 +#define a3 7 +#define t0 8 +#define t1 9 +#define t2 10 +#define t3 11 +#define t4 12 +#define t5 13 +#define t6 14 +#define t7 15 +#define ta0 12 /* alias for $t4 */ +#define ta1 13 /* alias for $t5 */ +#define ta2 14 /* alias for $t6 */ +#define ta3 15 /* alias for $t7 */ + +#define s0 16 +#define s1 17 +#define s2 18 +#define s3 19 +#define s4 20 +#define s5 21 +#define s6 22 +#define s7 23 +#define s8 30 /* == fp */ + +#define t8 24 +#define t9 25 +#define k0 26 +#define k1 27 + +#define gp 28 + +#define sp 29 +#define fp 30 +#define ra 31 + +#define ALL 0 +#define INST 1 +#define DATA 2 +#define ALLNOWB 3 +#define DATANOWB 4 +#define L2 5 + +/* + * MIPS32 Config0 Register (CP0 Register 16, Select 0) + */ +#define CFG0_M 0x80000000 /* Config1 implemented */ +#define CFG0_BE 0x00008000 /* Big Endian */ +#define CFG0_ATMASK 0x00006000 /* Architecture type: */ +#define CFG0_AT_M32 (0<<13) /* MIPS32 */ +#define CFG0_AT_M64_A32 (1<<13) /* MIPS64, 32-bit addresses */ +#define CFG0_AT_M64_A64 (2<<13) /* MIPS64, 64-bit addresses */ +#define CFG0_AT_RES (3<<13) +#define CFG0_ARMASK 0x00001c00 +#define CFG0_ARSHIFT 10 +#define CFG0_MTMASK 0x00000380 +#define CFG0_MT_NONE (0<<7) +#define CFG0_MT_TLB (1<<7) +#define CFG0_MT_BAT (2<<7) +#define CFG0_MT_NONSTD (3<<7) +#define CFG0_VI 0x00000008 /* Icache is virtual */ +#define CFG0_K0MASK 0x00000007 /* KSEG0 coherency algorithm */ + +/* + * MIPS32 Config1 Register (CP0 Register 16, Select 1) + */ +#define CFG1_M 0x80000000 /* Config2 implemented */ +#define CFG1_MMUSMASK 0x7e000000 /* mmu size - 1 */ +#define CFG1_MMUSSHIFT 25 +#define CFG1_ISMASK 0x01c00000 /* icache lines 64<<n */ +#define CFG1_ISSHIFT 22 +#define CFG1_ILMASK 0x00380000 /* icache line size 2<<n */ +#define CFG1_ILSHIFT 19 +#define CFG1_IAMASK 0x00070000 /* icache ways - 1 */ +#define CFG1_IASHIFT 16 +#define CFG1_DSMASK 0x0000e000 /* dcache lines 64<<n */ +#define CFG1_DSSHIFT 13 +#define CFG1_DLMASK 0x00001c00 /* dcache line size 2<<n */ +#define CFG1_DLSHIFT 10 + +/* + * MIPS32 Config1 Register (CP0 Register 16, Select 1) + */ +#define CFG1_M 0x80000000 /* Config2 implemented */ +#define CFG1_MMUSMASK 0x7e000000 /* mmu size - 1 */ +#define CFG1_MMUSSHIFT 25 +#define CFG1_ISMASK 0x01c00000 /* icache lines 64<<n */ +#define CFG1_ISSHIFT 22 +#define CFG1_ILMASK 0x00380000 /* icache line size 2<<n */ +#define CFG1_ILSHIFT 19 +#define CFG1_IAMASK 0x00070000 /* icache ways - 1 */ +#define CFG1_IASHIFT 16 +#define CFG1_DSMASK 0x0000e000 /* dcache lines 64<<n */ +#define CFG1_DSSHIFT 13 +#define CFG1_DLMASK 0x00001c00 /* dcache line size 2<<n */ +#define CFG1_DLSHIFT 10 +#define CFG1_DAMASK 0x00000380 /* dcache ways - 1 */ +#define CFG1_DASHIFT 7 +#define CFG1_C2 0x00000040 /* Coprocessor 2 present */ +#define CFG1_MD 0x00000020 /* MDMX implemented */ +#define CFG1_PC 0x00000010 /* performance counters implemented */ +#define CFG1_WR 0x00000008 /* watch registers implemented */ +#define CFG1_CA 0x00000004 /* compression (mips16) implemented */ +#define CFG1_EP 0x00000002 /* ejtag implemented */ +#define CFG1_FP 0x00000001 /* fpu implemented */ + +/* + * MIPS32r2 Config2 Register (CP0 Register 16, Select 2) + */ +#define CFG2_M 0x80000000 /* Config3 implemented */ +#define CFG2_TUMASK 0x70000000 /* tertiary cache control */ +#define CFG2_TUSHIFT 28 +#define CFG2_TSMASK 0x0f000000 /* tcache sets per wway 64<<n */ +#define CFG2_TSSHIFT 24 +#define CFG2_TLMASK 0x00f00000 /* tcache line size 2<<n */ +#define CFG2_TLSHIFT 20 +#define CFG2_TAMASK 0x000f0000 /* tcache ways - 1 */ +#define CFG2_TASHIFT 16 +#define CFG2_SUMASK 0x0000f000 /* secondary cache control */ +#define CFG2_SUSHIFT 12 +#define CFG2_SSMASK 0x00000f00 /* scache sets per wway 64<<n */ +#define CFG2_SSSHIFT 8 +#define CFG2_SLMASK 0x000000f0 /* scache line size 2<<n */ +#define CFG2_SLSHIFT 4 +#define CFG2_SAMASK 0x0000000f /* scache ways - 1 */ +#define CFG2_SASHIFT 0 + /* * MIPS32r2 Config3 Register (CP0 Register 16, Select 3) */ @@ -206,6 +342,95 @@ struct mips32_algorithm { #define CFG3_SM 0x00000002 /* SmartMIPS ASE */ #define CFG3_TL 0x00000001 /* Trace Logic */ +/* + * Cache operations + */ +#define Index_Invalidate_I 0x00 /* 0 0 */ +#define Index_Writeback_Inv_D 0x01 /* 0 1 */ +#define Index_Writeback_Inv_T 0x02 /* 0 2 */ +#define Index_Writeback_Inv_S 0x03 /* 0 3 */ +#define Index_Load_Tag_I 0x04 /* 1 0 */ +#define Index_Load_Tag_D 0x05 /* 1 1 */ +#define Index_Load_Tag_T 0x06 /* 1 2 */ +#define Index_Load_Tag_S 0x07 /* 1 3 */ +#define Index_Store_Tag_I 0x08 /* 2 0 */ +#define Index_Store_Tag_D 0x09 /* 2 1 */ +#define Index_Store_Tag_T 0x0A /* 2 2 */ +#define Index_Store_Tag_S 0x0B /* 2 3 */ +#define Hit_Invalidate_I 0x10 /* 4 0 */ +#define Hit_Invalidate_D 0x11 /* 4 1 */ +#define Hit_Invalidate_T 0x12 /* 4 2 */ +#define Hit_Invalidate_S 0x13 /* 4 3 */ +#define Fill_I 0x14 /* 5 0 */ +#define Hit_Writeback_Inv_D 0x15 /* 5 1 */ +#define Hit_Writeback_Inv_T 0x16 /* 5 2 */ +#define Hit_Writeback_Inv_S 0x17 /* 5 3 */ +#define Hit_Writeback_D 0x19 /* 6 1 */ +#define Hit_Writeback_T 0x1A /* 6 1 */ +#define Hit_Writeback_S 0x1B /* 6 3 */ +#define Fetch_Lock_I 0x1C /* 7 0 */ +#define Fetch_Lock_D 0x1D /* 7 1 */ + +/* + * MIPS32 Coprocessor 0 register numbers + */ +#define C0_INDEX 0 +#define C0_INX 0 +#define C0_RANDOM 1 +#define C0_RAND 1 +#define C0_ENTRYLO0 2 +#define C0_TLBLO0 2 +#define C0_ENTRYLO1 3 +#define C0_TLBLO1 3 +#define C0_CONTEXT 4 +#define C0_CTXT 4 +#define C0_PAGEMASK 5 +#define C0_PAGEGRAIN (5, 1) +#define C0_WIRED 6 +#define C0_HWRENA 7 +#define C0_BADVADDR 8 +#define C0_VADDR 8 +#define C0_COUNT 9 +#define C0_ENTRYHI 10 +#define C0_TLBHI 10 +#define C0_COMPARE 11 +#define C0_STATUS 12 +#define C0_SR 12 +#define C0_INTCTL (12, 1) +#define C0_SRSCTL (12, 2) +#define C0_SRSMAP (12, 3) +#define C0_CAUSE 13 +#define C0_CR 13 +#define C0_EPC 14 +#define C0_PRID 15 +#define C0_EBASE (15, 1) +#define C0_CONFIG 16 +#define C0_CONFIG0 (16, 0) +#define C0_CONFIG1 (16, 1) +#define C0_CONFIG2 (16, 2) +#define C0_CONFIG3 (16, 3) +#define C0_LLADDR 17 +#define C0_WATCHLO 18 +#define C0_WATCHHI 19 +#define C0_DEBUG 23 +#define C0_DEPC 24 +#define C0_PERFCNT 25 +#define C0_ERRCTL 26 +#define C0_CACHEERR 27 +#define C0_TAGLO 28 +#define C0_ITAGLO 28 +#define C0_DTAGLO (28, 2) +#define C0_TAGLO2 (28, 4) +#define C0_DATALO (28, 1) +#define C0_IDATALO (28, 1) +#define C0_DDATALO (28, 3) +#define C0_DATALO2 (28, 5) +#define C0_TAGHI 29 +#define C0_ITAGHI 29 +#define C0_DATAHI (29, 1) +#define C0_ERRPC 30 +#define C0_DESAVE 31 + #define MIPS32_OP_ADDIU 0x21 #define MIPS32_OP_ANDI 0x0C #define MIPS32_OP_BEQ 0x04 @@ -216,7 +441,7 @@ struct mips32_algorithm { #define MIPS32_OP_CACHE 0x2F #define MIPS32_OP_COP0 0x10 #define MIPS32_OP_EXT 0x1F -#define MIPS32_OP_J 0x02 +#define MIPS32_OP_J0 x02 #define MIPS32_OP_JR 0x08 #define MIPS32_OP_LUI 0x0F #define MIPS32_OP_LW 0x23 diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index f9985dd..3a09c7b 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -891,6 +891,173 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz return retval; } +int mips32_pracc_invalidate_cache(struct target *target, struct mips_ejtag *ejtag_info, + uint32_t addr, int size, int count, int cache) +{ + static uint32_t inv_inst_cache[] = { + MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ + + /* Determine how big the I$ is */ + MIPS32_MFC0(t2, 16, 1), /* C0_Config1 */ + + /* Isolate I$ Line Size */ + MIPS32_EXT(t3, t2, CFG1_ILSHIFT, 3), /* S_Config1IL, W_Config1IL */ + MIPS32_ADDIU(t6, zero, 2), + MIPS32_SLLV(t3, t6, t3), /* Now have true I$ line size in bytes */ + MIPS32_LUI(t6, 0x8000), /* Get a KSeg0 address for cacheops */ + + /* Clear TagLo/TagHi registers */ + MIPS32_MTC0(zero, C0_ITAGLO, 0), /* C0_ITagLo */ + MIPS32_MTC0(zero, C0_ITAGHI, 0), /* C0_ITagHi */ + }; + + uint32_t inv_data_cache_nowb[] = { + + MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ + MIPS32_MFC0(v0, 16, 1), /* read C0_Config1 */ + + /* Isolate D$ Line Size */ + MIPS32_EXT(v1, v0, CFG1_DLSHIFT, 3), /* extract DL */ + MIPS32_ADDIU(a2, zero, 2), /* li a2, 2 */ + MIPS32_SLLV(v1, a2, v1), /* Now have true D$ line size in bytes */ + + MIPS32_LUI(a2, 0x8000), /* Get a KSeg0 address for cacheops */ + + /* Clear TagLo/TagHi registers */ + MIPS32_MTC0(zero, C0_TAGLO, 0), /* write C0_TagLo */ + MIPS32_MTC0(zero, C0_TAGHI, 0), /* write C0_TagHi */ + MIPS32_MTC0(zero, C0_TAGLO, 2), /* write C0_DTagLo */ + MIPS32_MTC0(zero, C0_TAGHI, 2), /* write C0_DTagHi */ + + MIPS32_OR(a3, a0, zero), /* move a3, a0 */ + +/* next_dcache_tag: */ + /* Index Store Tag Cache Op */ + /* Will invalidate the tag entry, clear the lock bit, and clear the LRF bit */ + + MIPS32_CACHE(Index_Store_Tag_D, 0, a2), /* DCIndexStTag */ + MIPS32_ADD(a2, a2, v1), /* Get next line address */ + }; + + uint32_t done[] = { + MIPS32_LUI(t7, UPPER16(MIPS32_PRACC_TEXT)), + MIPS32_ORI(t7, t7, LOWER16(MIPS32_PRACC_TEXT)), + MIPS32_JR(t7), /* jr start */ + MIPS32_NOP + }; + + struct pracc_queue_info ctx = {.max_code = 65536+20}; /* alloc memory for the worst case */ + + uint32_t conf; + uint32_t clsiz; + uint32_t ways, sets, bpl; + + pracc_queue_init(&ctx); + if (ctx.retval != ERROR_OK) { + LOG_ERROR("pracc_queue_init failed"); + goto exit; + } + + /* Read Config1 Register to retrieve cache info */ + mips32_cp0_read(ejtag_info, &conf, 16, 1); + + switch (cache) { + case INST: + /* Extract cache line size */ + bpl = (conf >> CFG1_ILSHIFT) & 7; /* bit 21:19 */ + + /* Core configured with Instruction cache */ + if (bpl == 0) { + LOG_USER("no instructure cache configured"); + ctx.retval = ERROR_OK; + goto exit; + } + + for (int i = 0; i < (int) ARRAY_SIZE(inv_inst_cache); i++) + pracc_add(&ctx, 0, inv_inst_cache[i]); + + /** + * Find cache line size in bytes + */ + + /* Determine Instr Cache Size */ + ways = (conf >> CFG1_IASHIFT) & 7; /* bits 18:16 */ + ways++; + + sets = (conf >> CFG1_ISSHIFT) & 7; /* bits 24:22 */ + sets = 64 << sets; + clsiz = sets * ways; + + /* Flush Instruction Cache */ + for (int i = 0; i < (int)clsiz; i++) { + pracc_add(&ctx, 0, MIPS32_CACHE(Index_Store_Tag_I, 0, t6)); + pracc_add(&ctx, 0, MIPS32_ADD(t6, t6, t3)); + } + + break; + + case DATA: + case ALLNOWB: + case DATANOWB: + + /* Extract cache line size */ + bpl = (conf >> CFG1_DLSHIFT) & 7; /* bit 12:10 */ + + /* Core configured with Instruction cache */ + if (bpl == 0) { + LOG_USER("no data cache configured"); + ctx.retval = ERROR_OK; + goto exit; + } + + for (int i = 0; i < (int) ARRAY_SIZE(inv_inst_cache); i++) + pracc_add(&ctx, 0, inv_inst_cache[i]); + + /** + * Find cache line size in bytes + */ + + /* Determine Instr Cache Size */ + ways = (conf >> CFG1_DASHIFT) & 7; /* bits 9:7 */ + ways++; + + sets = (conf >> CFG1_DSSHIFT) & 7; /* bits 15:13 */ + sets = 64 << sets; + clsiz = sets * ways; + + /* Flush Instruction Cache */ + for (int i = 0; i < (int) clsiz; i++) { + if (cache == DATA) + pracc_add(&ctx, 0, MIPS32_CACHE(Hit_Writeback_Inv_D, 0, a2)); + else { + if ((cache == ALLNOWB) || (cache == DATANOWB)) + pracc_add(&ctx, 0, MIPS32_CACHE(Index_Store_Tag_D, 0, a2)); + } + + pracc_add(&ctx, 0, MIPS32_ADD(t6, t6, t3)); + } + + break; + + case L2: + break; + + } + + /* Write exit code */ + for (int i = 0; i < (int) ARRAY_SIZE(done); i++) + pracc_add(&ctx, 0, done[i]); + + /* Start code execution */ + ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); + if (ctx.retval != ERROR_OK) + LOG_DEBUG("mips32_pracc_queue_exec failed - ctx.retval: %d", ctx.retval); + +exit: + pracc_queue_free(&ctx); + return ctx.retval; +} + int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) { static const uint32_t cp0_write_code[] = { diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h index a7bc277..db81e62 100644 --- a/src/target/mips32_pracc.h +++ b/src/target/mips32_pracc.h @@ -51,6 +51,8 @@ struct pracc_queue_info { int store_count; uint32_t *pracc_list; /* Code and store addresses */ }; +int mips32_pracc_invalidate_cache(struct target *, struct mips_ejtag *, + uint32_t, int, int, int); void pracc_queue_init(struct pracc_queue_info *ctx); void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr); void pracc_queue_free(struct pracc_queue_info *ctx); -- ------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk _______________________________________________ OpenOCD-devel mailing list OpenOCD-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openocd-devel