Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2…
Browse files Browse the repository at this point in the history
…0160714' into staging

target-arm queue:
 * add virtio-mmio transport base address to device path
   (avoid an assertion failure with multiple virtio-scsi-devices)
 * revert hw/ptimer commit 5a50307 which causes regressions on
   SPARC guests
 * use Neon to accelerate zero-page checking on AArch64 hosts
 * set the MPIDR for TCG to match how KVM does it (and fit with
   GICv2/GICv3 restrictions on SGI target lists)
 * add some missing AArch32 TLBI hypervisor TLB operations
 * m25p80: Fix QIOR/DIOR handling for Winbond
 * hw/misc: fix typo in Aspeed SCU hw-strap2 property name
 * ast2400: pretend DMAs are done for U-boot
 * ast2400: some minor code cleanups

# gpg: Signature made Thu 14 Jul 2016 17:21:30 BST
# gpg:                using RSA key 0x3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20160714:
  ast2400: externalize revision numbers
  ast2400: pretend DMAs are done for U-boot
  ast2400: replace aspeed_smc_is_implemented()
  hw/misc: fix typo in Aspeed SCU hw-strap2 property name
  m25p80: Fix QIOR/DIOR handling for Winbond
  target-arm: Add missed AArch32 TLBI sytem registers
  hw/arm/virt: tcg: adjust MPIDR like KVM
  gic: provide defines for v2/v3 targetlist sizes
  target-arm: Use Neon for zero checking
  Revert "hw/ptimer: Perform counter wrap around if timer already expired"
  virtio-mmio: format transport base address in BusClass.get_dev_path

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jul 14, 2016
2 parents 1c8e93f + 79a9f32 commit 14c7d99
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 37 deletions.
2 changes: 0 additions & 2 deletions hw/arm/ast2400.c
Expand Up @@ -34,8 +34,6 @@
#define AST2400_FMC_FLASH_BASE 0x20000000
#define AST2400_SPI_FLASH_BASE 0x30000000

#define AST2400_A0_SILICON_REV 0x02000303

static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };

