Search
lxdream.org :: lxdream :: r841:808d64b05073
lxdream 0.9.1
released Jun 29
Download Now
changeset841:808d64b05073
parent840:c6a778c228a6
child842:286345299c49
authornkeynes
dateTue Sep 02 11:53:16 2008 +0000 (11 years ago)
Initial implementation of the performance counters, only working one for now
is raw clock cycles (0x23)
src/sh4/mmu.c
src/sh4/pmm.c
src/sh4/sh4.c
src/sh4/sh4core.h
src/sh4/sh4mmio.h
1.1 --- a/src/sh4/mmu.c Tue Sep 02 03:34:23 2008 +0000
1.2 +++ b/src/sh4/mmu.c Tue Sep 02 11:53:16 2008 +0000
1.3 @@ -192,10 +192,12 @@
1.4 val &= 0x0000001C;
1.5 break;
1.6 case PMCR1:
1.7 + PMM_write_control(0, val);
1.8 + val &= 0x0000C13F;
1.9 + break;
1.10 case PMCR2:
1.11 - if( val != 0 ) {
1.12 - WARN( "Performance counters not implemented" );
1.13 - }
1.14 + PMM_write_control(1, val);
1.15 + val &= 0x0000C13F;
1.16 break;
1.17 default:
1.18 break;
1.19 @@ -964,19 +966,3 @@
1.20 return TRUE;
1.21 }
1.22
1.23 -/********************************* PMM *************************************/
1.24 -
1.25 -/**
1.26 - * Side note - this is here (rather than in sh4mmio.c) as the control registers
1.27 - * are part of the MMU block, and it seems simplest to keep it all together.
1.28 - */
1.29 -
1.30 -int32_t mmio_region_PMM_read( uint32_t reg )
1.31 -{
1.32 - return MMIO_READ( PMM, reg );
1.33 -}
1.34 -
1.35 -void mmio_region_PMM_write( uint32_t reg, uint32_t val )
1.36 -{
1.37 - /* Read-only */
1.38 -}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/sh4/pmm.c Tue Sep 02 11:53:16 2008 +0000
2.3 @@ -0,0 +1,156 @@
2.4 +/**
2.5 + * $Id: pmm.c 833 2008-08-18 12:18:10Z nkeynes $
2.6 + *
2.7 + * PMM (performance counter) module
2.8 + *
2.9 + * Copyright (c) 2005 Nathan Keynes.
2.10 + *
2.11 + * This program is free software; you can redistribute it and/or modify
2.12 + * it under the terms of the GNU General Public License as published by
2.13 + * the Free Software Foundation; either version 2 of the License, or
2.14 + * (at your option) any later version.
2.15 + *
2.16 + * This program is distributed in the hope that it will be useful,
2.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.19 + * GNU General Public License for more details.
2.20 + */
2.21 +
2.22 +#include "sh4/sh4mmio.h"
2.23 +#include "sh4/sh4core.h"
2.24 +#include "clock.h"
2.25 +
2.26 +/*
2.27 + * Performance counter list from Paul Mundt's OProfile patch
2.28 + * Currently only 0x23 is actually supported, since it doesn't require any
2.29 + * actual instrumentation
2.30 + *
2.31 + * 0x01 Operand read access
2.32 + * 0x02 Operand write access
2.33 + * 0x03 UTLB miss
2.34 + * 0x04 Operand cache read miss
2.35 + * 0x05 Operand cache write miss
2.36 + * 0x06 Instruction fetch (w/ cache)
2.37 + * 0x07 Instruction TLB miss
2.38 + * 0x08 Instruction cache miss
2.39 + * 0x09 All operand accesses
2.40 + * 0x0a All instruction accesses
2.41 + * 0x0b OC RAM operand access
2.42 + * 0x0d On-chip I/O space access
2.43 + * 0x0e Operand access (r/w)
2.44 + * 0x0f Operand cache miss (r/w)
2.45 + * 0x10 Branch instruction
2.46 + * 0x11 Branch taken
2.47 + * 0x12 BSR/BSRF/JSR
2.48 + * 0x13 Instruction execution
2.49 + * 0x14 Instruction execution in parallel
2.50 + * 0x15 FPU Instruction execution
2.51 + * 0x16 Interrupt
2.52 + * 0x17 NMI
2.53 + * 0x18 trapa instruction execution
2.54 + * 0x19 UBCA match
2.55 + * 0x1a UBCB match
2.56 + * 0x21 Instruction cache fill
2.57 + * 0x22 Operand cache fill
2.58 + * 0x23 Elapsed time
2.59 + * 0x24 Pipeline freeze by I-cache miss
2.60 + * 0x25 Pipeline freeze by D-cache miss
2.61 + * 0x27 Pipeline freeze by branch instruction
2.62 + * 0x28 Pipeline freeze by CPU register
2.63 + * 0x29 Pipeline freeze by FPU
2.64 + */
2.65 +struct PMM_counter_struct {
2.66 + uint64_t count;
2.67 + uint32_t mode; /* if running only, otherwise 0 */
2.68 + uint32_t runfor;
2.69 +};
2.70 +
2.71 +static struct PMM_counter_struct PMM_counter[2] = {{0,0},{0,0}};
2.72 +
2.73 +void PMM_reset(void)
2.74 +{
2.75 + PMM_counter[0].count = 0;
2.76 + PMM_counter[0].mode = 0;
2.77 + PMM_counter[0].runfor = 0;
2.78 + PMM_counter[1].count = 0;
2.79 + PMM_counter[1].mode = 0;
2.80 + PMM_counter[1].runfor = 0;
2.81 +}
2.82 +
2.83 +void PMM_save_state( FILE *f ) {
2.84 + fwrite( &PMM_counter, sizeof(PMM_counter), 1, f );
2.85 +}
2.86 +
2.87 +int PMM_load_state( FILE *f )
2.88 +{
2.89 + fread( &PMM_counter, sizeof(PMM_counter), 1, f );
2.90 + return 0;
2.91 +}
2.92 +
2.93 +void PMM_count( int ctr, uint32_t runfor )
2.94 +{
2.95 + uint32_t delta = runfor - PMM_counter[ctr].runfor;
2.96 +
2.97 + switch( PMM_counter[ctr].mode ) {
2.98 + case 0x23:
2.99 + PMM_counter[ctr].count += (delta / (1000/SH4_BASE_RATE));
2.100 + break;
2.101 + default:
2.102 + break;
2.103 + }
2.104 +
2.105 + PMM_counter[ctr].runfor = runfor;
2.106 +}
2.107 +
2.108 +uint32_t PMM_run_slice( uint32_t nanosecs )
2.109 +{
2.110 + PMM_count( 0, nanosecs );
2.111 + PMM_count( 1, nanosecs );
2.112 + PMM_counter[0].runfor = 0;
2.113 + PMM_counter[1].runfor = 0;
2.114 + return nanosecs;
2.115 +}
2.116 +
2.117 +void PMM_write_control( int ctr, uint32_t val )
2.118 +{
2.119 + int is_running = ((val & PMCR_RUNNING) == PMCR_RUNNING);
2.120 +
2.121 + PMM_count(ctr, sh4r.slice_cycle);
2.122 + if( PMM_counter[ctr].mode == 0 && (val & PMCR_PMCLR) != 0 ) {
2.123 + PMM_counter[ctr].count = 0;
2.124 + }
2.125 + if( is_running ) {
2.126 + int mode = val & 0x3F;
2.127 + if( mode != PMM_counter[ctr].mode ) {
2.128 + /* Instrumentation setup goes here */
2.129 + PMM_counter[ctr].mode = mode;
2.130 + }
2.131 + } else if( PMM_counter[ctr].mode != 0 ) {
2.132 + /* Instrumentation removal goes here */
2.133 + PMM_counter[ctr].mode = 0;
2.134 + }
2.135 +}
2.136 +
2.137 +int32_t mmio_region_PMM_read( uint32_t reg )
2.138 +{
2.139 + switch( reg & 0x1F ) {
2.140 + case 0: return 0; /* not a register */
2.141 + case PMCTR1H:
2.142 + PMM_count(0, sh4r.slice_cycle);
2.143 + return ((uint32_t)(PMM_counter[0].count >> 32)) & 0x0000FFFF;
2.144 + case PMCTR1L:
2.145 + PMM_count(0, sh4r.slice_cycle);
2.146 + return (uint32_t)PMM_counter[0].count;
2.147 + case PMCTR2H:
2.148 + PMM_count(1, sh4r.slice_cycle);
2.149 + return ((uint32_t)(PMM_counter[1].count >> 32)) & 0x0000FFFF;
2.150 + default:
2.151 + PMM_count(1, sh4r.slice_cycle);
2.152 + return (uint32_t)PMM_counter[1].count;
2.153 + }
2.154 +}
2.155 +
2.156 +void mmio_region_PMM_write( uint32_t reg, uint32_t val )
2.157 +{
2.158 + /* Read-only */
2.159 +}
3.1 --- a/src/sh4/sh4.c Tue Sep 02 03:34:23 2008 +0000
3.2 +++ b/src/sh4/sh4.c Tue Sep 02 11:53:16 2008 +0000
3.3 @@ -118,6 +118,7 @@
3.4 CPG_reset();
3.5 INTC_reset();
3.6 MMU_reset();
3.7 + PMM_reset();
3.8 TMU_reset();
3.9 SCIF_reset();
3.10
3.11 @@ -156,6 +157,7 @@
3.12 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
3.13 TMU_run_slice( sh4r.slice_cycle );
3.14 SCIF_run_slice( sh4r.slice_cycle );
3.15 + PMM_run_slice( sh4r.slice_cycle );
3.16 dreamcast_stop();
3.17 return sh4r.slice_cycle;
3.18 }
3.19 @@ -193,6 +195,7 @@
3.20 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {
3.21 TMU_run_slice( nanosecs );
3.22 SCIF_run_slice( nanosecs );
3.23 + PMM_run_slice( sh4r.slice_cycle );
3.24 }
3.25 return nanosecs;
3.26 }
3.27 @@ -233,6 +236,7 @@
3.28
3.29 fwrite( &sh4r, sizeof(sh4r), 1, f );
3.30 MMU_save_state( f );
3.31 + PMM_save_state( f );
3.32 INTC_save_state( f );
3.33 TMU_save_state( f );
3.34 SCIF_save_state( f );
3.35 @@ -245,6 +249,7 @@
3.36 }
3.37 fread( &sh4r, sizeof(sh4r), 1, f );
3.38 MMU_load_state( f );
3.39 + PMM_load_state( f );
3.40 INTC_load_state( f );
3.41 TMU_load_state( f );
3.42 return SCIF_load_state( f );
3.43 @@ -458,6 +463,7 @@
3.44 /* Bring all running peripheral modules up to date, and then halt them. */
3.45 TMU_run_slice( sh4r.slice_cycle );
3.46 SCIF_run_slice( sh4r.slice_cycle );
3.47 + PMM_run_slice( sh4r.slice_cycle );
3.48 } else {
3.49 if( MMIO_READ( CPG, STBCR2 ) & 0x80 ) {
3.50 sh4r.sh4_state = SH4_STATE_DEEP_SLEEP;
4.1 --- a/src/sh4/sh4core.h Tue Sep 02 03:34:23 2008 +0000
4.2 +++ b/src/sh4/sh4core.h Tue Sep 02 11:53:16 2008 +0000
4.3 @@ -161,6 +161,11 @@
4.4 void TMU_save_state( FILE * );
4.5 int TMU_load_state( FILE * );
4.6 void TMU_update_clocks( void );
4.7 +void PMM_reset( void );
4.8 +void PMM_write_control( int, uint32_t );
4.9 +void PMM_save_state( FILE * );
4.10 +int PMM_load_state( FILE * );
4.11 +uint32_t PMM_run_slice( uint32_t );
4.12 uint32_t sh4_translate_run_slice(uint32_t);
4.13 uint32_t sh4_emulate_run_slice(uint32_t);
4.14
5.1 --- a/src/sh4/sh4mmio.h Tue Sep 02 03:34:23 2008 +0000
5.2 +++ b/src/sh4/sh4mmio.h Tue Sep 02 11:53:16 2008 +0000
5.3 @@ -229,6 +229,7 @@
5.4 #define PMCR_PMCLR 0x2000
5.5 #define PMCR_PMST 0x4000
5.6 #define PMCR_PMEN 0x8000
5.7 +#define PMCR_RUNNING (PMCR_PMST|PMCR_PMEN)
5.8
5.9 /* MMU functions */
5.10 void mmu_init(void);
.