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:
parent
16ef61c9e5
commit
658b222401
@ -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
|
||||
|
60
memory.c
60
memory.c
@ -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();
|
||||
}
|
||||
|
2
memory.h
2
memory.h
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user