diff options
-rw-r--r-- | Makefile.target | 2 | ||||
-rw-r--r-- | cpu-all.h | 12 | ||||
-rw-r--r-- | hw/hw.h | 5 | ||||
-rw-r--r-- | hw/isa.h | 8 | ||||
-rw-r--r-- | ioport.c | 258 | ||||
-rw-r--r-- | ioport.h | 54 | ||||
-rw-r--r-- | vl.c | 226 |
7 files changed, 317 insertions, 248 deletions
diff --git a/Makefile.target b/Makefile.target index a593503aab..7f7c1670ed 100644 --- a/Makefile.target +++ b/Makefile.target @@ -489,7 +489,7 @@ endif #CONFIG_BSD_USER ifndef CONFIG_USER_ONLY obj-y = vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o \ - gdbstub.o gdbstub-xml.o msix.o + gdbstub.o gdbstub-xml.o msix.o ioport.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o @@ -837,17 +837,7 @@ void cpu_set_log_filename(const char *filename); int cpu_str_to_log_mask(const char *str); /* IO ports API */ - -/* NOTE: as these functions may be even used when there is an isa - brige on non x86 targets, we always defined them */ -#ifndef NO_CPU_IO_DEFS -void cpu_outb(CPUState *env, int addr, int val); -void cpu_outw(CPUState *env, int addr, int val); -void cpu_outl(CPUState *env, int addr, int val); -int cpu_inb(CPUState *env, int addr); -int cpu_inw(CPUState *env, int addr); -int cpu_inl(CPUState *env, int addr); -#endif +#include "ioport.h" /* memory API */ @@ -10,6 +10,7 @@ #include "cpu-common.h" #endif +#include "ioport.h" #include "irq.h" /* VM Load/Save */ @@ -266,8 +267,4 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque); typedef int QEMUBootSetHandler(void *opaque, const char *boot_device); void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque); -/* These should really be in isa.h, but are here to make pc.h happy. */ -typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); -typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address); - #endif @@ -2,13 +2,9 @@ #define HW_ISA_H /* ISA bus */ -extern target_phys_addr_t isa_mem_base; +#include "ioport.h" -int register_ioport_read(int start, int length, int size, - IOPortReadFunc *func, void *opaque); -int register_ioport_write(int start, int length, int size, - IOPortWriteFunc *func, void *opaque); -void isa_unassign_ioport(int start, int length); +extern target_phys_addr_t isa_mem_base; void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size); diff --git a/ioport.c b/ioport.c new file mode 100644 index 0000000000..d875209115 --- /dev/null +++ b/ioport.c @@ -0,0 +1,258 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* + * splitted out ioport related stuffs from vl.c. + */ + +#include "ioport.h" + +/***********************************************************/ +/* IO Port */ + +//#define DEBUG_UNUSED_IOPORT +//#define DEBUG_IOPORT + +#ifdef DEBUG_IOPORT +# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__) +#else +# define LOG_IOPORT(...) do { } while (0) +#endif + +/* XXX: use a two level table to limit memory usage */ + +static void *ioport_opaque[MAX_IOPORTS]; +static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; +static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; + +static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; +static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; + +static uint32_t ioport_read(int index, uint32_t address) +{ + static IOPortReadFunc *default_func[3] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl + }; + IOPortReadFunc *func = ioport_read_table[index][address]; + if (!func) + func = default_func[index]; + return func(ioport_opaque[address], address); +} + +static void ioport_write(int index, uint32_t address, uint32_t data) +{ + static IOPortWriteFunc *default_func[3] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel + }; + IOPortWriteFunc *func = ioport_write_table[index][address]; + if (!func) + func = default_func[index]; + func(ioport_opaque[address], address, data); +} + +static uint32_t default_ioport_readb(void *opaque, uint32_t address) +{ +#ifdef DEBUG_UNUSED_IOPORT + fprintf(stderr, "unused inb: port=0x%04x\n", address); +#endif + return 0xff; +} + +static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data) +{ +#ifdef DEBUG_UNUSED_IOPORT + fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data); +#endif +} + +/* default is to make two byte accesses */ +static uint32_t default_ioport_readw(void *opaque, uint32_t address) +{ + uint32_t data; + data = ioport_read(0, address); + address = (address + 1) & (MAX_IOPORTS - 1); + data |= ioport_read(0, address) << 8; + return data; +} + +static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data) +{ + ioport_write(0, address, data & 0xff); + address = (address + 1) & (MAX_IOPORTS - 1); + ioport_write(0, address, (data >> 8) & 0xff); +} + +static uint32_t default_ioport_readl(void *opaque, uint32_t address) +{ +#ifdef DEBUG_UNUSED_IOPORT + fprintf(stderr, "unused inl: port=0x%04x\n", address); +#endif + return 0xffffffff; +} + +static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data) +{ +#ifdef DEBUG_UNUSED_IOPORT + fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data); +#endif +} + +/* size is the word size in byte */ +int register_ioport_read(int start, int length, int size, + IOPortReadFunc *func, void *opaque) +{ + int i, bsize; + + if (size == 1) { + bsize = 0; + } else if (size == 2) { + bsize = 1; + } else if (size == 4) { + bsize = 2; + } else { + hw_error("register_ioport_read: invalid size"); + return -1; + } + for(i = start; i < start + length; i += size) { + ioport_read_table[bsize][i] = func; + if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) + hw_error("register_ioport_read: invalid opaque"); + ioport_opaque[i] = opaque; + } + return 0; +} + +/* size is the word size in byte */ +int register_ioport_write(int start, int length, int size, + IOPortWriteFunc *func, void *opaque) +{ + int i, bsize; + + if (size == 1) { + bsize = 0; + } else if (size == 2) { + bsize = 1; + } else if (size == 4) { + bsize = 2; + } else { + hw_error("register_ioport_write: invalid size"); + return -1; + } + for(i = start; i < start + length; i += size) { + ioport_write_table[bsize][i] = func; + if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) + hw_error("register_ioport_write: invalid opaque"); + ioport_opaque[i] = opaque; + } + return 0; +} + +void isa_unassign_ioport(int start, int length) +{ + int i; + + for(i = start; i < start + length; i++) { + ioport_read_table[0][i] = default_ioport_readb; + ioport_read_table[1][i] = default_ioport_readw; + ioport_read_table[2][i] = default_ioport_readl; + + ioport_write_table[0][i] = default_ioport_writeb; + ioport_write_table[1][i] = default_ioport_writew; + ioport_write_table[2][i] = default_ioport_writel; + + ioport_opaque[i] = NULL; + } +} + +/***********************************************************/ + +void cpu_outb(CPUState *env, int addr, int val) +{ + LOG_IOPORT("outb: %04x %02x\n", addr, val); + ioport_write(0, addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif +} + +void cpu_outw(CPUState *env, int addr, int val) +{ + LOG_IOPORT("outw: %04x %04x\n", addr, val); + ioport_write(1, addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif +} + +void cpu_outl(CPUState *env, int addr, int val) +{ + LOG_IOPORT("outl: %04x %08x\n", addr, val); + ioport_write(2, addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif +} + +int cpu_inb(CPUState *env, int addr) +{ + int val; + val = ioport_read(0, addr); + LOG_IOPORT("inb : %04x %02x\n", addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif + return val; +} + +int cpu_inw(CPUState *env, int addr) +{ + int val; + val = ioport_read(1, addr); + LOG_IOPORT("inw : %04x %04x\n", addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif + return val; +} + +int cpu_inl(CPUState *env, int addr) +{ + int val; + val = ioport_read(2, addr); + LOG_IOPORT("inl : %04x %08x\n", addr, val); +#ifdef CONFIG_KQEMU + if (env) + env->last_io_time = cpu_get_time_fast(); +#endif + return val; +} + diff --git a/ioport.h b/ioport.h new file mode 100644 index 0000000000..309a402f86 --- /dev/null +++ b/ioport.h @@ -0,0 +1,54 @@ +/* + * defines ioport related functions + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + */ + +/************************************************************************** + * IO ports API + */ + +#ifndef IOPORT_H +#define IOPORT_H + +#include "qemu-common.h" + +#define MAX_IOPORTS (64 * 1024) + +/* These should really be in isa.h, but are here to make pc.h happy. */ +typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); +typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address); + +int register_ioport_read(int start, int length, int size, + IOPortReadFunc *func, void *opaque); +int register_ioport_write(int start, int length, int size, + IOPortWriteFunc *func, void *opaque); +void isa_unassign_ioport(int start, int length); + + +/* NOTE: as these functions may be even used when there is an isa + brige on non x86 targets, we always defined them */ +#if !defined(NO_CPU_IO_DEFS) && defined(NEED_CPU_H) +void cpu_outb(CPUState *env, int addr, int val); +void cpu_outw(CPUState *env, int addr, int val); +void cpu_outl(CPUState *env, int addr, int val); +int cpu_inb(CPUState *env, int addr); +int cpu_inw(CPUState *env, int addr); +int cpu_inl(CPUState *env, int addr); +#endif + +#endif /* IOPORT_H */ @@ -167,18 +167,9 @@ int main(int argc, char **argv) #include "slirp/libslirp.h" -//#define DEBUG_UNUSED_IOPORT -//#define DEBUG_IOPORT //#define DEBUG_NET //#define DEBUG_SLIRP - -#ifdef DEBUG_IOPORT -# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__) -#else -# define LOG_IOPORT(...) do { } while (0) -#endif - #define DEFAULT_RAM_SIZE 128 /* Max number of USB devices that can be specified on the commandline. */ @@ -187,14 +178,8 @@ int main(int argc, char **argv) /* Max number of bluetooth switches on the commandline. */ #define MAX_BT_CMDLINE 10 -/* XXX: use a two level table to limit memory usage */ -#define MAX_IOPORTS 65536 - static const char *data_dir; const char *bios_name = NULL; -static void *ioport_opaque[MAX_IOPORTS]; -static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; -static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available to store the VM snapshots */ DriveInfo drives_table[MAX_DRIVES+1]; @@ -294,217 +279,6 @@ uint8_t qemu_uuid[16]; target_phys_addr_t isa_mem_base = 0; PicState2 *isa_pic; -static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; -static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; - -static uint32_t ioport_read(int index, uint32_t address) -{ - static IOPortReadFunc *default_func[3] = { - default_ioport_readb, - default_ioport_readw, - default_ioport_readl - }; - IOPortReadFunc *func = ioport_read_table[index][address]; - if (!func) - func = default_func[index]; - return func(ioport_opaque[address], address); -} - -static void ioport_write(int index, uint32_t address, uint32_t data) -{ - static IOPortWriteFunc *default_func[3] = { - default_ioport_writeb, - default_ioport_writew, - default_ioport_writel - }; - IOPortWriteFunc *func = ioport_write_table[index][address]; - if (!func) - func = default_func[index]; - func(ioport_opaque[address], address, data); -} - -static uint32_t default_ioport_readb(void *opaque, uint32_t address) -{ -#ifdef DEBUG_UNUSED_IOPORT - fprintf(stderr, "unused inb: port=0x%04x\n", address); -#endif - return 0xff; -} - -static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data) -{ -#ifdef DEBUG_UNUSED_IOPORT - fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data); -#endif -} - -/* default is to make two byte accesses */ -static uint32_t default_ioport_readw(void *opaque, uint32_t address) -{ - uint32_t data; - data = ioport_read(0, address); - address = (address + 1) & (MAX_IOPORTS - 1); - data |= ioport_read(0, address) << 8; - return data; -} - -static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data) -{ - ioport_write(0, address, data & 0xff); - address = (address + 1) & (MAX_IOPORTS - 1); - ioport_write(0, address, (data >> 8) & 0xff); -} - -static uint32_t default_ioport_readl(void *opaque, uint32_t address) -{ -#ifdef DEBUG_UNUSED_IOPORT - fprintf(stderr, "unused inl: port=0x%04x\n", address); -#endif - return 0xffffffff; -} - -static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data) -{ -#ifdef DEBUG_UNUSED_IOPORT - fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data); -#endif -} - -/* size is the word size in byte */ -int register_ioport_read(int start, int length, int size, - IOPortReadFunc *func, void *opaque) -{ - int i, bsize; - - if (size == 1) { - bsize = 0; - } else if (size == 2) { - bsize = 1; - } else if (size == 4) { - bsize = 2; - } else { - hw_error("register_ioport_read: invalid size"); - return -1; - } - for(i = start; i < start + length; i += size) { - ioport_read_table[bsize][i] = func; - if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) - hw_error("register_ioport_read: invalid opaque"); - ioport_opaque[i] = opaque; - } - return 0; -} - -/* size is the word size in byte */ -int register_ioport_write(int start, int length, int size, - IOPortWriteFunc *func, void *opaque) -{ - int i, bsize; - - if (size == 1) { - bsize = 0; - } else if (size == 2) { - bsize = 1; - } else if (size == 4) { - bsize = 2; - } else { - hw_error("register_ioport_write: invalid size"); - return -1; - } - for(i = start; i < start + length; i += size) { - ioport_write_table[bsize][i] = func; - if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) - hw_error("register_ioport_write: invalid opaque"); - ioport_opaque[i] = opaque; - } - return 0; -} - -void isa_unassign_ioport(int start, int length) -{ - int i; - - for(i = start; i < start + length; i++) { - ioport_read_table[0][i] = default_ioport_readb; - ioport_read_table[1][i] = default_ioport_readw; - ioport_read_table[2][i] = default_ioport_readl; - - ioport_write_table[0][i] = default_ioport_writeb; - ioport_write_table[1][i] = default_ioport_writew; - ioport_write_table[2][i] = default_ioport_writel; - - ioport_opaque[i] = NULL; - } -} - -/***********************************************************/ - -void cpu_outb(CPUState *env, int addr, int val) -{ - LOG_IOPORT("outb: %04x %02x\n", addr, val); - ioport_write(0, addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif -} - -void cpu_outw(CPUState *env, int addr, int val) -{ - LOG_IOPORT("outw: %04x %04x\n", addr, val); - ioport_write(1, addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif -} - -void cpu_outl(CPUState *env, int addr, int val) -{ - LOG_IOPORT("outl: %04x %08x\n", addr, val); - ioport_write(2, addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif -} - -int cpu_inb(CPUState *env, int addr) -{ - int val; - val = ioport_read(0, addr); - LOG_IOPORT("inb : %04x %02x\n", addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif - return val; -} - -int cpu_inw(CPUState *env, int addr) -{ - int val; - val = ioport_read(1, addr); - LOG_IOPORT("inw : %04x %04x\n", addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif - return val; -} - -int cpu_inl(CPUState *env, int addr) -{ - int val; - val = ioport_read(2, addr); - LOG_IOPORT("inl : %04x %08x\n", addr, val); -#ifdef CONFIG_KQEMU - if (env) - env->last_io_time = cpu_get_time_fast(); -#endif - return val; -} - /***********************************************************/ void hw_error(const char *fmt, ...) { |