Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.8-201610…
Browse files Browse the repository at this point in the history
…28' into staging

ppc patch queue 2016-10-28

This pull request supersedes and extends the one from 2016-10-26
(which had a build bug).

Highlights:
  * SLOF (pseries guest firmware) update
  * Enable a number of extra testcases on ppc / pseries
  * Added the 'powernv' machine type
    - Almost enough to be minimally usable
    - But still missing necessary interrupt controller updates
  * Cleanup and consolidation of NVRAM handling on several platforms
    with related firmware
  * Substantial cleanup to device tree construction
  * Some more POWER9 instruction emulation
  * Cleanup to handling of pseries option vectors and CAS reboot
    handling (host/guest feature negotiation mechanism)
  * Significant cleanups to handling of PCI devices in test cases
  * New hotplug event infrastructure
  * Memory hot unplug support for pseries
  * Several bug fixes

The NVRAM cleanup affects some Sun sparc platforms as well as ppc
ones, but have been tested by the sparc maintainer (Mark Cave-Ayland).

The test additions also include substantial general changes to the
test framework that aren't strictly ppc related.  They don't seem to
break tests on other platforms, they're for the benefit of enabling
tests on ppc and there isn't a specific maintainer for them, so
they're included in this tree.

# gpg: Signature made Fri 28 Oct 2016 02:37:19 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.8-20161028: (73 commits)
  ppc: allow certain HV interrupts to be delivered to guests
  spapr: Memory hot-unplug support
  spapr: use count+index for memory hotplug
  spapr: Add DRC count indexed hotplug identifier type
  spapr: add hotplug interrupt machine options
  spapr_events: add support for dedicated hotplug event source
  spapr: update spapr hotplug documentation
  target-ppc: Add xvcmpnesp, xvcmpnedp instructions
  target-ppc: add xscmp[eq,gt,ge,ne]dp instructions
  tests: Add pseries machine to the prom-env-test, too
  spapr_nvram: Pre-initialize the NVRAM to support the -prom-env parameter
  libqos: Change PCI accessors to take opaque BAR handle
  tests: Don't assume structure of PCI IO base in ahci-test
  tests: Use qpci_mem{read,write} in ivshmem-test
  libqos: Add 64-bit PCI IO accessors
  tests: Clean up IO handling in ide-test
  libqos: Implement mmio accessors in terms of mem{read,write}
  libqos: Add streaming accessors for PCI MMIO
  tests: Adjust tco-test to use qpci_legacy_iomap()
  libqos: Better handling of PCI legacy IO
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Oct 28, 2016
2 parents 01b601f + 10c21b5 commit 66a77ea
Show file tree
Hide file tree
Showing 87 changed files with 4,983 additions and 1,714 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Expand Up @@ -31,3 +31,6 @@
[submodule "roms/u-boot"]
path = roms/u-boot
url = git://git.qemu-project.org/u-boot.git
[submodule "roms/skiboot"]
path = roms/skiboot
url = git://git.qemu.org/skiboot.git
1 change: 1 addition & 0 deletions MAINTAINERS
Expand Up @@ -656,6 +656,7 @@ F: include/hw/*/xics*
F: pc-bios/spapr-rtas/*
F: pc-bios/spapr-rtas.bin
F: pc-bios/slof.bin
F: pc-bios/skiboot.lid
F: docs/specs/ppc-spapr-hcalls.txt
F: docs/specs/ppc-spapr-hotplug.txt
F: tests/spapr*
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -421,7 +421,7 @@ qemu-icon.bmp qemu_logo_no_text.svg \
bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \
s390-ccw.img \
spapr-rtas.bin slof.bin \
spapr-rtas.bin slof.bin skiboot.lid \
palcode-clipper \
u-boot.e500
else
Expand Down
1 change: 1 addition & 0 deletions configure
Expand Up @@ -6131,6 +6131,7 @@ FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
FILES="$FILES pc-bios/qemu-icon.bmp"
for bios_file in \
$source_path/pc-bios/*.bin \
$source_path/pc-bios/*.lid \
$source_path/pc-bios/*.aml \
$source_path/pc-bios/*.rom \
$source_path/pc-bios/*.dtb \
Expand Down
1 change: 1 addition & 0 deletions default-configs/ppc64-softmmu.mak
Expand Up @@ -39,6 +39,7 @@ CONFIG_I8259=y
CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_PSERIES=y
CONFIG_POWERNV=y
CONFIG_PREP=y
CONFIG_MAC=y
CONFIG_E500=y
Expand Down
55 changes: 46 additions & 9 deletions docs/specs/ppc-spapr-hotplug.txt
Expand Up @@ -233,12 +233,27 @@ tools by host-level management such as an HMC. This level of management is not
applicable to PowerKVM, hence the reason for extending the notification
framework to support hotplug events.

Note that these events are not yet formally part of the PAPR+ specification,
but support for this format has already been implemented in DR-related
guest tools such as powerpc-utils/librtas, as well as kernel patches that have
been submitted to handle in-kernel processing of memory/cpu-related hotplug
events[1], and is planned for formal inclusion is PAPR+ specification. The
hotplug-specific payload is QEMU implemented as follows (with all values
The format for these EPOW-signalled events is described below under
"hotplug/unplug event structure". Note that these events are not
formally part of the PAPR+ specification, and have been superseded by a
newer format, also described below under "hotplug/unplug event structure",
and so are now deemed a "legacy" format. The formats are similar, but the
"modern" format contains additional fields/flags, which are denoted for the
purposes of this documentation with "#ifdef GUEST_SUPPORTS_MODERN" guards.

QEMU should assume support only for "legacy" fields/flags unless the guest
advertises support for the "modern" format via ibm,client-architecture-support
hcall by setting byte 5, bit 6 of it's ibm,architecture-vec-5 option vector
structure (as described by LoPAPR v11, B.6.2.3). As with "legacy" format events,
"modern" format events are surfaced to the guest via check-exception RTAS calls,
but use a dedicated event source to signal the guest. This event source is
advertised to the guest by the addition of a "hot-plug-events" node under
"/event-sources" node of the guest's device tree using the standard format
described in LoPAPR v11, B.6.12.1.

== hotplug/unplug event structure ==

The hotplug-specific payload in QEMU is implemented as follows (with all values
encoded in big-endian format):

struct rtas_event_log_v6_hp {
Expand All @@ -263,21 +278,43 @@ struct rtas_event_log_v6_hp {
#define RTAS_LOG_V6_HP_ACTION_ADD 1
#define RTAS_LOG_V6_HP_ACTION_REMOVE 2
uint8_t hotplug_action; /* action (add/remove) */
#define RTAS_LOG_V6_HP_ID_DRC_NAME 1
#define RTAS_LOG_V6_HP_ID_DRC_INDEX 2
#define RTAS_LOG_V6_HP_ID_DRC_COUNT 3
#define RTAS_LOG_V6_HP_ID_DRC_NAME 1
#define RTAS_LOG_V6_HP_ID_DRC_INDEX 2
#define RTAS_LOG_V6_HP_ID_DRC_COUNT 3
#ifdef GUEST_SUPPORTS_MODERN
#define RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED 4
#endif
uint8_t hotplug_identifier; /* type of the resource identifier,
* which serves as the discriminator
* for the 'drc' union field below
*/
#ifdef GUEST_SUPPORTS_MODERN
uint8_t capabilities; /* capability flags, currently unused
* by QEMU
*/
#else
uint8_t reserved;
#endif
union {
uint32_t index; /* DRC index of resource to take action
* on
*/
uint32_t count; /* number of DR resources to take
* action on (guest chooses which)
*/
#ifdef GUEST_SUPPORTS_MODERN
struct {
uint32_t count; /* number of DR resources to take
* action on
*/
uint32_t index; /* DRC index of first resource to take
* action on. guest will take action
* on DRC index <index> through
* DRC index <index + count - 1> in
* sequential order
*/
} count_indexed;
#endif
char name[1]; /* string representing the name of the
* DRC to take action on
*/
Expand Down
26 changes: 23 additions & 3 deletions hw/input/adb.c
Expand Up @@ -396,9 +396,15 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
d->devaddr = buf[1] & 0xf;
break;
default:
/* XXX: check this */
d->devaddr = buf[1] & 0xf;
d->handler = buf[2];
/* we support handlers:
* 1: Apple Standard Keyboard
* 2: Apple Extended Keyboard (LShift = RShift)
* 3: Apple Extended Keyboard (LShift != RShift)
*/
if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
d->handler = buf[2];
}
break;
}
}
Expand Down Expand Up @@ -437,6 +443,7 @@ static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
if (qcode >= ARRAY_SIZE(qcode_to_adb_keycode)) {
return;
}
/* FIXME: take handler into account when translating qcode */
keycode = qcode_to_adb_keycode[qcode];
if (keycode == NO_KEY) { /* We don't want to send this to the guest */
ADB_DPRINTF("Ignoring NO_KEY\n");
Expand Down Expand Up @@ -631,8 +638,21 @@ static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
d->devaddr = buf[1] & 0xf;
break;
default:
/* XXX: check this */
d->devaddr = buf[1] & 0xf;
/* we support handlers:
* 0x01: Classic Apple Mouse Protocol / 100 cpi operations
* 0x02: Classic Apple Mouse Protocol / 200 cpi operations
* we don't support handlers (at least):
* 0x03: Mouse systems A3 trackball
* 0x04: Extended Apple Mouse Protocol
* 0x2f: Microspeed mouse
* 0x42: Macally
* 0x5f: Microspeed mouse
* 0x66: Microspeed mouse
*/
if (buf[2] == 1 || buf[2] == 2) {
d->handler = buf[2];
}
break;
}
}
Expand Down
99 changes: 81 additions & 18 deletions hw/intc/xics.c
Expand Up @@ -35,6 +35,8 @@
#include "hw/ppc/xics.h"
#include "qemu/error-report.h"
#include "qapi/visitor.h"
#include "monitor/monitor.h"
#include "hw/intc/intc.h"

