mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 21:33:40 +08:00
onenand: convert to memory API
Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
64066a8fb6
commit
689a1921ae
69
hw/onenand.c
69
hw/onenand.c
@ -23,6 +23,8 @@
|
||||
#include "flash.h"
|
||||
#include "irq.h"
|
||||
#include "blockdev.h"
|
||||
#include "memory.h"
|
||||
#include "exec-memory.h"
|
||||
|
||||
/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
|
||||
#define PAGE_SHIFT 11
|
||||
@ -45,10 +47,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;
|
||||
|
||||
@ -100,31 +104,36 @@ 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);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -524,7 +533,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;
|
||||
@ -589,7 +599,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;
|
||||
@ -628,7 +638,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;
|
||||
@ -684,16 +694,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(BlockDriverState *bdrv,
|
||||
@ -714,8 +718,8 @@ void *onenand_init(BlockDriverState *bdrv,
|
||||
s->secs = size >> 9;
|
||||
s->blockwp = g_malloc(s->blocks);
|
||||
s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 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);
|
||||
s->bdrv = bdrv;
|
||||
if (!s->bdrv) {
|
||||
s->image = memset(g_malloc(size + (size >> 5)),
|
||||
@ -723,14 +727,15 @@ void *onenand_init(BlockDriverState *bdrv,
|
||||
}
|
||||
s->otp = memset(g_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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user