Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160330-1' into staging

target-arm queue:
 * virt: fix the virtual power button by adding a modelled
   "key press for 100ms" device
 * various improvements to m25p80 flash devices
 * implement new QMP query-gic-capability command to let the
   management layer know what versions of GIC we support

# gpg: Signature made Wed 30 Mar 2016 17:30:51 BST using RSA key ID 14360CDE
# 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>"

* remotes/pmaydell/tags/pull-target-arm-20160330-1:
  arm: implement query-gic-capabilities
  kvm: add kvm_device_supported() helper function
  arm: enhance kvm_arm_create_scratch_host_vcpu
  arm: qmp: add query-gic-capabilities interface
  block: m25p80: at25128a/at25256a models
  block: m25p80: n25q256a/n25q512a models
  block: m25p80: Implemented FSR register
  block: m25p80: Fast read and 4bytes commands
  block: m25p80: Dummy cycles for N25Q256/512
  block: m25p80: Add configuration registers
  block: m25p80: 4byte address mode
  block: m25p80: Extend address mode
  block: m25p80: Widen flags variable
  block: m25p80: RESET_ENABLE and RESET_MEMORY commands
  block: m25p80: Removed unused variable
  ARM: Virt: Use gpio_key for power button
  hw/gpio: Add the emulation of gpio_key

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2016-03-30 17:32:11 +01:00
14 changed files with 620 additions and 25 deletions
+1
View File
@@ -111,3 +111,4 @@ CONFIG_I82801B11=y
CONFIG_ACPI=y
CONFIG_SMBIOS=y
CONFIG_ASPEED_SOC=y
CONFIG_GPIO_KEY=y
+5 -2
View File
@@ -582,11 +582,11 @@ static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
g_free(nodename);
}
static DeviceState *pl061_dev;
static DeviceState *gpio_key_dev;
static void virt_powerdown_req(Notifier *n, void *opaque)
{
/* use gpio Pin 3 for power button event */
qemu_set_irq(qdev_get_gpio_in(pl061_dev, 3), 1);
qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
}
static Notifier virt_system_powerdown_notifier = {
@@ -596,6 +596,7 @@ static Notifier virt_system_powerdown_notifier = {
static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
{
char *nodename;
DeviceState *pl061_dev;
hwaddr base = vbi->memmap[VIRT_GPIO].base;
hwaddr size = vbi->memmap[VIRT_GPIO].size;
int irq = vbi->irqmap[VIRT_GPIO];
@@ -618,6 +619,8 @@ static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
qemu_fdt_setprop_cell(vbi->fdt, nodename, "phandle", phandle);
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
qdev_get_gpio_in(pl061_dev, 3));
qemu_fdt_add_subnode(vbi->fdt, "/gpio-keys");
qemu_fdt_setprop_string(vbi->fdt, "/gpio-keys", "compatible", "gpio-keys");
qemu_fdt_setprop_cell(vbi->fdt, "/gpio-keys", "#size-cells", 0);
+311 -19
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -3,6 +3,7 @@ common-obj-$(CONFIG_PL061) += pl061.o
common-obj-$(CONFIG_PUV3) += puv3_gpio.o
common-obj-$(CONFIG_ZAURUS) += zaurus.o
common-obj-$(CONFIG_E500) += mpc8xxx.o
common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o
obj-$(CONFIG_OMAP) += omap_gpio.o
obj-$(CONFIG_IMX) += imx_gpio.o
+104
View File
@@ -0,0 +1,104 @@
/*
* GPIO key
*
* Copyright (c) 2016 Linaro Limited
*
* Author: Shannon Zhao <shannon.zhao@linaro.org>
*
* Emulate a (human) keypress -- when the key is triggered by
* setting the incoming gpio line, the outbound irq line is
* raised for 100ms before being dropped again.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License; 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 "qemu/osdep.h"
#include "hw/sysbus.h"
#define TYPE_GPIOKEY "gpio-key"
#define GPIOKEY(obj) OBJECT_CHECK(GPIOKEYState, (obj), TYPE_GPIOKEY)
#define GPIO_KEY_LATENCY 100 /* 100ms */
typedef struct GPIOKEYState {
SysBusDevice parent_obj;
QEMUTimer *timer;
qemu_irq irq;
} GPIOKEYState;
static const VMStateDescription vmstate_gpio_key = {
.name = "gpio-key",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_TIMER_PTR(timer, GPIOKEYState),
VMSTATE_END_OF_LIST()
}
};
static void gpio_key_reset(DeviceState *dev)
{
GPIOKEYState *s = GPIOKEY(dev);
timer_del(s->timer);
}
static void gpio_key_timer_expired(void *opaque)
{
GPIOKEYState *s = (GPIOKEYState *)opaque;
qemu_set_irq(s->irq, 0);
timer_del(s->timer);
}
static void gpio_key_set_irq(void *opaque, int irq, int level)
{
GPIOKEYState *s = (GPIOKEYState *)opaque;
qemu_set_irq(s->irq, 1);
timer_mod(s->timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + GPIO_KEY_LATENCY);
}
static void gpio_key_realize(DeviceState *dev, Error **errp)
{
GPIOKEYState *s = GPIOKEY(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
sysbus_init_irq(sbd, &s->irq);
qdev_init_gpio_in(dev, gpio_key_set_irq, 1);
s->timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, gpio_key_timer_expired, s);
}
static void gpio_key_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = gpio_key_realize;
dc->vmsd = &vmstate_gpio_key;
dc->reset = &gpio_key_reset;
}
static const TypeInfo gpio_key_info = {
.name = TYPE_GPIOKEY,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GPIOKEYState),
.class_init = gpio_key_class_init,
};
static void gpio_key_register_types(void)
{
type_register_static(&gpio_key_info);
}
type_init(gpio_key_register_types)
+9
View File
@@ -306,6 +306,15 @@ void kvm_device_access(int fd, int group, uint64_t attr,
*/
int kvm_create_device(KVMState *s, uint64_t type, bool test);
/**
* kvm_device_supported - probe whether KVM supports specific device
*
* @vmfd: The fd handler for VM
* @type: type of device
*
* @return: true if supported, otherwise false.
*/
bool kvm_device_supported(int vmfd, uint64_t type);
/* Arch specific hooks */
+15
View File
@@ -2339,6 +2339,21 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test)
return test ? 0 : create_dev.fd;
}
bool kvm_device_supported(int vmfd, uint64_t type)
{
struct kvm_create_device create_dev = {
.type = type,
.fd = -1,
.flags = KVM_CREATE_DEVICE_TEST,
};
if (ioctl(vmfd, KVM_CHECK_EXTENSION, KVM_CAP_DEVICE_CTRL) <= 0) {
return false;
}
return (ioctl(vmfd, KVM_CREATE_DEVICE, &create_dev) >= 0);
}
int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source)
{
struct kvm_one_reg reg;
+8
View File
@@ -4259,3 +4259,11 @@ void qmp_dump_skeys(const char *filename, Error **errp)
error_setg(errp, QERR_FEATURE_DISABLED, "dump-skeys");
}
#endif
#ifndef TARGET_ARM
GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "query-gic-capabilities");
return NULL;
}
#endif
+36
View File
@@ -4134,3 +4134,39 @@
##
{ 'enum': 'ReplayMode',
'data': [ 'none', 'record', 'play' ] }
##
# @GICCapability:
#
# The struct describes capability for a specific GIC (Generic
# Interrupt Controller) version. These bits are not only decided by
# QEMU/KVM software version, but also decided by the hardware that
# the program is running upon.
#
# @version: version of GIC to be described. Currently, only 2 and 3
# are supported.
#
# @emulated: whether current QEMU/hardware supports emulated GIC
# device in user space.
#
# @kernel: whether current QEMU/hardware supports hardware
# accelerated GIC device in kernel.
#
# Since: 2.6
##
{ 'struct': 'GICCapability',
'data': { 'version': 'int',
'emulated': 'bool',
'kernel': 'bool' } }
##
# @query-gic-capabilities:
#
# This command is ARM-only. It will return a list of GICCapability
# objects that describe its capability bits.
#
# Returns: a list of GICCapability objects.
#
# Since: 2.6
##
{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
+27
View File
@@ -4853,3 +4853,30 @@ Example:
{"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840,
"pop-vlan": 1, "id": 251658240}
]}
EQMP
#if defined TARGET_ARM
{
.name = "query-gic-capabilities",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_gic_capabilities,
},
#endif
SQMP
query-gic-capabilities
---------------
Return a list of GICCapability objects, describing supported GIC
(Generic Interrupt Controller) versions.
Arguments: None
Example:
-> { "execute": "query-gic-capabilities" }
<- { "return": [{ "version": 2, "emulated": true, "kernel": false },
{ "version": 3, "emulated": false, "kernel": true } ] }
EQMP
+1 -1
View File
@@ -1,5 +1,5 @@
obj-y += arm-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o
obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o
obj-$(CONFIG_KVM) += kvm.o
obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
+13 -1
View File
@@ -62,13 +62,18 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
goto err;
}
if (!init) {
/* Caller doesn't want the VCPU to be initialized, so skip it */
goto finish;
}
ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
if (ret >= 0) {
ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
if (ret < 0) {
goto err;
}
} else {
} else if (cpus_to_try) {
/* Old kernel which doesn't know about the
* PREFERRED_TARGET ioctl: we know it will only support
* creating one kind of guest CPU which is its preferred
@@ -85,8 +90,15 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
if (ret < 0) {
goto err;
}
} else {
/* Treat a NULL cpus_to_try argument the same as an empty
* list, which means we will fail the call since this must
* be an old kernel which doesn't support PREFERRED_TARGET.
*/
goto err;
}
finish:
fdarray[0] = kvmfd;
fdarray[1] = vmfd;
fdarray[2] = cpufd;
+5 -2
View File
@@ -124,9 +124,12 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu);
* kvm_arm_create_scratch_host_vcpu:
* @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
* QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not
* know the PREFERRED_TARGET ioctl
* know the PREFERRED_TARGET ioctl. Passing NULL is the same as passing
* an empty array.
* @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
* @init: filled in with the necessary values for creating a host vcpu
* @init: filled in with the necessary values for creating a host
* vcpu. If NULL is provided, will not init the vCPU (though the cpufd
* will still be set up).
*
* Create a scratch vcpu in its own VM of the type preferred by the host
* kernel (as would be used for '-cpu host'), for purposes of probing it
+84
View File
@@ -0,0 +1,84 @@
/*
* QEMU monitor.c for ARM.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qmp-commands.h"
#include "hw/boards.h"
#include "kvm_arm.h"
static GICCapability *gic_cap_new(int version)
{
GICCapability *cap = g_new0(GICCapability, 1);
cap->version = version;
/* by default, support none */
cap->emulated = false;
cap->kernel = false;
return cap;
}
static GICCapabilityList *gic_cap_list_add(GICCapabilityList *head,
GICCapability *cap)
{
GICCapabilityList *item = g_new0(GICCapabilityList, 1);
item->value = cap;
item->next = head;
return item;
}
static inline void gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3)
{
#ifdef CONFIG_KVM
int fdarray[3];
if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, NULL)) {
return;
}
/* Test KVM GICv2 */
if (kvm_device_supported(fdarray[1], KVM_DEV_TYPE_ARM_VGIC_V2)) {
v2->kernel = true;
}
/* Test KVM GICv3 */
if (kvm_device_supported(fdarray[1], KVM_DEV_TYPE_ARM_VGIC_V3)) {
v3->kernel = true;
}
kvm_arm_destroy_scratch_host_vcpu(fdarray);
#endif
}
GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
{
GICCapabilityList *head = NULL;
GICCapability *v2 = gic_cap_new(2), *v3 = gic_cap_new(3);
v2->emulated = true;
/* TODO: we'd change to true after we get emulated GICv3. */
v3->emulated = false;
gic_cap_kvm_probe(v2, v3);
head = gic_cap_list_add(head, v2);
head = gic_cap_list_add(head, v3);
return head;
}