memory: I/O address space support

Allow registering I/O ports via the same mechanism as mmio ranges.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Avi Kivity 2011-07-26 14:26:08 +03:00 committed by Anthony Liguori
parent 16ef61c9e5
commit 658b222401
3 changed files with 64 additions and 1 deletions

View file

@ -31,6 +31,9 @@ MemoryRegion *get_system_memory(void);
/* Set the root memory region. This region is the system memory map. */
void set_system_memory_map(MemoryRegion *mr);
/* Set the I/O memory region. This region is the I/O memory map. */
void set_system_io_map(MemoryRegion *mr);
#endif
#endif

View file

@ -13,6 +13,7 @@
#include "memory.h"
#include "exec-memory.h"
#include "ioport.h"
#include <assert.h>
typedef struct AddrRange AddrRange;
@ -217,6 +218,52 @@ static AddressSpace address_space_memory = {
.ops = &address_space_ops_memory,
};
static void memory_region_iorange_read(IORange *iorange,
uint64_t offset,
unsigned width,
uint64_t *data)
{
MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
*data = mr->ops->read(mr->opaque, offset, width);
}
static void memory_region_iorange_write(IORange *iorange,
uint64_t offset,
unsigned width,
uint64_t data)
{
MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange);
mr->ops->write(mr->opaque, offset, data, width);
}
static const IORangeOps memory_region_iorange_ops = {
.read = memory_region_iorange_read,
.write = memory_region_iorange_write,
};
static void as_io_range_add(AddressSpace *as, FlatRange *fr)
{
iorange_init(&fr->mr->iorange, &memory_region_iorange_ops,
fr->addr.start,fr->addr.size);
ioport_register(&fr->mr->iorange);
}
static void as_io_range_del(AddressSpace *as, FlatRange *fr)
{
isa_unassign_ioport(fr->addr.start, fr->addr.size);
}
static const AddressSpaceOps address_space_ops_io = {
.range_add = as_io_range_add,
.range_del = as_io_range_del,
};
static AddressSpace address_space_io = {
.ops = &address_space_ops_io,
};
/* Render a memory region into the global view. Ranges in @view obscure
* ranges in @mr.
*/
@ -365,7 +412,12 @@ static void address_space_update_topology(AddressSpace *as)
static void memory_region_update_topology(void)
{
address_space_update_topology(&address_space_memory);
if (address_space_memory.root) {
address_space_update_topology(&address_space_memory);
}
if (address_space_io.root) {
address_space_update_topology(&address_space_io);
}
}
void memory_region_init(MemoryRegion *mr,
@ -777,3 +829,9 @@ void set_system_memory_map(MemoryRegion *mr)
address_space_memory.root = mr;
memory_region_update_topology();
}
void set_system_io_map(MemoryRegion *mr)
{
address_space_io.root = mr;
memory_region_update_topology();
}

View file

@ -22,6 +22,7 @@
#include "cpu-common.h"
#include "targphys.h"
#include "qemu-queue.h"
#include "iorange.h"
typedef struct MemoryRegionOps MemoryRegionOps;
typedef struct MemoryRegion MemoryRegion;
@ -91,6 +92,7 @@ struct MemoryRegion {
target_phys_addr_t offset;
bool backend_registered;
ram_addr_t ram_addr;
IORange iorange;
bool terminates;
MemoryRegion *alias;
target_phys_addr_t alias_offset;