int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
{
Expand Down Expand Up @@ -90,6 +92,47 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
}
}

static void xics_common_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
XICSState *xics = XICS_COMMON(obj);
ICSState *ics;
uint32_t i;

for (i = 0; i < xics->nr_servers; i++) {
ICPState *icp = &xics->ss[i];

if (!icp->output) {
continue;
}
monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
i, icp->xirr, icp->xirr_owner,
icp->pending_priority, icp->mfrr);
}

QLIST_FOREACH(ics, &xics->ics, list) {
monitor_printf(mon, "ICS %4x..%4x %p\n",
ics->offset, ics->offset + ics->nr_irqs - 1, ics);

if (!ics->irqs) {
continue;
}

for (i = 0; i < ics->nr_irqs; i++) {
ICSIRQState *irq = ics->irqs + i;

if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
continue;
}
monitor_printf(mon, " %4x %s %02x %02x\n",
ics->offset + i,
(irq->flags & XICS_FLAGS_IRQ_LSI) ?
"LSI" : "MSI",
irq->priority, irq->status);
}
}
}

/*
* XICS Common class - parent for emulated XICS and KVM-XICS
*/
Expand Down Expand Up @@ -140,6 +183,25 @@ static void xics_prop_set_nr_irqs(Object *obj, Visitor *v, const char *name,
info->set_nr_irqs(xics, value, errp);
}

