Refactored NAND/NAND ECC into separate files
This commit is contained in:
1 parent
df09005a18
commit
7475713599
7 files changed
+249
-147
No files matched your search
+9
-109
@@ -302,105 +302,6 @@ static const MemoryRegionOps sysic_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
/*
|
||||
NAND
|
||||
*/
|
||||
static int nand_read_cnt = 0;
|
||||
|
||||
static uint64_t s5l8900_nand_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
s5l8900_nand_s *s = (s5l8900_nand_s *) opaque;
|
||||
//fprintf(stderr, "%s: reading from 0x%08x\n", __func__, addr);
|
||||
|
||||
switch (addr) {
|
||||
case NAND_FMCTRL0:
|
||||
return s->fmctrl0;
|
||||
case NAND_FMFIFO:
|
||||
if(s->cmd == NAND_CMD_ID) {
|
||||
return 0xA514D3AD;
|
||||
}
|
||||
else if(s->cmd == NAND_CMD_READSTATUS) {
|
||||
return (1 << 6);
|
||||
}
|
||||
else {
|
||||
nand_read_cnt++;
|
||||
return 0x43303032;
|
||||
}
|
||||
|
||||
case NAND_FMCSTAT:
|
||||
return (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12); // this indicates that everything is ready, including our eight banks
|
||||
case NAND_RSCTRL:
|
||||
return s->rsctrl;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s5l8900_nand_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
s5l8900_nand_s *s = (s5l8900_nand_s *) opaque;
|
||||
|
||||
switch(addr) {
|
||||
case NAND_FMCTRL0:
|
||||
s->fmctrl0 = val;
|
||||
break;
|
||||
case NAND_CMD:
|
||||
s->cmd = val;
|
||||
break;
|
||||
case NAND_RSCTRL:
|
||||
s->rsctrl = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nand_ops = {
|
||||
.read = s5l8900_nand_read,
|
||||
.write = s5l8900_nand_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
/*
|
||||
NAND ECC
|
||||
*/
|
||||
static uint64_t s5l8900_nand_ecc_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
s5l8900_nand_ecc_s *s = (s5l8900_nand_ecc_s *) opaque;
|
||||
//fprintf(stderr, "%s: reading from 0x%08x\n", __func__, addr);
|
||||
|
||||
switch (addr) {
|
||||
case NANDECC_STATUS:
|
||||
return 0; // TODO: for now, we assume that all ECC operations are successful
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void s5l8900_nand_ecc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
s5l8900_nand_ecc_s *s = (s5l8900_nand_ecc_s *) opaque;
|
||||
|
||||
switch(addr) {
|
||||
case NANDECC_START:
|
||||
qemu_irq_raise(s->irq);
|
||||
break;
|
||||
case NANDECC_CLEARINT:
|
||||
qemu_irq_lower(s->irq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nand_ecc_ops = {
|
||||
.read = s5l8900_nand_ecc_read,
|
||||
.write = s5l8900_nand_ecc_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
/*
|
||||
USB PHYS
|
||||
*/
|
||||
@@ -928,19 +829,18 @@ static void ipod_touch_machine_init(MachineState *machine)
|
||||
memory_region_add_subregion(sysmem, ENGINE_8900_MEM_BASE, iomem);
|
||||
|
||||
// init NAND flash
|
||||
s5l8900_nand_s *nand_state = malloc(sizeof(s5l8900_nand_s));
|
||||
dev = qdev_new("itnand");
|
||||
ITNandState *nand_state = ITNAND(dev);
|
||||
nms->nand_state = nand_state;
|
||||
iomem = g_new(MemoryRegion, 1);
|
||||
memory_region_init_io(iomem, OBJECT(s), &nand_ops, s, "nand", 0x1000);
|
||||
memory_region_add_subregion(sysmem, NAND_MEM_BASE, iomem);
|
||||
memory_region_add_subregion(sysmem, NAND_MEM_BASE, &nand_state->iomem);
|
||||
|
||||
// init NAND ECC module
|
||||
s5l8900_nand_ecc_s *nand_ecc_state = malloc(sizeof(s5l8900_nand_ecc_s));
|
||||
dev = qdev_new("itnand_ecc");
|
||||
ITNandECCState *nand_ecc_state = ITNANDECC(dev);
|
||||
nms->nand_ecc_state = nand_ecc_state;
|
||||
nand_ecc_state->irq = s5l8900_get_irq(nms, S5L8900_NAND_ECC_IRQ);
|
||||
iomem = g_new(MemoryRegion, 1);
|
||||
memory_region_init_io(iomem, OBJECT(s), &nand_ecc_ops, nand_ecc_state, "nandecc", 0x100);
|
||||
memory_region_add_subregion(sysmem, NAND_ECC_MEM_BASE, iomem);
|
||||
SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_NAND_ECC_IRQ));
|
||||
memory_region_add_subregion(sysmem, NAND_ECC_MEM_BASE, &nand_ecc_state->iomem);
|
||||
|
||||
// init USB OTG
|
||||
dev = ipod_touch_init_usb_otg(nms->irq[0][13], s5l8900_usb_hwcfg);
|
||||
@@ -986,7 +886,7 @@ static void ipod_touch_machine_init(MachineState *machine)
|
||||
PL080State *pl080_1 = PL080(dev);
|
||||
object_property_set_link(OBJECT(dev), "downstream", OBJECT(sysmem), &error_fatal);
|
||||
memory_region_add_subregion(sysmem, DMAC0_MEM_BASE, &pl080_1->iomem);
|
||||
SysBusDevice *busdev = SYS_BUS_DEVICE(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize(busdev, &error_fatal);
|
||||
sysbus_connect_irq(busdev, 0, s5l8900_get_irq(nms, S5L8900_DMAC0_IRQ));
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "hw/arm/ipod_touch_nand.h"
|
||||
|
||||
static int nand_read_cnt = 0;
|
||||
|
||||
static uint64_t itnand_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
ITNandState *s = (ITNandState *) opaque;
|
||||
//fprintf(stderr, "%s: reading from 0x%08x\n", __func__, addr);
|
||||
|
||||
switch (addr) {
|
||||
case NAND_FMCTRL0:
|
||||
return s->fmctrl0;
|
||||
case NAND_FMFIFO:
|
||||
if(s->cmd == NAND_CMD_ID) {
|
||||
return 0xA514D3AD;
|
||||
}
|
||||
else if(s->cmd == NAND_CMD_READSTATUS) {
|
||||
return (1 << 6);
|
||||
}
|
||||
else {
|
||||
nand_read_cnt++;
|
||||
return 0x43303032;
|
||||
}
|
||||
|
||||
case NAND_FMCSTAT:
|
||||
return (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12); // this indicates that everything is ready, including our eight banks
|
||||
case NAND_RSCTRL:
|
||||
return s->rsctrl;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void itnand_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
ITNandState *s = (ITNandState *) opaque;
|
||||
|
||||
switch(addr) {
|
||||
case NAND_FMCTRL0:
|
||||
s->fmctrl0 = val;
|
||||
break;
|
||||
case NAND_CMD:
|
||||
s->cmd = val;
|
||||
break;
|
||||
case NAND_RSCTRL:
|
||||
s->rsctrl = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nand_ops = {
|
||||
.read = itnand_read,
|
||||
.write = itnand_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void itnand_init(Object *obj)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
ITNandState *s = ITNAND(obj);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &nand_ops, s, "nand", 0x1000);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
}
|
||||
|
||||
static void itnand_reset(DeviceState *d)
|
||||
{
|
||||
ITNandState *s = (ITNandState *) d;
|
||||
|
||||
s->fmctrl0 = 0;
|
||||
s->rsctrl = 0;
|
||||
s->cmd = 0;
|
||||
}
|
||||
|
||||
static void itnand_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
dc->reset = itnand_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo itnand_info = {
|
||||
.name = TYPE_ITNAND,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(ITNandState),
|
||||
.instance_init = itnand_init,
|
||||
.class_init = itnand_class_init,
|
||||
};
|
||||
|
||||
static void itnand_register_types(void)
|
||||
{
|
||||
type_register_static(&itnand_info);
|
||||
}
|
||||
|
||||
type_init(itnand_register_types)
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "hw/arm/ipod_touch_nand_ecc.h"
|
||||
|
||||
static uint64_t itnand_ecc_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
ITNandECCState *s = (ITNandECCState *) opaque;
|
||||
//fprintf(stderr, "%s: reading from 0x%08x\n", __func__, addr);
|
||||
|
||||
switch (addr) {
|
||||
case NANDECC_STATUS:
|
||||
return 0; // TODO: for now, we assume that all ECC operations are successful
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void itnand_ecc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
ITNandECCState *s = (ITNandECCState *) opaque;
|
||||
|
||||
switch(addr) {
|
||||
case NANDECC_START:
|
||||
qemu_irq_raise(s->irq);
|
||||
break;
|
||||
case NANDECC_CLEARINT:
|
||||
qemu_irq_lower(s->irq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nand_ecc_ops = {
|
||||
.read = itnand_ecc_read,
|
||||
.write = itnand_ecc_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void itnand_ecc_init(Object *obj)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
ITNandECCState *s = ITNANDECC(obj);
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &nand_ecc_ops, s, "nandecc", 0x100);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
}
|
||||
|
||||
static void itnand_ecc_reset(DeviceState *d)
|
||||
{
|
||||
ITNandECCState *s = (ITNandECCState *) d;
|
||||
|
||||
s->data_addr = 0;
|
||||
s->ecc_addr = 0;
|
||||
s->status = 0;
|
||||
s->setup = 0;
|
||||
}
|
||||
|
||||
static void itnand_ecc_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
dc->reset = itnand_ecc_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo itnand_ecc_info = {
|
||||
.name = TYPE_ITNANDECC,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(ITNandECCState),
|
||||
.instance_init = itnand_ecc_init,
|
||||
.class_init = itnand_ecc_class_init,
|
||||
};
|
||||
|
||||
static void itnand_ecc_register_types(void)
|
||||
{
|
||||
type_register_static(&itnand_ecc_info);
|
||||
}
|
||||
|
||||
type_init(itnand_ecc_register_types)
|
||||
+1
-1
@@ -58,6 +58,6 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.
|
||||
arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 'smmuv3.c'))
|
||||
arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
|
||||
arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
|
||||
arm_ss.add(when: 'CONFIG_IPOD_TOUCH', if_true: files('ipod_touch.c', 'xnu.c', 'xnu_mem.c', 'xnu_dtb.c', 'ipod_touch_spi.c', 'ipod_touch_aes.c', 'ipod_touch_sha1.c', 'ipod_touch_usb_otg.c', 'ipod_touch_8900_engine.c'))
|
||||
arm_ss.add(when: 'CONFIG_IPOD_TOUCH', if_true: files('ipod_touch.c', 'xnu.c', 'xnu_mem.c', 'xnu_dtb.c', 'ipod_touch_spi.c', 'ipod_touch_aes.c', 'ipod_touch_sha1.c', 'ipod_touch_usb_otg.c', 'ipod_touch_8900_engine.c', 'ipod_touch_nand.c', 'ipod_touch_nand_ecc.c'))
|
||||
|
||||
hw_arch += {'arm': arm_ss}
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "hw/arm/ipod_touch_sha1.h"
|
||||
#include "hw/arm/ipod_touch_8900_engine.h"
|
||||
#include "hw/arm/ipod_touch_usb_otg.h"
|
||||
#include "hw/arm/ipod_touch_nand.h"
|
||||
#include "hw/arm/ipod_touch_nand_ecc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define TYPE_IPOD_TOUCH "iPod-Touch"
|
||||
@@ -66,24 +68,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(s5l8900_lcd_state, IPOD_TOUCH_LCD)
|
||||
|
||||
#define S5L8900_NAND_ECC_IRQ 0x2B
|
||||
|
||||
// NAND
|
||||
#define NAND_FMCTRL0 0x0
|
||||
#define NAND_CMD 0x8
|
||||
#define NAND_FMCSTAT 0x48
|
||||
#define NAND_FMFIFO 0x80
|
||||
#define NAND_RSCTRL 0x100
|
||||
|
||||
#define NAND_CMD_ID 0x90
|
||||
#define NAND_CMD_READSTATUS 0x70
|
||||
|
||||
// NAND ECC
|
||||
#define NANDECC_DATA 0x4
|
||||
#define NANDECC_ECC 0x8
|
||||
#define NANDECC_START 0xC
|
||||
#define NANDECC_STATUS 0x10
|
||||
#define NANDECC_SETUP 0x14
|
||||
#define NANDECC_CLEARINT 0x40
|
||||
|
||||
typedef struct {
|
||||
MachineClass parent;
|
||||
} IPodTouchMachineClass;
|
||||
@@ -131,22 +115,6 @@ typedef struct s5l8900_timer_s
|
||||
|
||||
} s5l8900_timer_s;
|
||||
|
||||
typedef struct s5l8900_nand_s
|
||||
{
|
||||
uint32_t fmctrl0;
|
||||
uint32_t rsctrl;
|
||||
uint32_t cmd;
|
||||
} s5l8900_nand_s;
|
||||
|
||||
typedef struct s5l8900_nand_ecc_s
|
||||
{
|
||||
uint32_t data_addr;
|
||||
uint32_t ecc_addr;
|
||||
uint32_t status;
|
||||
uint32_t setup;
|
||||
qemu_irq irq;
|
||||
} s5l8900_nand_ecc_s;
|
||||
|
||||
typedef struct s5l8900_sysic_s
|
||||
{
|
||||
uint32_t power_state;
|
||||
@@ -178,8 +146,8 @@ typedef struct {
|
||||
s5l8900_usb_phys_s *usb_phys;
|
||||
S5L8900AESState *aes_state;
|
||||
S5L8900SHA1State *sha1_state;
|
||||
s5l8900_nand_s *nand_state;
|
||||
s5l8900_nand_ecc_s *nand_ecc_state;
|
||||
ITNandState *nand_state;
|
||||
ITNandECCState *nand_ecc_state;
|
||||
Clock *sysclk;
|
||||
uint32_t kpc_pa;
|
||||
uint32_t kbootargs_pa;
|
||||
@@ -188,7 +156,6 @@ typedef struct {
|
||||
char kernel_filename[1024];
|
||||
char dtb_filename[1024];
|
||||
char kern_args[256];
|
||||
uint64_t printf_buffer[256];
|
||||
} IPodTouchMachineState;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef HW_ARM_IPOD_TOUCH_NAND_H
|
||||
#define HW_ARM_IPOD_TOUCH_NAND_H
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#define NAND_FMCTRL0 0x0
|
||||
#define NAND_CMD 0x8
|
||||
#define NAND_FMCSTAT 0x48
|
||||
#define NAND_FMFIFO 0x80
|
||||
#define NAND_RSCTRL 0x100
|
||||
|
||||
#define NAND_CMD_ID 0x90
|
||||
#define NAND_CMD_READSTATUS 0x70
|
||||
|
||||
#define TYPE_ITNAND "itnand"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(ITNandState, ITNAND)
|
||||
|
||||
typedef struct ITNandState {
|
||||
SysBusDevice busdev;
|
||||
MemoryRegion iomem;
|
||||
uint32_t fmctrl0;
|
||||
uint32_t rsctrl;
|
||||
uint32_t cmd;
|
||||
qemu_irq irq;
|
||||
} ITNandState;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef HW_ARM_IPOD_TOUCH_NAND_ECC_H
|
||||
#define HW_ARM_IPOD_TOUCH_NAND_ECC_H
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/irq.h"
|
||||
|
||||
#define NANDECC_DATA 0x4
|
||||
#define NANDECC_ECC 0x8
|
||||
#define NANDECC_START 0xC
|
||||
#define NANDECC_STATUS 0x10
|
||||
#define NANDECC_SETUP 0x14
|
||||
#define NANDECC_CLEARINT 0x40
|
||||
|
||||
#define TYPE_ITNANDECC "itnand_ecc"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(ITNandECCState, ITNANDECC)
|
||||
|
||||
typedef struct ITNandECCState {
|
||||
SysBusDevice busdev;
|
||||
MemoryRegion iomem;
|
||||
uint32_t data_addr;
|
||||
uint32_t ecc_addr;
|
||||
uint32_t status;
|
||||
uint32_t setup;
|
||||
qemu_irq irq;
|
||||
} ITNandECCState;
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user