@@ -18,6 +18,10 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu-objects.h"
+#include "sysemu.h"
+#include "monitor.h"
+#include "pcie.h"
#include "pcie_port.h"
void pcie_port_init_reg(PCIDevice *d)
@@ -114,3 +118,81 @@ void pcie_chassis_del_slot(PCIESlot *s)
{
QLIST_REMOVE(s, next);
}
+
+/**************************************************************************
+ * glue for qemu monitor
+ */
+
+/* Parse [<chassis>.]<slot>, return -1 on error */
+static int pcie_parse_slot_addr(const char* slot_addr,
+ uint8_t *chassisp, uint16_t *slotp)
+{
+ const char *p;
+ char *e;
+ unsigned long val;
+ unsigned long chassis = 0;
+ unsigned long slot;
+
+ p = slot_addr;
+ val = strtoul(p, &e, 0);
+ if (e == p) {
+ return -1;
+ }
+ if (*e == '.') {
+ chassis = val;
+ p = e + 1;
+ val = strtoul(p, &e, 0);
+ if (e == p) {
+ return -1;
+ }
+ }
+ slot = val;
+
+ if (*e) {
+ return -1;
+ }
+
+ if (chassis > 0xff || slot > 0xffff) {
+ return -1;
+ }
+
+ *chassisp = chassis;
+ *slotp = slot;
+ return 0;
+}
+
+void pcie_attention_button_push_print(Monitor *mon, const QObject *data)
+{
+ QDict *qdict;
+
+ assert(qobject_type(data) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(data);
+
+ monitor_printf(mon, "OK chassis %d, slot %d\n",
+ (int) qdict_get_int(qdict, "chassis"),
+ (int) qdict_get_int(qdict, "slot"));
+}
+
+int pcie_attention_button_push(Monitor *mon, const QDict *qdict,
+ QObject **ret_data)
+{
+ const char* pcie_slot = qdict_get_str(qdict, "pcie_slot");
+ uint8_t chassis;
+ uint16_t slot;
+ PCIESlot *s;
+
+ if (pcie_parse_slot_addr(pcie_slot, &chassis, &slot) < 0) {
+ monitor_printf(mon, "invalid pcie slot address %s\n", pcie_slot);
+ return -1;
+ }
+ s = pcie_chassis_find_slot(chassis, slot);
+ if (!s) {
+ monitor_printf(mon, "slot is not found. %s\n", pcie_slot);
+ return -1;
+ }
+ pcie_cap_slot_push_attention_button(&s->port.br.dev);
+ *ret_data = qobject_from_jsonf("{ 'chassis': %d, 'slot': %d}",
+ chassis, slot);
+ assert(*ret_data);
+ return 0;
+}
@@ -1154,6 +1154,20 @@ Hot remove PCI device.
ETEXI
{
+ .name = "pcie_push_attention_button",
+ .args_type = "pcie_slot:s",
+ .params = "[<chassis>.]<slot>",
+ .help = "push pci express attention button",
+ .user_print = pcie_attention_button_push_print,
+ .mhandler.cmd_new = pcie_attention_button_push,
+ },
+
+STEXI
+@item pcie_abp
+Push PCI express attention button
+ETEXI
+
+ {
.name = "host_net_add",
.args_type = "device:s,opts:s?",
.params = "tap|user|socket|vde|dump [options]",
@@ -150,6 +150,10 @@ extern unsigned int nb_prom_envs;
void pci_device_hot_add(Monitor *mon, const QDict *qdict);
void drive_hot_add(Monitor *mon, const QDict *qdict);
void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
+/* pcie hotplug */
+void pcie_attention_button_push_print(Monitor *mon, const QObject *data);
+int pcie_attention_button_push(Monitor *mon, const QDict *qdict,
+ QObject **ret_data);
/* serial ports */
glue pcie_push_attention_button command. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- hw/pcie_port.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-monitor.hx | 14 +++++++++ sysemu.h | 4 +++ 3 files changed, 100 insertions(+), 0 deletions(-)