4
* Copyright (c) 2003-2008 Fabrice Bellard
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
* splitted out ioport related stuffs from vl.c.
30
/***********************************************************/
33
//#define DEBUG_UNUSED_IOPORT
34
//#define DEBUG_IOPORT
36
#ifdef DEBUG_UNUSED_IOPORT
37
# define LOG_UNUSED_IOPORT(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
39
# define LOG_UNUSED_IOPORT(fmt, ...) do{ } while (0)
43
# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
45
# define LOG_IOPORT(...) do { } while (0)
48
/* XXX: use a two level table to limit memory usage */
50
static void *ioport_opaque[MAX_IOPORTS];
51
static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
52
static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
54
static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
55
static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
57
static uint32_t ioport_read(int index, uint32_t address)
59
static IOPortReadFunc *default_func[3] = {
64
IOPortReadFunc *func = ioport_read_table[index][address];
66
func = default_func[index];
67
return func(ioport_opaque[address], address);
70
static void ioport_write(int index, uint32_t address, uint32_t data)
72
static IOPortWriteFunc *default_func[3] = {
73
default_ioport_writeb,
74
default_ioport_writew,
77
IOPortWriteFunc *func = ioport_write_table[index][address];
79
func = default_func[index];
80
func(ioport_opaque[address], address, data);
83
static uint32_t default_ioport_readb(void *opaque, uint32_t address)
85
LOG_UNUSED_IOPORT("unused inb: port=0x%04"PRIx32"\n", address);
89
static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
91
LOG_UNUSED_IOPORT("unused outb: port=0x%04"PRIx32" data=0x%02"PRIx32"\n",
95
/* default is to make two byte accesses */
96
static uint32_t default_ioport_readw(void *opaque, uint32_t address)
99
data = ioport_read(0, address);
100
address = (address + 1) & IOPORTS_MASK;
101
data |= ioport_read(0, address) << 8;
105
static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
107
ioport_write(0, address, data & 0xff);
108
address = (address + 1) & IOPORTS_MASK;
109
ioport_write(0, address, (data >> 8) & 0xff);
112
static uint32_t default_ioport_readl(void *opaque, uint32_t address)
114
LOG_UNUSED_IOPORT("unused inl: port=0x%04"PRIx32"\n", address);
118
static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
120
LOG_UNUSED_IOPORT("unused outl: port=0x%04"PRIx32" data=0x%02"PRIx32"\n",
124
static int ioport_bsize(int size, int *bsize)
128
} else if (size == 2) {
130
} else if (size == 4) {
138
/* size is the word size in byte */
139
int register_ioport_read(pio_addr_t start, int length, int size,
140
IOPortReadFunc *func, void *opaque)
144
if (ioport_bsize(size, &bsize)) {
145
hw_error("register_ioport_read: invalid size");
148
for(i = start; i < start + length; i += size) {
149
ioport_read_table[bsize][i] = func;
150
if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
151
hw_error("register_ioport_read: invalid opaque");
152
ioport_opaque[i] = opaque;
157
/* size is the word size in byte */
158
int register_ioport_write(pio_addr_t start, int length, int size,
159
IOPortWriteFunc *func, void *opaque)
163
if (ioport_bsize(size, &bsize)) {
164
hw_error("register_ioport_write: invalid size");
167
for(i = start; i < start + length; i += size) {
168
ioport_write_table[bsize][i] = func;
169
if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
170
hw_error("register_ioport_write: invalid opaque");
171
ioport_opaque[i] = opaque;
176
void isa_unassign_ioport(pio_addr_t start, int length)
180
for(i = start; i < start + length; i++) {
181
ioport_read_table[0][i] = default_ioport_readb;
182
ioport_read_table[1][i] = default_ioport_readw;
183
ioport_read_table[2][i] = default_ioport_readl;
185
ioport_write_table[0][i] = default_ioport_writeb;
186
ioport_write_table[1][i] = default_ioport_writew;
187
ioport_write_table[2][i] = default_ioport_writel;
189
ioport_opaque[i] = NULL;
193
/***********************************************************/
195
void cpu_outb(CPUState *env, pio_addr_t addr, uint8_t val)
197
LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
198
ioport_write(0, addr, val);
201
env->last_io_time = cpu_get_time_fast();
205
void cpu_outw(CPUState *env, pio_addr_t addr, uint16_t val)
207
LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
208
ioport_write(1, addr, val);
211
env->last_io_time = cpu_get_time_fast();
215
void cpu_outl(CPUState *env, pio_addr_t addr, uint32_t val)
217
LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
218
ioport_write(2, addr, val);
221
env->last_io_time = cpu_get_time_fast();
225
uint8_t cpu_inb(CPUState *env, pio_addr_t addr)
228
val = ioport_read(0, addr);
229
LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
232
env->last_io_time = cpu_get_time_fast();
237
uint16_t cpu_inw(CPUState *env, pio_addr_t addr)
240
val = ioport_read(1, addr);
241
LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
244
env->last_io_time = cpu_get_time_fast();
249
uint32_t cpu_inl(CPUState *env, pio_addr_t addr)
252
val = ioport_read(2, addr);
253
LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
256
env->last_io_time = cpu_get_time_fast();