Loading cpu-all.h +11 −3 Original line number Diff line number Diff line Loading @@ -877,9 +877,17 @@ extern ram_addr_t ram_size; typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); void cpu_register_physical_memory(target_phys_addr_t start_addr, void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset); ram_addr_t phys_offset, ram_addr_t region_offset); static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) { cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0); } ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); ram_addr_t qemu_ram_alloc(ram_addr_t); void qemu_ram_free(ram_addr_t addr); Loading exec.c +62 −20 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ typedef struct PageDesc { typedef struct PhysPageDesc { /* offset in host memory of the page + io_index in the low bits */ ram_addr_t phys_offset; ram_addr_t region_offset; } PhysPageDesc; #define L2_BITS 10 Loading Loading @@ -199,6 +200,7 @@ typedef struct subpage_t { CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE][4]; CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4]; void *opaque[TARGET_PAGE_SIZE][2][4]; ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4]; } subpage_t; #ifdef _WIN32 Loading Loading @@ -1969,7 +1971,13 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, and avoid full address decoding in every device. We can't use the high bits of pd for this because IO_MEM_ROMD uses these as a ram address. */ iotlb = (pd & ~TARGET_PAGE_MASK) + paddr; iotlb = (pd & ~TARGET_PAGE_MASK); if (p) { /* FIXME: What if this isn't page aligned? */ iotlb += p->region_offset; } else { iotlb += paddr; } } code_address = address; Loading Loading @@ -2209,10 +2217,11 @@ static inline void tlb_set_dirty(CPUState *env, #endif /* defined(CONFIG_USER_ONLY) */ #if !defined(CONFIG_USER_ONLY) static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory); ram_addr_t memory, ram_addr_t region_offset); static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, ram_addr_t orig_memory); ram_addr_t orig_memory, ram_addr_t region_offset); #define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \ need_subpage) \ do { \ Loading @@ -2235,10 +2244,15 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, /* register physical memory. 'size' must be a multiple of the target page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an io memory page */ void cpu_register_physical_memory(target_phys_addr_t start_addr, io memory page. The address used when calling the IO function is the offset from the start of the region, plus region_offset. Both start_region and regon_offset are rounded down to a page boundary before calculating this offset. This should not be a problem unless the low bits of start_addr and region_offset differ. */ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) ram_addr_t phys_offset, ram_addr_t region_offset) { target_phys_addr_t addr, end_addr; PhysPageDesc *p; Loading @@ -2256,6 +2270,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (kvm_enabled()) kvm_set_phys_mem(start_addr, size, phys_offset); region_offset &= TARGET_PAGE_MASK; size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; end_addr = start_addr + (target_phys_addr_t)size; for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { Loading @@ -2270,12 +2285,15 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { if (!(orig_memory & IO_MEM_SUBPAGE)) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, orig_memory); &p->phys_offset, orig_memory, p->region_offset); } else { subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT]; } subpage_register(subpage, start_addr2, end_addr2, phys_offset); subpage_register(subpage, start_addr2, end_addr2, phys_offset, region_offset); p->region_offset = 0; } else { p->phys_offset = phys_offset; if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM || Loading @@ -2285,10 +2303,11 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, } else { p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); p->phys_offset = phys_offset; p->region_offset = region_offset; if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM || (phys_offset & IO_MEM_ROMD)) (phys_offset & IO_MEM_ROMD)) { phys_offset += TARGET_PAGE_SIZE; else { }else { target_phys_addr_t start_addr2, end_addr2; int need_subpage = 0; Loading @@ -2297,12 +2316,15 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, IO_MEM_UNASSIGNED); &p->phys_offset, IO_MEM_UNASSIGNED, 0); subpage_register(subpage, start_addr2, end_addr2, phys_offset); phys_offset, region_offset); p->region_offset = 0; } } } region_offset += TARGET_PAGE_SIZE; } /* since each CPU stores ram addresses in its TLB cache, we must Loading Loading @@ -2609,12 +2631,13 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr uint32_t ret; unsigned int idx; idx = SUBPAGE_IDX(addr - mmio->base); idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__, mmio, len, addr, idx); #endif ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr); ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr + mmio->region_offset[idx][0][len]); return ret; } Loading @@ -2624,12 +2647,14 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, { unsigned int idx; idx = SUBPAGE_IDX(addr - mmio->base); idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__, mmio, len, addr, idx, value); #endif (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr, value); (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr + mmio->region_offset[idx][1][len], value); } static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr) Loading Loading @@ -2699,7 +2724,7 @@ static CPUWriteMemoryFunc *subpage_write[] = { }; static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory) ram_addr_t memory, ram_addr_t region_offset) { int idx, eidx; unsigned int i; Loading @@ -2718,10 +2743,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, if (io_mem_read[memory][i]) { 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; } } } Loading @@ -2730,7 +2757,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, } static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, ram_addr_t orig_memory) ram_addr_t orig_memory, ram_addr_t region_offset) { subpage_t *mmio; int subpage_memory; Loading @@ -2744,7 +2771,8 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, mmio, base, TARGET_PAGE_SIZE, subpage_memory); #endif *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); } return mmio; Loading Loading @@ -2878,6 +2906,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (is_write) { if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; /* XXX: could force cpu_single_env to NULL to avoid potential bugs */ if (l >= 4 && ((addr & 3) == 0)) { Loading Loading @@ -2915,6 +2945,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; if (l >= 4 && ((addr & 3) == 0)) { /* 32 bit read access */ val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); Loading Loading @@ -3004,6 +3036,8 @@ uint32_t ldl_phys(target_phys_addr_t addr) !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); } else { /* RAM case */ Loading Loading @@ -3034,6 +3068,8 @@ uint64_t ldq_phys(target_phys_addr_t addr) !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; #ifdef TARGET_WORDS_BIGENDIAN val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32; val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4); Loading Loading @@ -3085,6 +3121,8 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); Loading Loading @@ -3119,6 +3157,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; #ifdef TARGET_WORDS_BIGENDIAN io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32); io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val); Loading Loading @@ -3150,6 +3190,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; Loading hw/arm_gic.c +5 −11 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ do { printf("arm_gic: " fmt , ##args); } while (0) #ifdef NVIC static const uint8_t gic_id[] = { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 }; #define GIC_DIST_OFFSET 0 /* The NVIC has 16 internal vectors. However these are not exposed through the normal GIC interface. */ #define GIC_BASE_IRQ 32 #else static const uint8_t gic_id[] = { 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; #define GIC_DIST_OFFSET 0x1000 #define GIC_BASE_IRQ 0 #endif Loading Loading @@ -76,7 +74,6 @@ typedef struct gic_irq_state typedef struct gic_state { uint32_t base; qemu_irq parent_irq[NCPU]; int enabled; int cpu_enabled[NCPU]; Loading Loading @@ -252,7 +249,6 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) cpu = gic_get_current_cpu(); cm = 1 << cpu; offset -= s->base + GIC_DIST_OFFSET; if (offset < 0x100) { #ifndef NVIC if (offset == 0) Loading Loading @@ -365,7 +361,7 @@ static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset) #ifdef NVIC gic_state *s = (gic_state *)opaque; uint32_t addr; addr = offset - s->base; addr = offset; if (addr < 0x100 || addr > 0xd00) return nvic_readl(s->nvic, addr); #endif Loading @@ -383,7 +379,6 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, int cpu; cpu = gic_get_current_cpu(); offset -= s->base + GIC_DIST_OFFSET; if (offset < 0x100) { #ifdef NVIC goto bad_reg; Loading Loading @@ -526,13 +521,13 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset, gic_state *s = (gic_state *)opaque; #ifdef NVIC uint32_t addr; addr = offset - s->base; addr = offset; if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) { nvic_writel(s->nvic, addr, value); return; } #endif if (offset - s->base == GIC_DIST_OFFSET + 0xf00) { if (offset == 0xf00) { int cpu; int irq; int mask; Loading Loading @@ -723,7 +718,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) return 0; } static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq) static gic_state *gic_init(uint32_t dist_base, qemu_irq *parent_irq) { gic_state *s; int iomemtype; Loading @@ -738,9 +733,8 @@ static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq) } iomemtype = cpu_register_io_memory(0, gic_dist_readfn, gic_dist_writefn, s); cpu_register_physical_memory(base + GIC_DIST_OFFSET, 0x00001000, cpu_register_physical_memory(dist_base, 0x00001000, iomemtype); s->base = base; gic_reset(s); register_savevm("arm_gic", -1, 1, gic_save, gic_load, s); return s; Loading hw/arm_sysctl.c +0 −4 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ #define LOCK_VALUE 0xa05f typedef struct { uint32_t base; uint32_t sys_id; uint32_t leds; uint16_t lockval; Loading @@ -29,7 +28,6 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; offset -= s->base; switch (offset) { case 0x00: /* ID */ return s->sys_id; Loading Loading @@ -108,7 +106,6 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, uint32_t val) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; offset -= s->base; switch (offset) { case 0x08: /* LED */ Loading Loading @@ -199,7 +196,6 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id) s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state)); if (!s) return; s->base = base; s->sys_id = sys_id; /* The MPcore bootloader uses these flags to start secondary CPUs. We don't use a bootloader, so do this here. */ Loading hw/arm_timer.c +0 −8 Original line number Diff line number Diff line Loading @@ -190,7 +190,6 @@ static void *arm_timer_init(uint32_t freq, qemu_irq irq) typedef struct { void *timer[2]; int level[2]; uint32_t base; qemu_irq irq; } sp804_state; Loading @@ -208,7 +207,6 @@ static uint32_t sp804_read(void *opaque, target_phys_addr_t offset) sp804_state *s = (sp804_state *)opaque; /* ??? Don't know the PrimeCell ID for this device. */ offset -= s->base; if (offset < 0x20) { return arm_timer_read(s->timer[0], offset); } else { Loading @@ -221,7 +219,6 @@ static void sp804_write(void *opaque, target_phys_addr_t offset, { sp804_state *s = (sp804_state *)opaque; offset -= s->base; if (offset < 0x20) { arm_timer_write(s->timer[0], offset, value); } else { Loading Loading @@ -268,7 +265,6 @@ void sp804_init(uint32_t base, qemu_irq irq) s = (sp804_state *)qemu_mallocz(sizeof(sp804_state)); qi = qemu_allocate_irqs(sp804_set_irq, s, 2); s->base = base; s->irq = irq; /* ??? The timers are actually configurable between 32kHz and 1MHz, but we don't implement that. */ Loading @@ -285,7 +281,6 @@ void sp804_init(uint32_t base, qemu_irq irq) typedef struct { void *timer[3]; uint32_t base; } icp_pit_state; static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) Loading @@ -294,7 +289,6 @@ static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) int n; /* ??? Don't know the PrimeCell ID for this device. */ offset -= s->base; n = offset >> 8; if (n > 3) cpu_abort(cpu_single_env, "sp804_read: Bad timer %d\n", n); Loading @@ -308,7 +302,6 @@ static void icp_pit_write(void *opaque, target_phys_addr_t offset, icp_pit_state *s = (icp_pit_state *)opaque; int n; offset -= s->base; n = offset >> 8; if (n > 3) cpu_abort(cpu_single_env, "sp804_write: Bad timer %d\n", n); Loading @@ -335,7 +328,6 @@ void icp_pit_init(uint32_t base, qemu_irq *pic, int irq) icp_pit_state *s; s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state)); s->base = base; /* Timer 0 runs at the system clock speed (40MHz). */ s->timer[0] = arm_timer_init(40000000, pic[irq]); /* The other two timers run at 1MHz. */ Loading Loading
cpu-all.h +11 −3 Original line number Diff line number Diff line Loading @@ -877,9 +877,17 @@ extern ram_addr_t ram_size; typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); void cpu_register_physical_memory(target_phys_addr_t start_addr, void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset); ram_addr_t phys_offset, ram_addr_t region_offset); static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) { cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0); } ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); ram_addr_t qemu_ram_alloc(ram_addr_t); void qemu_ram_free(ram_addr_t addr); Loading
exec.c +62 −20 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ typedef struct PageDesc { typedef struct PhysPageDesc { /* offset in host memory of the page + io_index in the low bits */ ram_addr_t phys_offset; ram_addr_t region_offset; } PhysPageDesc; #define L2_BITS 10 Loading Loading @@ -199,6 +200,7 @@ typedef struct subpage_t { CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE][4]; CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4]; void *opaque[TARGET_PAGE_SIZE][2][4]; ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4]; } subpage_t; #ifdef _WIN32 Loading Loading @@ -1969,7 +1971,13 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, and avoid full address decoding in every device. We can't use the high bits of pd for this because IO_MEM_ROMD uses these as a ram address. */ iotlb = (pd & ~TARGET_PAGE_MASK) + paddr; iotlb = (pd & ~TARGET_PAGE_MASK); if (p) { /* FIXME: What if this isn't page aligned? */ iotlb += p->region_offset; } else { iotlb += paddr; } } code_address = address; Loading Loading @@ -2209,10 +2217,11 @@ static inline void tlb_set_dirty(CPUState *env, #endif /* defined(CONFIG_USER_ONLY) */ #if !defined(CONFIG_USER_ONLY) static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory); ram_addr_t memory, ram_addr_t region_offset); static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, ram_addr_t orig_memory); ram_addr_t orig_memory, ram_addr_t region_offset); #define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \ need_subpage) \ do { \ Loading @@ -2235,10 +2244,15 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, /* register physical memory. 'size' must be a multiple of the target page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an io memory page */ void cpu_register_physical_memory(target_phys_addr_t start_addr, io memory page. The address used when calling the IO function is the offset from the start of the region, plus region_offset. Both start_region and regon_offset are rounded down to a page boundary before calculating this offset. This should not be a problem unless the low bits of start_addr and region_offset differ. */ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) ram_addr_t phys_offset, ram_addr_t region_offset) { target_phys_addr_t addr, end_addr; PhysPageDesc *p; Loading @@ -2256,6 +2270,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (kvm_enabled()) kvm_set_phys_mem(start_addr, size, phys_offset); region_offset &= TARGET_PAGE_MASK; size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; end_addr = start_addr + (target_phys_addr_t)size; for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { Loading @@ -2270,12 +2285,15 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { if (!(orig_memory & IO_MEM_SUBPAGE)) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, orig_memory); &p->phys_offset, orig_memory, p->region_offset); } else { subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT]; } subpage_register(subpage, start_addr2, end_addr2, phys_offset); subpage_register(subpage, start_addr2, end_addr2, phys_offset, region_offset); p->region_offset = 0; } else { p->phys_offset = phys_offset; if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM || Loading @@ -2285,10 +2303,11 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, } else { p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); p->phys_offset = phys_offset; p->region_offset = region_offset; if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM || (phys_offset & IO_MEM_ROMD)) (phys_offset & IO_MEM_ROMD)) { phys_offset += TARGET_PAGE_SIZE; else { }else { target_phys_addr_t start_addr2, end_addr2; int need_subpage = 0; Loading @@ -2297,12 +2316,15 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, IO_MEM_UNASSIGNED); &p->phys_offset, IO_MEM_UNASSIGNED, 0); subpage_register(subpage, start_addr2, end_addr2, phys_offset); phys_offset, region_offset); p->region_offset = 0; } } } region_offset += TARGET_PAGE_SIZE; } /* since each CPU stores ram addresses in its TLB cache, we must Loading Loading @@ -2609,12 +2631,13 @@ static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr uint32_t ret; unsigned int idx; idx = SUBPAGE_IDX(addr - mmio->base); idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__, mmio, len, addr, idx); #endif ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr); ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr + mmio->region_offset[idx][0][len]); return ret; } Loading @@ -2624,12 +2647,14 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, { unsigned int idx; idx = SUBPAGE_IDX(addr - mmio->base); idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__, mmio, len, addr, idx, value); #endif (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr, value); (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr + mmio->region_offset[idx][1][len], value); } static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr) Loading Loading @@ -2699,7 +2724,7 @@ static CPUWriteMemoryFunc *subpage_write[] = { }; static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory) ram_addr_t memory, ram_addr_t region_offset) { int idx, eidx; unsigned int i; Loading @@ -2718,10 +2743,12 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, if (io_mem_read[memory][i]) { 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; } } } Loading @@ -2730,7 +2757,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, } static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, ram_addr_t orig_memory) ram_addr_t orig_memory, ram_addr_t region_offset) { subpage_t *mmio; int subpage_memory; Loading @@ -2744,7 +2771,8 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, mmio, base, TARGET_PAGE_SIZE, subpage_memory); #endif *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); } return mmio; Loading Loading @@ -2878,6 +2906,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (is_write) { if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; /* XXX: could force cpu_single_env to NULL to avoid potential bugs */ if (l >= 4 && ((addr & 3) == 0)) { Loading Loading @@ -2915,6 +2945,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; if (l >= 4 && ((addr & 3) == 0)) { /* 32 bit read access */ val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); Loading Loading @@ -3004,6 +3036,8 @@ uint32_t ldl_phys(target_phys_addr_t addr) !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); } else { /* RAM case */ Loading Loading @@ -3034,6 +3068,8 @@ uint64_t ldq_phys(target_phys_addr_t addr) !(pd & IO_MEM_ROMD)) { /* I/O case */ io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; #ifdef TARGET_WORDS_BIGENDIAN val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32; val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4); Loading Loading @@ -3085,6 +3121,8 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); Loading Loading @@ -3119,6 +3157,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; #ifdef TARGET_WORDS_BIGENDIAN io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32); io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val); Loading Loading @@ -3150,6 +3190,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; Loading
hw/arm_gic.c +5 −11 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ do { printf("arm_gic: " fmt , ##args); } while (0) #ifdef NVIC static const uint8_t gic_id[] = { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 }; #define GIC_DIST_OFFSET 0 /* The NVIC has 16 internal vectors. However these are not exposed through the normal GIC interface. */ #define GIC_BASE_IRQ 32 #else static const uint8_t gic_id[] = { 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; #define GIC_DIST_OFFSET 0x1000 #define GIC_BASE_IRQ 0 #endif Loading Loading @@ -76,7 +74,6 @@ typedef struct gic_irq_state typedef struct gic_state { uint32_t base; qemu_irq parent_irq[NCPU]; int enabled; int cpu_enabled[NCPU]; Loading Loading @@ -252,7 +249,6 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) cpu = gic_get_current_cpu(); cm = 1 << cpu; offset -= s->base + GIC_DIST_OFFSET; if (offset < 0x100) { #ifndef NVIC if (offset == 0) Loading Loading @@ -365,7 +361,7 @@ static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset) #ifdef NVIC gic_state *s = (gic_state *)opaque; uint32_t addr; addr = offset - s->base; addr = offset; if (addr < 0x100 || addr > 0xd00) return nvic_readl(s->nvic, addr); #endif Loading @@ -383,7 +379,6 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, int cpu; cpu = gic_get_current_cpu(); offset -= s->base + GIC_DIST_OFFSET; if (offset < 0x100) { #ifdef NVIC goto bad_reg; Loading Loading @@ -526,13 +521,13 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset, gic_state *s = (gic_state *)opaque; #ifdef NVIC uint32_t addr; addr = offset - s->base; addr = offset; if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) { nvic_writel(s->nvic, addr, value); return; } #endif if (offset - s->base == GIC_DIST_OFFSET + 0xf00) { if (offset == 0xf00) { int cpu; int irq; int mask; Loading Loading @@ -723,7 +718,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) return 0; } static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq) static gic_state *gic_init(uint32_t dist_base, qemu_irq *parent_irq) { gic_state *s; int iomemtype; Loading @@ -738,9 +733,8 @@ static gic_state *gic_init(uint32_t base, qemu_irq *parent_irq) } iomemtype = cpu_register_io_memory(0, gic_dist_readfn, gic_dist_writefn, s); cpu_register_physical_memory(base + GIC_DIST_OFFSET, 0x00001000, cpu_register_physical_memory(dist_base, 0x00001000, iomemtype); s->base = base; gic_reset(s); register_savevm("arm_gic", -1, 1, gic_save, gic_load, s); return s; Loading
hw/arm_sysctl.c +0 −4 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ #define LOCK_VALUE 0xa05f typedef struct { uint32_t base; uint32_t sys_id; uint32_t leds; uint16_t lockval; Loading @@ -29,7 +28,6 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; offset -= s->base; switch (offset) { case 0x00: /* ID */ return s->sys_id; Loading Loading @@ -108,7 +106,6 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, uint32_t val) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; offset -= s->base; switch (offset) { case 0x08: /* LED */ Loading Loading @@ -199,7 +196,6 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id) s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state)); if (!s) return; s->base = base; s->sys_id = sys_id; /* The MPcore bootloader uses these flags to start secondary CPUs. We don't use a bootloader, so do this here. */ Loading
hw/arm_timer.c +0 −8 Original line number Diff line number Diff line Loading @@ -190,7 +190,6 @@ static void *arm_timer_init(uint32_t freq, qemu_irq irq) typedef struct { void *timer[2]; int level[2]; uint32_t base; qemu_irq irq; } sp804_state; Loading @@ -208,7 +207,6 @@ static uint32_t sp804_read(void *opaque, target_phys_addr_t offset) sp804_state *s = (sp804_state *)opaque; /* ??? Don't know the PrimeCell ID for this device. */ offset -= s->base; if (offset < 0x20) { return arm_timer_read(s->timer[0], offset); } else { Loading @@ -221,7 +219,6 @@ static void sp804_write(void *opaque, target_phys_addr_t offset, { sp804_state *s = (sp804_state *)opaque; offset -= s->base; if (offset < 0x20) { arm_timer_write(s->timer[0], offset, value); } else { Loading Loading @@ -268,7 +265,6 @@ void sp804_init(uint32_t base, qemu_irq irq) s = (sp804_state *)qemu_mallocz(sizeof(sp804_state)); qi = qemu_allocate_irqs(sp804_set_irq, s, 2); s->base = base; s->irq = irq; /* ??? The timers are actually configurable between 32kHz and 1MHz, but we don't implement that. */ Loading @@ -285,7 +281,6 @@ void sp804_init(uint32_t base, qemu_irq irq) typedef struct { void *timer[3]; uint32_t base; } icp_pit_state; static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) Loading @@ -294,7 +289,6 @@ static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) int n; /* ??? Don't know the PrimeCell ID for this device. */ offset -= s->base; n = offset >> 8; if (n > 3) cpu_abort(cpu_single_env, "sp804_read: Bad timer %d\n", n); Loading @@ -308,7 +302,6 @@ static void icp_pit_write(void *opaque, target_phys_addr_t offset, icp_pit_state *s = (icp_pit_state *)opaque; int n; offset -= s->base; n = offset >> 8; if (n > 3) cpu_abort(cpu_single_env, "sp804_write: Bad timer %d\n", n); Loading @@ -335,7 +328,6 @@ void icp_pit_init(uint32_t base, qemu_irq *pic, int irq) icp_pit_state *s; s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state)); s->base = base; /* Timer 0 runs at the system clock speed (40MHz). */ s->timer[0] = arm_timer_init(40000000, pic[irq]); /* The other two timers run at 1MHz. */ Loading