[PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
 };
 
+static const struct mips_perf_event i6400_event_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = { 0x00, CNTR_EVEN | CNTR_ODD },
+       [PERF_COUNT_HW_INSTRUCTIONS]        = { 0x01, CNTR_EVEN | CNTR_ODD },
+       /* These only count dcache, not icache */
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = { 0x45, CNTR_EVEN | CNTR_ODD },
+       [PERF_COUNT_HW_CACHE_MISSES]        = { 0x48, CNTR_EVEN | CNTR_ODD },
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x15, CNTR_EVEN | CNTR_ODD },
+       [PERF_COUNT_HW_BRANCH_MISSES]       = { 0x16, CNTR_EVEN | CNTR_ODD },
+};
+
 static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = {
        [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN },
        [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD },
 },
 };
 
+static const struct mips_perf_event i6400_cache_map
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x46, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x49, CNTR_EVEN | CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x47, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x4a, CNTR_EVEN | CNTR_ODD },
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x84, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x85, CNTR_EVEN | CNTR_ODD },
+       },
+},
+[C(DTLB)] = {
+       /* Can't distinguish read & write */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x40, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x41, CNTR_EVEN | CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x40, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x41, CNTR_EVEN | CNTR_ODD },
+       },
+},
+[C(BPU)] = {
+       /* Conditional branches / mispredicted */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x15, CNTR_EVEN | CNTR_ODD },
+               [C(RESULT_MISS)]        = { 0x16, CNTR_EVEN | CNTR_ODD },
+       },
+},
+};
+
 static const struct mips_perf_event loongson3_cache_map
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                break;
        case CPU_I6400:
                mipspmu.name = "mips/I6400";
-               mipspmu.general_event_map = &mipsxxcore_event_map2;
-               mipspmu.cache_event_map = &mipsxxcore_cache_map2;
+               mipspmu.general_event_map = &i6400_event_map;
+               mipspmu.cache_event_map = &i6400_cache_map;
                break;
        case CPU_1004K:
                mipspmu.name = "mips/1004K";