Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 323:067583c1a704
prev312:2c34bdc36cbd
next336:c3455be86ee2
author nkeynes
date Thu Jan 25 10:18:42 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Increase SH4 speed to 100Mips
file annotate diff log raw
nkeynes@30
     1
/**
nkeynes@323
     2
 * $Id: sh4mmio.c,v 1.11 2007-01-25 08:21:56 nkeynes Exp $
nkeynes@30
     3
 * 
nkeynes@30
     4
 * Miscellaneous and not-really-implemented SH4 peripheral modules. Also
nkeynes@30
     5
 * responsible for including the IMPL side of the SH4 MMIO pages.
nkeynes@30
     6
 * Most of these will eventually be split off into their own files.
nkeynes@30
     7
 *
nkeynes@30
     8
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@30
     9
 *
nkeynes@30
    10
 * This program is free software; you can redistribute it and/or modify
nkeynes@30
    11
 * it under the terms of the GNU General Public License as published by
nkeynes@30
    12
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@30
    13
 * (at your option) any later version.
nkeynes@30
    14
 *
nkeynes@30
    15
 * This program is distributed in the hope that it will be useful,
nkeynes@30
    16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@30
    17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@30
    18
 * GNU General Public License for more details.
nkeynes@30
    19
 */
nkeynes@35
    20
#define MODULE sh4_module
nkeynes@30
    21
nkeynes@1
    22
#include "dream.h"
nkeynes@1
    23
#include "mem.h"
nkeynes@19
    24
#include "clock.h"
nkeynes@1
    25
#include "sh4core.h"
nkeynes@1
    26
#include "sh4mmio.h"
nkeynes@1
    27
#define MMIO_IMPL
nkeynes@1
    28
#include "sh4mmio.h"
nkeynes@1
    29
nkeynes@1
    30
/********************************* MMU *************************************/
nkeynes@1
    31
nkeynes@92
    32
MMIO_REGION_READ_DEFFN( MMU )
nkeynes@1
    33
nkeynes@10
    34
#define OCRAM_START (0x1C000000>>PAGE_BITS)
nkeynes@10
    35
#define OCRAM_END   (0x20000000>>PAGE_BITS)
nkeynes@10
    36
nkeynes@10
    37
static char *cache = NULL;
nkeynes@10
    38
nkeynes@1
    39
void mmio_region_MMU_write( uint32_t reg, uint32_t val )
nkeynes@1
    40
{
nkeynes@1
    41
    switch(reg) {
nkeynes@1
    42
        case CCR:
nkeynes@10
    43
            mmu_set_cache_mode( val & (CCR_OIX|CCR_ORA) );
nkeynes@1
    44
            break;
nkeynes@1
    45
        default:
nkeynes@1
    46
            break;
nkeynes@1
    47
    }
nkeynes@1
    48
    MMIO_WRITE( MMU, reg, val );
nkeynes@1
    49
}
nkeynes@1
    50
nkeynes@1
    51
nkeynes@312
    52
void MMU_init() 
nkeynes@10
    53
{
nkeynes@19
    54
    cache = mem_alloc_pages(2);
nkeynes@10
    55
}
nkeynes@10
    56
nkeynes@312
    57
void MMU_reset()
nkeynes@312
    58
{
nkeynes@312
    59
    mmio_region_MMU_write( CCR, 0 );
nkeynes@312
    60
}
nkeynes@312
    61
nkeynes@312
    62
void MMU_save_state( FILE *f )
nkeynes@312
    63
{
nkeynes@312
    64
    fwrite( cache, 4096, 2, f );
nkeynes@312
    65
}
nkeynes@312
    66
nkeynes@312
    67
int MMU_load_state( FILE *f )
nkeynes@312
    68
{
nkeynes@312
    69
    /* Setup the cache mode according to the saved register value
nkeynes@312
    70
     * (mem_load runs before this point to load all MMIO data)
nkeynes@312
    71
     */
nkeynes@312
    72
    mmio_region_MMU_write( CCR, MMIO_READ(MMU, CCR) );
nkeynes@312
    73
    if( fread( cache, 4096, 2, f ) != 2 ) {
nkeynes@312
    74
	return 1;
nkeynes@312
    75
    }
nkeynes@312
    76
    return 0;
nkeynes@312
    77
}
nkeynes@312
    78
nkeynes@10
    79
