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. */
|
/* Set the root memory region. This region is the system memory map. */
|
||||||
void set_system_memory_map(MemoryRegion *mr);
|
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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
60
memory.c
60
memory.c
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "exec-memory.h"
|
#include "exec-memory.h"
|
||||||
|
#include "ioport.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
typedef struct AddrRange AddrRange;
|
typedef struct AddrRange AddrRange;
|
||||||
|
@ -217,6 +218,52 @@ static AddressSpace address_space_memory = {
|
||||||
.ops = &address_space_ops_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
|
/* Render a memory region into the global view. Ranges in @view obscure
|
||||||
* ranges in @mr.
|
* ranges in @mr.
|
||||||
*/
|
*/
|
||||||
|
@ -365,7 +412,12 @@ static void address_space_update_topology(AddressSpace *as)
|
||||||
|
|
||||||
static void memory_region_update_topology(void)
|
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,
|
void memory_region_init(MemoryRegion *mr,
|
||||||
|
@ -777,3 +829,9 @@ void set_system_memory_map(MemoryRegion *mr)
|
||||||
address_space_memory.root = mr;
|
address_space_memory.root = mr;
|
||||||
memory_region_update_topology();
|
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 "cpu-common.h"
|
||||||
#include "targphys.h"
|
#include "targphys.h"
|
||||||
#include "qemu-queue.h"
|
#include "qemu-queue.h"
|
||||||
|
#include "iorange.h"
|
||||||
|
|
||||||
typedef struct MemoryRegionOps MemoryRegionOps;
|
typedef struct MemoryRegionOps MemoryRegionOps;
|
||||||
typedef struct MemoryRegion MemoryRegion;
|
typedef struct MemoryRegion MemoryRegion;
|
||||||
|
@ -91,6 +92,7 @@ struct MemoryRegion {
|
||||||
target_phys_addr_t offset;
|
target_phys_addr_t offset;
|
||||||
bool backend_registered;
|
bool backend_registered;
|
||||||
ram_addr_t ram_addr;
|
ram_addr_t ram_addr;
|
||||||
|
IORange iorange;
|
||||||
bool terminates;
|
bool terminates;
|
||||||
MemoryRegion *alias;
|
MemoryRegion *alias;
|
||||||
target_phys_addr_t alias_offset;
|
target_phys_addr_t alias_offset;
|
||||||
|
|
Loading…
Reference in New Issue