Search
lxdream.org :: lxdream/src/mmio.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/mmio.h
changeset 975:007bf7eb944f
prev953:f4a156508ad1
next1067:d3c00ffccfcd
author nkeynes
date Mon Feb 09 00:13:46 2009 +0000 (11 years ago)
permissions -rw-r--r--
last change Fail cleanly if the display doesn't actually support GLX, rather than crashing horribly
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * mmio.h defines a complicated batch of macros used to build up the 
     5  * memory-mapped I/O regions in a reasonably readable fashion.
     6  *
     7  * Copyright (c) 2005 Nathan Keynes.
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or
    12  * (at your option) any later version.
    13  *
    14  * This program is distributed in the hope that it will be useful,
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  * GNU General Public License for more details.
    18  */
    19 #ifndef lxdream_mmio_H
    20 #define lxdream_mmio_H 1
    22 #ifdef __cplusplus
    23 extern "C" {
    24 #if 0
    25 }
    26 #endif
    27 #endif
    29 #include <stdint.h>
    30 #include <stdlib.h>
    31 #include "mem.h"
    33 #define LXDREAM_PAGE_TABLE_ENTRIES 128*1024
    34 #define LXDREAM_PAGE_SIZE 4096
    35 #define LXDREAM_PAGE_BITS 12
    37 #define PORT_R 1
    38 #define PORT_W 2
    39 #define PORT_MEM 4 /* store written value */
    40 #define PORT_RW 3
    41 #define PORT_MR 5
    42 #define PORT_MRW 7
    43 #define PORT_NOTRACE 16
    44 #define UNDEFINED 0xDEADBEEF /* This has to be a value that nothing inits to */
    46 struct mmio_region {
    47     char *id, *desc;
    48     uint32_t base;
    49     struct mem_region_fn fn;
    50     char *mem;
    51     char *save_mem; /* Used to compare for gui updates */
    52     struct mmio_port {
    53         char *id, *desc;
    54         int width;
    55         uint32_t offset;
    56         uint32_t def_val;
    57         int flags;
    58         uint32_t *val;
    59     } ports[80];
    60     struct mmio_port **index; /* reverse lookup by address */
    61     int trace_flag; /* set to 1 to enable transfer traces */
    62 };
    64 void register_io_region( struct mmio_region *mmio );
    65 void register_io_regions( struct mmio_region **mmiolist );
    67 extern struct mmio_region *io_rgn[];
    68 extern uint32_t num_io_rgns;
    70 #define MMIO_READ( id, r ) *((int32_t *)(mmio_region_##id.mem + (r)))
    71 #define MMIO_READF( id, r ) *((float *)(mmio_region_##id.mem + (r)))
    72 #define MMIO_WRITE( id, r, v ) *((int32_t *)(mmio_region_##id.mem + (r))) = (v)
    73 #define MMIO_ADDR( id, r) ((int32_t *)(mmio_region_##id.mem + (r)))
    74 #define MMIO_REG( id, r ) ((int32_t *)(mmio_region_##id.mem + (r)))
    75 #define MMIO_REGID( mid, r ) (mmio_region_##mid.index[(r)>>2] != NULL ? \
    76             mmio_region_##mid.index[(r)>>2]->id : "<UNDEF>" )
    77 #define MMIO_REGDESC( mid, r) (mmio_region_##mid.index[(r)>>2] != NULL ? \
    78             mmio_region_##mid.index[(r)>>2]->desc : "Undefined register" )
    79 #define MMIO_TRACE( mid ) mmio_region_##mid.trace_flag = 1
    80 #define MMIO_NOTRACE( mid ) mmio_region_##mid.trace_flag = 0
    82 #define MMIO_REGID_BYNUM( mid, r ) (io_rgn[mid]->index[(r)>>2] != NULL ? \
    83             io_rgn[mid]->index[(r)>>2]->id : "<UNDEF>" )
    84 #define MMIO_REGDESC_BYNUM( mid, r ) (io_rgn[mid]->index[(r)>>2] != NULL ? \
    85             io_rgn[mid]->index[(r)>>2]->desc : "Undefined register" )
    86 #define MMIO_NOTRACE_BYNUM( mid, r ) (io_rgn[mid]->index[(r)>>2] != NULL ? \
    87 				      (io_rgn[mid]->index[(r)>>2]->flags & PORT_NOTRACE) : 0 )
    88 #define MMIO_NAME_BYNUM( mid ) (io_rgn[mid]->id)
    90 #define MMIO_REGID_IOBYNUM( io, r ) (io->index[(r)>>2] != NULL ? \
    91             io->index[(r)>>2]->id : "<UNDEF>" )
    92 #define MMIO_REGDESC_IOBYNUM( io, r ) (io->index[(r)>>2] != NULL ? \
    93             io->index[(r)>>2]->desc : "Undefined register" )
    94 #define MMIO_NOTRACE_IOBYNUM( io, r ) (io->index[(r)>>2] != NULL ? \
    95 				      (io->index[(r)>>2]->flags & PORT_NOTRACE) : 0 )
    97 #ifdef __cplusplus
    98 }
    99 #endif
   101 #endif
   103 #ifdef MMIO_IMPL
   105 #ifndef MMIO_IMPL_INCLUDED
   106 #define MMIO_IMPL_INCLUDED
   107 #undef MMIO_REGION_BEGIN
   108 #undef LONG_PORT
   109 #undef WORD_PORT
   110 #undef BYTE_PORT
   111 #undef MMIO_REGION_END
   112 #undef MMIO_REGION_LIST_BEGIN
   113 #undef MMIO_REGION
   114 #undef MMIO_REGION_LIST_END
   115 #define MMIO_REGION_BEGIN(b,id,d) struct mmio_region mmio_region_##id = { #id, d, b, {mmio_region_##id##_read, mmio_region_##id##_write,mmio_region_##id##_read_word, mmio_region_##id##_write,mmio_region_##id##_read_byte, mmio_region_##id##_write,NULL, NULL, unmapped_prefetch, mmio_region_##id##_read_byte}, 0, 0, {
   116 #define LONG_PORT( o,id,f,def,d ) { #id, d, 32, o, def, f },
   117 #define WORD_PORT( o,id,f,def,d ) { #id, d, 16, o, def, f },
   118 #define BYTE_PORT( o,id,f,def,d ) { #id, d, 8, o, def, f },
   119 #define MMIO_REGION_END {NULL, NULL, 0, 0, 0, 0} } };
   120 #define MMIO_REGION_LIST_BEGIN(id) struct mmio_region *mmio_list_##id[] = {
   121 #define MMIO_REGION( id ) &mmio_region_##id,
   122 #define MMIO_REGION_LIST_END NULL};
   124 /* Stub defines for modules we haven't got to yet, or ones which don't
   125  * actually need any direct code on read and/or write
   126  */
   127 #define MMIO_REGION_READ_STUBFN( id ) \
   128 int32_t FASTCALL mmio_region_##id##_read( uint32_t reg ) { \
   129     reg = reg & 0xFFF; \
   130     int32_t val = MMIO_READ( id, reg ); \
   131     WARN( "Read from unimplemented module %s (%03X => %08X) [%s: %s]",\
   132           #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \
   133     return val; \
   134 }
   135 #define MMIO_REGION_WRITE_STUBFN( id ) \
   136 void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \
   137     reg = reg & 0xFFF; \
   138     WARN( "Write to unimplemented module %s (%03X <= %08X) [%s: %s]", \
   139           #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \
   140     MMIO_WRITE( id, reg, val ); \
   141 }
   142 #define MMIO_REGION_STUBFNS( id ) \
   143     MMIO_REGION_READ_STUBFN( id ) \
   144     MMIO_REGION_WRITE_STUBFN( id )
   145 #define MMIO_REGION_READ_DEFFN( id ) \
   146 int32_t FASTCALL mmio_region_##id##_read( uint32_t reg ) { \
   147     return MMIO_READ( id, reg&0xFFF ); \
   148 }
   149 #define MMIO_REGION_WRITE_DEFFN( id ) \
   150 void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \
   151     MMIO_WRITE( id, reg&0xFFF, val ); \
   152 }
   153 #define MMIO_REGION_DEFFNS( id ) \
   154     MMIO_REGION_READ_DEFFN( id ) \
   155     MMIO_REGION_WRITE_DEFFN( id )
   157 #endif
   159 #else
   161 #ifndef MMIO_IFACE_INCLUDED
   162 #define MMIO_IFACE_INCLUDED
   163 #define MMIO_REGION_BEGIN(b,id,d) \
   164 extern struct mmio_region mmio_region_##id; \
   165 int32_t FASTCALL mmio_region_##id##_read(uint32_t); \
   166 int32_t FASTCALL mmio_region_##id##_read_word(uint32_t); \
   167 int32_t FASTCALL mmio_region_##id##_read_byte(uint32_t); \
   168 void FASTCALL mmio_region_##id##_write(uint32_t, uint32_t); \
   169 enum mmio_region_##id##_port_t {
   170 #define LONG_PORT( o,id,f,def,d ) id = o,
   171 #define WORD_PORT( o,id,f,def,d ) id = o,
   172 #define BYTE_PORT( o,id,f,def,d ) id = o,
   173 #define MMIO_REGION_END };
   174 #define MMIO_REGION_LIST_BEGIN(id) extern struct mmio_region *mmio_list_##id[];
   175 #define MMIO_REGION( id )
   176 #define MMIO_REGION_LIST_END
   177 #endif
   179 #define MMIO_REGION_WRITE_FN( id, reg, val ) \
   180 void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val )
   182 #define MMIO_REGION_READ_FN( id, reg ) \
   183 int32_t FASTCALL mmio_region_##id##_read( uint32_t reg )
   185 #define MMIO_REGION_READ_DEFSUBFNS( id ) \
   186 int32_t FASTCALL mmio_region_##id##_read_word( uint32_t reg ) { return SIGNEXT16(mmio_region_##id##_read(reg)); } \
   187 int32_t FASTCALL mmio_region_##id##_read_byte( uint32_t reg ) { return SIGNEXT8(mmio_region_##id##_read(reg)); }
   190 #endif
.