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
…0180820' into staging

target-arm queue:
 * Fix crash on conditional instruction in an IT block
 * docs/generic-loader: mention U-Boot and Intel HEX executable formats
 * hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
 * imx_serial: Generate interrupt on receive data ready if enabled
 * Fix various minor bugs in AArch32 Hyp related coprocessor registers
 * Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
 * Implement AArch32 ERET instruction
 * hw/arm/virt: Add virt-3.1 machine type
 * sdhci: add i.MX SD Stable Clock bit
 * Remove now-obsolete MMIO request_ptr APIs
 * hw/timer/m48t59: Move away from old_mmio accessors
 * hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
 * nvic: Expose NMI line
 * hw/dma/pl080: cleanups and new features required for use in MPS boards

# gpg: Signature made Mon 20 Aug 2018 11:30:12 BST
# gpg:                using RSA key 3C2525ED14360CDE
# 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-20180820: (25 commits)
  hw/dma/pl080: Remove hw_error() if DMA is enabled
  hw/dma/pl080: Correct bug in register address decode logic
  hw/dma/pl080: Provide device reset function
  hw/dma/pl080: Don't use CPU address space for DMA accesses
  hw/dma/pl080: Support all three interrupt lines
  hw/dma/pl080: Allow use as embedded-struct device
  nvic: Expose NMI line
  hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
  hw/timer/m48t59: Move away from old_mmio accessors
  hw/misc: Remove mmio_interface device
  memory: Remove MMIO request_ptr APIs
  hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code
  sdhci: add i.MX SD Stable Clock bit
  hw/arm/virt: Add virt-3.1 machine type
  target/arm: Implement AArch32 ERET instruction
  target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
  target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2
  target/arm: Implement AArch32 Hyp FARs
  target/arm: Implement AArch32 HVBAR
  target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Aug 20, 2018
2 parents 627fce6 + b85fad1 commit 62c3484
Show file tree
Hide file tree
Showing 31 changed files with 716 additions and 529 deletions.
3 changes: 3 additions & 0 deletions MAINTAINERS
Expand Up @@ -445,6 +445,7 @@ F: hw/char/pl011.c
F: include/hw/char/pl011.h
F: hw/display/pl110*
F: hw/dma/pl080.c
F: include/hw/dma/pl080.h
F: hw/dma/pl330.c
F: hw/gpio/pl061.c
F: hw/input/pl050.c
Expand All @@ -456,6 +457,8 @@ F: hw/timer/cmsdk-apb-timer.c
F: include/hw/timer/cmsdk-apb-timer.h
F: hw/char/cmsdk-apb-uart.c
F: include/hw/char/cmsdk-apb-uart.h
F: hw/watchdog/cmsdk-apb-watchdog.c
F: include/hw/watchdog/cmsdk-apb-watchdog.h
F: hw/misc/tz-ppc.c
F: include/hw/misc/tz-ppc.h
F: hw/misc/tz-mpc.c
Expand Down
1 change: 1 addition & 0 deletions Makefile.objs
Expand Up @@ -240,6 +240,7 @@ trace-events-subdirs += hw/tpm
trace-events-subdirs += hw/usb
trace-events-subdirs += hw/vfio
trace-events-subdirs += hw/virtio
trace-events-subdirs += hw/watchdog
trace-events-subdirs += hw/xen
trace-events-subdirs += io
trace-events-subdirs += linux-user
Expand Down
1 change: 1 addition & 0 deletions default-configs/arm-softmmu.mak
Expand Up @@ -104,6 +104,7 @@ CONFIG_STM32F205_SOC=y

CONFIG_CMSDK_APB_TIMER=y
CONFIG_CMSDK_APB_UART=y
CONFIG_CMSDK_APB_WATCHDOG=y

CONFIG_MPS2_FPGAIO=y
CONFIG_MPS2_SCC=y
Expand Down
20 changes: 10 additions & 10 deletions docs/generic-loader.txt
Expand Up @@ -56,25 +56,25 @@ An example of setting CPU 0's PC to 0x8000 is:

Loading Files
-------------
The loader device also allows files to be loaded into memory. It can load raw
files and ELF executable files. Raw files are loaded verbatim. ELF executable
files are loaded by an ELF loader. The syntax is shown below:
The loader device also allows files to be loaded into memory. It can load ELF,
U-Boot, and Intel HEX executable formats as well as raw images. The syntax is
shown below:

-device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]

<file> - A file to be loaded into memory
<addr> - The addr in memory that the file should be loaded. This is
ignored if you are using an ELF (unless force-raw is true).
This is required if you aren't loading an ELF.
<addr> - The memory address where the file should be loaded. This is
required for raw images and ignored for non-raw files.
<cpu-num> - This specifies the CPU that should be used. This is an
optional argument and will cause the CPU's PC to be set to
where the image is stored or in the case of an ELF file to
the value in the header. This option should only be used
for the boot image.
the memory address where the raw file is loaded or the entry
point specified in the executable format header. This option
should only be used for the boot image.
This will also cause the image to be written to the specified
CPU's address space. If not specified, the default is CPU 0.
<force-raw> - Setting force-raw=on forces the file to be treated as a raw
image. This can be used to load ELF files as if they were raw.
image. This can be used to load supported executable formats
as if they were raw.

All values are parsed using the standard QemuOps parsing. This allows the user
to specify any values in any format supported. By default the values
Expand Down
1 change: 1 addition & 0 deletions hw/arm/armv7m.c
Expand Up @@ -202,6 +202,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
*/
qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");

/* Wire the NVIC up to the CPU */
sbd = SYS_BUS_DEVICE(&s->nvic);
Expand Down
8 changes: 7 additions & 1 deletion hw/arm/realview.c
Expand Up @@ -201,7 +201,13 @@ static void realview_init(MachineState *machine,
pl011_create(0x1000c000, pic[15], serial_hd(3));

/* DMA controller is optional, apparently. */
sysbus_create_simple("pl081", 0x10030000, pic[24]);
dev = qdev_create(NULL, "pl081");
object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
&error_fatal);
qdev_init_nofail(dev);
busdev = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(busdev, 0, 0x10030000);
sysbus_connect_irq(busdev, 0, pic[24]);

sysbus_create_simple("sp804", 0x10011000, pic[4]);
sysbus_create_simple("sp804", 0x10012000, pic[5]);
Expand Down
9 changes: 8 additions & 1 deletion hw/arm/versatilepb.c
Expand Up @@ -287,7 +287,14 @@ static void versatile_init(MachineState *machine, int board_id)
pl011_create(0x101f3000, pic[14], serial_hd(2));
pl011_create(0x10009000, sic[6], serial_hd(3));

sysbus_create_simple("pl080", 0x10130000, pic[17]);
dev = qdev_create(NULL, "pl080");
object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
&error_fatal);
qdev_init_nofail(dev);
busdev = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(busdev, 0, 0x10130000);
sysbus_connect_irq(busdev, 0, pic[17]);

sysbus_create_simple("sp804", 0x101e2000, pic[4]);
sysbus_create_simple("sp804", 0x101e3000, pic[5]);

Expand Down
21 changes: 16 additions & 5 deletions hw/arm/virt.c
Expand Up @@ -1791,10 +1791,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);

#define VIRT_COMPAT_2_12 \
HW_COMPAT_2_12

static void virt_3_0_instance_init(Object *obj)
static void virt_3_1_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
Expand Down Expand Up @@ -1864,10 +1861,24 @@ static void virt_3_0_instance_init(Object *obj)
vms->irqmap = a15irqmap;
}

static void virt_machine_3_1_options(MachineClass *mc)
{
}
DEFINE_VIRT_MACHINE_AS_LATEST(3, 1)

static void virt_3_0_instance_init(Object *obj)
{
virt_3_1_instance_init(obj);
}

static void virt_machine_3_0_options(MachineClass *mc)
{
virt_machine_3_1_options(mc);
}
DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
DEFINE_VIRT_MACHINE(3, 0)

#define VIRT_COMPAT_2_12 \
HW_COMPAT_2_12