void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
const char *typename, Error **errp)
{
int i;

xics->nr_servers = nr_servers;

xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
for (i = 0; i < xics->nr_servers; i++) {
char name[32];
ICPState *icp = &xics->ss[i];

object_initialize(icp, sizeof(*icp), typename);
snprintf(name, sizeof(name), "icp[%d]", i);
object_property_add_child(OBJECT(xics), name, OBJECT(icp), errp);
icp->xics = xics;
}
}

static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
Expand All @@ -155,7 +217,7 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
Error **errp)
{
XICSState *xics = XICS_COMMON(obj);
XICSStateClass *info = XICS_COMMON_GET_CLASS(xics);
XICSStateClass *xsc = XICS_COMMON_GET_CLASS(xics);
Error *error = NULL;
int64_t value;

Expand All @@ -170,8 +232,8 @@ static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
return;
}

assert(info->set_nr_servers);
info->set_nr_servers(xics, value, errp);
assert(xsc->set_nr_servers);
xsc->set_nr_servers(xics, value, errp);
}

static void xics_common_initfn(Object *obj)
Expand All @@ -190,8 +252,10 @@ static void xics_common_initfn(Object *obj)
static void xics_common_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);

dc->reset = xics_common_reset;
ic->print_info = xics_common_pic_print_info;
}

