filename | src/sh4/pmm.c |
changeset | 1021:848db285a184 |
prev | 975:007bf7eb944f |
author | nkeynes |
date | Mon Sep 13 10:13:42 2010 +1000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Implement shadow-execution 'core' to run translator + interpreter side by side (for testing) |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * PMM (performance counter) module
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include "sh4/sh4mmio.h"
20 #include "sh4/sh4core.h"
21 #include "clock.h"
23 /*
24 * Performance counter list from Paul Mundt's OProfile patch
25 * Currently only 0x23 is actually supported, since it doesn't require any
26 * actual instrumentation
27 *
28 * 0x01 Operand read access
29 * 0x02 Operand write access
30 * 0x03 UTLB miss
31 * 0x04 Operand cache read miss
32 * 0x05 Operand cache write miss
33 * 0x06 Instruction fetch (w/ cache)
34 * 0x07 Instruction TLB miss
35 * 0x08 Instruction cache miss
36 * 0x09 All operand accesses
37 * 0x0a All instruction accesses
38 * 0x0b OC RAM operand access
39 * 0x0d On-chip I/O space access
40 * 0x0e Operand access (r/w)
41 * 0x0f Operand cache miss (r/w)
42 * 0x10 Branch instruction
43 * 0x11 Branch taken
44 * 0x12 BSR/BSRF/JSR
45 * 0x13 Instruction execution
46 * 0x14 Instruction execution in parallel
47 * 0x15 FPU Instruction execution
48 * 0x16 Interrupt
49 * 0x17 NMI
50 * 0x18 trapa instruction execution
51 * 0x19 UBCA match
52 * 0x1a UBCB match
53 * 0x21 Instruction cache fill
54 * 0x22 Operand cache fill
55 * 0x23 Elapsed time
56 * 0x24 Pipeline freeze by I-cache miss
57 * 0x25 Pipeline freeze by D-cache miss
58 * 0x27 Pipeline freeze by branch instruction
59 * 0x28 Pipeline freeze by CPU register
60 * 0x29 Pipeline freeze by FPU
61 */
62 struct PMM_counter_struct {
63 uint64_t count;
64 uint32_t mode; /* if running only, otherwise 0 */
65 uint32_t runfor;
66 };
68 static struct PMM_counter_struct PMM_counter[2] = {{0,0},{0,0}};
70 void PMM_reset(void)
71 {
72 PMM_counter[0].count = 0;
73 PMM_counter[0].mode = 0;
74 PMM_counter[0].runfor = 0;
75 PMM_counter[1].count = 0;
76 PMM_counter[1].mode = 0;
77 PMM_counter[1].runfor = 0;
78 }
80 void PMM_save_state( FILE *f ) {
81 fwrite( &PMM_counter, sizeof(PMM_counter), 1, f );
82 }
84 int PMM_load_state( FILE *f )
85 {
86 fread( &PMM_counter, sizeof(PMM_counter), 1, f );
87 return 0;
88 }
90 void PMM_count( int ctr, uint32_t runfor )
91 {
92 uint32_t delta = runfor - PMM_counter[ctr].runfor;
94 switch( PMM_counter[ctr].mode ) {
95 case 0x23:
96 PMM_counter[ctr].count += (delta / (1000/SH4_BASE_RATE));
97 break;
98 default:
99 break;
100 }
102 PMM_counter[ctr].runfor = runfor;
103 }
105 uint32_t PMM_run_slice( uint32_t nanosecs )
106 {
107 PMM_count( 0, nanosecs );
108 PMM_count( 1, nanosecs );
109 PMM_counter[0].runfor = 0;
110 PMM_counter[1].runfor = 0;
111 return nanosecs;
112 }
114 void PMM_write_control( int ctr, uint32_t val )
115 {
116 int is_running = ((val & PMCR_RUNNING) == PMCR_RUNNING);
118 PMM_count(ctr, sh4r.slice_cycle);
119 if( PMM_counter[ctr].mode == 0 && (val & PMCR_PMCLR) != 0 ) {
120 PMM_counter[ctr].count = 0;
121 }
122 if( is_running ) {
123 int mode = val & 0x3F;
124 if( mode != PMM_counter[ctr].mode ) {
125 /* Instrumentation setup goes here */
126 PMM_counter[ctr].mode = mode;
127 }
128 } else if( PMM_counter[ctr].mode != 0 ) {
129 /* Instrumentation removal goes here */
130 PMM_counter[ctr].mode = 0;
131 }
132 }
134 MMIO_REGION_READ_FN( PMM, reg )
135 {
136 switch( reg & 0x1F ) {
137 case 0: return 0; /* not a register */
138 case PMCTR1H:
139 PMM_count(0, sh4r.slice_cycle);
140 return ((uint32_t)(PMM_counter[0].count >> 32)) & 0x0000FFFF;
141 case PMCTR1L:
142 PMM_count(0, sh4r.slice_cycle);
143 return (uint32_t)PMM_counter[0].count;
144 case PMCTR2H:
145 PMM_count(1, sh4r.slice_cycle);
146 return ((uint32_t)(PMM_counter[1].count >> 32)) & 0x0000FFFF;
147 default:
148 PMM_count(1, sh4r.slice_cycle);
149 return (uint32_t)PMM_counter[1].count;
150 }
151 }
153 MMIO_REGION_WRITE_FN( PMM, reg, val )
154 {
155 /* Read-only */
156 }
158 MMIO_REGION_READ_DEFSUBFNS(PMM)
.