mirror of https://github.com/xqemu/xqemu.git
Remove IO_MEM_SUBWIDTH.
Greatly simplify the subpage implementation by not supporting multiple devices at the same address at different widths. We don't need full copies of mem_read/mem_write/opaque for each address, only a single index back into the main io_mem_* arrays. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
6495a04457
commit
f64052478e
|
@ -125,7 +125,6 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
|
||||||
/* Acts like a ROM when read and like a device when written. */
|
/* Acts like a ROM when read and like a device when written. */
|
||||||
#define IO_MEM_ROMD (1)
|
#define IO_MEM_ROMD (1)
|
||||||
#define IO_MEM_SUBPAGE (2)
|
#define IO_MEM_SUBPAGE (2)
|
||||||
#define IO_MEM_SUBWIDTH (4)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
113
exec.c
113
exec.c
|
@ -2549,16 +2549,15 @@ static inline void tlb_set_dirty(CPUState *env,
|
||||||
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
|
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
|
||||||
typedef struct subpage_t {
|
typedef struct subpage_t {
|
||||||
target_phys_addr_t base;
|
target_phys_addr_t base;
|
||||||
CPUReadMemoryFunc * const *mem_read[TARGET_PAGE_SIZE][4];
|
ram_addr_t sub_io_index[TARGET_PAGE_SIZE];
|
||||||
CPUWriteMemoryFunc * const *mem_write[TARGET_PAGE_SIZE][4];
|
ram_addr_t region_offset[TARGET_PAGE_SIZE];
|
||||||
void *opaque[TARGET_PAGE_SIZE][2][4];
|
|
||||||
ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4];
|
|
||||||
} subpage_t;
|
} subpage_t;
|
||||||
|
|
||||||
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||||
ram_addr_t memory, ram_addr_t region_offset);
|
ram_addr_t memory, ram_addr_t region_offset);
|
||||||
static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
|
static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
|
||||||
ram_addr_t orig_memory, ram_addr_t region_offset);
|
ram_addr_t orig_memory,
|
||||||
|
ram_addr_t region_offset);
|
||||||
#define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
|
#define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
|
||||||
need_subpage) \
|
need_subpage) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -2596,7 +2595,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
|
||||||
PhysPageDesc *p;
|
PhysPageDesc *p;
|
||||||
CPUState *env;
|
CPUState *env;
|
||||||
ram_addr_t orig_size = size;
|
ram_addr_t orig_size = size;
|
||||||
void *subpage;
|
subpage_t *subpage;
|
||||||
|
|
||||||
cpu_notify_set_memory(start_addr, size, phys_offset);
|
cpu_notify_set_memory(start_addr, size, phys_offset);
|
||||||
|
|
||||||
|
@ -2615,7 +2614,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
|
||||||
|
|
||||||
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
|
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
|
||||||
need_subpage);
|
need_subpage);
|
||||||
if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
|
if (need_subpage) {
|
||||||
if (!(orig_memory & IO_MEM_SUBPAGE)) {
|
if (!(orig_memory & IO_MEM_SUBPAGE)) {
|
||||||
subpage = subpage_init((addr & TARGET_PAGE_MASK),
|
subpage = subpage_init((addr & TARGET_PAGE_MASK),
|
||||||
&p->phys_offset, orig_memory,
|
&p->phys_offset, orig_memory,
|
||||||
|
@ -2647,7 +2646,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
|
||||||
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
|
CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
|
||||||
end_addr2, need_subpage);
|
end_addr2, need_subpage);
|
||||||
|
|
||||||
if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
|
if (need_subpage) {
|
||||||
subpage = subpage_init((addr & TARGET_PAGE_MASK),
|
subpage = subpage_init((addr & TARGET_PAGE_MASK),
|
||||||
&p->phys_offset, IO_MEM_UNASSIGNED,
|
&p->phys_offset, IO_MEM_UNASSIGNED,
|
||||||
addr & TARGET_PAGE_MASK);
|
addr & TARGET_PAGE_MASK);
|
||||||
|
@ -3145,89 +3144,65 @@ static CPUWriteMemoryFunc * const watch_mem_write[3] = {
|
||||||
watch_mem_writel,
|
watch_mem_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
|
static inline uint32_t subpage_readlen (subpage_t *mmio,
|
||||||
unsigned int len)
|
target_phys_addr_t addr,
|
||||||
|
unsigned int len)
|
||||||
{
|
{
|
||||||
uint32_t ret;
|
unsigned int idx = SUBPAGE_IDX(addr);
|
||||||
unsigned int idx;
|
|
||||||
|
|
||||||
idx = SUBPAGE_IDX(addr);
|
|
||||||
#if defined(DEBUG_SUBPAGE)
|
#if defined(DEBUG_SUBPAGE)
|
||||||
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
|
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
|
||||||
mmio, len, addr, idx);
|
mmio, len, addr, idx);
|
||||||
#endif
|
#endif
|
||||||
ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len],
|
|
||||||
addr + mmio->region_offset[idx][0][len]);
|
|
||||||
|
|
||||||
return ret;
|
addr += mmio->region_offset[idx];
|
||||||
|
idx = mmio->sub_io_index[idx];
|
||||||
|
return io_mem_read[idx][len](io_mem_opaque[idx], addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
|
static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
|
||||||
uint32_t value, unsigned int len)
|
uint32_t value, unsigned int len)
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
unsigned int idx = SUBPAGE_IDX(addr);
|
||||||
|
|
||||||
idx = SUBPAGE_IDX(addr);
|
|
||||||
#if defined(DEBUG_SUBPAGE)
|
#if defined(DEBUG_SUBPAGE)
|
||||||
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
|
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n",
|
||||||
mmio, len, addr, idx, value);
|
__func__, mmio, len, addr, idx, value);
|
||||||
#endif
|
#endif
|
||||||
(**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len],
|
|
||||||
addr + mmio->region_offset[idx][1][len],
|
addr += mmio->region_offset[idx];
|
||||||
value);
|
idx = mmio->sub_io_index[idx];
|
||||||
|
io_mem_write[idx][len](io_mem_opaque[idx], addr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
|
static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return subpage_readlen(opaque, addr, 0);
|
return subpage_readlen(opaque, addr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subpage_writeb (void *opaque, target_phys_addr_t addr,
|
static void subpage_writeb (void *opaque, target_phys_addr_t addr,
|
||||||
uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
|
|
||||||
#endif
|
|
||||||
subpage_writelen(opaque, addr, value, 0);
|
subpage_writelen(opaque, addr, value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
|
static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return subpage_readlen(opaque, addr, 1);
|
return subpage_readlen(opaque, addr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subpage_writew (void *opaque, target_phys_addr_t addr,
|
static void subpage_writew (void *opaque, target_phys_addr_t addr,
|
||||||
uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
|
|
||||||
#endif
|
|
||||||
subpage_writelen(opaque, addr, value, 1);
|
subpage_writelen(opaque, addr, value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
|
static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return subpage_readlen(opaque, addr, 2);
|
return subpage_readlen(opaque, addr, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subpage_writel (void *opaque,
|
static void subpage_writel (void *opaque, target_phys_addr_t addr,
|
||||||
target_phys_addr_t addr, uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_SUBPAGE)
|
|
||||||
printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
|
|
||||||
#endif
|
|
||||||
subpage_writelen(opaque, addr, value, 2);
|
subpage_writelen(opaque, addr, value, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3247,7 +3222,6 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||||
ram_addr_t memory, ram_addr_t region_offset)
|
ram_addr_t memory, ram_addr_t region_offset)
|
||||||
{
|
{
|
||||||
int idx, eidx;
|
int idx, eidx;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
|
if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -3257,27 +3231,18 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||||
printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
|
printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
|
||||||
mmio, start, end, idx, eidx, memory);
|
mmio, start, end, idx, eidx, memory);
|
||||||
#endif
|
#endif
|
||||||
memory >>= IO_MEM_SHIFT;
|
memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
|
||||||
for (; idx <= eidx; idx++) {
|
for (; idx <= eidx; idx++) {
|
||||||
for (i = 0; i < 4; i++) {
|
mmio->sub_io_index[idx] = memory;
|
||||||
if (io_mem_read[memory][i]) {
|
mmio->region_offset[idx] = region_offset;
|
||||||
mmio->mem_read[idx][i] = &io_mem_read[memory][i];
|
|
||||||
mmio->opaque[idx][0][i] = io_mem_opaque[memory];
|
|
||||||
mmio->region_offset[idx][0][i] = region_offset;
|
|
||||||
}
|
|
||||||
if (io_mem_write[memory][i]) {
|
|
||||||
mmio->mem_write[idx][i] = &io_mem_write[memory][i];
|
|
||||||
mmio->opaque[idx][1][i] = io_mem_opaque[memory];
|
|
||||||
mmio->region_offset[idx][1][i] = region_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
|
static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
|
||||||
ram_addr_t orig_memory, ram_addr_t region_offset)
|
ram_addr_t orig_memory,
|
||||||
|
ram_addr_t region_offset)
|
||||||
{
|
{
|
||||||
subpage_t *mmio;
|
subpage_t *mmio;
|
||||||
int subpage_memory;
|
int subpage_memory;
|
||||||
|
@ -3291,8 +3256,7 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
|
||||||
mmio, base, TARGET_PAGE_SIZE, subpage_memory);
|
mmio, base, TARGET_PAGE_SIZE, subpage_memory);
|
||||||
#endif
|
#endif
|
||||||
*phys = subpage_memory | IO_MEM_SUBPAGE;
|
*phys = subpage_memory | IO_MEM_SUBPAGE;
|
||||||
subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory,
|
subpage_register(mmio, 0, TARGET_PAGE_SIZE-1, orig_memory, region_offset);
|
||||||
region_offset);
|
|
||||||
|
|
||||||
return mmio;
|
return mmio;
|
||||||
}
|
}
|
||||||
|
@ -3322,8 +3286,6 @@ static int cpu_register_io_memory_fixed(int io_index,
|
||||||
CPUWriteMemoryFunc * const *mem_write,
|
CPUWriteMemoryFunc * const *mem_write,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
int i, subwidth = 0;
|
|
||||||
|
|
||||||
if (io_index <= 0) {
|
if (io_index <= 0) {
|
||||||
io_index = get_free_io_mem_idx();
|
io_index = get_free_io_mem_idx();
|
||||||
if (io_index == -1)
|
if (io_index == -1)
|
||||||
|
@ -3334,14 +3296,11 @@ static int cpu_register_io_memory_fixed(int io_index,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0;i < 3; i++) {
|
memcpy(io_mem_read[io_index], mem_read, 3 * sizeof(CPUReadMemoryFunc*));
|
||||||
if (!mem_read[i] || !mem_write[i])
|
memcpy(io_mem_write[io_index], mem_write, 3 * sizeof(CPUWriteMemoryFunc*));
|
||||||
subwidth = IO_MEM_SUBWIDTH;
|
|
||||||
io_mem_read[io_index][i] = mem_read[i];
|
|
||||||
io_mem_write[io_index][i] = mem_write[i];
|
|
||||||
}
|
|
||||||
io_mem_opaque[io_index] = opaque;
|
io_mem_opaque[io_index] = opaque;
|
||||||
return (io_index << IO_MEM_SHIFT) | subwidth;
|
|
||||||
|
return (io_index << IO_MEM_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
|
int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
|
||||||
|
|
Loading…
Reference in New Issue