Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> --- hw/onenand.c | 70 +++++++++++++++++++++++++++++++-------------------------- 1 files changed, 38 insertions(+), 32 deletions(-) diff --git a/hw/onenand.c b/hw/onenand.c index 71c1ab4..fe53090 100644 --- a/hw/onenand.c +++ b/hw/onenand.c @@ -23,6 +23,7 @@ #include "flash.h" #include "irq.h" #include "blockdev.h" +#include "memory.h" /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */ #define PAGE_SHIFT 11 @@ -41,10 +42,12 @@ typedef struct { uint8_t *image; uint8_t *otp; uint8_t *current; - ram_addr_t ram; + MemoryRegion ram; + MemoryRegion mapped_ram; uint8_t *boot[2]; uint8_t *data[2][2]; - int iomemtype; + MemoryRegion iomem; + MemoryRegion container; int cycle; int otpmode; @@ -96,31 +99,38 @@ enum { ONEN_LOCK_UNLOCKED = 1 << 2, }; +static void onenand_mem_setup(OneNANDState *s) +{ + /* XXX: We should use IO_MEM_ROMD but we broke it earlier... + * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to + * write boot commands. Also take note of the BWPS bit. */ + memory_region_init(&s->container, "onenand", 0x10000 << s->shift); + memory_region_add_subregion(&s->container, 0, &s->iomem); + memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram", + &s->ram, 0x0200 << s->shift, + 0xbe00 << s->shift); + memory_region_add_subregion_overlap(&s->container, + 0x0200 << s->shift, + &s->mapped_ram, + 1); +} + +#include "exec-memory.h" + void onenand_base_update(void *opaque, target_phys_addr_t new) { OneNANDState *s = (OneNANDState *) opaque; s->base = new; - /* XXX: We should use IO_MEM_ROMD but we broke it earlier... - * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to - * write boot commands. Also take note of the BWPS bit. */ - cpu_register_physical_memory(s->base + (0x0000 << s->shift), - 0x0200 << s->shift, s->iomemtype); - cpu_register_physical_memory(s->base + (0x0200 << s->shift), - 0xbe00 << s->shift, - (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM); - if (s->iomemtype) - cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift), - 0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift)); + memory_region_add_subregion(get_system_memory(), s->base, &s->container); } void onenand_base_unmap(void *opaque) { OneNANDState *s = (OneNANDState *) opaque; - cpu_register_physical_memory(s->base, - 0x10000 << s->shift, IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), &s->container); } static void onenand_intr_update(OneNANDState *s) @@ -443,7 +453,8 @@ static void onenand_command(OneNANDState *s, int cmd) onenand_intr_update(s); } -static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) +static uint64_t onenand_read(void *opaque, target_phys_addr_t addr, + unsigned size) { OneNANDState *s = (OneNANDState *) opaque; int offset = addr >> s->shift; @@ -508,7 +519,7 @@ static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) } static void onenand_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { OneNANDState *s = (OneNANDState *) opaque; int offset = addr >> s->shift; @@ -547,7 +558,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, break; default: - fprintf(stderr, "%s: unknown OneNAND boot command %x\n", + fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n", __FUNCTION__, value); } break; @@ -603,16 +614,10 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const onenand_readfn[] = { - onenand_read, /* TODO */ - onenand_read, - onenand_read, -}; - -static CPUWriteMemoryFunc * const onenand_writefn[] = { - onenand_write, /* TODO */ - onenand_write, - onenand_write, +static const MemoryRegionOps onenand_ops = { + .read = onenand_read, + .write = onenand_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; void *onenand_init(uint32_t id, int regshift, qemu_irq irq) @@ -630,8 +635,8 @@ void *onenand_init(uint32_t id, int regshift, qemu_irq irq) s->secs = size >> 9; s->blockwp = qemu_malloc(s->blocks); s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0; - s->iomemtype = cpu_register_io_memory(onenand_readfn, - onenand_writefn, s, DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand", + 0x10000 << s->shift); if (!dinfo) s->image = memset(qemu_malloc(size + (size >> 5)), 0xff, size + (size >> 5)); @@ -639,14 +644,15 @@ void *onenand_init(uint32_t id, int regshift, qemu_irq irq) s->bdrv = dinfo->bdrv; s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT), 0xff, (64 + 2) << PAGE_SHIFT); - s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift); - ram = qemu_get_ram_ptr(s->ram); + memory_region_init_ram(&s->ram, NULL, "onenand.ram", 0xc000 << s->shift); + ram = memory_region_get_ram_ptr(&s->ram); s->boot[0] = ram + (0x0000 << s->shift); s->boot[1] = ram + (0x8000 << s->shift); s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift); s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift); s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift); s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift); + onenand_mem_setup(s); onenand_reset(s, 1); -- 1.7.5.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html