Search
lxdream.org :: lxdream/src/sh4/pmm.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/pmm.c
changeset 841:808d64b05073
next929:fd8cb0c82f5f
author nkeynes
date Thu Dec 11 23:26:03 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Disable the generational translation cache - I've got no evidence that it
actually helps performance, and it simplifies things to get rid of it (in
particular, translated code doesn't have to worry about being moved now).
view annotate diff log raw
     1 /**
     2  * $Id: pmm.c 833 2008-08-18 12:18:10Z nkeynes $
     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 int32_t mmio_region_PMM_read( uint32_t 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 void mmio_region_PMM_write( uint32_t reg, uint32_t val )
   154 {
   155     /* Read-only */
   156 }
.