Expand Down
25 changes: 24 additions & 1 deletion hw/arm/virt.c
Expand Up @@ -52,7 +52,8 @@
#include "hw/arm/sysbus-fdt.h"
#include "hw/platform-bus.h"
#include "hw/arm/fdt.h"
#include "hw/intc/arm_gic_common.h"
#include "hw/intc/arm_gic.h"
#include "hw/intc/arm_gicv3_common.h"
#include "kvm_arm.h"
#include "hw/smbios/smbios.h"
#include "qapi/visitor.h"
Expand Down Expand Up @@ -82,6 +83,7 @@ typedef struct VirtBoardInfo {
typedef struct {
MachineClass parent;
VirtBoardInfo *daughterboard;
bool disallow_affinity_adjustment;
} VirtMachineClass;

typedef struct {
Expand Down Expand Up @@ -1165,6 +1167,7 @@ void virt_guest_info_machine_done(Notifier *notifier, void *data)
static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
qemu_irq pic[NUM_IRQS];
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *secure_sysmem = NULL;
Expand All @@ -1181,6 +1184,7 @@ static void machvirt_init(MachineState *machine)
CPUClass *cc;
Error *err = NULL;
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
uint8_t clustersz;

if (!cpu_model) {
cpu_model = "cortex-a15";
Expand Down Expand Up @@ -1226,8 +1230,10 @@ static void machvirt_init(MachineState *machine)
*/
if (gic_version == 3) {
virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000;
clustersz = GICV3_TARGETLIST_BITS;
} else {
virt_max_cpus = GIC_NCPU;
clustersz = GIC_TARGETLIST_BITS;
}

if (max_cpus > virt_max_cpus) {
Expand Down Expand Up @@ -1281,6 +1287,20 @@ static void machvirt_init(MachineState *machine)

for (n = 0; n < smp_cpus; n++) {
Object *cpuobj = object_new(typename);
if (!vmc->disallow_affinity_adjustment) {
/* Adjust MPIDR like 64-bit KVM hosts, which incorporate the
* GIC's target-list limitations. 32-bit KVM hosts currently
* always create clusters of 4 CPUs, but that is expected to
* change when they gain support for gicv3. When KVM is enabled
* it will override the changes we make here, therefore our
* purposes are to make TCG consistent (with 64-bit KVM hosts)
* and to improve SGI efficiency.
*/
uint8_t aff1 = n / clustersz;
uint8_t aff0 = n % clustersz;
object_property_set_int(cpuobj, (aff1 << ARM_AFF1_SHIFT) | aff0,
"mp-affinity", NULL);
}

if (!vms->secure) {
object_property_set_bool(cpuobj, false, "has_el3", NULL);
Expand Down Expand Up @@ -1507,7 +1527,10 @@ static void virt_2_6_instance_init(Object *obj)

static void virt_machine_2_6_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));

virt_machine_2_7_options(mc);
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
vmc->disallow_affinity_adjustment = true;
}
DEFINE_VIRT_MACHINE(2, 6)
6 changes: 4 additions & 2 deletions hw/block/m25p80.c
Expand Up @@ -149,6 +149,7 @@ typedef struct FlashPartInfo {
*/

#define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1
#define WINBOND_CONTINUOUS_READ_MODE_CMD_LEN 1

static const FlashPartInfo known_devices[] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
Expand Down Expand Up @@ -777,7 +778,7 @@ static void decode_dio_read_cmd(Flash *s)
/* Dummy cycles modeled with bytes writes instead of bits */
switch (get_man(s)) {
case MAN_WINBOND:
s->needed_bytes += 8;
s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
break;
case MAN_SPANSION:
s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
Expand Down Expand Up @@ -816,7 +817,8 @@ static void decode_qio_read_cmd(Flash *s)
/* Dummy cycles modeled with bytes writes instead of bits */
switch (get_man(s)) {
case MAN_WINBOND:
s->needed_bytes += 8;
s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
s->needed_bytes += 4;
break;
case MAN_SPANSION:
s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
Expand Down
9 changes: 2 additions & 7 deletions hw/core/ptimer.c
Expand Up @@ -93,7 +93,7 @@ uint64_t ptimer_get_count(ptimer_state *s)
bool oneshot = (s->enabled == 2);

/* Figure out the current counter value. */
if (s->period == 0 || (expired && (oneshot || use_icount))) {
if (expired) {
/* Prevent timer underflowing if it should already have
triggered. */
counter = 0;
Expand All @@ -120,7 +120,7 @@ uint64_t ptimer_get_count(ptimer_state *s)
backwards.
*/

rem = expired ? now - next : next - now;
rem = next - now;
div = period;

clz1 = clz64(rem);
Expand All @@ -140,11 +140,6 @@ uint64_t ptimer_get_count(ptimer_state *s)
div += 1;
}
counter = rem / div;

if (expired && counter != 0) {
/* Wrap around periodic counter. */
counter = s->limit - (counter - 1) % s->limit;
}
}
} else {
counter = s->delta;
Expand Down
6 changes: 2 additions & 4 deletions hw/misc/aspeed_scu.c
Expand Up @@ -88,8 +88,6 @@
#define PROT_KEY_UNLOCK 0x1688A8A8
#define SCU_IO_REGION_SIZE 0x20000

#define AST2400_A0_SILICON_REV 0x02000303U

static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
[SYS_RST_CTRL] = 0xFFCFFEDCU,
[CLK_SEL] = 0xF3F40000U,
Expand Down Expand Up @@ -212,7 +210,7 @@ static void aspeed_scu_reset(DeviceState *dev)

static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };

static bool is_supported_silicon_rev(uint32_t silicon_rev)
bool is_supported_silicon_rev(uint32_t silicon_rev)
{
int i;

Expand Down Expand Up @@ -255,7 +253,7 @@ static const VMStateDescription vmstate_aspeed_scu = {
static Property aspeed_scu_properties[] = {
DEFINE_PROP_UINT32("silicon-rev", AspeedSCUState, silicon_rev, 0),
DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0),
DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap1, 0),
DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap2, 0),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down
39 changes: 19 additions & 20 deletions hw/ssi/aspeed_smc.c
Expand Up @@ -273,6 +273,9 @@ static void aspeed_smc_reset(DeviceState *d)

memset(s->regs, 0, sizeof s->regs);

/* Pretend DMA is done (u-boot initialization) */
s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;

/* Unselect all slaves */
for (i = 0; i < s->num_cs; ++i) {
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
Expand All @@ -281,12 +284,6 @@ static void aspeed_smc_reset(DeviceState *d)
aspeed_smc_update_cs(s);
}

static bool aspeed_smc_is_implemented(AspeedSMCState *s, hwaddr addr)
{
return (addr == s->r_conf || addr == s->r_timings || addr == s->r_ce_ctrl ||
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs));
}

static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
{
AspeedSMCState *s = ASPEED_SMC(opaque);
Expand All @@ -300,13 +297,17 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
return 0;
}

if (!aspeed_smc_is_implemented(s, addr)) {
if (addr == s->r_conf ||
addr == s->r_timings ||
addr == s->r_ce_ctrl ||
addr == R_INTR_CTRL ||
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs)) {
return s->regs[addr];
} else {
qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
__func__, addr);
__func__, addr);
return 0;
}

return s->regs[addr];
}

static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
Expand All @@ -324,20 +325,18 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
return;
}

