提交 3e508732 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'pmaydell/arm-devs.for-upstream' into staging

# By Peter Crosthwaite (3) and others
# Via Peter Maydell
* pmaydell/arm-devs.for-upstream:
  nand: Don't inherit from Sysbus
  block/nand: Convert Sysbus::init to Device::realize
  block/nand: QOM casting sweep
  i.MX31: Fix PRCS bit test
  arm/boot: Free dtb blob memory after use
  i.MX: Rework functions/types name and use new style initialization
  i.MX: Implement a more complete version of the GPT timer.
  ARM: Allow dumping of device tree

Message-id: 1372184516-32397-1-git-send-email-peter.maydell@linaro.org
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
...@@ -237,14 +237,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -237,14 +237,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
if (!filename) { if (!filename) {
fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename); fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
return -1; goto fail;
} }
fdt = load_device_tree(filename, &size); fdt = load_device_tree(filename, &size);
if (!fdt) { if (!fdt) {
fprintf(stderr, "Couldn't open dtb file %s\n", filename); fprintf(stderr, "Couldn't open dtb file %s\n", filename);
g_free(filename); g_free(filename);
return -1; goto fail;
} }
g_free(filename); g_free(filename);
...@@ -252,7 +252,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -252,7 +252,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells"); scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
if (acells == 0 || scells == 0) { if (acells == 0 || scells == 0) {
fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n"); fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
return -1; goto fail;
} }
mem_reg_propsize = acells + scells; mem_reg_propsize = acells + scells;
...@@ -264,7 +264,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -264,7 +264,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
} else if (hival != 0) { } else if (hival != 0) {
fprintf(stderr, "qemu: dtb file not compatible with " fprintf(stderr, "qemu: dtb file not compatible with "
"RAM start address > 4GB\n"); "RAM start address > 4GB\n");
exit(1); goto fail;
} }
mem_reg_property[acells + scells - 1] = cpu_to_be32(binfo->ram_size); mem_reg_property[acells + scells - 1] = cpu_to_be32(binfo->ram_size);
hival = cpu_to_be32(binfo->ram_size >> 32); hival = cpu_to_be32(binfo->ram_size >> 32);
...@@ -273,13 +273,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -273,13 +273,14 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
} else if (hival != 0) { } else if (hival != 0) {
fprintf(stderr, "qemu: dtb file not compatible with " fprintf(stderr, "qemu: dtb file not compatible with "
"RAM size > 4GB\n"); "RAM size > 4GB\n");
exit(1); goto fail;
} }
rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property, rc = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
mem_reg_propsize * sizeof(uint32_t)); mem_reg_propsize * sizeof(uint32_t));
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "couldn't set /memory/reg\n"); fprintf(stderr, "couldn't set /memory/reg\n");
goto fail;
} }
if (binfo->kernel_cmdline && *binfo->kernel_cmdline) { if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
...@@ -287,6 +288,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -287,6 +288,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
binfo->kernel_cmdline); binfo->kernel_cmdline);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/bootargs\n"); fprintf(stderr, "couldn't set /chosen/bootargs\n");
goto fail;
} }
} }
...@@ -295,18 +297,27 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) ...@@ -295,18 +297,27 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
binfo->initrd_start); binfo->initrd_start);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
goto fail;
} }
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
binfo->initrd_start + binfo->initrd_size); binfo->initrd_start + binfo->initrd_size);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
goto fail;
} }
} }
qemu_devtree_dumpdtb(fdt, size);
cpu_physical_memory_write(addr, fdt, size); cpu_physical_memory_write(addr, fdt, size);
g_free(fdt);
return 0; return 0;
fail:
g_free(fdt);
return -1;
} }
static void do_cpu_reset(void *opaque) static void do_cpu_reset(void *opaque)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
# include "hw/hw.h" # include "hw/hw.h"
# include "hw/block/flash.h" # include "hw/block/flash.h"
# include "sysemu/blockdev.h" # include "sysemu/blockdev.h"
# include "hw/sysbus.h" #include "hw/qdev.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
# define NAND_CMD_READ0 0x00 # define NAND_CMD_READ0 0x00
...@@ -54,7 +54,8 @@ ...@@ -54,7 +54,8 @@
typedef struct NANDFlashState NANDFlashState; typedef struct NANDFlashState NANDFlashState;
struct NANDFlashState { struct NANDFlashState {
SysBusDevice busdev; DeviceState parent_obj;
uint8_t manf_id, chip_id; uint8_t manf_id, chip_id;
uint8_t buswidth; /* in BYTES */ uint8_t buswidth; /* in BYTES */
int size, pages; int size, pages;
...@@ -82,6 +83,11 @@ struct NANDFlashState { ...@@ -82,6 +83,11 @@ struct NANDFlashState {
uint32_t ioaddr_vmstate; uint32_t ioaddr_vmstate;
}; };
#define TYPE_NAND "nand"
#define NAND(obj) \
OBJECT_CHECK(NANDFlashState, (obj), TYPE_NAND)
static void mem_and(uint8_t *dest, const uint8_t *src, size_t n) static void mem_and(uint8_t *dest, const uint8_t *src, size_t n)
{ {
/* Like memcpy() but we logical-AND the data into the destination */ /* Like memcpy() but we logical-AND the data into the destination */
...@@ -224,7 +230,7 @@ static const struct { ...@@ -224,7 +230,7 @@ static const struct {
static void nand_reset(DeviceState *dev) static void nand_reset(DeviceState *dev)
{ {
NANDFlashState *s = FROM_SYSBUS(NANDFlashState, SYS_BUS_DEVICE(dev)); NANDFlashState *s = NAND(dev);
s->cmd = NAND_CMD_READ0; s->cmd = NAND_CMD_READ0;
s->addr = 0; s->addr = 0;
s->addrlen = 0; s->addrlen = 0;
...@@ -279,7 +285,7 @@ static void nand_command(NANDFlashState *s) ...@@ -279,7 +285,7 @@ static void nand_command(NANDFlashState *s)
break; break;
case NAND_CMD_RESET: case NAND_CMD_RESET:
nand_reset(&s->busdev.qdev); nand_reset(DEVICE(s));
break; break;
case NAND_CMD_PAGEPROGRAM1: case NAND_CMD_PAGEPROGRAM1:
...@@ -319,14 +325,14 @@ static void nand_command(NANDFlashState *s) ...@@ -319,14 +325,14 @@ static void nand_command(NANDFlashState *s)
static void nand_pre_save(void *opaque) static void nand_pre_save(void *opaque)
{ {
NANDFlashState *s = opaque; NANDFlashState *s = NAND(opaque);
s->ioaddr_vmstate = s->ioaddr - s->io; s->ioaddr_vmstate = s->ioaddr - s->io;
} }
static int nand_post_load(void *opaque, int version_id) static int nand_post_load(void *opaque, int version_id)
{ {
NANDFlashState *s = opaque; NANDFlashState *s = NAND(opaque);
if (s->ioaddr_vmstate > sizeof(s->io)) { if (s->ioaddr_vmstate > sizeof(s->io)) {
return -EINVAL; return -EINVAL;
...@@ -362,10 +368,10 @@ static const VMStateDescription vmstate_nand = { ...@@ -362,10 +368,10 @@ static const VMStateDescription vmstate_nand = {
} }
}; };
static int nand_device_init(SysBusDevice *dev) static void nand_realize(DeviceState *dev, Error **errp)
{ {
int pagesize; int pagesize;
NANDFlashState *s = FROM_SYSBUS(NANDFlashState, dev); NANDFlashState *s = NAND(dev);
s->buswidth = nand_flash_ids[s->chip_id].width >> 3; s->buswidth = nand_flash_ids[s->chip_id].width >> 3;
s->size = nand_flash_ids[s->chip_id].size << 20; s->size = nand_flash_ids[s->chip_id].size << 20;
...@@ -388,16 +394,17 @@ static int nand_device_init(SysBusDevice *dev) ...@@ -388,16 +394,17 @@ static int nand_device_init(SysBusDevice *dev)
nand_init_2048(s); nand_init_2048(s);
break; break;
default: default:
error_report("Unsupported NAND block size"); error_setg(errp, "Unsupported NAND block size %#x\n",
return -1; 1 << s->page_shift);
return;
} }
pagesize = 1 << s->oob_shift; pagesize = 1 << s->oob_shift;
s->mem_oob = 1; s->mem_oob = 1;
if (s->bdrv) { if (s->bdrv) {
if (bdrv_is_read_only(s->bdrv)) { if (bdrv_is_read_only(s->bdrv)) {
error_report("Can't use a read-only drive"); error_setg(errp, "Can't use a read-only drive");
return -1; return;
} }
if (bdrv_getlength(s->bdrv) >= if (bdrv_getlength(s->bdrv) >=
(s->pages << s->page_shift) + (s->pages << s->oob_shift)) { (s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
...@@ -413,8 +420,6 @@ static int nand_device_init(SysBusDevice *dev) ...@@ -413,8 +420,6 @@ static int nand_device_init(SysBusDevice *dev)
} }
/* Give s->ioaddr a sane value in case we save state before it is used. */ /* Give s->ioaddr a sane value in case we save state before it is used. */
s->ioaddr = s->io; s->ioaddr = s->io;
return 0;
} }
static Property nand_properties[] = { static Property nand_properties[] = {
...@@ -427,17 +432,16 @@ static Property nand_properties[] = { ...@@ -427,17 +432,16 @@ static Property nand_properties[] = {
static void nand_class_init(ObjectClass *klass, void *data) static void nand_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = nand_device_init; dc->realize = nand_realize;
dc->reset = nand_reset; dc->reset = nand_reset;
dc->vmsd = &vmstate_nand; dc->vmsd = &vmstate_nand;
dc->props = nand_properties; dc->props = nand_properties;
} }
static const TypeInfo nand_info = { static const TypeInfo nand_info = {
.name = "nand", .name = TYPE_NAND,
.parent = TYPE_SYS_BUS_DEVICE, .parent = TYPE_DEVICE,
.instance_size = sizeof(NANDFlashState), .instance_size = sizeof(NANDFlashState),
.class_init = nand_class_init, .class_init = nand_class_init,
}; };
...@@ -456,7 +460,8 @@ static void nand_register_types(void) ...@@ -456,7 +460,8 @@ static void nand_register_types(void)
void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
uint8_t ce, uint8_t wp, uint8_t gnd) uint8_t ce, uint8_t wp, uint8_t gnd)
{ {
NANDFlashState *s = (NANDFlashState *) dev; NANDFlashState *s = NAND(dev);
s->cle = cle; s->cle = cle;
s->ale = ale; s->ale = ale;
s->ce = ce; s->ce = ce;
...@@ -477,7 +482,8 @@ void nand_getpins(DeviceState *dev, int *rb) ...@@ -477,7 +482,8 @@ void nand_getpins(DeviceState *dev, int *rb)
void nand_setio(DeviceState *dev, uint32_t value) void nand_setio(DeviceState *dev, uint32_t value)
{ {
int i; int i;
NANDFlashState *s = (NANDFlashState *) dev; NANDFlashState *s = NAND(dev);
if (!s->ce && s->cle) { if (!s->ce && s->cle) {
if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2) if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2)
...@@ -581,7 +587,7 @@ uint32_t nand_getio(DeviceState *dev) ...@@ -581,7 +587,7 @@ uint32_t nand_getio(DeviceState *dev)
{ {
int offset; int offset;
uint32_t x = 0; uint32_t x = 0;
NANDFlashState *s = (NANDFlashState *) dev; NANDFlashState *s = NAND(dev);
/* Allow sequential reading */ /* Allow sequential reading */
if (!s->iolen && s->cmd == NAND_CMD_READ0) { if (!s->iolen && s->cmd == NAND_CMD_READ0) {
......
...@@ -153,7 +153,7 @@ static void update_clocks(IMXCCMState *s) ...@@ -153,7 +153,7 @@ static void update_clocks(IMXCCMState *s)
* approach * approach
*/ */
if ((s->ccmr & CCMR_PRCS) == 1) { if ((s->ccmr & CCMR_PRCS) == 2) {
s->pll_refclk_freq = CKIL_FREQ * 1024; s->pll_refclk_freq = CKIL_FREQ * 1024;
} else { } else {
s->pll_refclk_freq = CKIH_FREQ; s->pll_refclk_freq = CKIH_FREQ;
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册