Search
lxdream.org :: lxdream/src/mmio.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/mmio.h
changeset 10:c898b37506e0
next31:495e480360d7
author nkeynes
date Mon Dec 12 10:37:41 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Use cpu-specific is_valid_page function
file annotate diff log raw
nkeynes@10
     1
#ifndef dream_mmio_H
nkeynes@10
     2
#define dream_mmio_H 1
nkeynes@10
     3
nkeynes@10
     4
#ifdef __cplusplus
nkeynes@10
     5
extern "C" {
nkeynes@10
     6
#if 0
nkeynes@10
     7
}
nkeynes@10
     8
#endif
nkeynes@10
     9
#endif
nkeynes@10
    10
nkeynes@10
    11
#include <stdint.h>
nkeynes@10
    12
#include <stdlib.h>
nkeynes@10
    13
#include "sh4core.h"
nkeynes@10
    14
nkeynes@10
    15
#define PAGE_TABLE_ENTRIES 128*1024
nkeynes@10
    16
#define PAGE_SIZE 4096
nkeynes@10
    17
#define PAGE_BITS 12
nkeynes@10
    18
nkeynes@10
    19
#define PORT_R 1
nkeynes@10
    20
#define PORT_W 2
nkeynes@10
    21
#define PORT_MEM 4 /* store written value */
nkeynes@10
    22
#define PORT_RW 3
nkeynes@10
    23
#define PORT_MR 5
nkeynes@10
    24
#define PORT_MRW 7
nkeynes@10
    25
#define UNDEFINED 0xDEADBEEF /* This has to be a value that nothing inits to */
nkeynes@10
    26
nkeynes@10
    27
struct mmio_region {
nkeynes@10
    28
    char *id, *desc;
nkeynes@10
    29
    uint32_t base;
nkeynes@10
    30
    int32_t (*io_read)(uint32_t addr);
nkeynes@10
    31
    void (*io_write)(uint32_t addr, uint32_t val);
nkeynes@10
    32
    char *mem;
nkeynes@10
    33
    char *save_mem; /* Used to compare for gui updates */
nkeynes@10
    34
    struct mmio_port {
nkeynes@10
    35
        char *id, *desc;
nkeynes@10
    36
        int width;
nkeynes@10
    37
        uint32_t offset;
nkeynes@10
    38
        uint32_t def_val;
nkeynes@10
    39
        int flags;
nkeynes@10
    40
        uint32_t *val;
nkeynes@10
    41
    } ports[80];
nkeynes@10
    42
    struct mmio_port **index; /* reverse lookup by address */
nkeynes@10
    43
    int trace_flag; /* set to 1 to enable transfer traces */
nkeynes@10
    44
};
nkeynes@10
    45
nkeynes@10
    46
void register_io_region( struct mmio_region *mmio );
nkeynes@10
    47
void register_io_regions( struct mmio_region **mmiolist );
nkeynes@10
    48
nkeynes@10
    49
extern struct mmio_region *io_rgn[];
nkeynes@10
    50
extern int num_io_rgns;
nkeynes@10
    51
nkeynes@10
    52
#define MMIO_READ( id, r ) *((int32_t *)(mmio_region_##id.mem + (r)))
nkeynes@10
    53
#define MMIO_WRITE( id, r, v ) *((int32_t *)(mmio_region_##id.mem + (r))) = (v)
nkeynes@10
    54
#define MMIO_REG( id, r ) ((int32_t *)(mmio_region_##id.mem + (r)))
nkeynes@10
    55
#define MMIO_REGID( mid, r ) (mmio_region_##mid.index[(r)>>2] != NULL ? \
nkeynes@10
    56
            mmio_region_##mid.index[(r)>>2]->id : "<UNDEF>" )
nkeynes@10
    57
#define MMIO_REGDESC( mid, r) (mmio_region_##mid.index[(r)>>2] != NULL ? \
nkeynes@10
    58
            mmio_region_##mid.index[(r)>>2]->desc : "Undefined register" )
nkeynes@10
    59
#define MMIO_TRACE( mid ) mmio_region_##mid.trace_flag = 1
nkeynes@10
    60
#define MMIO_NOTRACE( mid ) mmio_region_##mid.trace_flag = 0
nkeynes@10
    61
nkeynes@10
    62
#define MMIO_REGID_BYNUM( mid, r ) (io_rgn[mid]->index[(r)>>2] != NULL ? \
nkeynes@10
    63
            io_rgn[mid]->index[(r)>>2]->id : "<UNDEF>" )
nkeynes@10
    64
#define MMIO_REGDESC_BYNUM( mid, r ) (io_rgn[mid]->index[(r)>>2] != NULL ? \
nkeynes@10
    65
            io_rgn[mid]->index[(r)>>2]->desc : "Undefined register" )
nkeynes@10
    66
#define MMIO_NAME_BYNUM( mid ) (io_rgn[mid]->id)
nkeynes@10
    67
nkeynes@10
    68
#ifdef __cplusplus
nkeynes@10
    69
}
nkeynes@10
    70
#endif
nkeynes@10
    71
nkeynes@10
    72
#endif
nkeynes@10
    73
nkeynes@10
    74
#ifdef MMIO_IMPL
nkeynes@10
    75
nkeynes@10
    76
#ifndef MMIO_IMPL_INCLUDED
nkeynes@10
    77
#define MMIO_IMPL_INCLUDED
nkeynes@10
    78
#undef MMIO_REGION_BEGIN
nkeynes@10
    79
