filename | src/mmio.h |
changeset | 929:fd8cb0c82f5f |
prev | 796:a2dc83592467 |
next | 946:d41ee7994db7 |
author | nkeynes |
date | Sat Dec 27 02:59:35 2008 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | Replace fpscr_mask/fpscr flags in xlat_cache_block with a single xlat_sh4_mode, which tracks the field of the same name in sh4r - actually a little faster this way. Now depends on SR.MD, FPSCR.PR and FPSCR.SZ (although it doesn't benefit from the SR flag yet). Also fixed the failure to check the flags in the common case (code address returned by previous block) which took away the performance benefits, but oh well. |
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, mmio_region_##id##_write,mmio_region_##id##_read, mmio_region_##id##_write,NULL, NULL}, 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 )
156 #endif
158 #else
160 #ifndef MMIO_IFACE_INCLUDED
161 #define MMIO_IFACE_INCLUDED
162 #define MMIO_REGION_BEGIN(b,id,d) \
163 extern struct mmio_region mmio_region_##id; \
164 int32_t FASTCALL mmio_region_##id##_read(uint32_t); \
165 void FASTCALL mmio_region_##id##_write(uint32_t, uint32_t); \
166 enum mmio_region_##id##_port_t {
167 #define LONG_PORT( o,id,f,def,d ) id = o,
168 #define WORD_PORT( o,id,f,def,d ) id = o,
169 #define BYTE_PORT( o,id,f,def,d ) id = o,
170 #define MMIO_REGION_END };
171 #define MMIO_REGION_LIST_BEGIN(id) extern struct mmio_region *mmio_list_##id[];
172 #define MMIO_REGION( id )
173 #define MMIO_REGION_LIST_END
174 #endif
176 #define MMIO_REGION_WRITE_FN( id, reg, val ) \
177 void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val )
179 #define MMIO_REGION_READ_FN( id, reg ) \
180 int32_t FASTCALL mmio_region_##id##_read( uint32_t reg )
183 #endif
.