static void virt_2_12_instance_init(Object *obj)
{
Expand Down
3 changes: 2 additions & 1 deletion hw/char/imx_serial.c
Expand Up @@ -74,8 +74,9 @@ static void imx_update(IMXSerialState *s)
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
/*
* TCEN and TXDC are both bit 3
* RDR and DREN are both bit 0
*/
mask |= s->ucr4 & UCR4_TCEN;
mask |= s->ucr4 & (UCR4_TCEN | UCR4_DREN);

usr2 = s->usr2 & mask;

Expand Down
113 changes: 67 additions & 46 deletions hw/dma/pl080.c
Expand Up @@ -11,8 +11,9 @@
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "qemu/log.h"
#include "hw/dma/pl080.h"
#include "qapi/error.h"

#define PL080_MAX_CHANNELS 8
#define PL080_CONF_E 0x1
#define PL080_CONF_M1 0x2
#define PL080_CONF_M2 0x4
Expand All @@ -30,36 +31,6 @@
#define PL080_CCTRL_D 0x02000000
#define PL080_CCTRL_S 0x01000000

typedef struct {
uint32_t src;
uint32_t dest;
uint32_t lli;
uint32_t ctrl;
uint32_t conf;
} pl080_channel;

#define TYPE_PL080 "pl080"
#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)

typedef struct PL080State {
SysBusDevice parent_obj;

MemoryRegion iomem;
uint8_t tc_int;
uint8_t tc_mask;
uint8_t err_int;
uint8_t err_mask;
uint32_t conf;
uint32_t sync;
uint32_t req_single;
uint32_t req_burst;
pl080_channel chan[PL080_MAX_CHANNELS];
int nchannels;
/* Flag to avoid recursive DMA invocations. */
int running;
qemu_irq irq;
} PL080State;

static const VMStateDescription vmstate_pl080_channel = {
.name = "pl080_channel",
.version_id = 1,
Expand Down Expand Up @@ -105,11 +76,12 @@ static const unsigned char pl081_id[] =

static void pl080_update(PL080State *s)
{
if ((s->tc_int & s->tc_mask)
|| (s->err_int & s->err_mask))
qemu_irq_raise(s->irq);
else
qemu_irq_lower(s->irq);
bool tclevel = (s->tc_int & s->tc_mask);
bool errlevel = (s->err_int & s->err_mask);

qemu_set_irq(s->interr, errlevel);
qemu_set_irq(s->inttc, tclevel);
qemu_set_irq(s->irq, errlevel || tclevel);
}

static void pl080_run(PL080State *s)
Expand Down Expand Up @@ -138,7 +110,6 @@ static void pl080_run(PL080State *s)
if ((s->conf & PL080_CONF_E) == 0)
return;

hw_error("DMA active\n");
/* If we are already in the middle of a DMA operation then indicate that
there may be new DMA requests and return immediately. */
if (s->running) {
Expand Down Expand Up @@ -190,14 +161,16 @@ hw_error("DMA active\n");
swidth = 1 << ((ch->ctrl >> 18) & 7);
dwidth = 1 << ((ch->ctrl >> 21) & 7);
for (n = 0; n < dwidth; n+= swidth) {
cpu_physical_memory_read(ch->src, buff + n, swidth);
address_space_read(&s->downstream_as, ch->src,
MEMTXATTRS_UNSPECIFIED, buff + n, swidth);
if (ch->ctrl & PL080_CCTRL_SI)
ch->src += swidth;
}
xsize = (dwidth < swidth) ? swidth : dwidth;
/* ??? This may pad the value incorrectly for dwidth < 32. */
for (n = 0; n < xsize; n += dwidth) {
cpu_physical_memory_write(ch->dest + n, buff + n, dwidth);
address_space_write(&s->downstream_as, ch->dest + n,
MEMTXATTRS_UNSPECIFIED, buff + n, dwidth);
if (ch->ctrl & PL080_CCTRL_DI)
ch->dest += swidth;
}
Expand All @@ -207,19 +180,19 @@ hw_error("DMA active\n");
if (size == 0) {
/* Transfer complete. */
if (ch->lli) {
ch->src = address_space_ldl_le(&address_space_memory,
ch->src = address_space_ldl_le(&s->downstream_as,
ch->lli,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->dest = address_space_ldl_le(&address_space_memory,
ch->dest = address_space_ldl_le(&s->downstream_as,
ch->lli + 4,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->ctrl = address_space_ldl_le(&address_space_memory,
ch->ctrl = address_space_ldl_le(&s->downstream_as,
ch->lli + 12,
MEMTXATTRS_UNSPECIFIED,
NULL);
ch->lli = address_space_ldl_le(&address_space_memory,
ch->lli = address_space_ldl_le(&s->downstream_as,
ch->lli + 8,
MEMTXATTRS_UNSPECIFIED,
NULL);
Expand Down Expand Up @@ -255,7 +228,7 @@ static uint64_t pl080_read(void *opaque, hwaddr offset,
i = (offset & 0xe0) >> 5;
if (i >= s->nchannels)
goto bad_offset;
switch (offset >> 2) {
switch ((offset >> 2) & 7) {
case 0: /* SrcAddr */
return s->chan[i].src;
case 1: /* DestAddr */
Expand Down Expand Up @@ -316,7 +289,7 @@ static void pl080_write(void *opaque, hwaddr offset,
i = (offset & 0xe0) >> 5;
if (i >= s->nchannels)
goto bad_offset;
switch (offset >> 2) {
switch ((offset >> 2) & 7) {
case 0: /* SrcAddr */
s->chan[i].src = value;
break;
Expand All @@ -334,6 +307,7 @@ static void pl080_write(void *opaque, hwaddr offset,
pl080_run(s);
break;
}
return;
}
switch (offset >> 2) {
case 2: /* IntTCClear */
Expand Down Expand Up @@ -374,6 +348,30 @@ static const MemoryRegionOps pl080_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};

static void pl080_reset(DeviceState *dev)
{
PL080State *s = PL080(dev);
int i;

s->tc_int = 0;
s->tc_mask = 0;
s->err_int = 0;
s->err_mask = 0;
s->conf = 0;
s->sync = 0;
s->req_single = 0;
s->req_burst = 0;
s->running = 0;

for (i = 0; i < s->nchannels; i++) {
s->chan[i].src = 0;
s->chan[i].dest = 0;
s->chan[i].lli = 0;
s->chan[i].ctrl = 0;
s->chan[i].conf = 0;
}
}

static void pl080_init(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
Expand All @@ -382,21 +380,44 @@ static void pl080_init(Object *obj)
memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
sysbus_init_irq(sbd, &s->interr);
sysbus_init_irq(sbd, &s->inttc);
s->nchannels = 8;
}

static void pl080_realize(DeviceState *dev, Error **errp)
{
PL080State *s = PL080(dev);

if (!s->downstream) {
error_setg(errp, "PL080 'downstream' link not set");
return;
}

address_space_init(&s->downstream_as, s->downstream, "pl080-downstream");
}

static void pl081_init(Object *obj)
{
PL080State *s = PL080(obj);

s->nchannels = 2;
}

static Property pl080_properties[] = {
DEFINE_PROP_LINK("downstream", PL080State, downstream,
TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};

static void pl080_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);

dc->vmsd = &vmstate_pl080;
dc->realize = pl080_realize;
dc->props = pl080_properties;
dc->reset = pl080_reset;
}

static const TypeInfo pl080_info = {
Expand All @@ -408,7 +429,7 @@ static const TypeInfo pl080_info = {
};

static const TypeInfo pl081_info = {
.name = "pl081",
.name = TYPE_PL081,
.parent = TYPE_PL080,
.instance_init = pl081_init,
};
Expand Down
2 changes: 1 addition & 1 deletion hw/intc/arm_gicv3_its_kvm.c
Expand Up @@ -211,7 +211,7 @@ static void kvm_arm_its_reset(DeviceState *dev)
return;
}

error_report("ITS KVM: full reset is not supported by the host kernel");
warn_report("ITS KVM: full reset is not supported by the host kernel");

if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR)) {
Expand Down

0 comments on commit 62c3484

Please sign in to comment.