static const TypeInfo xics_common_info = {
Expand All @@ -201,6 +265,10 @@ static const TypeInfo xics_common_info = {
.class_size = sizeof(XICSStateClass),
.instance_init = xics_common_initfn,
.class_init = xics_common_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};

/*
Expand Down Expand Up @@ -258,22 +326,20 @@ static void icp_check_ipi(ICPState *ss)
qemu_irq_raise(ss->output);
}

static void icp_resend(XICSState *xics, int server)
static void icp_resend(ICPState *ss)
{
ICPState *ss = xics->ss + server;
ICSState *ics;

if (ss->mfrr < CPPR(ss)) {
icp_check_ipi(ss);
}
QLIST_FOREACH(ics, &xics->ics, list) {
QLIST_FOREACH(ics, &ss->xics->ics, list) {
ics_resend(ics);
}
}

void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
void icp_set_cppr(ICPState *ss, uint8_t cppr)
{
ICPState *ss = xics->ss + server;
uint8_t old_cppr;
uint32_t old_xisr;

Expand All @@ -293,15 +359,13 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
}
} else {
if (!XISR(ss)) {
icp_resend(xics, server);
icp_resend(ss);
}
}
}

void icp_set_mfrr(XICSState *xics, int server, uint8_t mfrr)
void icp_set_mfrr(ICPState *ss, uint8_t mfrr)
{
ICPState *ss = xics->ss + server;

ss->mfrr = mfrr;
if (mfrr < CPPR(ss)) {
icp_check_ipi(ss);
Expand Down Expand Up @@ -330,23 +394,22 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr)
return ss->xirr;
}

void icp_eoi(XICSState *xics, int server, uint32_t xirr)
void icp_eoi(ICPState *ss, uint32_t xirr)
{
ICPState *ss = xics->ss + server;
ICSState *ics;
uint32_t irq;

/* Send EOI -> ICS */
ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
trace_xics_icp_eoi(server, xirr, ss->xirr);
trace_xics_icp_eoi(ss->cs->cpu_index, xirr, ss->xirr);
irq = xirr & XISR_MASK;
QLIST_FOREACH(ics, &xics->ics, list) {
QLIST_FOREACH(ics, &ss->xics->ics, list) {
if (ics_valid_irq(ics, irq)) {
ics_eoi(ics, irq);
}
}
if (!XISR(ss)) {
icp_resend(xics, server);
icp_resend(ss);
}
}

Expand Down Expand Up @@ -605,7 +668,7 @@ static int ics_simple_post_load(ICSState *ics, int version_id)
int i;

for (i = 0; i < ics->xics->nr_servers; i++) {
icp_resend(ics->xics, i);
icp_resend(&ics->xics->ss[i]);
}

return 0;
Expand Down
13 changes: 1 addition & 12 deletions hw/intc/xics_kvm.c
Expand Up @@ -373,18 +373,7 @@ static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
Error **errp)
{
int i;

xics->nr_servers = nr_servers;

xics->ss = g_malloc0(xics->nr_servers * sizeof(ICPState));
for (i = 0; i < xics->nr_servers; i++) {
char buffer[32];
object_initialize(&xics->ss[i], sizeof(xics->ss[i]), TYPE_KVM_ICP);
snprintf(buffer, sizeof(buffer), "icp[%d]", i);
object_property_add_child(OBJECT(xics), buffer, OBJECT(&xics->ss[i]),
errp);
}
xics_set_nr_servers(xics, nr_servers, TYPE_KVM_ICP, errp);
}

static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
Expand Down

0 comments on commit 66a77ea

Please sign in to comment.