void mmu_set_cache_mode( int mode )
nkeynes@10
    80
{
nkeynes@10
    81
    uint32_t i;
nkeynes@10
    82
    switch( mode ) {
nkeynes@10
    83
        case MEM_OC_INDEX0: /* OIX=0 */
nkeynes@10
    84
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    85
                page_map[i] = cache + ((i&0x02)<<(PAGE_BITS-1));
nkeynes@10
    86
            break;
nkeynes@10
    87
        case MEM_OC_INDEX1: /* OIX=1 */
nkeynes@10
    88
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    89
                page_map[i] = cache + ((i&0x02000000)>>(25-PAGE_BITS));
nkeynes@10
    90
            break;
nkeynes@10
    91
        default: /* disabled */
nkeynes@10
    92
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    93
                page_map[i] = NULL;
nkeynes@10
    94
            break;
nkeynes@10
    95
    }
nkeynes@10
    96
}
nkeynes@10
    97
nkeynes@10
    98
nkeynes@1
    99
/********************************* BSC *************************************/
nkeynes@1
   100
nkeynes@323
   101
uint32_t bsc_input = 0x0300;
nkeynes@1
   102
nkeynes@323
   103
uint16_t bsc_read_pdtra()
nkeynes@1
   104
{
nkeynes@323
   105
    int i;
nkeynes@323
   106
    uint32_t pctra = MMIO_READ( BSC, PCTRA );
nkeynes@323
   107
    uint16_t output = MMIO_READ( BSC, PDTRA );
nkeynes@323
   108
    uint16_t input_mask = 0, output_mask = 0;
nkeynes@323
   109
    for( i=0; i<16; i++ ) {
nkeynes@323
   110
	int bits = (pctra >> (i<<1)) & 0x03;
nkeynes@323
   111
	if( bits == 2 ) input_mask |= (1<<i);
nkeynes@323
   112
	else if( bits != 0 ) output_mask |= (1<<i);
nkeynes@323
   113
    }
nkeynes@323
   114
nkeynes@323
   115
    /* ??? */
nkeynes@323
   116
    if( ((output | (~output_mask)) & 0x03) == 3 ) {
nkeynes@323
   117
        output |= 0x03;
nkeynes@1
   118
    } else {
nkeynes@323
   119
        output &= ~0x03;
nkeynes@1
   120
    }
nkeynes@323
   121
nkeynes@323
   122
    return (bsc_input & input_mask) | output;
nkeynes@1
   123
}
nkeynes@1
   124
nkeynes@323
   125
uint32_t bsc_read_pdtrb()
nkeynes@1
   126
{
nkeynes@1
   127
    int i;
nkeynes@323
   128
    uint32_t pctrb = MMIO_READ( BSC, PCTRB );
nkeynes@323
   129
    uint16_t output = MMIO_READ( BSC, PDTRB );
nkeynes@323
   130
    uint16_t input_mask = 0, output_mask = 0;
nkeynes@323
   131
    for( i=0; i<4; i++ ) {
nkeynes@323
   132
	int bits = (pctrb >> (i<<1)) & 0x03;
nkeynes@323
   133
	if( bits == 2 ) input_mask |= (1<<i);
nkeynes@323
   134
	else if( bits != 0 ) output_mask |= (1<<i);
nkeynes@1
   135
    }
nkeynes@323
   136
nkeynes@323
   137
    return ((bsc_input>>16) & input_mask) | output;
nkeynes@323
   138
nkeynes@1
   139
}
nkeynes@1
   140
nkeynes@323
   141
MMIO_REGION_WRITE_STUBFN(BSC)
nkeynes@323
   142
nkeynes@1
   143
int32_t mmio_region_BSC_read( uint32_t reg )
nkeynes@1
   144
{
nkeynes@1
   145
    int32_t val;
nkeynes@323
   146
    int i;
nkeynes@1
   147
    switch( reg ) {
nkeynes@1
   148
        case PDTRA:
nkeynes@323
   149
	    val = bsc_read_pdtra();
nkeynes@323
   150
	    break;
nkeynes@1
   151
        case PDTRB:
nkeynes@323
   152
	    val = bsc_read_pdtrb();
nkeynes@323
   153
	    break;
nkeynes@1
   154
        default:
nkeynes@1
   155
            val = MMIO_READ( BSC, reg );
nkeynes@1
   156
    }
nkeynes@1
   157
    WARN( "Read from (mostly) unimplemented BSC (%03X => %08X) [%s: %s]",
nkeynes@1
   158
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
   159
    return val;
nkeynes@1
   160
}
nkeynes@1
   161
nkeynes@1
   162
/********************************* UBC *************************************/
nkeynes@1
   163
nkeynes@1
   164
MMIO_REGION_STUBFNS( UBC )
nkeynes@1
   165
nkeynes@1
   166
nkeynes@1
   167
/********************************** SCI *************************************/
nkeynes@1
   168
nkeynes@1
   169
MMIO_REGION_STUBFNS( SCI )
nkeynes@1
   170
.