diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-04-23 11:49:59 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-04-23 11:49:59 -0500 |
commit | 5469963394eba2df7c0a093a3792dc82e060cd65 (patch) | |
tree | 2c0dfdf11e86232d49d59b1a4bc0f06ce7c14a22 /hw | |
parent | 53878a132aaadbedbe8fe0e44afa032a4ed73aea (diff) | |
parent | 3c30dd5a68e9fee6af67cfd0d14ed7520820f36a (diff) |
Merge remote-tracking branch 'origin/master' into staging
* origin/master: (27 commits)
target-arm: Move reset handling to arm_cpu_reset
target-arm: Drop cpu_reset_model_id()
target-arm: Move cache ID register setup to cpu specific init fns
target-arm: Move OMAP cp15_i_{max,min} reset to cpu_state_reset
target-arm: Move feature register setup to per-CPU init fns
target-arm: Move iWMMXT wCID reset to cpu_state_reset
target-arm: Drop JTAG_ID documentation
target-arm: Move SCTLR reset value setup to per cpu init fns
target-arm: Move CTR setup to per cpu init fns
target-arm: Move MVFR* setup to per cpu init fns
target-arm: Move FPSID config to cpu init fns
target-arm: Move feature bit settings to CPU init fns
target-arm: Add QOM subclasses for each ARM cpu implementation
target-arm: remind to keep arm features in sync with linux-user/elfload.c
tci: GETPC() macro must return an uintptr_t
gdbstub: Synchronize CPU state unconditionally in gdb_set_cpu_pc
softfloat: make USE_SOFTFLOAT_STRUCT_TYPES compile
target-xtensa: add tests for LOOPNEZ and LOOPGTZ
target-xtensa: fix LOOPNEZ/LOOPGTZ translation
qtest: add m48t59 tests for Sparc
...
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm_mptimer.c | 3 | ||||
-rw-r--r-- | hw/realview.c | 83 | ||||
-rw-r--r-- | hw/versatile_i2c.c | 105 | ||||
-rw-r--r-- | hw/versatilepb.c | 22 |
4 files changed, 132 insertions, 81 deletions
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c index df7fb4c9bd..fe43cbb5f1 100644 --- a/hw/arm_mptimer.c +++ b/hw/arm_mptimer.c @@ -228,6 +228,9 @@ static void timerblock_reset(timerblock *tb) tb->control = 0; tb->status = 0; tb->tick = 0; + if (tb->timer) { + qemu_del_timer(tb->timer); + } } static void arm_mptimer_reset(DeviceState *dev) diff --git a/hw/realview.c b/hw/realview.c index cf55204c96..ecf470179a 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -15,91 +15,13 @@ #include "net.h" #include "sysemu.h" #include "boards.h" -#include "bitbang_i2c.h" +#include "i2c.h" #include "blockdev.h" #include "exec-memory.h" #define SMP_BOOT_ADDR 0xe0000000 #define SMP_BOOTREG_ADDR 0x10000030 -typedef struct { - SysBusDevice busdev; - MemoryRegion iomem; - bitbang_i2c_interface *bitbang; - int out; - int in; -} RealViewI2CState; - -static uint64_t realview_i2c_read(void *opaque, target_phys_addr_t offset, - unsigned size) -{ - RealViewI2CState *s = (RealViewI2CState *)opaque; - - if (offset == 0) { - return (s->out & 1) | (s->in << 1); - } else { - hw_error("realview_i2c_read: Bad offset 0x%x\n", (int)offset); - return -1; - } -} - -static void realview_i2c_write(void *opaque, target_phys_addr_t offset, - uint64_t value, unsigned size) -{ - RealViewI2CState *s = (RealViewI2CState *)opaque; - - switch (offset) { - case 0: - s->out |= value & 3; - break; - case 4: - s->out &= ~value; - break; - default: - hw_error("realview_i2c_write: Bad offset 0x%x\n", (int)offset); - } - bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); - s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); -} - -static const MemoryRegionOps realview_i2c_ops = { - .read = realview_i2c_read, - .write = realview_i2c_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int realview_i2c_init(SysBusDevice *dev) -{ - RealViewI2CState *s = FROM_SYSBUS(RealViewI2CState, dev); - i2c_bus *bus; - - bus = i2c_init_bus(&dev->qdev, "i2c"); - s->bitbang = bitbang_i2c_init(bus); - memory_region_init_io(&s->iomem, &realview_i2c_ops, s, - "realview-i2c", 0x1000); - sysbus_init_mmio(dev, &s->iomem); - return 0; -} - -static void realview_i2c_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = realview_i2c_init; -} - -static TypeInfo realview_i2c_info = { - .name = "realview_i2c", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(RealViewI2CState), - .class_init = realview_i2c_class_init, -}; - -static void realview_register_types(void) -{ - type_register_static(&realview_i2c_info); -} - /* Board init. */ static struct arm_boot_info realview_binfo = { @@ -328,7 +250,7 @@ static void realview_init(ram_addr_t ram_size, } } - dev = sysbus_create_simple("realview_i2c", 0x10002000, NULL); + dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); @@ -492,4 +414,3 @@ static void realview_machine_init(void) } machine_init(realview_machine_init); -type_init(realview_register_types) diff --git a/hw/versatile_i2c.c b/hw/versatile_i2c.c new file mode 100644 index 0000000000..88f530aefc --- /dev/null +++ b/hw/versatile_i2c.c @@ -0,0 +1,105 @@ +/* + * ARM Versatile I2C controller + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com> + * + * This file is derived from hw/realview.c by Paul Brook + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "sysbus.h" +#include "bitbang_i2c.h" + +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + bitbang_i2c_interface *bitbang; + int out; + int in; +} VersatileI2CState; + +static uint64_t versatile_i2c_read(void *opaque, target_phys_addr_t offset, + unsigned size) +{ + VersatileI2CState *s = (VersatileI2CState *)opaque; + + if (offset == 0) { + return (s->out & 1) | (s->in << 1); + } else { + hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + return -1; + } +} + +static void versatile_i2c_write(void *opaque, target_phys_addr_t offset, + uint64_t value, unsigned size) +{ + VersatileI2CState *s = (VersatileI2CState *)opaque; + + switch (offset) { + case 0: + s->out |= value & 3; + break; + case 4: + s->out &= ~value; + break; + default: + hw_error("%s: Bad offset 0x%x\n", __func__, (int)offset); + } + bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0); + s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); +} + +static const MemoryRegionOps versatile_i2c_ops = { + .read = versatile_i2c_read, + .write = versatile_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int versatile_i2c_init(SysBusDevice *dev) +{ + VersatileI2CState *s = FROM_SYSBUS(VersatileI2CState, dev); + i2c_bus *bus; + + bus = i2c_init_bus(&dev->qdev, "i2c"); + s->bitbang = bitbang_i2c_init(bus); + memory_region_init_io(&s->iomem, &versatile_i2c_ops, s, + "versatile_i2c", 0x1000); + sysbus_init_mmio(dev, &s->iomem); + return 0; +} + +static void versatile_i2c_class_init(ObjectClass *klass, void *data) +{ + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = versatile_i2c_init; +} + +static const TypeInfo versatile_i2c_info = { + .name = "versatile_i2c", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(VersatileI2CState), + .class_init = versatile_i2c_class_init, +}; + +static void versatile_i2c_register_types(void) +{ + type_register_static(&versatile_i2c_info); +} + +type_init(versatile_i2c_register_types) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 25afb1eb31..7c79c54d08 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -13,9 +13,15 @@ #include "net.h" #include "sysemu.h" #include "pci.h" +#include "i2c.h" #include "boards.h" #include "blockdev.h" #include "exec-memory.h" +#include "flash.h" + +#define VERSATILE_FLASH_ADDR 0x34000000 +#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024) +#define VERSATILE_FLASH_SECT_SIZE (256 * 1024) /* Primary interrupt controller. */ @@ -178,8 +184,10 @@ static void versatile_init(ram_addr_t ram_size, DeviceState *pl041; PCIBus *pci_bus; NICInfo *nd; + i2c_bus *i2c; int n; int done_smc = 0; + DriveInfo *dinfo; if (!cpu_model) cpu_model = "arm926"; @@ -268,6 +276,10 @@ static void versatile_init(ram_addr_t ram_size, /* Add PL031 Real Time Clock. */ sysbus_create_simple("pl031", 0x101e8000, pic[10]); + dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); + i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); + i2c_create_slave(i2c, "ds1338", 0x68); + /* Add PL041 AACI Interface to the LM4549 codec */ pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); @@ -310,6 +322,16 @@ static void versatile_init(ram_addr_t ram_size, /* 0x101f2000 UART1. */ /* 0x101f3000 UART2. */ /* 0x101f4000 SSPI. */ + /* 0x34000000 NOR Flash */ + + dinfo = drive_get(IF_PFLASH, 0, 0); + if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash", + VERSATILE_FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, + VERSATILE_FLASH_SECT_SIZE, + VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE, + 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) { + fprintf(stderr, "qemu: Error registering flash memory.\n"); + } versatile_binfo.ram_size = ram_size; versatile_binfo.kernel_filename = kernel_filename; |