#undef LONG_PORT
nkeynes@10
    80
#undef WORD_PORT
nkeynes@10
    81
#undef BYTE_PORT
nkeynes@10
    82
#undef MMIO_REGION_END
nkeynes@10
    83
#undef MMIO_REGION_LIST_BEGIN
nkeynes@10
    84
#undef MMIO_REGION
nkeynes@10
    85
#undef MMIO_REGION_LIST_END
nkeynes@10
    86
#define MMIO_REGION_BEGIN(b,id,d) struct mmio_region mmio_region_##id = { #id, d, b, mmio_region_##id##_read, mmio_region_##id##_write, 0, 0, {
nkeynes@10
    87
#define LONG_PORT( o,id,f,def,d ) { #id, d, 32, o, def, f },
nkeynes@10
    88
#define WORD_PORT( o,id,f,def,d ) { #id, d, 16, o, def, f },
nkeynes@10
    89
#define BYTE_PORT( o,id,f,def,d ) { #id, d, 8, o, def, f },
nkeynes@10
    90
#define MMIO_REGION_END {NULL, NULL, 0, 0, 0, 0} } };
nkeynes@10
    91
#define MMIO_REGION_LIST_BEGIN(id) struct mmio_region *mmio_list_##id[] = {
nkeynes@10
    92
#define MMIO_REGION( id ) &mmio_region_##id,
nkeynes@10
    93
#define MMIO_REGION_LIST_END NULL};
nkeynes@10
    94
nkeynes@10
    95
/* Stub defines for modules we haven't got to yet, or ones which don't
nkeynes@10
    96
 * actually need any direct code on read and/or write
nkeynes@10
    97
 */
nkeynes@10
    98
#define MMIO_REGION_READ_STUBFN( id ) \
nkeynes@10
    99
int32_t mmio_region_##id##_read( uint32_t reg ) { \
nkeynes@10
   100
    int32_t val = MMIO_READ( id, reg ); \
nkeynes@10
   101
    WARN( "Read from unimplemented module %s (%03X => %08X) [%s: %s]",\
nkeynes@10
   102
          #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \
nkeynes@10
   103
    return val; \
nkeynes@10
   104
}
nkeynes@10
   105
#define MMIO_REGION_WRITE_STUBFN( id ) \
nkeynes@10
   106
void mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \
nkeynes@10
   107
    WARN( "Write to unimplemented module %s (%03X <= %08X) [%s: %s]", \
nkeynes@10
   108
          #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \
nkeynes@10
   109
    MMIO_WRITE( id, reg, val ); \
nkeynes@10
   110
}
nkeynes@10
   111
#define MMIO_REGION_STUBFNS( id ) \
nkeynes@10
   112
    MMIO_REGION_READ_STUBFN( id ) \
nkeynes@10
   113
    MMIO_REGION_WRITE_STUBFN( id )
nkeynes@10
   114
#define MMIO_REGION_READ_DEFFN( id ) \
nkeynes@10
   115
int32_t mmio_region_##id##_read( uint32_t reg ) { \
nkeynes@10
   116
    return MMIO_READ( id, reg ); \
nkeynes@10
   117
}
nkeynes@10
   118
#define MMIO_REGION_WRITE_DEFFN( id ) \
nkeynes@10
   119
void mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \
nkeynes@10
   120
    MMIO_WRITE( id, reg, val ); \
nkeynes@10
   121
}
nkeynes@10
   122
#define MMIO_REGION_DEFFNS( id ) \
nkeynes@10
   123
    MMIO_REGION_READ_DEFFN( id ) \
nkeynes@10
   124
    MMIO_REGION_WRITE_DEFFN( id )
nkeynes@10
   125
#endif
nkeynes@10
   126
nkeynes@10
   127
#define MMIO_REGION_WRITE_FN( id, reg, val ) \
nkeynes@10
   128
void mmio_region_##id##_write( uint32_t reg, uint32_t val )
nkeynes@10
   129
nkeynes@10
   130
#define MMIO_REGION_READ_FN( id, reg ) \
nkeynes@10
   131
int32_t mmio_region_##id##_read( uint32_t reg )
nkeynes@10
   132
nkeynes@10
   133
#else
nkeynes@10
   134
nkeynes@10
   135
#ifndef MMIO_IFACE_INCLUDED
nkeynes@10
   136
#define MMIO_IFACE_INCLUDED
nkeynes@10
   137
#define MMIO_REGION_BEGIN(b,id,d) \
nkeynes@10
   138
extern struct mmio_region mmio_region_##id; \
nkeynes@10
   139
int32_t mmio_region_##id##_read(uint32_t); \
nkeynes@10
   140
void mmio_region_##id##_write(uint32_t, uint32_t); \
nkeynes@10
   141
enum mmio_region_##id##_port_t {
nkeynes@10
   142
#define LONG_PORT( o,id,f,def,d ) id = o,
nkeynes@10
   143
#define WORD_PORT( o,id,f,def,d ) id = o,
nkeynes@10
   144
#define BYTE_PORT( o,id,f,def,d ) id = o,
nkeynes@10
   145
#define MMIO_REGION_END };
nkeynes@10
   146
#define MMIO_REGION_LIST_BEGIN(id) extern struct mmio_region *mmio_list_##id[];
nkeynes@10
   147
#define MMIO_REGION( id )
nkeynes@10
   148
#define MMIO_REGION_LIST_END
nkeynes@10
   149
#endif
nkeynes@10
   150
nkeynes@10
   151
#endif
nkeynes@10
   152
.