Search
lxdream.org :: lxdream/src/sh4/sh4mmio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mmio.c
changeset 54:d8b73031289c
prev35:21a4be098304
next92:108450d84ce8
author nkeynes
date Sat Jan 21 11:38:10 2006 +0000 (18 years ago)
permissions -rw-r--r--
last change Fix P4 to include E000000
file annotate diff log raw
nkeynes@30
     1
/**
nkeynes@54
     2
 * $Id: sh4mmio.c,v 1.7 2006-01-01 08:08:40 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@1
    32
MMIO_REGION_READ_STUBFN( 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
            INFO( "Cache mode set to %08X", val );
nkeynes@1
    45
            break;
nkeynes@1
    46
        default:
nkeynes@1
    47
            break;
nkeynes@1
    48
    }
nkeynes@1
    49
    MMIO_WRITE( MMU, reg, val );
nkeynes@1
    50
}
nkeynes@1
    51
nkeynes@1
    52
nkeynes@10
    53
void mmu_init() 
nkeynes@10
    54
{
nkeynes@19
    55
    cache = mem_alloc_pages(2);
nkeynes@10
    56
}
nkeynes@10
    57
nkeynes@10
    58
void mmu_set_cache_mode( int mode )
nkeynes@10
    59
{
nkeynes@10
    60
    uint32_t i;
nkeynes@10
    61
    switch( mode ) {
nkeynes@10
    62
        case MEM_OC_INDEX0: /* OIX=0 */
nkeynes@10
    63
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    64
                page_map[i] = cache + ((i&0x02)<<(PAGE_BITS-1));
nkeynes@10
    65
            break;
nkeynes@10
    66
        case MEM_OC_INDEX1: /* OIX=1 */
nkeynes@10
    67
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    68
                page_map[i] = cache + ((i&0x02000000)>>(25-PAGE_BITS));
nkeynes@10
    69
            break;
nkeynes@10
    70
        default: /* disabled */
nkeynes@10
    71
            for( i=OCRAM_START; i<OCRAM_END; i++ )
nkeynes@10
    72
                page_map[i] = NULL;
nkeynes@10
    73
            break;
nkeynes@10
    74
    }
nkeynes@10
    75
}
nkeynes@10
    76
nkeynes@10
    77
nkeynes@1
    78
/********************************* BSC *************************************/
nkeynes@1
    79
nkeynes@1
    80
uint16_t bsc_output_mask_lo = 0, bsc_output_mask_hi = 0;
nkeynes@1
    81
uint16_t bsc_input_mask_lo = 0, bsc_input_mask_hi = 0;
nkeynes@1
    82
uint32_t bsc_output = 0, bsc_input = 0x0300;
nkeynes@1
    83
nkeynes@1
    84
void bsc_out( int output, int mask )
nkeynes@1
    85
{
nkeynes@1
    86
    /* Go figure... The BIOS won't start without this mess though */
nkeynes@1
    87
    if( ((output | (~mask)) & 0x03) == 3 ) {
nkeynes@1
    88
        bsc_output |= 0x03;
nkeynes@1
    89
    } else {
nkeynes@1
    90
        bsc_output &= ~0x03;
nkeynes@1
    91
    }
nkeynes@1
    92
}
nkeynes@1
    93
nkeynes@1
    94
void mmio_region_BSC_write( uint32_t reg, uint32_t val )
nkeynes@1
    95
{
nkeynes@1
    96
    int i;
nkeynes@1
    97
    switch( reg ) {
nkeynes@1
    98
        case PCTRA:
nkeynes@1
    99
            bsc_input_mask_lo = bsc_output_mask_lo = 0;
nkeynes@1
   100
            for( i=0; i<16; i++ ) {
nkeynes@1
   101
                int bits = (val >> (i<<1)) & 0x03;
nkeynes@1
   102
                if( bits == 2 ) bsc_input_mask_lo |= (1<<i);
nkeynes@1
   103
                else if( bits != 0 ) bsc_output_mask_lo |= (1<<i);
nkeynes@1
   104
            }
nkeynes@1
   105
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
   106
                (MMIO_READ( BSC, PDTRA ) & bsc_output_mask_lo);
nkeynes@1
   107
            bsc_out( MMIO_READ( BSC, PDTRA ) | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
   108
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
   109
            break;
nkeynes@1
   110
        case PCTRB:
nkeynes@1
   111
            bsc_input_mask_hi = bsc_output_mask_hi = 0;
nkeynes@1
   112
            for( i=0; i<4; i++ ) {
nkeynes@1
   113
                int bits = (val >> (i>>1)) & 0x03;
nkeynes@1
   114
                if( bits == 2 ) bsc_input_mask_hi |= (1<<i);
nkeynes@1
   115
                else if( bits != 0 ) bsc_output_mask_hi |= (1<<i);
nkeynes@1
   116
            }
nkeynes@1
   117
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
   118
                ((MMIO_READ( BSC, PDTRA ) & bsc_output_mask_hi)<<16);
nkeynes@1
   119
            break;
nkeynes@1
   120
        case PDTRA:
nkeynes@1
   121
            bsc_output = (bsc_output&0x000F0000) |
nkeynes@1
   122
                (val & bsc_output_mask_lo );
nkeynes@1
   123
            bsc_out( val | ((MMIO_READ(BSC,PDTRB)<<16)),
nkeynes@1
   124
                     bsc_output_mask_lo | (bsc_output_mask_hi<<16) );
nkeynes@1
   125
            break;
nkeynes@1
   126
        case PDTRB:
nkeynes@1
   127
            bsc_output = (bsc_output&0xFFFF) |
nkeynes@1
   128
                ( (val & bsc_output_mask_hi)<<16 );
nkeynes@1
   129
            break;
nkeynes@1
   130
    }
nkeynes@1
   131
    WARN( "Write to (mostly) unimplemented BSC (%03X <= %08X) [%s: %s]",
nkeynes@1
   132
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
   133
    MMIO_WRITE( BSC, reg, val );
nkeynes@1
   134
}
nkeynes@1
   135
nkeynes@1
   136
int32_t mmio_region_BSC_read( uint32_t reg )
nkeynes@1
   137
{
nkeynes@1
   138
    int32_t val;
nkeynes@1
   139
    switch( reg ) {
nkeynes@1
   140
        case PDTRA:
nkeynes@1
   141
            val = (bsc_input & bsc_input_mask_lo) | (bsc_output&0xFFFF);
nkeynes@1
   142
            break;
nkeynes@1
   143
        case PDTRB:
nkeynes@1
   144
            val = ((bsc_input>>16) & bsc_input_mask_hi) | (bsc_output>>16);
nkeynes@1
   145
            break;
nkeynes@1
   146
        default:
nkeynes@1
   147
            val = MMIO_READ( BSC, reg );
nkeynes@1
   148
    }
nkeynes@1
   149
    WARN( "Read from (mostly) unimplemented BSC (%03X => %08X) [%s: %s]",
nkeynes@1
   150
          reg, val, MMIO_REGID(BSC,reg), MMIO_REGDESC(BSC,reg) );
nkeynes@1
   151
    return val;
nkeynes@1
   152
}
nkeynes@1
   153
nkeynes@1
   154
/********************************* UBC *************************************/
nkeynes@1
   155
nkeynes@1
   156
MMIO_REGION_STUBFNS( UBC )
nkeynes@1
   157
nkeynes@1
   158
nkeynes@1
   159
/********************************** SCI *************************************/
nkeynes@1
   160
nkeynes@1
   161
MMIO_REGION_STUBFNS( SCI )
nkeynes@1
   162
.