if (!aspeed_smc_is_implemented(s, addr)) {
if (addr == s->r_conf ||
addr == s->r_timings ||
addr == s->r_ce_ctrl) {
s->regs[addr] = value;
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
s->regs[addr] = value;
aspeed_smc_update_cs(s);
} else {
qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
__func__, addr);
return;
}

/*
* Not much to do apart from storing the value and set the cs
* lines if the register is a controlling one.
*/
s->regs[addr] = value;
if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
aspeed_smc_update_cs(s);
}
}

static const MemoryRegionOps aspeed_smc_ops = {
Expand Down
49 changes: 49 additions & 0 deletions hw/virtio/virtio-mmio.c
Expand Up @@ -91,6 +91,7 @@ typedef struct {
VirtioBusState bus;
bool ioeventfd_disabled;
bool ioeventfd_started;
bool format_transport_address;
} VirtIOMMIOProxy;

static bool virtio_mmio_ioeventfd_started(DeviceState *d)
Expand Down Expand Up @@ -469,6 +470,12 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,

/* virtio-mmio device */

static Property virtio_mmio_properties[] = {
DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy,
format_transport_address, true),
DEFINE_PROP_END_OF_LIST(),
};

static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
{
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
Expand All @@ -489,6 +496,7 @@ static void virtio_mmio_class_init(ObjectClass *klass, void *data)
dc->realize = virtio_mmio_realizefn;
dc->reset = virtio_mmio_reset;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->props = virtio_mmio_properties;
}

static const TypeInfo virtio_mmio_info = {
Expand All @@ -500,6 +508,46 @@ static const TypeInfo virtio_mmio_info = {

/* virtio-mmio-bus. */

static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
{
BusState *virtio_mmio_bus;
VirtIOMMIOProxy *virtio_mmio_proxy;
char *proxy_path;
SysBusDevice *proxy_sbd;
char *path;

virtio_mmio_bus = qdev_get_parent_bus(dev);
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
proxy_path = qdev_get_dev_path(DEVICE(virtio_mmio_proxy));

/*
* If @format_transport_address is false, then we just perform the same as
* virtio_bus_get_dev_path(): we delegate the address formatting for the
* device on the virtio-mmio bus to the bus that the virtio-mmio proxy
* (i.e., the device that implements the virtio-mmio bus) resides on. In
* this case the base address of the virtio-mmio transport will be
* invisible.
*/
if (!virtio_mmio_proxy->format_transport_address) {
return proxy_path;
}

/* Otherwise, we append the base address of the transport. */
proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
assert(proxy_sbd->num_mmio == 1);
assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);

if (proxy_path) {
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
proxy_sbd->mmio[0].addr);
} else {
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
proxy_sbd->mmio[0].addr);
}
g_free(proxy_path);
return path;
}

static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *bus_class = BUS_CLASS(klass);
Expand All @@ -516,6 +564,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
k->has_variable_vring_alignment = true;
bus_class->max_dev = 1;
bus_class->get_dev_path = virtio_mmio_bus_get_dev_path;
}

static const TypeInfo virtio_mmio_bus_info = {
Expand Down
6 changes: 5 additions & 1 deletion include/hw/compat.h
Expand Up @@ -2,7 +2,11 @@
#define HW_COMPAT_H

#define HW_COMPAT_2_6 \
/* empty */
{\
.driver = "virtio-mmio",\
.property = "format_transport_address",\
.value = "off",\
},

#define HW_COMPAT_2_5 \
{\
Expand Down
3 changes: 3 additions & 0 deletions include/hw/intc/arm_gic.h
Expand Up @@ -23,6 +23,9 @@

#include "arm_gic_common.h"

/* Number of SGI target-list bits */
#define GIC_TARGETLIST_BITS 8

#define TYPE_ARM_GIC "arm_gic"
#define ARM_GIC(obj) \
OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
Expand Down
3 changes: 3 additions & 0 deletions include/hw/intc/arm_gicv3_common.h
Expand Up @@ -35,6 +35,9 @@
#define GICV3_MAXIRQ 1020
#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)

/* Number of SGI target-list bits */
#define GICV3_TARGETLIST_BITS 16

/* Minimum BPR for Secure, or when security not enabled */
#define GIC_MIN_BPR 0
/* Minimum BPR for Nonsecure when security is enabled */
Expand Down
5 changes: 5 additions & 0 deletions include/hw/misc/aspeed_scu.h
Expand Up @@ -31,4 +31,9 @@ typedef struct AspeedSCUState {
uint32_t hw_strap2;
} AspeedSCUState;

#define AST2400_A0_SILICON_REV 0x02000303U
#define AST2500_A0_SILICON_REV 0x04000303U

extern bool is_supported_silicon_rev(uint32_t silicon_rev);

#endif /* ASPEED_SCU_H */

0 comments on commit 14c7d99

Please sign in to comment.