From patchwork Thu Sep 19 21:39:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164902 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Q3c5iV/Q"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9Y61lMSz9sNf for ; Fri, 20 Sep 2019 07:51:54 +1000 (AEST) Received: from localhost ([::1]:48804 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4L9-0004Z6-DO for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:51:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56261) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49Z-0001W2-UH for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49L-00067W-5f for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from mail-oi1-x241.google.com ([2607:f8b0:4864:20::241]:43686) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49K-00066k-V8 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:39 -0400 Received: by mail-oi1-x241.google.com with SMTP id t84so5521oih.10 for ; Thu, 19 Sep 2019 14:39:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=Vieta1X04i/SCs0pvbOIwKwN90/dIHs868zzWk/WUvk=; b=Q3c5iV/QLclzXeadOegbKBTIjw779E4O3K+NB25XGRPtbzqQ6YgqDIHCOC4ynrB85M bSTmBPY4qEdXKwF3tGAHeVBgL4jXgIfwdM4NF+Zp3C/Ea6GwkN9Ny/FG9dRrT1lv4ZuQ J65NnZhbvmW5j9OQblW/vxThez5kAvftWJCfp5vMqfPEB86W7xH1+hMWYUA9bHPUx5vd azGhKkOuZthRv4dhlADsL2eDMjITui3QcclpHEfpUZCQlzwihsoAkRocL5X7xksAzpcj 0fiSNba09x0JYzzG1jNeX79WF5PAYnp9PoGuB7j1UvD09mJQx1MuWz0IeF1m/rLh5iew pfvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=Vieta1X04i/SCs0pvbOIwKwN90/dIHs868zzWk/WUvk=; b=kB1HS+tILejjPqjJ3qK1pe9Ydq14RMwEeoi6fxmfKEMIPNFyjEMGjqSpBCYpcD7je2 d9vkqwyT+5+1GcjZ7NwjdDwSLLZDGwkFvUS+6fN8BtfhVLkEcJjJpl3pSg9c2CzB4nHD 9h8Lf/Ua8wPx4b+DNPODEkKMYRFQqcNXe01G0flqccnBiv1MBAT2t2Yn7iIsjV8uBPwJ AFQwc4vgF+AQs/fH+L7jH5dpbLSBGP22UXswj8b1SbLs0Ef1wHk/xkVxOlTSjC+INv9L 55jNnXCzDvXZ1XCox20YtsR4SWumUJswk5PdhRbmth8em9ldhav7RBuehksqALOIgA7j txlg== X-Gm-Message-State: APjAAAWJl12ug3I1jnqTRTcVA1nXrRzq8lsNBzZf4Qcop3832o0VI3VD /g12MAF98CaVZ1NTqnTVsA== X-Google-Smtp-Source: APXvYqwVtJCdOSLwXHpleUZ7VSyo3ZBD1QvwcfjawDG9QNvZgeUHVHINaoyRm6UULxUvLYfPvIVr6A== X-Received: by 2002:aca:4b85:: with SMTP id y127mr66837oia.70.1568929177082; Thu, 19 Sep 2019 14:39:37 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id e5sm27780otr.81.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:36 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 9B7F11800D2; Thu, 19 Sep 2019 21:39:35 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 01/15] ipmi: Fix watchdog NMI handling Date: Thu, 19 Sep 2019 16:39:10 -0500 Message-Id: <20190919213924.31852-2-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::241 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard The wrong logic was used for detection (so it wouldn't work at all) and the wrong interface was used to inject the NMI if the detection logic was correct. Signed-off-by: Corey Minyard Reviewed-by: Cédric Le Goater --- hw/ipmi/ipmi.c | 6 +++--- hw/ipmi/ipmi_bmc_sim.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c index 136c86b7a7..cbe158f815 100644 --- a/hw/ipmi/ipmi.c +++ b/hw/ipmi/ipmi.c @@ -28,9 +28,8 @@ #include "qom/object_interfaces.h" #include "sysemu/runstate.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc.h" -#include "qapi/visitor.h" #include "qemu/module.h" +#include "hw/nmi.h" static uint32_t ipmi_current_uuid = 1; @@ -60,7 +59,8 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) if (checkonly) { return 0; } - qmp_inject_nmi(NULL); + /* We don't care what CPU we use. */ + nmi_monitor_handle(0, NULL); return 0; case IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP: diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c index 246a6d390c..8f63bb7181 100644 --- a/hw/ipmi/ipmi_bmc_sim.c +++ b/hw/ipmi/ipmi_bmc_sim.c @@ -1194,7 +1194,7 @@ static void set_watchdog_timer(IPMIBmcSim *ibs, break; case IPMI_BMC_WATCHDOG_PRE_NMI: - if (!k->do_hw_op(s, IPMI_SEND_NMI, 1)) { + if (k->do_hw_op(s, IPMI_SEND_NMI, 1)) { /* NMI not supported. */ rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD); return; From patchwork Thu Sep 19 21:39:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164900 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="f6eO/JHk"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9ST0J5Pz9sNf for ; Fri, 20 Sep 2019 07:47:52 +1000 (AEST) Received: from localhost ([::1]:48776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4HE-0007yi-Mg for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:47:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56263) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49Z-0001W5-UF for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49L-00067e-9A for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from mail-ot1-x341.google.com ([2607:f8b0:4864:20::341]:41334) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49L-00067P-4A for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:39 -0400 Received: by mail-ot1-x341.google.com with SMTP id g13so4435599otp.8 for ; Thu, 19 Sep 2019 14:39:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=5IGB425rPWZv6PIAxxgYjNsziWO2Aym53s828C6B59k=; b=f6eO/JHkxF8rpFPmPfyZBdK5XnzYZ08xkGF6yBaNn+tGSlFPUDHgJhLxBgxgWDyKeG T8VjjlVVd+lerZ7Qcpf1ZMdQ5r6Sndlle8hYEx53foA2NxWV+egPmaYggxHQ/PoDZ+Mp uNg7meWFpF34+w73my3BhJLL5PXaS8xJRNUd5LmJ67NccZtrxQbvTesFBV4j6ISbacGI h2cZv7mi6q3oR7xCsD/bE3O1ArNtC+zfJiIdppSeZiA9ECv6cZIXhMSAW3RnYzr4dQVh EeVo0nBQv9O4qkdDeC9+v+Suwswr4qbMiIUNgpt7nw3aCg8S85X8J9BRi9Q9rJs21cqZ 0QCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=5IGB425rPWZv6PIAxxgYjNsziWO2Aym53s828C6B59k=; b=byeK+xSI55BH/75NR3QuGb+tcZmm/Lbe54abJ0JZgPftP7zd1c1s2NCFnRk4yl3v2x mNneLxwjcoAs0R3SHLSUSRX2+WWVxn7l4vpWvju0P9woySiXcpszLqCAoj/j3ONJCsgv ociRi6VLK3YbIidL/Rp4scZ7R3ovnEZtUdwsGncE5WqBKu/vI8ORQrg64lglv51f3ICg 61LPFTJBsCr2zQUJL2XR7zGyF4EVC3cSfnvOAyMyfOKpxfwwIzPyGOi7a+j5aWVnwnP8 BTsnyD6uOmg/Mq32dtm5T4mki/xMOPE7J2zJWLgbAP5uKhuaab9VEerACUIjNrhmUoAw VIvA== X-Gm-Message-State: APjAAAUATTlgIXbdM3pPKnTQxNwk6csUl9KwLJUn36GxdmKmLOVb2BO3 pDsDWUqwRFblo5xhNWgfkA== X-Google-Smtp-Source: APXvYqxxbatzF0qNdrR6VcJgnE+Q1xRiwpH4RgsqIdkBs7PWk5tp6e5fKc/KI6+RuLNGmZr/g1a0TQ== X-Received: by 2002:a9d:128c:: with SMTP id g12mr9010106otg.239.1568929178116; Thu, 19 Sep 2019 14:39:38 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id t12sm34378otl.35.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:36 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id BF44B18059B; Thu, 19 Sep 2019 21:39:35 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 02/15] ipmi: Fix the get watchdog command Date: Thu, 19 Sep 2019 16:39:11 -0500 Message-Id: <20190919213924.31852-3-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::341 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard It wasn't returning the set timeout like it should have been. Signed-off-by: Corey Minyard Reviewed-by: Cédric Le Goater --- hw/ipmi/ipmi_bmc_sim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c index 8f63bb7181..afb99e33d7 100644 --- a/hw/ipmi/ipmi_bmc_sim.c +++ b/hw/ipmi/ipmi_bmc_sim.c @@ -1228,6 +1228,8 @@ static void get_watchdog_timer(IPMIBmcSim *ibs, rsp_buffer_push(rsp, ibs->watchdog_action); rsp_buffer_push(rsp, ibs->watchdog_pretimeout); rsp_buffer_push(rsp, ibs->watchdog_expired); + rsp_buffer_push(rsp, ibs->watchdog_timeout & 0xff); + rsp_buffer_push(rsp, (ibs->watchdog_timeout >> 8) & 0xff); if (ibs->watchdog_running) { long timeout; timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000) From patchwork Thu Sep 19 21:39:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164909 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oYnvqhqJ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9jK1YyTz9sCJ for ; Fri, 20 Sep 2019 07:59:01 +1000 (AEST) Received: from localhost ([::1]:48866 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4S2-0004r9-DY for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:58:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56216) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49P-0001T0-Rn for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49L-000684-Gb for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:43 -0400 Received: from mail-oi1-x241.google.com ([2607:f8b0:4864:20::241]:40008) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49L-00067S-Ak for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:39 -0400 Received: by mail-oi1-x241.google.com with SMTP id k9so16840oib.7 for ; Thu, 19 Sep 2019 14:39:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=gp7YET4wc6HTTyajO3GZqgH8xALg6OOqzmcQarhMc/A=; b=oYnvqhqJcstRfXPGzvwwhURw/CTGjpBQ9arB7+1FkxrsE7XWR/wtiphJOYFv051TgR MvS2bxB8BkU6gBXubfXCXWCUuSHrBcdvVFZsTg/Jvoxy3hMTOCgr0iJ/XjHXQvtu0g41 oIBrkd7oaQbWgcx91M/qGt5y0cLWQGlWtMcWTWEpb30SiOrqD+vRE6RN0G+8N3MNw62F I3+ns0EmwZRzPU80J03cX/QbI3Z28QDA3B9GcdYPQeRZ+ZesjzT/n+mw3ROdwyL5vVpj 1rMyYEgdq0THVS28Im65gkiQ3K6yxeciJdQ2sDriUKRqysbN6qv9k2jnKDqpVQCp1t9X pRrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=gp7YET4wc6HTTyajO3GZqgH8xALg6OOqzmcQarhMc/A=; b=R4eA7aJYW7OpPIfTOZimBGK7FS1oW6GkLa68AymaFMtS/b0ZtKawbXFAG3NBH3kC8s 0uYpdtJhOO7BlzEkgPuQD4hjDxeAxEWyJh0xOgRv+jP2o34JZVIkyh2HsukAtkqpAc5z S0rudx9rY4TfiDK7Uq51WTi9aps4qZJaHa+H93RoQNoTE6vw8ozwgtwFmvadvSQy/VcG c5mapmbfj9DRo2N8f/A1eMFlELGqRTtYLW//ljglghVRIBV9y+arJjKrViEATptrkZCg vzPVDoiNB5zS9M2Kglx1VTzEFeh6RVvIOGhxCHwzXHPgqXjPE7waQnpb6hVbtiTBd/Bs ffPQ== X-Gm-Message-State: APjAAAWDv2jfOH88QWvdJNlAaYRdTjBHL2Mcc0uofcButgUdv1YkfEpI cCEu03bXhiBz/9DGbECq1g== X-Google-Smtp-Source: APXvYqwt9tTqXxSnj8j1BDdudFVIpeMcEUlprODOq+y3u0gGgk1qWwoKocw3R5zmXYHZfdTEFZ6sIg== X-Received: by 2002:a54:410f:: with SMTP id l15mr60371oic.92.1568929178513; Thu, 19 Sep 2019 14:39:38 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id w20sm31167otk.73.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:36 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id E727018059C; Thu, 19 Sep 2019 21:39:35 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 03/15] ipmi: Generate an interrupt on watchdog pretimeout expiry Date: Thu, 19 Sep 2019 16:39:12 -0500 Message-Id: <20190919213924.31852-4-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::241 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Add the watchdog pretimeout to the bits that cause an interrupt on attn. Otherwise the user won't know. Signed-off-by: Corey Minyard Reviewed-by: Cédric Le Goater --- hw/ipmi/ipmi_bmc_sim.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c index afb99e33d7..6e6cd1b47d 100644 --- a/hw/ipmi/ipmi_bmc_sim.c +++ b/hw/ipmi/ipmi_bmc_sim.c @@ -477,7 +477,9 @@ static int attn_set(IPMIBmcSim *ibs) static int attn_irq_enabled(IPMIBmcSim *ibs) { - return (IPMI_BMC_MSG_INTS_ON(ibs) && IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs)) + return (IPMI_BMC_MSG_INTS_ON(ibs) && + (IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs) || + IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs))) || (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) && IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs)); } From patchwork Thu Sep 19 21:39:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164899 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hru8wI97"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9Rm4fXrz9sNx for ; Fri, 20 Sep 2019 07:47:16 +1000 (AEST) Received: from localhost ([::1]:48756 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4Gf-0007QN-JA for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:47:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56228) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49R-0001Tu-79 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49M-00069e-WA for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:44 -0400 Received: from mail-oi1-x241.google.com ([2607:f8b0:4864:20::241]:42040) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49M-00069Y-R2 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:40 -0400 Received: by mail-oi1-x241.google.com with SMTP id i185so9735oif.9 for ; Thu, 19 Sep 2019 14:39:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=cVK217iyCckYWeLWjL20H8sYo3oU/9iWz2Z9ZL5bhw8=; b=hru8wI973heFuYi/HxwK1UZ45mIPRZqK5XJdwzGl6uUQeG96OsTQUIhGYKy9gBb/DQ W+dYf3fYBUeqCUlIaEg9gX7rBH93OZFPbt+aJSIg7ntTGMJoEnlULq6CN2BtkkJqAkd/ oZSo3oFTcHtaWjw2ROGFosYqOXK+cQUDBDK+TcJl1PlWLR1ISdHL7E/REOdWPD7LOZl4 6OiYthZoyjz8qGUVtwnD9HN0kxqaBxxEEuhbx2v+6pam6D+D80UQ3sg3GZyIndqh7Paq S4e+jTZKTWXABFIv3IoFhw6SmpuMk/tSMDIDgPSuzw18fIUSp3vn37gke2AiyF7nl2xP zBHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=cVK217iyCckYWeLWjL20H8sYo3oU/9iWz2Z9ZL5bhw8=; b=e0cAbKuHLul+yT91i5TL/CRXHQDNFAr6z4k55FuhN2NRsGE3l574bazr3y4so+lYJM h0hv3sA/HdzOTVoYMc65GvbrExX5s/9jSN9G740mrD473pv3uskKo8ZF9kXAu3+m4dpy tnX44GDEMGQD2ClnSt8MkqKoGJoAauNmhjzB6mNkTyjpG2yXBoIkVASXVNQuab9lK5AT agL6ZcMgO3IY+0KPSOz+WX1Ee3BGZlSULjs/yDKbycJ+uwdePK6vr2fne65IOgJ0zZkR sEZhcZ1iP3HavYxHF4RbV3xLqhGGK2Oe20BfvTp4xnL/2KZxDoXFEv//kg4Bu/2VCsIj Otdg== X-Gm-Message-State: APjAAAXg6Yj5/cqA9E9LSYE/0V+AujuUK7s9yjJrzDcjrDuFLcxbhZfu WqrVzlU2nFv9AMbZK8KXvg== X-Google-Smtp-Source: APXvYqzDNP0IC6aL+Nq1/7VRCiTRB1CQRvuZ02UGd3SaqgAxo/UoHfg3rjUltDldqKoXFU7MMms9pw== X-Received: by 2002:a54:4382:: with SMTP id u2mr63112oiv.96.1568929179958; Thu, 19 Sep 2019 14:39:39 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id v6sm38601oie.4.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:36 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 1D93918059D; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 04/15] tests:ipmi: Fix IPMI BT tests Date: Thu, 19 Sep 2019 16:39:13 -0500 Message-Id: <20190919213924.31852-5-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::241 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard The IPMI BT tests had a race condition, if it receive an IPMI command to enable interrupt, it would write the message to enable interrupts after it wrote the command response. So the test code could receive the command response and issue the next command before the device handled the interrupt enable command, and thus no interrupt. So send the message to enable interrupt before the command response. Also add some sleeps to give qemu time to handle responses, there was no delay before, and it could result in an invalid timeout. And re-enable the tests, as hopefully they are fixed now. Note that I was unable to reproduce this even with the instructions Peter gave me, but hopefully this fixes the issue. Cc: Peter Maydell Signed-off-by: Corey Minyard --- tests/Makefile.include | 3 +-- tests/ipmi-bt-test.c | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/Makefile.include b/tests/Makefile.include index 793632ca72..479664f899 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -170,8 +170,7 @@ check-qtest-i386-$(CONFIG_SGA) += tests/boot-serial-test$(EXESUF) check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-i386-$(CONFIG_ISA_IPMI_KCS) += tests/ipmi-kcs-test$(EXESUF) -# Disabled temporarily as it fails intermittently especially under NetBSD VM -# check-qtest-i386-$(CONFIG_ISA_IPMI_BT) += tests/ipmi-bt-test$(EXESUF) +check-qtest-i386-$(CONFIG_ISA_IPMI_BT) += tests/ipmi-bt-test$(EXESUF) check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-i386-y += tests/device-plug-test$(EXESUF) diff --git a/tests/ipmi-bt-test.c b/tests/ipmi-bt-test.c index fc4c83b5db..a42207d416 100644 --- a/tests/ipmi-bt-test.c +++ b/tests/ipmi-bt-test.c @@ -30,7 +30,7 @@ #include -#include "libqtest.h" +#include "libqtest-single.h" #include "qemu-common.h" #define IPMI_IRQ 5 @@ -99,6 +99,7 @@ static void bt_wait_b_busy(void) unsigned int count = 1000; while (IPMI_BT_CTLREG_GET_B_BUSY() != 0) { g_assert(--count != 0); + usleep(100); } } @@ -107,6 +108,7 @@ static void bt_wait_b2h_atn(void) unsigned int count = 1000; while (IPMI_BT_CTLREG_GET_B2H_ATN() == 0) { g_assert(--count != 0); + usleep(100); } } @@ -240,13 +242,13 @@ static void emu_msg_handler(void) write_emu_msg(msg, msg_len); } else if ((msg[1] == set_bmc_globals_cmd[0]) && (msg[2] == set_bmc_globals_cmd[1])) { + write_emu_msg(enable_irq_cmd, sizeof(enable_irq_cmd)); memcpy(msg + 1, set_bmc_globals_rsp, sizeof(set_bmc_globals_rsp)); msg_len = sizeof(set_bmc_globals_rsp) + 1; msg[msg_len] = -ipmb_checksum(msg, msg_len, 0); msg_len++; msg[msg_len++] = 0xa0; write_emu_msg(msg, msg_len); - write_emu_msg(enable_irq_cmd, sizeof(enable_irq_cmd)); } else { g_assert(0); } From patchwork Thu Sep 19 21:39:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164914 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZkPB2Qv/"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9sQ1g5Xz9sPV for ; Fri, 20 Sep 2019 08:06:02 +1000 (AEST) Received: from localhost ([::1]:48932 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4Yp-0003QD-EO for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:05:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56280) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49b-0001Xm-6T for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49Q-0006AN-3q for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from mail-oi1-x243.google.com ([2607:f8b0:4864:20::243]:46631) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49P-0006AC-TQ for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:44 -0400 Received: by mail-oi1-x243.google.com with SMTP id k25so3980224oiw.13 for ; Thu, 19 Sep 2019 14:39:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gWzJgnmTsjgDALss2ZvZftEVRHxBMzzLKAhMT/OJ2C4=; b=ZkPB2Qv/ZTphNpr1Cclbl3gSK3dZziExaL0MZGDcu14/ggovvDLoCqNMeeng7b5b2r PHSWJn9qIh6Ujt9mZnbKfVA8Y0egX9Ix5dMJr11C/8mckWjSVf0LuiOtJ7fGzDVKUopu wrD1LZ17BvJBm0C/HZOLsjKTn7HUe+tjMO19ki6RSwd9nI9clh4e96zISBLlGtxRdZdj LODrkSMe9fOZyH0zYDEwnui6mZ3pbMGe4Q7ZOCu5NtAJ08sGjtorTbBlOAc7sJ0U3O41 sKaU5pig5DkOD8ipzGuGxPWjzOE0+e0AN6z0TIAmeZbrVN3EFQCxN52HyfFxGqwdh6Yt Oqyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=gWzJgnmTsjgDALss2ZvZftEVRHxBMzzLKAhMT/OJ2C4=; b=lQF7fTU01lUorYT2cx0VDP2mCyZVN0lismbqKwYzMmbsCnxC9vfJGmIC6p7TnfPwNC NdpZJ/Xv8oAw4EDdJ21Dmls2Kq4ZqcO9OP+OLxjxCVoTZ1ShohZ3m1T2+9WCLpxMVmM0 DAdQq9SauS0vsfi9vK2OuodaEEDthxQ8H9/+nAAS0l1JIUum+ILjiKeqej1a7wIAFyef RTZWXPg6nVg6+fdUtZVjCKdX2ESblUzrq4DW4dqyKTA/KGe1XTidV/cjaBZmUDx+kGZy Px2rku4SN7DRQCPlgCmm1Vvfjf9yIqeVFd1VZUojr4vj43gyyIpx4ummk1Hpzq5Et1xC Je3Q== X-Gm-Message-State: APjAAAWZLgyOdcRPkmgGpfHxVDKhYy12Mm/ngjGztklAZs0KxSgtMpjA w2nc16PEwregkFOPa2kwMg== X-Google-Smtp-Source: APXvYqyQ2lfqpjjaLX6qhYLtBAa2f+Bq/a8RtqwE2Z8IalQXEMAvxn3ouTVqfzjEf4vI/h7jvpsbPQ== X-Received: by 2002:aca:4cf:: with SMTP id 198mr22057oie.109.1568929183027; Thu, 19 Sep 2019 14:39:43 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id 8sm35705oti.41.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 37AEE18059E; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 05/15] qdev: Add a no default uuid property Date: Thu, 19 Sep 2019 16:39:14 -0500 Message-Id: <20190919213924.31852-6-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::243 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard This is for IPMI, which will behave differently if the UUID is not set. Signed-off-by: Corey Minyard Cc: Fam Zheng Cc: Michael S. Tsirkin Cc: Marc-André Lureau Reviewed-by: Cédric Le Goater --- include/hw/qdev-properties.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 2e98dd60db..c6a8cb5516 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -238,6 +238,13 @@ extern const PropertyInfo qdev_prop_pcie_link_width; #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard) +#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) { \ + .name = (_name), \ + .info = &qdev_prop_uuid, \ + .offset = offsetof(_state, _field) \ + + type_check(QemuUUID, typeof_field(_state, _field)), \ + } + #define DEFINE_PROP_END_OF_LIST() \ {} From patchwork Thu Sep 19 21:39:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164903 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="MODA8HxX"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9YK23bzz9sNk for ; Fri, 20 Sep 2019 07:52:05 +1000 (AEST) Received: from localhost ([::1]:48814 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4LK-0004nb-Vr for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:52:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56279) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49b-0001Xl-5v for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49Q-0006BE-Mw for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:51 -0400 Received: from mail-ot1-x341.google.com ([2607:f8b0:4864:20::341]:39887) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49Q-0006AJ-5s for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:44 -0400 Received: by mail-ot1-x341.google.com with SMTP id s22so4450325otr.6 for ; Thu, 19 Sep 2019 14:39:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1Pjbx+Wnn2Hez+/RZX8qjdxBLtlG9/L1XOZzyZuYu4E=; b=MODA8HxXoAYEdS4G0BA48XGwsbtCnWYQVWR43SedkHgX/TRCQ92Hf6ZUyT7la6IQFn dZHdLVF5cBp1IbVFScdVamBB+B9oyuhovd2pHDYNY6pS8niXCWW1uKrrlzNyMT1vlooA qj6UOIjipB3FbhE3N1VpxOIUDPD8S3iGHZ9ToPRZRU5hbzbMnF5Tm703SS0uDKTIVMl4 G24VwjvZ1D9IkWt7+Cgh/6QW1kdm711cLb/8ZnT9mWLudh2VMs1hDylGd1sN6jKOQOU6 KL6KjL897xls0xwFwNC7lCWJWZ9esvBtBblML4+9h/jdVWUeQ5CAvLUs4N5vufZpdeOC Mlsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=1Pjbx+Wnn2Hez+/RZX8qjdxBLtlG9/L1XOZzyZuYu4E=; b=MmQSXf+/9Yvsl6356idZLpASoBE4uO1X5zUiwSHHCi0yO9OR46mJRPV7yDPXCrEBPy mkCTIxBEy36E2xoWo+ey0ssRlDHUHbhwSqvi6rQAGxaCcvdKEV+sgOT2/NCXyFnch+Od jnRLQsUnwdcyW5RF303XKeK3K20eoxsZVK9oUea6t6e1d5cC4tyMyjbiHP+4LDXAtqHL AvO9TawynPK/ZizAumWB2pxTyCVDiXkR7Yb456MTNoYWNpOtVfkpuOINjlYY9TcXtuUR h/ZWA9aEMU9samqd/MATHL+fmIZlAd2V4kXfZ39oHUGPdTp7TFnZSMubd6CBpXo9U4op VSkw== X-Gm-Message-State: APjAAAUoFbXvLNEhXyOpzEAKYcmDRe5WnYGxVuR4O8Ligs/G29exWcxA /EHjZoSM6uiqpponQtPErQ== X-Google-Smtp-Source: APXvYqy2nMQwTTCAwQR7z41kN7M6OtBeDHlstB/6r5GnC89fgbOiY/G1VwwyHjIC3RRqTq+GuXgt8A== X-Received: by 2002:a9d:2901:: with SMTP id d1mr8948253otb.285.1568929183379; Thu, 19 Sep 2019 14:39:43 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id b4sm33766oiy.30.2019.09.19.14.39.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 5C61B18059F; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 06/15] ipmi: Add a UUID device property Date: Thu, 19 Sep 2019 16:39:15 -0500 Message-Id: <20190919213924.31852-7-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::341 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Using the UUID that qemu generates probably isn't the best thing to do, allow it to be passed in via properties, and use QemuUUID for the type. If the UUID is not set, return an unsupported command error. This way we are not providing an all-zero (or randomly generated) GUID to the IPMI user. This lets the host fall back to the other method of using the get device id command to determind the BMC being accessed. Signed-off-by: Corey Minyard Cc: Cédric Le Goater Cc: David Gibson Cc: Michael S. Tsirkin Cc: Paolo Bonzini Reviewed-by: Cédric Le Goater --- hw/ipmi/ipmi_bmc_sim.c | 22 ++++++++++++++-------- qemu-options.hx | 10 +++++++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c index 6e6cd1b47d..71e56f3b13 100644 --- a/hw/ipmi/ipmi_bmc_sim.c +++ b/hw/ipmi/ipmi_bmc_sim.c @@ -223,7 +223,7 @@ struct IPMIBmcSim { uint8_t restart_cause; uint8_t acpi_power_state[2]; - uint8_t uuid[16]; + QemuUUID uuid; IPMISel sel; IPMISdr sdr; @@ -941,8 +941,19 @@ static void get_device_guid(IPMIBmcSim *ibs, { unsigned int i; + /* An uninitialized uuid is all zeros, use that to know if it is set. */ for (i = 0; i < 16; i++) { - rsp_buffer_push(rsp, ibs->uuid[i]); + if (ibs->uuid.data[i]) { + goto uuid_set; + } + } + /* No uuid is set, return an error. */ + rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD); + return; + + uuid_set: + for (i = 0; i < 16; i++) { + rsp_buffer_push(rsp, ibs->uuid.data[i]); } } @@ -1986,12 +1997,6 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp) ibs->acpi_power_state[0] = 0; ibs->acpi_power_state[1] = 0; - if (qemu_uuid_set) { - memcpy(&ibs->uuid, &qemu_uuid, 16); - } else { - memset(&ibs->uuid, 0, 16); - } - ipmi_init_sensors_from_sdrs(ibs); register_cmds(ibs); @@ -2011,6 +2016,7 @@ static Property ipmi_sim_properties[] = { DEFINE_PROP_UINT8("fwrev2", IPMIBmcSim, fwrev2, 0), DEFINE_PROP_UINT32("mfg_id", IPMIBmcSim, mfg_id, 0), DEFINE_PROP_UINT16("product_id", IPMIBmcSim, product_id, 0), + DEFINE_PROP_UUID_NODEFAULT("guid", IPMIBmcSim, uuid), DEFINE_PROP_END_OF_LIST(), }; diff --git a/qemu-options.hx b/qemu-options.hx index bbfd936d29..ed9292f65e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -701,7 +701,7 @@ possible drivers and properties, use @code{-device help} and @code{-device @var{driver},help}. Some drivers are: -@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}][,furareasize=@var{val}][,furdatafile=@var{file}] +@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}][,furareasize=@var{val}][,furdatafile=@var{file}][,guid=@var{uuid}] Add an IPMI BMC. This is a simulation of a hardware management interface processor that normally sits on a system. It provides @@ -714,8 +714,8 @@ controllers. If you don't know what this means, it is safe to ignore it. @table @option -@item bmc=@var{id} -The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above. +@item id=@var{id} +The BMC id for interfaces to use this device. @item slave_addr=@var{val} Define slave address to use for the BMC. The default is 0x20. @item sdrfile=@var{file} @@ -724,6 +724,10 @@ file containing raw Sensor Data Records (SDR) data. The default is none. size of a Field Replaceable Unit (FRU) area. The default is 1024. @item frudatafile=@var{file} file containing raw Field Replaceable Unit (FRU) inventory data. The default is none. +@item guid=@var{uuid} +value for the GUID for the BMC, in standard UUID format. If this is set, +get "Get GUID" command to the BMC will return it. Otherwise "Get GUID" +will return an error. @end table @item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}] From patchwork Thu Sep 19 21:39:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164910 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mvVcZVEd"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9jP2bxFz9sCJ for ; Fri, 20 Sep 2019 07:59:05 +1000 (AEST) Received: from localhost ([::1]:48864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4S6-0004oA-Em for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:59:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56295) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49f-0001Z0-S1 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49R-0006C4-VX for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:55 -0400 Received: from mail-ot1-x344.google.com ([2607:f8b0:4864:20::344]:33391) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49R-0006BA-6J for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:45 -0400 Received: by mail-ot1-x344.google.com with SMTP id g25so4486110otl.0 for ; Thu, 19 Sep 2019 14:39:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8rVa9CFTYqJ95fuPu+QB6hOLbcYInouzovgeRrSODuo=; b=mvVcZVEdrItYKdmJKrYyGWmNRJVXmDbRQTs4nQUpZ7Jvb3kLbqKO6kyDczMMikrGaM Jl0M3gEZOL6AVgaDilFHANJAeKnuznq8f4d7SrIMg6dYd/p5fVOn6mGQH759LzlG6fTb oZ8FQC3Jmr7lWz1iMFOr5H8jLjKQdmAI/CP0U6VR913mahxAr7c4eRVo4cxH7rC4jy+m KcEIHG/70QfS7qTv/6a+XUkaKP6BE3DWNVLIOTE9TzRlXjLWZMb9b2jH954uVYbWFhpU ExrqfOGXQAEVasfGtyAK6ZLFyVclg9KjDAfvvNkZyrWPeDV5zGFX0GqiacB6CtxWSPk2 EiDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=8rVa9CFTYqJ95fuPu+QB6hOLbcYInouzovgeRrSODuo=; b=ZSnJiz2w4WfZri9EVFfXzNoy7/wkFIuq4EANZnn1ngHP0qqsYdJ9iK7oAxUNfelHT+ 8Jss2PjDXl+dTD/PLTIcXAYUkmSXRe7mqI6gFlX3SmFxcTu8KmwgMTcz5v2YlA55I7Js b/VAew1jCz0oOik0YFOZ0Rugz89pTdiO1B1eW5refO+2sBNUoBBi983LRQ3uwwTEJY2M xLSyAtLjOnMbnDCP64df4b4+5zGd3hG9/YBQpp3EQl4FarGl6O7L90J4KDyFqe9sQEzW jR7Kqtrrgh5NeGsB7uYrERra+iiewhh0Q7h0d834fTiTTHVMNw/wkFIWOgDd/lE+PpjL OjZw== X-Gm-Message-State: APjAAAWMMGsEpxIZ/bJyWTI5AIq6m5B50kKkbR+hpOn98bJjeCL9m6bA BwSKVCtjA5PNgLmYjDlq0g== X-Google-Smtp-Source: APXvYqyMcCQ06/DBrZfFypYoY0oQMLHY9YPp24vioNDJLj2QOZQ4OLbj2Qz3nxtvS1HDHjKXe8BuVA== X-Received: by 2002:a05:6830:134b:: with SMTP id r11mr4365530otq.154.1568929183699; Thu, 19 Sep 2019 14:39:43 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id o184sm40134oia.28.2019.09.19.14.39.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 7B1301805A0; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 07/15] ipmi: Split out KCS-specific code from ISA KCS code Date: Thu, 19 Sep 2019 16:39:16 -0500 Message-Id: <20190919213924.31852-8-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::344 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Get ready for PCI and other KCS interfaces. No functional changes, just split the code into the generic KCS code and the ISA-specific code. Signed-off-by: Corey Minyard Reviewed-by: Philippe Mathieu-Daudé --- hw/ipmi/Makefile.objs | 2 +- hw/ipmi/ipmi_kcs.c | 408 ++++++++++++++++++++++++++++++++++++ hw/ipmi/isa_ipmi_kcs.c | 417 ++----------------------------------- include/hw/ipmi/ipmi_kcs.h | 75 +++++++ 4 files changed, 505 insertions(+), 397 deletions(-) create mode 100644 hw/ipmi/ipmi_kcs.c create mode 100644 include/hw/ipmi/ipmi_kcs.h diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 1b422bbee0..6835d2f64a 100644 --- a/hw/ipmi/Makefile.objs +++ b/hw/ipmi/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-$(CONFIG_IPMI) += ipmi.o +common-obj-$(CONFIG_IPMI) += ipmi.o ipmi_kcs.o common-obj-$(CONFIG_IPMI_LOCAL) += ipmi_bmc_sim.o common-obj-$(CONFIG_IPMI_EXTERN) += ipmi_bmc_extern.o common-obj-$(CONFIG_ISA_IPMI_KCS) += isa_ipmi_kcs.o diff --git a/hw/ipmi/ipmi_kcs.c b/hw/ipmi/ipmi_kcs.c new file mode 100644 index 0000000000..dab1af8bc8 --- /dev/null +++ b/hw/ipmi/ipmi_kcs.c @@ -0,0 +1,408 @@ +/* + * QEMU IPMI KCS emulation + * + * Copyright (c) 2015,2017 Corey Minyard, MontaVista Software, LLC + * + * 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 "migration/vmstate.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/ipmi/ipmi_kcs.h" + +#define IPMI_KCS_OBF_BIT 0 +#define IPMI_KCS_IBF_BIT 1 +#define IPMI_KCS_SMS_ATN_BIT 2 +#define IPMI_KCS_CD_BIT 3 + +#define IPMI_KCS_OBF_MASK (1 << IPMI_KCS_OBF_BIT) +#define IPMI_KCS_GET_OBF(d) (((d) >> IPMI_KCS_OBF_BIT) & 0x1) +#define IPMI_KCS_SET_OBF(d, v) (d) = (((d) & ~IPMI_KCS_OBF_MASK) | \ + (((v) & 1) << IPMI_KCS_OBF_BIT)) +#define IPMI_KCS_IBF_MASK (1 << IPMI_KCS_IBF_BIT) +#define IPMI_KCS_GET_IBF(d) (((d) >> IPMI_KCS_IBF_BIT) & 0x1) +#define IPMI_KCS_SET_IBF(d, v) (d) = (((d) & ~IPMI_KCS_IBF_MASK) | \ + (((v) & 1) << IPMI_KCS_IBF_BIT)) +#define IPMI_KCS_SMS_ATN_MASK (1 << IPMI_KCS_SMS_ATN_BIT) +#define IPMI_KCS_GET_SMS_ATN(d) (((d) >> IPMI_KCS_SMS_ATN_BIT) & 0x1) +#define IPMI_KCS_SET_SMS_ATN(d, v) (d) = (((d) & ~IPMI_KCS_SMS_ATN_MASK) | \ + (((v) & 1) << IPMI_KCS_SMS_ATN_BIT)) +#define IPMI_KCS_CD_MASK (1 << IPMI_KCS_CD_BIT) +#define IPMI_KCS_GET_CD(d) (((d) >> IPMI_KCS_CD_BIT) & 0x1) +#define IPMI_KCS_SET_CD(d, v) (d) = (((d) & ~IPMI_KCS_CD_MASK) | \ + (((v) & 1) << IPMI_KCS_CD_BIT)) + +#define IPMI_KCS_IDLE_STATE 0 +#define IPMI_KCS_READ_STATE 1 +#define IPMI_KCS_WRITE_STATE 2 +#define IPMI_KCS_ERROR_STATE 3 + +#define IPMI_KCS_GET_STATE(d) (((d) >> 6) & 0x3) +#define IPMI_KCS_SET_STATE(d, v) ((d) = ((d) & ~0xc0) | (((v) & 0x3) << 6)) + +#define IPMI_KCS_ABORT_STATUS_CMD 0x60 +#define IPMI_KCS_WRITE_START_CMD 0x61 +#define IPMI_KCS_WRITE_END_CMD 0x62 +#define IPMI_KCS_READ_CMD 0x68 + +#define IPMI_KCS_STATUS_NO_ERR 0x00 +#define IPMI_KCS_STATUS_ABORTED_ERR 0x01 +#define IPMI_KCS_STATUS_BAD_CC_ERR 0x02 +#define IPMI_KCS_STATUS_LENGTH_ERR 0x06 + +static void ipmi_kcs_raise_irq(IPMIKCS *ik) +{ + if (ik->use_irq && ik->irqs_enabled && ik->raise_irq) { + ik->raise_irq(ik); + } +} + +static void ipmi_kcs_lower_irq(IPMIKCS *ik) +{ + if (ik->lower_irq) { + ik->lower_irq(ik); + } +} + +#define SET_OBF() \ + do { \ + IPMI_KCS_SET_OBF(ik->status_reg, 1); \ + if (!ik->obf_irq_set) { \ + ik->obf_irq_set = 1; \ + if (!ik->atn_irq_set) { \ + ipmi_kcs_raise_irq(ik); \ + } \ + } \ + } while (0) + +static void ipmi_kcs_signal(IPMIKCS *ik, IPMIInterface *ii) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + + ik->do_wake = 1; + while (ik->do_wake) { + ik->do_wake = 0; + iic->handle_if_event(ii); + } +} + +static void ipmi_kcs_handle_event(IPMIInterface *ii) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + if (ik->cmd_reg == IPMI_KCS_ABORT_STATUS_CMD) { + if (IPMI_KCS_GET_STATE(ik->status_reg) != IPMI_KCS_ERROR_STATE) { + ik->waiting_rsp++; /* Invalidate the message */ + ik->outmsg[0] = IPMI_KCS_STATUS_ABORTED_ERR; + ik->outlen = 1; + ik->outpos = 0; + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); + SET_OBF(); + } + goto out; + } + + switch (IPMI_KCS_GET_STATE(ik->status_reg)) { + case IPMI_KCS_IDLE_STATE: + if (ik->cmd_reg == IPMI_KCS_WRITE_START_CMD) { + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_WRITE_STATE); + ik->cmd_reg = -1; + ik->write_end = 0; + ik->inlen = 0; + SET_OBF(); + } + break; + + case IPMI_KCS_READ_STATE: + handle_read: + if (ik->outpos >= ik->outlen) { + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_IDLE_STATE); + SET_OBF(); + } else if (ik->data_in_reg == IPMI_KCS_READ_CMD) { + ik->data_out_reg = ik->outmsg[ik->outpos]; + ik->outpos++; + SET_OBF(); + } else { + ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; + ik->outlen = 1; + ik->outpos = 0; + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); + SET_OBF(); + goto out; + } + break; + + case IPMI_KCS_WRITE_STATE: + if (ik->data_in_reg != -1) { + /* + * Don't worry about input overrun here, that will be + * handled in the BMC. + */ + if (ik->inlen < sizeof(ik->inmsg)) { + ik->inmsg[ik->inlen] = ik->data_in_reg; + } + ik->inlen++; + } + if (ik->write_end) { + IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(ik->bmc); + ik->outlen = 0; + ik->write_end = 0; + ik->outpos = 0; + bk->handle_command(ik->bmc, ik->inmsg, ik->inlen, sizeof(ik->inmsg), + ik->waiting_rsp); + goto out_noibf; + } else if (ik->cmd_reg == IPMI_KCS_WRITE_END_CMD) { + ik->cmd_reg = -1; + ik->write_end = 1; + } + SET_OBF(); + break; + + case IPMI_KCS_ERROR_STATE: + if (ik->data_in_reg != -1) { + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); + ik->data_in_reg = IPMI_KCS_READ_CMD; + goto handle_read; + } + break; + } + + if (ik->cmd_reg != -1) { + /* Got an invalid command */ + ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; + ik->outlen = 1; + ik->outpos = 0; + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); + } + + out: + ik->cmd_reg = -1; + ik->data_in_reg = -1; + IPMI_KCS_SET_IBF(ik->status_reg, 0); + out_noibf: + return; +} + +static void ipmi_kcs_handle_rsp(IPMIInterface *ii, uint8_t msg_id, + unsigned char *rsp, unsigned int rsp_len) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + if (ik->waiting_rsp == msg_id) { + ik->waiting_rsp++; + if (rsp_len > sizeof(ik->outmsg)) { + ik->outmsg[0] = rsp[0]; + ik->outmsg[1] = rsp[1]; + ik->outmsg[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; + ik->outlen = 3; + } else { + memcpy(ik->outmsg, rsp, rsp_len); + ik->outlen = rsp_len; + } + IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); + ik->data_in_reg = IPMI_KCS_READ_CMD; + ipmi_kcs_signal(ik, ii); + } +} + + +static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) +{ + IPMIInterface *ii = opaque; + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + uint32_t ret; + + switch (addr & 1) { + case 0: + ret = ik->data_out_reg; + IPMI_KCS_SET_OBF(ik->status_reg, 0); + if (ik->obf_irq_set) { + ik->obf_irq_set = 0; + if (!ik->atn_irq_set) { + ipmi_kcs_lower_irq(ik); + } + } + break; + case 1: + ret = ik->status_reg; + if (ik->atn_irq_set) { + ik->atn_irq_set = 0; + if (!ik->obf_irq_set) { + ipmi_kcs_lower_irq(ik); + } + } + break; + } + return ret; +} + +static void ipmi_kcs_ioport_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + IPMIInterface *ii = opaque; + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + if (IPMI_KCS_GET_IBF(ik->status_reg)) { + return; + } + + switch (addr & 1) { + case 0: + ik->data_in_reg = val; + break; + + case 1: + ik->cmd_reg = val; + break; + } + IPMI_KCS_SET_IBF(ik->status_reg, 1); + ipmi_kcs_signal(ik, ii); +} + +const MemoryRegionOps ipmi_kcs_io_ops = { + .read = ipmi_kcs_ioport_read, + .write = ipmi_kcs_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void ipmi_kcs_set_atn(IPMIInterface *ii, int val, int irq) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + IPMI_KCS_SET_SMS_ATN(ik->status_reg, val); + if (val) { + if (irq && !ik->atn_irq_set) { + ik->atn_irq_set = 1; + if (!ik->obf_irq_set) { + ipmi_kcs_raise_irq(ik); + } + } + } else { + if (ik->atn_irq_set) { + ik->atn_irq_set = 0; + if (!ik->obf_irq_set) { + ipmi_kcs_lower_irq(ik); + } + } + } +} + +static void ipmi_kcs_set_irq_enable(IPMIInterface *ii, int val) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + ik->irqs_enabled = val; +} + +static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIKCS *ik = iic->get_backend_data(ii); + + ik->io_length = 2; + memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); +} + +int ipmi_kcs_vmstate_post_load(void *opaque, int version) +{ + IPMIKCS *ik = opaque; + + /* Make sure all the values are sane. */ + if (ik->outpos >= MAX_IPMI_MSG_SIZE || ik->outlen >= MAX_IPMI_MSG_SIZE || + ik->outpos >= ik->outlen) { + qemu_log_mask(LOG_GUEST_ERROR, + "ipmi:kcs: vmstate transfer received bad out values: %d %d\n", + ik->outpos, ik->outlen); + ik->outpos = 0; + ik->outlen = 0; + } + + if (ik->inlen >= MAX_IPMI_MSG_SIZE) { + qemu_log_mask(LOG_GUEST_ERROR, + "ipmi:kcs: vmstate transfer received bad in value: %d\n", + ik->inlen); + ik->inlen = 0; + } + + return 0; +} + +static bool vmstate_kcs_before_version2(void *opaque, int version) +{ + return version <= 1; +} + +const VMStateDescription vmstate_IPMIKCS = { + .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", + .version_id = 2, + .minimum_version_id = 1, + .post_load = ipmi_kcs_vmstate_post_load, + .fields = (VMStateField[]) { + VMSTATE_BOOL(obf_irq_set, IPMIKCS), + VMSTATE_BOOL(atn_irq_set, IPMIKCS), + VMSTATE_UNUSED_TEST(vmstate_kcs_before_version2, 1), /* Was use_irq */ + VMSTATE_BOOL(irqs_enabled, IPMIKCS), + VMSTATE_UINT32(outpos, IPMIKCS), + VMSTATE_UINT32_V(outlen, IPMIKCS, 2), + VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), + VMSTATE_UINT32_V(inlen, IPMIKCS, 2), + VMSTATE_UINT8_ARRAY(inmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), + VMSTATE_BOOL(write_end, IPMIKCS), + VMSTATE_UINT8(status_reg, IPMIKCS), + VMSTATE_UINT8(data_out_reg, IPMIKCS), + VMSTATE_INT16(data_in_reg, IPMIKCS), + VMSTATE_INT16(cmd_reg, IPMIKCS), + VMSTATE_UINT8(waiting_rsp, IPMIKCS), + VMSTATE_END_OF_LIST() + } +}; + +void ipmi_kcs_get_fwinfo(IPMIKCS *ik, IPMIFwInfo *info) +{ + info->interface_name = "kcs"; + info->interface_type = IPMI_SMBIOS_KCS; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = ik->io_base; + info->i2c_slave_address = ik->bmc->slave_addr; + info->register_length = ik->io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; +} + +void ipmi_kcs_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_kcs_init; + iic->set_atn = ipmi_kcs_set_atn; + iic->handle_rsp = ipmi_kcs_handle_rsp; + iic->handle_if_event = ipmi_kcs_handle_event; + iic->set_irq_enable = ipmi_kcs_set_irq_enable; +} diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 374b2a0709..8e32774f85 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -1,7 +1,7 @@ /* * QEMU ISA IPMI KCS emulation * - * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC + * Copyright (c) 2015,2017 Corey Minyard, MontaVista Software, LLC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,338 +26,12 @@ #include "qemu/log.h" #include "qemu/module.h" #include "qapi/error.h" -#include "hw/ipmi/ipmi.h" #include "hw/irq.h" +#include "hw/ipmi/ipmi_kcs.h" #include "hw/isa/isa.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -#define IPMI_KCS_OBF_BIT 0 -#define IPMI_KCS_IBF_BIT 1 -#define IPMI_KCS_SMS_ATN_BIT 2 -#define IPMI_KCS_CD_BIT 3 - -#define IPMI_KCS_OBF_MASK (1 << IPMI_KCS_OBF_BIT) -#define IPMI_KCS_GET_OBF(d) (((d) >> IPMI_KCS_OBF_BIT) & 0x1) -#define IPMI_KCS_SET_OBF(d, v) (d) = (((d) & ~IPMI_KCS_OBF_MASK) | \ - (((v) & 1) << IPMI_KCS_OBF_BIT)) -#define IPMI_KCS_IBF_MASK (1 << IPMI_KCS_IBF_BIT) -#define IPMI_KCS_GET_IBF(d) (((d) >> IPMI_KCS_IBF_BIT) & 0x1) -#define IPMI_KCS_SET_IBF(d, v) (d) = (((d) & ~IPMI_KCS_IBF_MASK) | \ - (((v) & 1) << IPMI_KCS_IBF_BIT)) -#define IPMI_KCS_SMS_ATN_MASK (1 << IPMI_KCS_SMS_ATN_BIT) -#define IPMI_KCS_GET_SMS_ATN(d) (((d) >> IPMI_KCS_SMS_ATN_BIT) & 0x1) -#define IPMI_KCS_SET_SMS_ATN(d, v) (d) = (((d) & ~IPMI_KCS_SMS_ATN_MASK) | \ - (((v) & 1) << IPMI_KCS_SMS_ATN_BIT)) -#define IPMI_KCS_CD_MASK (1 << IPMI_KCS_CD_BIT) -#define IPMI_KCS_GET_CD(d) (((d) >> IPMI_KCS_CD_BIT) & 0x1) -#define IPMI_KCS_SET_CD(d, v) (d) = (((d) & ~IPMI_KCS_CD_MASK) | \ - (((v) & 1) << IPMI_KCS_CD_BIT)) - -#define IPMI_KCS_IDLE_STATE 0 -#define IPMI_KCS_READ_STATE 1 -#define IPMI_KCS_WRITE_STATE 2 -#define IPMI_KCS_ERROR_STATE 3 - -#define IPMI_KCS_GET_STATE(d) (((d) >> 6) & 0x3) -#define IPMI_KCS_SET_STATE(d, v) ((d) = ((d) & ~0xc0) | (((v) & 0x3) << 6)) - -#define IPMI_KCS_ABORT_STATUS_CMD 0x60 -#define IPMI_KCS_WRITE_START_CMD 0x61 -#define IPMI_KCS_WRITE_END_CMD 0x62 -#define IPMI_KCS_READ_CMD 0x68 - -#define IPMI_KCS_STATUS_NO_ERR 0x00 -#define IPMI_KCS_STATUS_ABORTED_ERR 0x01 -#define IPMI_KCS_STATUS_BAD_CC_ERR 0x02 -#define IPMI_KCS_STATUS_LENGTH_ERR 0x06 - -typedef struct IPMIKCS { - IPMIBmc *bmc; - - bool do_wake; - - qemu_irq irq; - - uint32_t io_base; - unsigned long io_length; - MemoryRegion io; - - bool obf_irq_set; - bool atn_irq_set; - bool use_irq; - bool irqs_enabled; - - uint8_t outmsg[MAX_IPMI_MSG_SIZE]; - uint32_t outpos; - uint32_t outlen; - - uint8_t inmsg[MAX_IPMI_MSG_SIZE]; - uint32_t inlen; - bool write_end; - - uint8_t status_reg; - uint8_t data_out_reg; - - int16_t data_in_reg; /* -1 means not written */ - int16_t cmd_reg; - - /* - * This is a response number that we send with the command to make - * sure that the response matches the command. - */ - uint8_t waiting_rsp; -} IPMIKCS; - -#define SET_OBF() \ - do { \ - IPMI_KCS_SET_OBF(ik->status_reg, 1); \ - if (ik->use_irq && ik->irqs_enabled && !ik->obf_irq_set) { \ - ik->obf_irq_set = 1; \ - if (!ik->atn_irq_set) { \ - qemu_irq_raise(ik->irq); \ - } \ - } \ - } while (0) - -static void ipmi_kcs_signal(IPMIKCS *ik, IPMIInterface *ii) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - - ik->do_wake = 1; - while (ik->do_wake) { - ik->do_wake = 0; - iic->handle_if_event(ii); - } -} - -static void ipmi_kcs_handle_event(IPMIInterface *ii) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - if (ik->cmd_reg == IPMI_KCS_ABORT_STATUS_CMD) { - if (IPMI_KCS_GET_STATE(ik->status_reg) != IPMI_KCS_ERROR_STATE) { - ik->waiting_rsp++; /* Invalidate the message */ - ik->outmsg[0] = IPMI_KCS_STATUS_ABORTED_ERR; - ik->outlen = 1; - ik->outpos = 0; - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); - SET_OBF(); - } - goto out; - } - - switch (IPMI_KCS_GET_STATE(ik->status_reg)) { - case IPMI_KCS_IDLE_STATE: - if (ik->cmd_reg == IPMI_KCS_WRITE_START_CMD) { - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_WRITE_STATE); - ik->cmd_reg = -1; - ik->write_end = 0; - ik->inlen = 0; - SET_OBF(); - } - break; - - case IPMI_KCS_READ_STATE: - handle_read: - if (ik->outpos >= ik->outlen) { - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_IDLE_STATE); - SET_OBF(); - } else if (ik->data_in_reg == IPMI_KCS_READ_CMD) { - ik->data_out_reg = ik->outmsg[ik->outpos]; - ik->outpos++; - SET_OBF(); - } else { - ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; - ik->outlen = 1; - ik->outpos = 0; - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); - SET_OBF(); - goto out; - } - break; - - case IPMI_KCS_WRITE_STATE: - if (ik->data_in_reg != -1) { - /* - * Don't worry about input overrun here, that will be - * handled in the BMC. - */ - if (ik->inlen < sizeof(ik->inmsg)) { - ik->inmsg[ik->inlen] = ik->data_in_reg; - } - ik->inlen++; - } - if (ik->write_end) { - IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(ik->bmc); - ik->outlen = 0; - ik->write_end = 0; - ik->outpos = 0; - bk->handle_command(ik->bmc, ik->inmsg, ik->inlen, sizeof(ik->inmsg), - ik->waiting_rsp); - goto out_noibf; - } else if (ik->cmd_reg == IPMI_KCS_WRITE_END_CMD) { - ik->cmd_reg = -1; - ik->write_end = 1; - } - SET_OBF(); - break; - - case IPMI_KCS_ERROR_STATE: - if (ik->data_in_reg != -1) { - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); - ik->data_in_reg = IPMI_KCS_READ_CMD; - goto handle_read; - } - break; - } - - if (ik->cmd_reg != -1) { - /* Got an invalid command */ - ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; - ik->outlen = 1; - ik->outpos = 0; - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); - } - - out: - ik->cmd_reg = -1; - ik->data_in_reg = -1; - IPMI_KCS_SET_IBF(ik->status_reg, 0); - out_noibf: - return; -} - -static void ipmi_kcs_handle_rsp(IPMIInterface *ii, uint8_t msg_id, - unsigned char *rsp, unsigned int rsp_len) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - if (ik->waiting_rsp == msg_id) { - ik->waiting_rsp++; - if (rsp_len > sizeof(ik->outmsg)) { - ik->outmsg[0] = rsp[0]; - ik->outmsg[1] = rsp[1]; - ik->outmsg[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; - ik->outlen = 3; - } else { - memcpy(ik->outmsg, rsp, rsp_len); - ik->outlen = rsp_len; - } - IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); - ik->data_in_reg = IPMI_KCS_READ_CMD; - ipmi_kcs_signal(ik, ii); - } -} - - -static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) -{ - IPMIInterface *ii = opaque; - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - uint32_t ret; - - switch (addr & 1) { - case 0: - ret = ik->data_out_reg; - IPMI_KCS_SET_OBF(ik->status_reg, 0); - if (ik->obf_irq_set) { - ik->obf_irq_set = 0; - if (!ik->atn_irq_set) { - qemu_irq_lower(ik->irq); - } - } - break; - case 1: - ret = ik->status_reg; - if (ik->atn_irq_set) { - ik->atn_irq_set = 0; - if (!ik->obf_irq_set) { - qemu_irq_lower(ik->irq); - } - } - break; - } - return ret; -} - -static void ipmi_kcs_ioport_write(void *opaque, hwaddr addr, uint64_t val, - unsigned size) -{ - IPMIInterface *ii = opaque; - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - if (IPMI_KCS_GET_IBF(ik->status_reg)) { - return; - } - - switch (addr & 1) { - case 0: - ik->data_in_reg = val; - break; - - case 1: - ik->cmd_reg = val; - break; - } - IPMI_KCS_SET_IBF(ik->status_reg, 1); - ipmi_kcs_signal(ik, ii); -} - -const MemoryRegionOps ipmi_kcs_io_ops = { - .read = ipmi_kcs_ioport_read, - .write = ipmi_kcs_ioport_write, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static void ipmi_kcs_set_atn(IPMIInterface *ii, int val, int irq) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - IPMI_KCS_SET_SMS_ATN(ik->status_reg, val); - if (val) { - if (irq && !ik->atn_irq_set && ik->use_irq && ik->irqs_enabled) { - ik->atn_irq_set = 1; - if (!ik->obf_irq_set) { - qemu_irq_raise(ik->irq); - } - } - } else { - if (ik->atn_irq_set) { - ik->atn_irq_set = 0; - if (!ik->obf_irq_set) { - qemu_irq_lower(ik->irq); - } - } - } -} - -static void ipmi_kcs_set_irq_enable(IPMIInterface *ii, int val) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - ik->irqs_enabled = val; -} - -static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIKCS *ik = iic->get_backend_data(ii); - - ik->io_length = 2; - memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); -} - #define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs" #define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \ TYPE_ISA_IPMI_KCS) @@ -365,36 +39,32 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) typedef struct ISAIPMIKCSDevice { ISADevice dev; int32_t isairq; + qemu_irq irq; IPMIKCS kcs; uint32_t uuid; } ISAIPMIKCSDevice; -static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info) +static void isa_ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info) { ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii); - info->interface_name = "kcs"; - info->interface_type = IPMI_SMBIOS_KCS; - info->ipmi_spec_major_revision = 2; - info->ipmi_spec_minor_revision = 0; - info->base_address = iik->kcs.io_base; - info->i2c_slave_address = iik->kcs.bmc->slave_addr; - info->register_length = iik->kcs.io_length; - info->register_spacing = 1; - info->memspace = IPMI_MEMSPACE_IO; - info->irq_type = IPMI_LEVEL_IRQ; + ipmi_kcs_get_fwinfo(&iik->kcs, info); info->interrupt_number = iik->isairq; info->uuid = iik->uuid; } -static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) +static void isa_ipmi_kcs_raise_irq(IPMIKCS *ik) { - iic->init = ipmi_kcs_init; - iic->set_atn = ipmi_kcs_set_atn; - iic->handle_rsp = ipmi_kcs_handle_rsp; - iic->handle_if_event = ipmi_kcs_handle_event; - iic->set_irq_enable = ipmi_kcs_set_irq_enable; - iic->get_fwinfo = ipmi_kcs_get_fwinfo; + ISAIPMIKCSDevice *iik = ik->opaque; + + qemu_irq_raise(iik->irq); +} + +static void isa_ipmi_kcs_lower_irq(IPMIKCS *ik) +{ + ISAIPMIKCSDevice *iik = ik->opaque; + + qemu_irq_lower(iik->irq); } static void ipmi_isa_realize(DeviceState *dev, Error **errp) @@ -412,14 +82,17 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) iik->uuid = ipmi_next_uuid(); iik->kcs.bmc->intf = ii; + iik->kcs.opaque = iik; iic->init(ii, errp); if (*errp) return; if (iik->isairq > 0) { - isa_init_irq(isadev, &iik->kcs.irq, iik->isairq); + isa_init_irq(isadev, &iik->irq, iik->isairq); iik->kcs.use_irq = 1; + iik->kcs.raise_irq = isa_ipmi_kcs_raise_irq; + iik->kcs.lower_irq = isa_ipmi_kcs_lower_irq; } qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length); @@ -427,60 +100,11 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); } -static int ipmi_kcs_vmstate_post_load(void *opaque, int version) -{ - IPMIKCS *ik = opaque; - - /* Make sure all the values are sane. */ - if (ik->outpos >= MAX_IPMI_MSG_SIZE || ik->outlen >= MAX_IPMI_MSG_SIZE || - ik->outpos >= ik->outlen) { - qemu_log_mask(LOG_GUEST_ERROR, - "ipmi:kcs: vmstate transfer received bad out values: %d %d\n", - ik->outpos, ik->outlen); - ik->outpos = 0; - ik->outlen = 0; - } - - if (ik->inlen >= MAX_IPMI_MSG_SIZE) { - qemu_log_mask(LOG_GUEST_ERROR, - "ipmi:kcs: vmstate transfer received bad in value: %d\n", - ik->inlen); - ik->inlen = 0; - } - - return 0; -} - static bool vmstate_kcs_before_version2(void *opaque, int version) { return version <= 1; } -static const VMStateDescription vmstate_IPMIKCS = { - .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", - .version_id = 2, - .minimum_version_id = 1, - .post_load = ipmi_kcs_vmstate_post_load, - .fields = (VMStateField[]) { - VMSTATE_BOOL(obf_irq_set, IPMIKCS), - VMSTATE_BOOL(atn_irq_set, IPMIKCS), - VMSTATE_UNUSED_TEST(vmstate_kcs_before_version2, 1), /* Was use_irq */ - VMSTATE_BOOL(irqs_enabled, IPMIKCS), - VMSTATE_UINT32(outpos, IPMIKCS), - VMSTATE_UINT32_V(outlen, IPMIKCS, 2), - VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), - VMSTATE_UINT32_V(inlen, IPMIKCS, 2), - VMSTATE_UINT8_ARRAY(inmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), - VMSTATE_BOOL(write_end, IPMIKCS), - VMSTATE_UINT8(status_reg, IPMIKCS), - VMSTATE_UINT8(data_out_reg, IPMIKCS), - VMSTATE_INT16(data_in_reg, IPMIKCS), - VMSTATE_INT16(cmd_reg, IPMIKCS), - VMSTATE_UINT8(waiting_rsp, IPMIKCS), - VMSTATE_END_OF_LIST() - } -}; - static const VMStateDescription vmstate_ISAIPMIKCSDevice = { .name = TYPE_IPMI_INTERFACE, .version_id = 2, @@ -531,6 +155,7 @@ static void isa_ipmi_kcs_class_init(ObjectClass *oc, void *data) iic->get_backend_data = isa_ipmi_kcs_get_backend_data; ipmi_kcs_class_init(iic); + iic->get_fwinfo = isa_ipmi_kcs_get_fwinfo; } static const TypeInfo isa_ipmi_kcs_info = { diff --git a/include/hw/ipmi/ipmi_kcs.h b/include/hw/ipmi/ipmi_kcs.h new file mode 100644 index 0000000000..91d76d08f4 --- /dev/null +++ b/include/hw/ipmi/ipmi_kcs.h @@ -0,0 +1,75 @@ +/* + * QEMU IPMI KCS emulation + * + * Copyright (c) 2015,2017 Corey Minyard, MontaVista Software, LLC + * + * 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. + */ + +#ifndef HW_IPMI_KCS_H +#define HW_IPMI_KCS_H + +#include "hw/ipmi/ipmi.h" + +typedef struct IPMIKCS { + IPMIBmc *bmc; + + bool do_wake; + + bool obf_irq_set; + bool atn_irq_set; + bool irqs_enabled; + + uint8_t outmsg[MAX_IPMI_MSG_SIZE]; + uint32_t outpos; + uint32_t outlen; + + uint8_t inmsg[MAX_IPMI_MSG_SIZE]; + uint32_t inlen; + bool write_end; + + uint8_t status_reg; + uint8_t data_out_reg; + + int16_t data_in_reg; /* -1 means not written */ + int16_t cmd_reg; + + /* + * This is a response number that we send with the command to make + * sure that the response matches the command. + */ + uint8_t waiting_rsp; + + uint32_t io_base; + unsigned long io_length; + MemoryRegion io; + + void (*raise_irq)(struct IPMIKCS *ik); + void (*lower_irq)(struct IPMIKCS *ik); + void *opaque; + + bool use_irq; +} IPMIKCS; + +void ipmi_kcs_get_fwinfo(IPMIKCS *ik, IPMIFwInfo *info); +void ipmi_kcs_class_init(IPMIInterfaceClass *iic); +extern const VMStateDescription vmstate_IPMIKCS; +int ipmi_kcs_vmstate_post_load(void *opaque, int version); + +#endif /* HW_IPMI_KCS_H */ From patchwork Thu Sep 19 21:39:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164918 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RI7gKIxT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9xg6xwrz9sPX for ; Fri, 20 Sep 2019 08:09:43 +1000 (AEST) Received: from localhost ([::1]:48982 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4cP-0007ST-EK for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:09:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56373) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49m-0001eR-TI for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49f-0006FF-M6 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:06 -0400 Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:35898) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49X-0006CP-VO for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:55 -0400 Received: by mail-ot1-x342.google.com with SMTP id 67so4471061oto.3 for ; Thu, 19 Sep 2019 14:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=boJaD5eMnHUdi/NC4fPiImECEPwSfx1CFjfaYYLNAMs=; b=RI7gKIxTdywCXrwztQrfhsFae0j35xo2bZ1ctdQK0ZwOjFEk2p0qs5dS6EP5tlQ7Tk VDapJAOfM/n3o11zVaytnNkKrrOPD2EAquA+qqckli5f+fX/0GAzFABwNghCc8OgzIb3 dsszFFDfGRWAllI0wcjho8qfpzxdGpOb5mimUfYF5EarFH+coCa8wOIR26PzktuqX1vb m1dwCEfa+PG2EWG4gN5tlfFGfTqjQ5VIDXKjFOjzeNFfI5HX9XICdGMMUNsgQU5UYk74 bmHGIvTHPEDB+mv4bZtOfCl1ThGna+AZKHBlgvrXMs2TBct86QTFpZ2fe1oQzZ05deuS BhPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=boJaD5eMnHUdi/NC4fPiImECEPwSfx1CFjfaYYLNAMs=; b=IPrYq1tudFq0Kai3ZOja1JIFQ10mPe0C8Hosh4DazZZA88BY8gLgSGo3S34jHhQP6+ cH4FiB/sE1IZwfrWyhLEvFH/MAyguCn+++OSOwXocJJLFV8L2oxQ3O6lTzivF/qOBZf1 FPWa2eGJ0GnqTJGIYNgYP98PxMWk47SyL2UsdVErjRX8qRqinomk8FQjMbPehb/u9vOv yjzukfRrgnSsVr57vfzy85SC6Eja1q1wGnLcO8PgtaU2naqWJoGP2hdq0SEQ5z05GRzS KctwfBR9YVnvtD49FI/QJHsJrn+/6GSnfoRg55z4j43TK87sZPIT2vuiaJCBkzpD4Ez0 A7NQ== X-Gm-Message-State: APjAAAX5OCAHPEGs0gL8i+T7ZYQzWpiYJK9OEVRsf6YTuQx/LPTzHIfn ig9lDpq0SrStCZTN+PIzCQ== X-Google-Smtp-Source: APXvYqwq7dT+Bpmj16sKpXMPig2VDRXWPBkgk24G79YfJ+FITet6mrolk8j3klKBC/AfBLkkL5ykqQ== X-Received: by 2002:a05:6830:1ac5:: with SMTP id r5mr9217517otc.338.1568929185792; Thu, 19 Sep 2019 14:39:45 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id q14sm33551otc.50.2019.09.19.14.39.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id A479B1800CE; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 08/15] ipmi: Split out BT-specific code from ISA BT code Date: Thu, 19 Sep 2019 16:39:17 -0500 Message-Id: <20190919213924.31852-9-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Get ready for PCI and other BT interfaces. No functional changes, just split the code into generic BT code and ISA-specific BT code. Signed-off-by: Corey Minyard Reviewed-by: Philippe Mathieu-Daudé --- hw/ipmi/Makefile.objs | 2 +- hw/ipmi/ipmi_bt.c | 426 ++++++++++++++++++++++++++++++++++++ hw/ipmi/isa_ipmi_bt.c | 441 ++------------------------------------ include/hw/ipmi/ipmi_bt.h | 72 +++++++ 4 files changed, 520 insertions(+), 421 deletions(-) create mode 100644 hw/ipmi/ipmi_bt.c create mode 100644 include/hw/ipmi/ipmi_bt.h diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 6835d2f64a..4ffa45a66c 100644 --- a/hw/ipmi/Makefile.objs +++ b/hw/ipmi/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-$(CONFIG_IPMI) += ipmi.o ipmi_kcs.o +common-obj-$(CONFIG_IPMI) += ipmi.o ipmi_kcs.o ipmi_bt.o common-obj-$(CONFIG_IPMI_LOCAL) += ipmi_bmc_sim.o common-obj-$(CONFIG_IPMI_EXTERN) += ipmi_bmc_extern.o common-obj-$(CONFIG_ISA_IPMI_KCS) += isa_ipmi_kcs.o diff --git a/hw/ipmi/ipmi_bt.c b/hw/ipmi/ipmi_bt.c new file mode 100644 index 0000000000..e6765ca4f8 --- /dev/null +++ b/hw/ipmi/ipmi_bt.c @@ -0,0 +1,426 @@ +/* + * QEMU IPMI BT emulation + * + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC + * + * 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 "migration/vmstate.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/ipmi/ipmi_bt.h" + +/* Control register */ +#define IPMI_BT_CLR_WR_BIT 0 +#define IPMI_BT_CLR_RD_BIT 1 +#define IPMI_BT_H2B_ATN_BIT 2 +#define IPMI_BT_B2H_ATN_BIT 3 +#define IPMI_BT_SMS_ATN_BIT 4 +#define IPMI_BT_HBUSY_BIT 6 +#define IPMI_BT_BBUSY_BIT 7 + +#define IPMI_BT_GET_CLR_WR(d) (((d) >> IPMI_BT_CLR_WR_BIT) & 0x1) + +#define IPMI_BT_GET_CLR_RD(d) (((d) >> IPMI_BT_CLR_RD_BIT) & 0x1) + +#define IPMI_BT_GET_H2B_ATN(d) (((d) >> IPMI_BT_H2B_ATN_BIT) & 0x1) + +#define IPMI_BT_B2H_ATN_MASK (1 << IPMI_BT_B2H_ATN_BIT) +#define IPMI_BT_GET_B2H_ATN(d) (((d) >> IPMI_BT_B2H_ATN_BIT) & 0x1) +#define IPMI_BT_SET_B2H_ATN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_ATN_MASK) | \ + (!!(v) << IPMI_BT_B2H_ATN_BIT))) + +#define IPMI_BT_SMS_ATN_MASK (1 << IPMI_BT_SMS_ATN_BIT) +#define IPMI_BT_GET_SMS_ATN(d) (((d) >> IPMI_BT_SMS_ATN_BIT) & 0x1) +#define IPMI_BT_SET_SMS_ATN(d, v) ((d) = (((d) & ~IPMI_BT_SMS_ATN_MASK) | \ + (!!(v) << IPMI_BT_SMS_ATN_BIT))) + +#define IPMI_BT_HBUSY_MASK (1 << IPMI_BT_HBUSY_BIT) +#define IPMI_BT_GET_HBUSY(d) (((d) >> IPMI_BT_HBUSY_BIT) & 0x1) +#define IPMI_BT_SET_HBUSY(d, v) ((d) = (((d) & ~IPMI_BT_HBUSY_MASK) | \ + (!!(v) << IPMI_BT_HBUSY_BIT))) + +#define IPMI_BT_BBUSY_MASK (1 << IPMI_BT_BBUSY_BIT) +#define IPMI_BT_SET_BBUSY(d, v) ((d) = (((d) & ~IPMI_BT_BBUSY_MASK) | \ + (!!(v) << IPMI_BT_BBUSY_BIT))) + + +/* Mask register */ +#define IPMI_BT_B2H_IRQ_EN_BIT 0 +#define IPMI_BT_B2H_IRQ_BIT 1 + +#define IPMI_BT_B2H_IRQ_EN_MASK (1 << IPMI_BT_B2H_IRQ_EN_BIT) +#define IPMI_BT_GET_B2H_IRQ_EN(d) (((d) >> IPMI_BT_B2H_IRQ_EN_BIT) & 0x1) +#define IPMI_BT_SET_B2H_IRQ_EN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_EN_MASK) |\ + (!!(v) << IPMI_BT_B2H_IRQ_EN_BIT))) + +#define IPMI_BT_B2H_IRQ_MASK (1 << IPMI_BT_B2H_IRQ_BIT) +#define IPMI_BT_GET_B2H_IRQ(d) (((d) >> IPMI_BT_B2H_IRQ_BIT) & 0x1) +#define IPMI_BT_SET_B2H_IRQ(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_MASK) | \ + (!!(v) << IPMI_BT_B2H_IRQ_BIT))) + +#define IPMI_CMD_GET_BT_INTF_CAP 0x36 + +static void ipmi_bt_raise_irq(IPMIBT *ib) +{ + if (ib->use_irq && ib->irqs_enabled && ib->raise_irq) { + ib->raise_irq(ib); + } +} + +static void ipmi_bt_lower_irq(IPMIBT *ib) +{ + if (ib->lower_irq) { + ib->lower_irq(ib); + } +} + +static void ipmi_bt_handle_event(IPMIInterface *ii) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + if (ib->inlen < 4) { + goto out; + } + /* Note that overruns are handled by handle_command */ + if (ib->inmsg[0] != (ib->inlen - 1)) { + /* Length mismatch, just ignore. */ + IPMI_BT_SET_BBUSY(ib->control_reg, 1); + ib->inlen = 0; + goto out; + } + if ((ib->inmsg[1] == (IPMI_NETFN_APP << 2)) && + (ib->inmsg[3] == IPMI_CMD_GET_BT_INTF_CAP)) { + /* We handle this one ourselves. */ + ib->outmsg[0] = 9; + ib->outmsg[1] = ib->inmsg[1] | 0x04; + ib->outmsg[2] = ib->inmsg[2]; + ib->outmsg[3] = ib->inmsg[3]; + ib->outmsg[4] = 0; + ib->outmsg[5] = 1; /* Only support 1 outstanding request. */ + if (sizeof(ib->inmsg) > 0xff) { /* Input buffer size */ + ib->outmsg[6] = 0xff; + } else { + ib->outmsg[6] = (unsigned char) sizeof(ib->inmsg); + } + if (sizeof(ib->outmsg) > 0xff) { /* Output buffer size */ + ib->outmsg[7] = 0xff; + } else { + ib->outmsg[7] = (unsigned char) sizeof(ib->outmsg); + } + ib->outmsg[8] = 10; /* Max request to response time */ + ib->outmsg[9] = 0; /* Don't recommend retries */ + ib->outlen = 10; + IPMI_BT_SET_BBUSY(ib->control_reg, 0); + IPMI_BT_SET_B2H_ATN(ib->control_reg, 1); + if (!IPMI_BT_GET_B2H_IRQ(ib->mask_reg) && + IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); + ipmi_bt_raise_irq(ib); + } + goto out; + } + ib->waiting_seq = ib->inmsg[2]; + ib->inmsg[2] = ib->inmsg[1]; + { + IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(ib->bmc); + bk->handle_command(ib->bmc, ib->inmsg + 2, ib->inlen - 2, + sizeof(ib->inmsg), ib->waiting_rsp); + } + out: + return; +} + +static void ipmi_bt_handle_rsp(IPMIInterface *ii, uint8_t msg_id, + unsigned char *rsp, unsigned int rsp_len) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + if (ib->waiting_rsp == msg_id) { + ib->waiting_rsp++; + if (rsp_len > (sizeof(ib->outmsg) - 2)) { + ib->outmsg[0] = 4; + ib->outmsg[1] = rsp[0]; + ib->outmsg[2] = ib->waiting_seq; + ib->outmsg[3] = rsp[1]; + ib->outmsg[4] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; + ib->outlen = 5; + } else { + ib->outmsg[0] = rsp_len + 1; + ib->outmsg[1] = rsp[0]; + ib->outmsg[2] = ib->waiting_seq; + memcpy(ib->outmsg + 3, rsp + 1, rsp_len - 1); + ib->outlen = rsp_len + 2; + } + IPMI_BT_SET_BBUSY(ib->control_reg, 0); + IPMI_BT_SET_B2H_ATN(ib->control_reg, 1); + if (!IPMI_BT_GET_B2H_IRQ(ib->mask_reg) && + IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); + ipmi_bt_raise_irq(ib); + } + } +} + + +static uint64_t ipmi_bt_ioport_read(void *opaque, hwaddr addr, unsigned size) +{ + IPMIInterface *ii = opaque; + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + uint32_t ret = 0xff; + + switch (addr & 3) { + case 0: + ret = ib->control_reg; + break; + case 1: + if (ib->outpos < ib->outlen) { + ret = ib->outmsg[ib->outpos]; + ib->outpos++; + if (ib->outpos == ib->outlen) { + ib->outpos = 0; + ib->outlen = 0; + } + } else { + ret = 0xff; + } + break; + case 2: + ret = ib->mask_reg; + break; + } + return ret; +} + +static void ipmi_bt_signal(IPMIBT *ib, IPMIInterface *ii) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + + ib->do_wake = 1; + while (ib->do_wake) { + ib->do_wake = 0; + iic->handle_if_event(ii); + } +} + +static void ipmi_bt_ioport_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + IPMIInterface *ii = opaque; + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + switch (addr & 3) { + case 0: + if (IPMI_BT_GET_CLR_WR(val)) { + ib->inlen = 0; + } + if (IPMI_BT_GET_CLR_RD(val)) { + ib->outpos = 0; + } + if (IPMI_BT_GET_B2H_ATN(val)) { + IPMI_BT_SET_B2H_ATN(ib->control_reg, 0); + } + if (IPMI_BT_GET_SMS_ATN(val)) { + IPMI_BT_SET_SMS_ATN(ib->control_reg, 0); + } + if (IPMI_BT_GET_HBUSY(val)) { + /* Toggle */ + IPMI_BT_SET_HBUSY(ib->control_reg, + !IPMI_BT_GET_HBUSY(ib->control_reg)); + } + if (IPMI_BT_GET_H2B_ATN(val)) { + IPMI_BT_SET_BBUSY(ib->control_reg, 1); + ipmi_bt_signal(ib, ii); + } + break; + + case 1: + if (ib->inlen < sizeof(ib->inmsg)) { + ib->inmsg[ib->inlen] = val; + } + ib->inlen++; + break; + + case 2: + if (IPMI_BT_GET_B2H_IRQ_EN(val) != + IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { + if (IPMI_BT_GET_B2H_IRQ_EN(val)) { + if (IPMI_BT_GET_B2H_ATN(ib->control_reg) || + IPMI_BT_GET_SMS_ATN(ib->control_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); + ipmi_bt_raise_irq(ib); + } + IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 1); + } else { + if (IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); + ipmi_bt_lower_irq(ib); + } + IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 0); + } + } + if (IPMI_BT_GET_B2H_IRQ(val) && IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); + ipmi_bt_lower_irq(ib); + } + break; + } +} + +static const MemoryRegionOps ipmi_bt_io_ops = { + .read = ipmi_bt_ioport_read, + .write = ipmi_bt_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void ipmi_bt_set_atn(IPMIInterface *ii, int val, int irq) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + if (!!val == IPMI_BT_GET_SMS_ATN(ib->control_reg)) { + return; + } + + IPMI_BT_SET_SMS_ATN(ib->control_reg, val); + if (val) { + if (irq && !IPMI_BT_GET_B2H_ATN(ib->control_reg) && + IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); + ipmi_bt_raise_irq(ib); + } + } else { + if (!IPMI_BT_GET_B2H_ATN(ib->control_reg) && + IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); + ipmi_bt_lower_irq(ib); + } + } +} + +static void ipmi_bt_handle_reset(IPMIInterface *ii, bool is_cold) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + if (is_cold) { + /* Disable the BT interrupt on reset */ + if (IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { + IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); + ipmi_bt_lower_irq(ib); + } + IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 0); + } +} + +static void ipmi_bt_set_irq_enable(IPMIInterface *ii, int val) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + ib->irqs_enabled = val; +} + +static void ipmi_bt_init(IPMIInterface *ii, Error **errp) +{ + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + IPMIBT *ib = iic->get_backend_data(ii); + + ib->io_length = 3; + + memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3); +} + +int ipmi_bt_vmstate_post_load(void *opaque, int version) +{ + IPMIBT *ib = opaque; + + /* Make sure all the values are sane. */ + if (ib->outpos >= MAX_IPMI_MSG_SIZE || ib->outlen >= MAX_IPMI_MSG_SIZE || + ib->outpos >= ib->outlen) { + qemu_log_mask(LOG_GUEST_ERROR, + "ipmi:bt: vmstate transfer received bad out values: %d %d\n", + ib->outpos, ib->outlen); + ib->outpos = 0; + ib->outlen = 0; + } + + if (ib->inlen >= MAX_IPMI_MSG_SIZE) { + qemu_log_mask(LOG_GUEST_ERROR, + "ipmi:bt: vmstate transfer received bad in value: %d\n", + ib->inlen); + ib->inlen = 0; + } + + return 0; +} + +const VMStateDescription vmstate_IPMIBT = { + .name = TYPE_IPMI_INTERFACE_PREFIX "bt", + .version_id = 1, + .minimum_version_id = 1, + .post_load = ipmi_bt_vmstate_post_load, + .fields = (VMStateField[]) { + VMSTATE_BOOL(obf_irq_set, IPMIBT), + VMSTATE_BOOL(atn_irq_set, IPMIBT), + VMSTATE_BOOL(irqs_enabled, IPMIBT), + VMSTATE_UINT32(outpos, IPMIBT), + VMSTATE_UINT32(outlen, IPMIBT), + VMSTATE_UINT8_ARRAY(outmsg, IPMIBT, MAX_IPMI_MSG_SIZE), + VMSTATE_UINT32(inlen, IPMIBT), + VMSTATE_UINT8_ARRAY(inmsg, IPMIBT, MAX_IPMI_MSG_SIZE), + VMSTATE_UINT8(control_reg, IPMIBT), + VMSTATE_UINT8(mask_reg, IPMIBT), + VMSTATE_UINT8(waiting_rsp, IPMIBT), + VMSTATE_UINT8(waiting_seq, IPMIBT), + VMSTATE_END_OF_LIST() + } +}; + +void ipmi_bt_get_fwinfo(struct IPMIBT *ib, IPMIFwInfo *info) +{ + info->interface_name = "bt"; + info->interface_type = IPMI_SMBIOS_BT; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = ib->io_base; + info->register_length = ib->io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; +} + +void ipmi_bt_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_bt_init; + iic->set_atn = ipmi_bt_set_atn; + iic->handle_rsp = ipmi_bt_handle_rsp; + iic->handle_if_event = ipmi_bt_handle_event; + iic->set_irq_enable = ipmi_bt_set_irq_enable; + iic->reset = ipmi_bt_handle_reset; +} diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index a696096cbb..c102778712 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -26,403 +26,46 @@ #include "qemu/log.h" #include "qemu/module.h" #include "qapi/error.h" -#include "hw/ipmi/ipmi.h" #include "hw/irq.h" +#include "hw/ipmi/ipmi_bt.h" #include "hw/isa/isa.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -/* Control register */ -#define IPMI_BT_CLR_WR_BIT 0 -#define IPMI_BT_CLR_RD_BIT 1 -#define IPMI_BT_H2B_ATN_BIT 2 -#define IPMI_BT_B2H_ATN_BIT 3 -#define IPMI_BT_SMS_ATN_BIT 4 -#define IPMI_BT_HBUSY_BIT 6 -#define IPMI_BT_BBUSY_BIT 7 - -#define IPMI_BT_GET_CLR_WR(d) (((d) >> IPMI_BT_CLR_WR_BIT) & 0x1) - -#define IPMI_BT_GET_CLR_RD(d) (((d) >> IPMI_BT_CLR_RD_BIT) & 0x1) - -#define IPMI_BT_GET_H2B_ATN(d) (((d) >> IPMI_BT_H2B_ATN_BIT) & 0x1) - -#define IPMI_BT_B2H_ATN_MASK (1 << IPMI_BT_B2H_ATN_BIT) -#define IPMI_BT_GET_B2H_ATN(d) (((d) >> IPMI_BT_B2H_ATN_BIT) & 0x1) -#define IPMI_BT_SET_B2H_ATN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_ATN_MASK) | \ - (!!(v) << IPMI_BT_B2H_ATN_BIT))) - -#define IPMI_BT_SMS_ATN_MASK (1 << IPMI_BT_SMS_ATN_BIT) -#define IPMI_BT_GET_SMS_ATN(d) (((d) >> IPMI_BT_SMS_ATN_BIT) & 0x1) -#define IPMI_BT_SET_SMS_ATN(d, v) ((d) = (((d) & ~IPMI_BT_SMS_ATN_MASK) | \ - (!!(v) << IPMI_BT_SMS_ATN_BIT))) - -#define IPMI_BT_HBUSY_MASK (1 << IPMI_BT_HBUSY_BIT) -#define IPMI_BT_GET_HBUSY(d) (((d) >> IPMI_BT_HBUSY_BIT) & 0x1) -#define IPMI_BT_SET_HBUSY(d, v) ((d) = (((d) & ~IPMI_BT_HBUSY_MASK) | \ - (!!(v) << IPMI_BT_HBUSY_BIT))) - -#define IPMI_BT_BBUSY_MASK (1 << IPMI_BT_BBUSY_BIT) -#define IPMI_BT_SET_BBUSY(d, v) ((d) = (((d) & ~IPMI_BT_BBUSY_MASK) | \ - (!!(v) << IPMI_BT_BBUSY_BIT))) - - -/* Mask register */ -#define IPMI_BT_B2H_IRQ_EN_BIT 0 -#define IPMI_BT_B2H_IRQ_BIT 1 - -#define IPMI_BT_B2H_IRQ_EN_MASK (1 << IPMI_BT_B2H_IRQ_EN_BIT) -#define IPMI_BT_GET_B2H_IRQ_EN(d) (((d) >> IPMI_BT_B2H_IRQ_EN_BIT) & 0x1) -#define IPMI_BT_SET_B2H_IRQ_EN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_EN_MASK) |\ - (!!(v) << IPMI_BT_B2H_IRQ_EN_BIT))) - -#define IPMI_BT_B2H_IRQ_MASK (1 << IPMI_BT_B2H_IRQ_BIT) -#define IPMI_BT_GET_B2H_IRQ(d) (((d) >> IPMI_BT_B2H_IRQ_BIT) & 0x1) -#define IPMI_BT_SET_B2H_IRQ(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_MASK) | \ - (!!(v) << IPMI_BT_B2H_IRQ_BIT))) - -typedef struct IPMIBT { - IPMIBmc *bmc; - - bool do_wake; - - qemu_irq irq; - - uint32_t io_base; - unsigned long io_length; - MemoryRegion io; - - bool obf_irq_set; - bool atn_irq_set; - bool use_irq; - bool irqs_enabled; - - uint8_t outmsg[MAX_IPMI_MSG_SIZE]; - uint32_t outpos; - uint32_t outlen; - - uint8_t inmsg[MAX_IPMI_MSG_SIZE]; - uint32_t inlen; - - uint8_t control_reg; - uint8_t mask_reg; - - /* - * This is a response number that we send with the command to make - * sure that the response matches the command. - */ - uint8_t waiting_rsp; - uint8_t waiting_seq; -} IPMIBT; - -#define IPMI_CMD_GET_BT_INTF_CAP 0x36 - -static void ipmi_bt_handle_event(IPMIInterface *ii) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - if (ib->inlen < 4) { - goto out; - } - /* Note that overruns are handled by handle_command */ - if (ib->inmsg[0] != (ib->inlen - 1)) { - /* Length mismatch, just ignore. */ - IPMI_BT_SET_BBUSY(ib->control_reg, 1); - ib->inlen = 0; - goto out; - } - if ((ib->inmsg[1] == (IPMI_NETFN_APP << 2)) && - (ib->inmsg[3] == IPMI_CMD_GET_BT_INTF_CAP)) { - /* We handle this one ourselves. */ - ib->outmsg[0] = 9; - ib->outmsg[1] = ib->inmsg[1] | 0x04; - ib->outmsg[2] = ib->inmsg[2]; - ib->outmsg[3] = ib->inmsg[3]; - ib->outmsg[4] = 0; - ib->outmsg[5] = 1; /* Only support 1 outstanding request. */ - if (sizeof(ib->inmsg) > 0xff) { /* Input buffer size */ - ib->outmsg[6] = 0xff; - } else { - ib->outmsg[6] = (unsigned char) sizeof(ib->inmsg); - } - if (sizeof(ib->outmsg) > 0xff) { /* Output buffer size */ - ib->outmsg[7] = 0xff; - } else { - ib->outmsg[7] = (unsigned char) sizeof(ib->outmsg); - } - ib->outmsg[8] = 10; /* Max request to response time */ - ib->outmsg[9] = 0; /* Don't recommend retries */ - ib->outlen = 10; - IPMI_BT_SET_BBUSY(ib->control_reg, 0); - IPMI_BT_SET_B2H_ATN(ib->control_reg, 1); - if (ib->use_irq && ib->irqs_enabled && - !IPMI_BT_GET_B2H_IRQ(ib->mask_reg) && - IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); - qemu_irq_raise(ib->irq); - } - goto out; - } - ib->waiting_seq = ib->inmsg[2]; - ib->inmsg[2] = ib->inmsg[1]; - { - IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(ib->bmc); - bk->handle_command(ib->bmc, ib->inmsg + 2, ib->inlen - 2, - sizeof(ib->inmsg), ib->waiting_rsp); - } - out: - return; -} - -static void ipmi_bt_handle_rsp(IPMIInterface *ii, uint8_t msg_id, - unsigned char *rsp, unsigned int rsp_len) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - if (ib->waiting_rsp == msg_id) { - ib->waiting_rsp++; - if (rsp_len > (sizeof(ib->outmsg) - 2)) { - ib->outmsg[0] = 4; - ib->outmsg[1] = rsp[0]; - ib->outmsg[2] = ib->waiting_seq; - ib->outmsg[3] = rsp[1]; - ib->outmsg[4] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; - ib->outlen = 5; - } else { - ib->outmsg[0] = rsp_len + 1; - ib->outmsg[1] = rsp[0]; - ib->outmsg[2] = ib->waiting_seq; - memcpy(ib->outmsg + 3, rsp + 1, rsp_len - 1); - ib->outlen = rsp_len + 2; - } - IPMI_BT_SET_BBUSY(ib->control_reg, 0); - IPMI_BT_SET_B2H_ATN(ib->control_reg, 1); - if (ib->use_irq && ib->irqs_enabled && - !IPMI_BT_GET_B2H_IRQ(ib->mask_reg) && - IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); - qemu_irq_raise(ib->irq); - } - } -} - - -static uint64_t ipmi_bt_ioport_read(void *opaque, hwaddr addr, unsigned size) -{ - IPMIInterface *ii = opaque; - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - uint32_t ret = 0xff; - - switch (addr & 3) { - case 0: - ret = ib->control_reg; - break; - case 1: - if (ib->outpos < ib->outlen) { - ret = ib->outmsg[ib->outpos]; - ib->outpos++; - if (ib->outpos == ib->outlen) { - ib->outpos = 0; - ib->outlen = 0; - } - } else { - ret = 0xff; - } - break; - case 2: - ret = ib->mask_reg; - break; - } - return ret; -} - -static void ipmi_bt_signal(IPMIBT *ib, IPMIInterface *ii) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - - ib->do_wake = 1; - while (ib->do_wake) { - ib->do_wake = 0; - iic->handle_if_event(ii); - } -} - -static void ipmi_bt_ioport_write(void *opaque, hwaddr addr, uint64_t val, - unsigned size) -{ - IPMIInterface *ii = opaque; - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - switch (addr & 3) { - case 0: - if (IPMI_BT_GET_CLR_WR(val)) { - ib->inlen = 0; - } - if (IPMI_BT_GET_CLR_RD(val)) { - ib->outpos = 0; - } - if (IPMI_BT_GET_B2H_ATN(val)) { - IPMI_BT_SET_B2H_ATN(ib->control_reg, 0); - } - if (IPMI_BT_GET_SMS_ATN(val)) { - IPMI_BT_SET_SMS_ATN(ib->control_reg, 0); - } - if (IPMI_BT_GET_HBUSY(val)) { - /* Toggle */ - IPMI_BT_SET_HBUSY(ib->control_reg, - !IPMI_BT_GET_HBUSY(ib->control_reg)); - } - if (IPMI_BT_GET_H2B_ATN(val)) { - IPMI_BT_SET_BBUSY(ib->control_reg, 1); - ipmi_bt_signal(ib, ii); - } - break; - - case 1: - if (ib->inlen < sizeof(ib->inmsg)) { - ib->inmsg[ib->inlen] = val; - } - ib->inlen++; - break; - - case 2: - if (IPMI_BT_GET_B2H_IRQ_EN(val) != - IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { - if (IPMI_BT_GET_B2H_IRQ_EN(val)) { - if (IPMI_BT_GET_B2H_ATN(ib->control_reg) || - IPMI_BT_GET_SMS_ATN(ib->control_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); - qemu_irq_raise(ib->irq); - } - IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 1); - } else { - if (IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); - qemu_irq_lower(ib->irq); - } - IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 0); - } - } - if (IPMI_BT_GET_B2H_IRQ(val) && IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); - qemu_irq_lower(ib->irq); - } - break; - } -} - -static const MemoryRegionOps ipmi_bt_io_ops = { - .read = ipmi_bt_ioport_read, - .write = ipmi_bt_ioport_write, - .impl = { - .min_access_size = 1, - .max_access_size = 1, - }, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static void ipmi_bt_set_atn(IPMIInterface *ii, int val, int irq) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - if (!!val == IPMI_BT_GET_SMS_ATN(ib->control_reg)) { - return; - } - - IPMI_BT_SET_SMS_ATN(ib->control_reg, val); - if (val) { - if (irq && ib->use_irq && ib->irqs_enabled && - !IPMI_BT_GET_B2H_ATN(ib->control_reg) && - IPMI_BT_GET_B2H_IRQ_EN(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 1); - qemu_irq_raise(ib->irq); - } - } else { - if (!IPMI_BT_GET_B2H_ATN(ib->control_reg) && - IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); - qemu_irq_lower(ib->irq); - } - } -} - -static void ipmi_bt_handle_reset(IPMIInterface *ii, bool is_cold) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - if (is_cold) { - /* Disable the BT interrupt on reset */ - if (IPMI_BT_GET_B2H_IRQ(ib->mask_reg)) { - IPMI_BT_SET_B2H_IRQ(ib->mask_reg, 0); - qemu_irq_lower(ib->irq); - } - IPMI_BT_SET_B2H_IRQ_EN(ib->mask_reg, 0); - } -} - -static void ipmi_bt_set_irq_enable(IPMIInterface *ii, int val) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - ib->irqs_enabled = val; -} - -static void ipmi_bt_init(IPMIInterface *ii, Error **errp) -{ - IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); - IPMIBT *ib = iic->get_backend_data(ii); - - ib->io_length = 3; - - memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3); -} - - #define TYPE_ISA_IPMI_BT "isa-ipmi-bt" #define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \ - TYPE_ISA_IPMI_BT) + TYPE_ISA_IPMI_BT) typedef struct ISAIPMIBTDevice { ISADevice dev; int32_t isairq; + qemu_irq irq; IPMIBT bt; uint32_t uuid; } ISAIPMIBTDevice; -static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) +static void isa_ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) { ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii); - info->interface_name = "bt"; - info->interface_type = IPMI_SMBIOS_BT; - info->ipmi_spec_major_revision = 2; - info->ipmi_spec_minor_revision = 0; - info->base_address = iib->bt.io_base; - info->register_length = iib->bt.io_length; - info->register_spacing = 1; - info->memspace = IPMI_MEMSPACE_IO; - info->irq_type = IPMI_LEVEL_IRQ; + ipmi_bt_get_fwinfo(&iib->bt, info); info->interrupt_number = iib->isairq; info->i2c_slave_address = iib->bt.bmc->slave_addr; info->uuid = iib->uuid; } -static void ipmi_bt_class_init(IPMIInterfaceClass *iic) +static void isa_ipmi_bt_raise_irq(IPMIBT *ib) { - iic->init = ipmi_bt_init; - iic->set_atn = ipmi_bt_set_atn; - iic->handle_rsp = ipmi_bt_handle_rsp; - iic->handle_if_event = ipmi_bt_handle_event; - iic->set_irq_enable = ipmi_bt_set_irq_enable; - iic->reset = ipmi_bt_handle_reset; - iic->get_fwinfo = ipmi_bt_get_fwinfo; + ISAIPMIBTDevice *iib = ib->opaque; + + qemu_irq_raise(iib->irq); +} + +static void isa_ipmi_bt_lower_irq(IPMIBT *ib) +{ + ISAIPMIBTDevice *iib = ib->opaque; + + qemu_irq_lower(iib->irq); } static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) @@ -440,14 +83,17 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) iib->uuid = ipmi_next_uuid(); iib->bt.bmc->intf = ii; + iib->bt.opaque = iib; iic->init(ii, errp); if (*errp) return; if (iib->isairq > 0) { - isa_init_irq(isadev, &iib->bt.irq, iib->isairq); + isa_init_irq(isadev, &iib->irq, iib->isairq); iib->bt.use_irq = 1; + iib->bt.raise_irq = isa_ipmi_bt_raise_irq; + iib->bt.lower_irq = isa_ipmi_bt_lower_irq; } qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length); @@ -455,52 +101,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base); } -static int ipmi_bt_vmstate_post_load(void *opaque, int version) -{ - IPMIBT *ib = opaque; - - /* Make sure all the values are sane. */ - if (ib->outpos >= MAX_IPMI_MSG_SIZE || ib->outlen >= MAX_IPMI_MSG_SIZE || - ib->outpos >= ib->outlen) { - qemu_log_mask(LOG_GUEST_ERROR, - "ipmi:bt: vmstate transfer received bad out values: %d %d\n", - ib->outpos, ib->outlen); - ib->outpos = 0; - ib->outlen = 0; - } - - if (ib->inlen >= MAX_IPMI_MSG_SIZE) { - qemu_log_mask(LOG_GUEST_ERROR, - "ipmi:bt: vmstate transfer received bad in value: %d\n", - ib->inlen); - ib->inlen = 0; - } - - return 0; -} - -const VMStateDescription vmstate_IPMIBT = { - .name = TYPE_IPMI_INTERFACE_PREFIX "bt", - .version_id = 1, - .minimum_version_id = 1, - .post_load = ipmi_bt_vmstate_post_load, - .fields = (VMStateField[]) { - VMSTATE_BOOL(obf_irq_set, IPMIBT), - VMSTATE_BOOL(atn_irq_set, IPMIBT), - VMSTATE_BOOL(irqs_enabled, IPMIBT), - VMSTATE_UINT32(outpos, IPMIBT), - VMSTATE_UINT32(outlen, IPMIBT), - VMSTATE_UINT8_ARRAY(outmsg, IPMIBT, MAX_IPMI_MSG_SIZE), - VMSTATE_UINT32(inlen, IPMIBT), - VMSTATE_UINT8_ARRAY(inmsg, IPMIBT, MAX_IPMI_MSG_SIZE), - VMSTATE_UINT8(control_reg, IPMIBT), - VMSTATE_UINT8(mask_reg, IPMIBT), - VMSTATE_UINT8(waiting_rsp, IPMIBT), - VMSTATE_UINT8(waiting_seq, IPMIBT), - VMSTATE_END_OF_LIST() - } -}; - static const VMStateDescription vmstate_ISAIPMIBTDevice = { .name = TYPE_IPMI_INTERFACE_PREFIX "isa-bt", .version_id = 2, @@ -548,6 +148,7 @@ static void isa_ipmi_bt_class_init(ObjectClass *oc, void *data) iic->get_backend_data = isa_ipmi_bt_get_backend_data; ipmi_bt_class_init(iic); + iic->get_fwinfo = isa_ipmi_bt_get_fwinfo; } static const TypeInfo isa_ipmi_bt_info = { diff --git a/include/hw/ipmi/ipmi_bt.h b/include/hw/ipmi/ipmi_bt.h new file mode 100644 index 0000000000..9667aaa88a --- /dev/null +++ b/include/hw/ipmi/ipmi_bt.h @@ -0,0 +1,72 @@ +/* + * QEMU IPMI BT emulation + * + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC + * + * 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. + */ + +#ifndef HW_IPMI_BT_H +#define HW_IPMI_BT_H + +#include "hw/ipmi/ipmi.h" + +typedef struct IPMIBT { + IPMIBmc *bmc; + + bool do_wake; + + bool obf_irq_set; + bool atn_irq_set; + bool irqs_enabled; + + uint8_t outmsg[MAX_IPMI_MSG_SIZE]; + uint32_t outpos; + uint32_t outlen; + + uint8_t inmsg[MAX_IPMI_MSG_SIZE]; + uint32_t inlen; + + uint8_t control_reg; + uint8_t mask_reg; + + /* + * This is a response number that we send with the command to make + * sure that the response matches the command. + */ + uint8_t waiting_rsp; + uint8_t waiting_seq; + + uint32_t io_base; + unsigned long io_length; + MemoryRegion io; + + void (*raise_irq)(struct IPMIBT *ib); + void (*lower_irq)(struct IPMIBT *ib); + void *opaque; + + bool use_irq; +} IPMIBT; + +void ipmi_bt_get_fwinfo(IPMIBT *ik, IPMIFwInfo *info); +void ipmi_bt_class_init(IPMIInterfaceClass *iic); +extern const VMStateDescription vmstate_IPMIBT; +int ipmi_bt_vmstate_post_load(void *opaque, int version); + +#endif /* HW_IPMI_BT_H */ From patchwork Thu Sep 19 21:39:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164907 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="kN7/2o9D"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9dw2FFyz9sCJ for ; Fri, 20 Sep 2019 07:56:04 +1000 (AEST) Received: from localhost ([::1]:48846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4PB-0000aJ-KB for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:56:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56296) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49f-0001Z1-T1 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49Y-0006Db-01 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:59 -0400 Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:33390) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49S-0006C1-9r for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:46 -0400 Received: by mail-ot1-x342.google.com with SMTP id g25so4486150otl.0 for ; Thu, 19 Sep 2019 14:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=FcIfcrqIGdpNZl0S22ugT9WUisJdVXVDfqKYhKlZSoQ=; b=kN7/2o9D03jyfVfwsavgiTyiXYcyNW8sRl6OzafoArVqj3AzOookWMYd2DqwlQRaiH ppYM+xc/jH2mwmDwjDos8KCfMv8C/34a4WW2cefD8YdkJE7osjXxxOWjodzLxSqHvtif PP02ShaZLnFfLg3U0e63mkQjzKJpBsWYAi2m5OlKKamtBlfVX2dU/4718BiiXJQNoUS6 FCWYm+nGWncfmLDLrzT5fCDWwzEKiCeSc6+5iBUPjok39jXelAOIL3Kr3AoJZJb7bsJW b7HaAlwCZGiyGYw7Zx0VPiUKvV93RlZGdUV1hSjen0if14MESehaFuMxkREyUlhqByw/ 3QUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=FcIfcrqIGdpNZl0S22ugT9WUisJdVXVDfqKYhKlZSoQ=; b=VldzhyX7naJ4WPNkpnawbSy7Hy+R2ASKLrdifX39cx+Br52Ps6mCLaC7bzXQOSJU62 GgrHmSl//AVAstQTbfqCpfzhhT2MH4taHrUyB5/FvEYMnW5nK4G31p/lYq9s18OBrWtm WHxZhm0w5TMaJHOUI6BGuN+nAPgrK7dPsz6Y5x4ex1yRTXu82Ik62n+rBhqqDYZpCD33 TEF3nowRZO9LlOyV9uSsw9M/G0981NA9DjJfx4/oGHFGlERLiTJWdI8Ve5FozRAW7/je 0LS2CCRzGb7PuNpPB6JHUWkGlKSwCBMhldVniQlF592c91Auf6iUDoegRmkT5FGVmrd/ xsxA== X-Gm-Message-State: APjAAAVAiJxjhNRg4wCAEgQFnTZ0vcK/c+GSw3i3hAUYSmpqjvWq0X3p x3m1l2FLRmp5aNOktxOvqg== X-Google-Smtp-Source: APXvYqxiFLyFY+o48vbm299gHXPWa27uVdt3yg15qm0GzO96vexGrxFJ/Ph0hzb/x4IZvacYhxn3pw== X-Received: by 2002:a05:6830:1d6c:: with SMTP id l12mr8885792oti.140.1568929185358; Thu, 19 Sep 2019 14:39:45 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id g129sm32949oib.50.2019.09.19.14.39.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id D13901805A1; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 09/15] ipmi: Allow a size value to be passed for I/O space Date: Thu, 19 Sep 2019 16:39:18 -0500 Message-Id: <20190919213924.31852-10-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard PCI device I/O must be >= 8 bytes in length or they don't work. Allow the size to be passed in, the default size of 2 or 3 won't work. Signed-off-by: Corey Minyard --- hw/ipmi/ipmi_bt.c | 19 +++++++++++++++---- hw/ipmi/ipmi_kcs.c | 23 +++++++++++++++++++---- hw/ipmi/isa_ipmi_bt.c | 2 +- hw/ipmi/isa_ipmi_kcs.c | 2 +- include/hw/ipmi/ipmi.h | 7 ++++++- include/hw/ipmi/ipmi_bt.h | 1 + include/hw/ipmi/ipmi_kcs.h | 1 + 7 files changed, 44 insertions(+), 11 deletions(-) diff --git a/hw/ipmi/ipmi_bt.c b/hw/ipmi/ipmi_bt.c index e6765ca4f8..22f94fb98d 100644 --- a/hw/ipmi/ipmi_bt.c +++ b/hw/ipmi/ipmi_bt.c @@ -189,7 +189,7 @@ static uint64_t ipmi_bt_ioport_read(void *opaque, hwaddr addr, unsigned size) IPMIBT *ib = iic->get_backend_data(ii); uint32_t ret = 0xff; - switch (addr & 3) { + switch (addr & ib->size_mask) { case 0: ret = ib->control_reg; break; @@ -208,6 +208,9 @@ static uint64_t ipmi_bt_ioport_read(void *opaque, hwaddr addr, unsigned size) case 2: ret = ib->mask_reg; break; + default: + ret = 0xff; + break; } return ret; } @@ -230,7 +233,7 @@ static void ipmi_bt_ioport_write(void *opaque, hwaddr addr, uint64_t val, IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); IPMIBT *ib = iic->get_backend_data(ii); - switch (addr & 3) { + switch (addr & ib->size_mask) { case 0: if (IPMI_BT_GET_CLR_WR(val)) { ib->inlen = 0; @@ -285,6 +288,9 @@ static void ipmi_bt_ioport_write(void *opaque, hwaddr addr, uint64_t val, ipmi_bt_lower_irq(ib); } break; + default: + /* Ignore. */ + break; } } @@ -346,14 +352,19 @@ static void ipmi_bt_set_irq_enable(IPMIInterface *ii, int val) ib->irqs_enabled = val; } -static void ipmi_bt_init(IPMIInterface *ii, Error **errp) +static void ipmi_bt_init(IPMIInterface *ii, unsigned int min_size, Error **errp) { IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); IPMIBT *ib = iic->get_backend_data(ii); + if (min_size == 0) { + min_size = 4; + } + ib->size_mask = min_size - 1; ib->io_length = 3; - memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3); + memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", + min_size); } int ipmi_bt_vmstate_post_load(void *opaque, int version) diff --git a/hw/ipmi/ipmi_kcs.c b/hw/ipmi/ipmi_kcs.c index dab1af8bc8..a77612946a 100644 --- a/hw/ipmi/ipmi_kcs.c +++ b/hw/ipmi/ipmi_kcs.c @@ -232,7 +232,7 @@ static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) IPMIKCS *ik = iic->get_backend_data(ii); uint32_t ret; - switch (addr & 1) { + switch (addr & ik->size_mask) { case 0: ret = ik->data_out_reg; IPMI_KCS_SET_OBF(ik->status_reg, 0); @@ -243,6 +243,7 @@ static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) } } break; + case 1: ret = ik->status_reg; if (ik->atn_irq_set) { @@ -252,6 +253,9 @@ static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) } } break; + + default: + ret = 0xff; } return ret; } @@ -267,7 +271,7 @@ static void ipmi_kcs_ioport_write(void *opaque, hwaddr addr, uint64_t val, return; } - switch (addr & 1) { + switch (addr & ik->size_mask) { case 0: ik->data_in_reg = val; break; @@ -275,6 +279,10 @@ static void ipmi_kcs_ioport_write(void *opaque, hwaddr addr, uint64_t val, case 1: ik->cmd_reg = val; break; + + default: + /* Ignore. */ + break; } IPMI_KCS_SET_IBF(ik->status_reg, 1); ipmi_kcs_signal(ik, ii); @@ -321,13 +329,20 @@ static void ipmi_kcs_set_irq_enable(IPMIInterface *ii, int val) ik->irqs_enabled = val; } -static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) +/* min_size must be a power of 2. */ +static void ipmi_kcs_init(IPMIInterface *ii, unsigned int min_size, + Error **errp) { IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); IPMIKCS *ik = iic->get_backend_data(ii); + if (min_size == 0) { + min_size = 2; + } + ik->size_mask = min_size - 1; ik->io_length = 2; - memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); + memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", + min_size); } int ipmi_kcs_vmstate_post_load(void *opaque, int version) diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index c102778712..9a87ffd3f0 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -85,7 +85,7 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) iib->bt.bmc->intf = ii; iib->bt.opaque = iib; - iic->init(ii, errp); + iic->init(ii, 0, errp); if (*errp) return; diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 8e32774f85..ca3ea36a3f 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -84,7 +84,7 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) iik->kcs.bmc->intf = ii; iik->kcs.opaque = iik; - iic->init(ii, errp); + iic->init(ii, 0, errp); if (*errp) return; diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h index 70871da0a7..6f2413b39b 100644 --- a/include/hw/ipmi/ipmi.h +++ b/include/hw/ipmi/ipmi.h @@ -118,7 +118,12 @@ typedef struct IPMIInterface IPMIInterface; typedef struct IPMIInterfaceClass { InterfaceClass parent; - void (*init)(struct IPMIInterface *s, Error **errp); + /* + * min_size is the requested I/O size and must be a power of 2. + * This is so PCI (or other busses) can request a bigger range. + * Use 0 for the default. + */ + void (*init)(struct IPMIInterface *s, unsigned int min_size, Error **errp); /* * Perform various operations on the hardware. If checkonly is diff --git a/include/hw/ipmi/ipmi_bt.h b/include/hw/ipmi/ipmi_bt.h index 9667aaa88a..8a4316ea7c 100644 --- a/include/hw/ipmi/ipmi_bt.h +++ b/include/hw/ipmi/ipmi_bt.h @@ -56,6 +56,7 @@ typedef struct IPMIBT { uint32_t io_base; unsigned long io_length; MemoryRegion io; + unsigned long size_mask; void (*raise_irq)(struct IPMIBT *ib); void (*lower_irq)(struct IPMIBT *ib); diff --git a/include/hw/ipmi/ipmi_kcs.h b/include/hw/ipmi/ipmi_kcs.h index 91d76d08f4..6e6ef4c539 100644 --- a/include/hw/ipmi/ipmi_kcs.h +++ b/include/hw/ipmi/ipmi_kcs.h @@ -59,6 +59,7 @@ typedef struct IPMIKCS { uint32_t io_base; unsigned long io_length; MemoryRegion io; + unsigned long size_mask; void (*raise_irq)(struct IPMIKCS *ik); void (*lower_irq)(struct IPMIKCS *ik); From patchwork Thu Sep 19 21:39:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164905 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="L0lujuMy"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9dW3c1Vz9sCJ for ; Fri, 20 Sep 2019 07:55:43 +1000 (AEST) Received: from localhost ([::1]:48838 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4Oq-000090-JH for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:55:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56292) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49f-0001Yx-MZ for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49S-0006CC-3W for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:55 -0400 Received: from mail-ot1-x341.google.com ([2607:f8b0:4864:20::341]:33389) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49R-0006Bb-8O for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:39:45 -0400 Received: by mail-ot1-x341.google.com with SMTP id g25so4486123otl.0 for ; Thu, 19 Sep 2019 14:39:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=SZ14L8l0Spjq6/ThzBDUirtAqlBzB2jLWm1AH1q1hs4=; b=L0lujuMy43rlng/dMaQfYBtzKggUQuSrLNyHHrzP+49AT7DjO6wG9ffOX2NIH7P+q8 vEL9L3iD7IG8sOFq+pVzZjI+me/u7JnBeo7NaS3/TRlwN2ac8KNTYYUPwMW3MViNOUBR kOHRCXrstya/BbBv5eBwWY3YTV6QrXQpKFtMJD5iJi0ci513SmwlmhZ11iLQ8yVnOW83 /GH4tPtZQja4khD3+rVk85WoJ4RHdtowH7MM5ZoMU44I8fahjuFeyu7k4MYHGG4pawIN 7XV6dVVgEfaIWxxL13V+dcUVKMlEic9PmN8YgWnGUPuMa5Zzxk3pWr2vBYs3YxNS9IJm rzuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=SZ14L8l0Spjq6/ThzBDUirtAqlBzB2jLWm1AH1q1hs4=; b=oANG39lKLXjX+RvZooNUgjTtMcU6lYCZzW04aZ4uZrfoyS8/8m3x9AeH5cs1xNMZqW SWfS0zRyZiNQeuheiirsKE2I2r88ghh84OxwzzP1AT/RFss0T9EJuZxh72YxL2lHWyQE rlGsxWsw00JzAtJQVxi6aeYQW7bRPi/MxeKd6RLXAzc+WvzFASfYfcl7xUNOA0bokBme rSbDainVDRxcmPG1NNMWCid4XZO3GT5/tVtgXe2BIQ4JkfoxwqdrW1BeuC9/lDD8uTFI b+tqr+8OsoKBwZ7Fqsqxav4pEWv2ZeWt89LOCLh+WS5NQndURrsR+ZiWVSdl6V34ibXb covw== X-Gm-Message-State: APjAAAWvWUbJl9sFpAimTcXweNtIrhB2lzpdu8LubtJEXtNDgM4zs0D7 8alhyKOiZsWp3bhiSAgRuw== X-Google-Smtp-Source: APXvYqzslGAmP+/hOt3M7FRWJkxc2qX4k9P2Py6D3epM6uRRjC08EwngY2Ne8d5yqpRMit2FgqrZng== X-Received: by 2002:a05:6830:1492:: with SMTP id s18mr3499985otq.283.1568929184475; Thu, 19 Sep 2019 14:39:44 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id r26sm32373oij.46.2019.09.19.14.39.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id F3BDB1805A2; Thu, 19 Sep 2019 21:39:36 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 10/15] smbios:ipmi: Ignore IPMI devices with no fwinfo function Date: Thu, 19 Sep 2019 16:39:19 -0500 Message-Id: <20190919213924.31852-11-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::341 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Not all devices have fwinfo (like the coming PCI one), so ignore them if the their fwinfo function is NULL. Cc: Michael S. Tsirkin Cc: Igor Mammedov Signed-off-by: Corey Minyard --- hw/smbios/smbios_type_38.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c index 0c08f282de..168b886647 100644 --- a/hw/smbios/smbios_type_38.c +++ b/hw/smbios/smbios_type_38.c @@ -94,6 +94,9 @@ static void smbios_add_ipmi_devices(BusState *bus) ii = IPMI_INTERFACE(obj); iic = IPMI_INTERFACE_GET_CLASS(obj); memset(&info, 0, sizeof(info)); + if (!iic->get_fwinfo) { + continue; + } iic->get_fwinfo(ii, &info); smbios_build_one_type_38(&info); continue; From patchwork Thu Sep 19 21:39:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164917 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LlIuVFu7"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9wP0TT7z9sQy for ; Fri, 20 Sep 2019 08:08:35 +1000 (AEST) Received: from localhost ([::1]:48960 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4bH-00068m-TD for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:08:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56406) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49t-0001g4-QV for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49h-0006GL-Vs for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:10 -0400 Received: from mail-oi1-x244.google.com ([2607:f8b0:4864:20::244]:46633) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49h-0006Ck-Iy for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:01 -0400 Received: by mail-oi1-x244.google.com with SMTP id k25so3980360oiw.13 for ; Thu, 19 Sep 2019 14:39:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZeJscWWKCUqiou1c6ENFoRKdom+VlVVzvF6Ij/ADxY8=; b=LlIuVFu7iox26nwKXtbnS5S+yTa30ZO7hy++XNwNRDS1LdFU6vXAquZVcm+pY2M+hL zjIXst0ODSEGNUX2t6X3osUEblt6nZgwLkHjMJivLdhaiXAeThohJ0ffj1XP9O2c6xJf SqPOlKgkn297XMFwtlTNrmlwoMsyHJwO+6q+JHVi1BPzsc5Mwkc46rCZWrn+9f/e6+e3 Fv/r4sSh9pIwTmjkLLZ3ZalMgnBZOJGG7qptMkg5xiNZwLjuJQhfMtb5y5doUTVBwaY7 GebK4DGF57u7RQtlhXaCB/cdSNhQ1ggYX1nEmUKIiA6nxFB3L0f6KzyY0hmBtXA/xcfK jvqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ZeJscWWKCUqiou1c6ENFoRKdom+VlVVzvF6Ij/ADxY8=; b=YWID6/liIgbkPsJXiU88Ns3Q6HfKKlBsLQGZWrBep5b7REwiEtvbHJQWU3qUlsLagd Nm2qf+HvSDNsSR5DEfEqOxqJ1iyuxtABd+1yXCfaoFhxBt6kuRSD/78y41Yt8swzD2L6 3yzAABppkwKolExmApxV/+3WNohCu9gC5PXoSH0oe4+rFRJsskAVZbcv98ElrqmRzL9L 2hbfPJ0XSwQ/6GmmQf2GFN2fP+ijk2lV1ucsEHs/QTxhw3lOH0tzlYsN4/QMkYF6eMYP 1QqSOkV4Zwp7J5z6nT0ATnUPmZuzQQibZRAUvVoAc4rYHQvc2+hbfsvrO+SrKlkf1a94 D+jw== X-Gm-Message-State: APjAAAX0pNY7VWuD0u06LLwfCF0sEgQJfdYQqVyC91IATLzRxE2JqRj2 MLJhKJdT7vv9VfFv4FSOdA== X-Google-Smtp-Source: APXvYqzf9CzQ5a6EGZ4mrTk1/AzSLiZYNEhChc+eoim7fdSaJwaxUICqY7YTn/9JbrKz/nDvdD5Mqg== X-Received: by 2002:aca:701:: with SMTP id 1mr27606oih.85.1568929187394; Thu, 19 Sep 2019 14:39:47 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id t10sm32498oib.49.2019.09.19.14.39.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 2950E1800D2; Thu, 19 Sep 2019 21:39:37 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 11/15] ipmi: Add PCI IPMI interfaces Date: Thu, 19 Sep 2019 16:39:20 -0500 Message-Id: <20190919213924.31852-12-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::244 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Pretty straightforward, just hook the current KCS and BT code into the PCI system with the proper configuration. Cc: Michael S. Tsirkin Cc: M: Marcel Apfelbaum Signed-off-by: Corey Minyard --- default-configs/i386-softmmu.mak | 2 + hw/i386/Kconfig | 2 + hw/ipmi/Kconfig | 10 +++ hw/ipmi/Makefile.objs | 2 + hw/ipmi/pci_ipmi_bt.c | 146 +++++++++++++++++++++++++++++++ hw/ipmi/pci_ipmi_kcs.c | 146 +++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + 7 files changed, 309 insertions(+) create mode 100644 hw/ipmi/pci_ipmi_bt.c create mode 100644 hw/ipmi/pci_ipmi_kcs.c diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index ba3fb3ff50..2294c0be5a 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -10,6 +10,8 @@ #CONFIG_ISA_DEBUG=n #CONFIG_ISA_IPMI_BT=n #CONFIG_ISA_IPMI_KCS=n +#CONFIG_PCI_IPMI_KCS=n +#CONFIG_PCI_IPMI_BT=n #CONFIG_PCI_DEVICES=n #CONFIG_PVPANIC=n #CONFIG_QXL=n diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index c7a9d6315c..d10f4e3e8b 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -8,6 +8,8 @@ config PC imply HYPERV imply ISA_IPMI_KCS imply ISA_IPMI_BT + imply PCI_IPMI_KCS + imply PCI_IPMI_BT imply ISA_DEBUG imply PARALLEL imply PCI_DEVICES diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig index b944fae100..12db4e81ad 100644 --- a/hw/ipmi/Kconfig +++ b/hw/ipmi/Kconfig @@ -20,3 +20,13 @@ config ISA_IPMI_BT bool depends on ISA_BUS select IPMI + +config PCI_IPMI_KCS + bool + depends on PCI + select IPMI + +config PCI_IPMI_BT + bool + depends on PCI + select IPMI diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 4ffa45a66c..2d7f080a86 100644 --- a/hw/ipmi/Makefile.objs +++ b/hw/ipmi/Makefile.objs @@ -2,4 +2,6 @@ common-obj-$(CONFIG_IPMI) += ipmi.o ipmi_kcs.o ipmi_bt.o common-obj-$(CONFIG_IPMI_LOCAL) += ipmi_bmc_sim.o common-obj-$(CONFIG_IPMI_EXTERN) += ipmi_bmc_extern.o common-obj-$(CONFIG_ISA_IPMI_KCS) += isa_ipmi_kcs.o +common-obj-$(CONFIG_PCI_IPMI_KCS) += pci_ipmi_kcs.o common-obj-$(CONFIG_ISA_IPMI_BT) += isa_ipmi_bt.o +common-obj-$(CONFIG_PCI_IPMI_BT) += pci_ipmi_bt.o diff --git a/hw/ipmi/pci_ipmi_bt.c b/hw/ipmi/pci_ipmi_bt.c new file mode 100644 index 0000000000..6ed925a665 --- /dev/null +++ b/hw/ipmi/pci_ipmi_bt.c @@ -0,0 +1,146 @@ +/* + * QEMU PCI IPMI BT emulation + * + * Copyright (c) 2017 Corey Minyard, MontaVista Software, LLC + * + * 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 "migration/vmstate.h" +#include "qapi/error.h" +#include "hw/ipmi/ipmi_bt.h" +#include "hw/pci/pci.h" + +#define TYPE_PCI_IPMI_BT "pci-ipmi-bt" +#define PCI_IPMI_BT(obj) OBJECT_CHECK(PCIIPMIBTDevice, (obj), \ + TYPE_PCI_IPMI_BT) + +typedef struct PCIIPMIBTDevice { + PCIDevice dev; + IPMIBT bt; + bool irq_enabled; + uint32_t uuid; +} PCIIPMIBTDevice; + +static void pci_ipmi_raise_irq(IPMIBT *ik) +{ + PCIIPMIBTDevice *pik = ik->opaque; + + pci_set_irq(&pik->dev, true); +} + +static void pci_ipmi_lower_irq(IPMIBT *ik) +{ + PCIIPMIBTDevice *pik = ik->opaque; + + pci_set_irq(&pik->dev, false); +} + +static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp) +{ + PCIIPMIBTDevice *pik = PCI_IPMI_BT(pd); + IPMIInterface *ii = IPMI_INTERFACE(pd); + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + + if (!pik->bt.bmc) { + error_setg(errp, "IPMI device requires a bmc attribute to be set"); + return; + } + + pik->uuid = ipmi_next_uuid(); + + pik->bt.bmc->intf = ii; + pik->bt.opaque = pik; + + pci_config_set_prog_interface(pd->config, 0x02); /* BT */ + pci_config_set_interrupt_pin(pd->config, 0x01); + pik->bt.use_irq = 1; + pik->bt.raise_irq = pci_ipmi_raise_irq; + pik->bt.lower_irq = pci_ipmi_lower_irq; + + iic->init(ii, 8, errp); + if (*errp) { + return; + } + pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pik->bt.io); +} + +const VMStateDescription vmstate_PCIIPMIBTDevice = { + .name = TYPE_IPMI_INTERFACE_PREFIX "pci-bt", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, PCIIPMIBTDevice), + VMSTATE_STRUCT(bt, PCIIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT), + VMSTATE_END_OF_LIST() + } +}; + +static void pci_ipmi_bt_instance_init(Object *obj) +{ + PCIIPMIBTDevice *pik = PCI_IPMI_BT(obj); + + ipmi_bmc_find_and_link(obj, (Object **) &pik->bt.bmc); +} + +static void *pci_ipmi_bt_get_backend_data(IPMIInterface *ii) +{ + PCIIPMIBTDevice *pik = PCI_IPMI_BT(ii); + + return &pik->bt; +} + +static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); + IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); + + pdc->vendor_id = PCI_VENDOR_ID_QEMU; + pdc->device_id = PCI_DEVICE_ID_QEMU_IPMI; + pdc->revision = 1; + pdc->class_id = PCI_CLASS_SERIAL_IPMI; + + dc->vmsd = &vmstate_PCIIPMIBTDevice; + dc->desc = "PCI IPMI BT"; + pdc->realize = pci_ipmi_bt_realize; + + iic->get_backend_data = pci_ipmi_bt_get_backend_data; + ipmi_bt_class_init(iic); +} + +static const TypeInfo pci_ipmi_bt_info = { + .name = TYPE_PCI_IPMI_BT, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIIPMIBTDevice), + .instance_init = pci_ipmi_bt_instance_init, + .class_init = pci_ipmi_bt_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_IPMI_INTERFACE }, + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { } + } +}; + +static void pci_ipmi_bt_register_types(void) +{ + type_register_static(&pci_ipmi_bt_info); +} + +type_init(pci_ipmi_bt_register_types) diff --git a/hw/ipmi/pci_ipmi_kcs.c b/hw/ipmi/pci_ipmi_kcs.c new file mode 100644 index 0000000000..eeba63baa4 --- /dev/null +++ b/hw/ipmi/pci_ipmi_kcs.c @@ -0,0 +1,146 @@ +/* + * QEMU PCI IPMI KCS emulation + * + * Copyright (c) 2017 Corey Minyard, MontaVista Software, LLC + * + * 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 "migration/vmstate.h" +#include "qapi/error.h" +#include "hw/ipmi/ipmi_kcs.h" +#include "hw/pci/pci.h" + +#define TYPE_PCI_IPMI_KCS "pci-ipmi-kcs" +#define PCI_IPMI_KCS(obj) OBJECT_CHECK(PCIIPMIKCSDevice, (obj), \ + TYPE_PCI_IPMI_KCS) + +typedef struct PCIIPMIKCSDevice { + PCIDevice dev; + IPMIKCS kcs; + bool irq_enabled; + uint32_t uuid; +} PCIIPMIKCSDevice; + +static void pci_ipmi_raise_irq(IPMIKCS *ik) +{ + PCIIPMIKCSDevice *pik = ik->opaque; + + pci_set_irq(&pik->dev, true); +} + +static void pci_ipmi_lower_irq(IPMIKCS *ik) +{ + PCIIPMIKCSDevice *pik = ik->opaque; + + pci_set_irq(&pik->dev, false); +} + +static void pci_ipmi_kcs_realize(PCIDevice *pd, Error **errp) +{ + PCIIPMIKCSDevice *pik = PCI_IPMI_KCS(pd); + IPMIInterface *ii = IPMI_INTERFACE(pd); + IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); + + if (!pik->kcs.bmc) { + error_setg(errp, "IPMI device requires a bmc attribute to be set"); + return; + } + + pik->uuid = ipmi_next_uuid(); + + pik->kcs.bmc->intf = ii; + pik->kcs.opaque = pik; + + pci_config_set_prog_interface(pd->config, 0x01); /* KCS */ + pci_config_set_interrupt_pin(pd->config, 0x01); + pik->kcs.use_irq = 1; + pik->kcs.raise_irq = pci_ipmi_raise_irq; + pik->kcs.lower_irq = pci_ipmi_lower_irq; + + iic->init(ii, 8, errp); + if (*errp) { + return; + } + pci_register_bar(pd, 0, PCI_BASE_ADDRESS_SPACE_IO, &pik->kcs.io); +} + +const VMStateDescription vmstate_PCIIPMIKCSDevice = { + .name = TYPE_IPMI_INTERFACE_PREFIX "pci-kcs", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, PCIIPMIKCSDevice), + VMSTATE_STRUCT(kcs, PCIIPMIKCSDevice, 1, vmstate_IPMIKCS, IPMIKCS), + VMSTATE_END_OF_LIST() + } +}; + +static void pci_ipmi_kcs_instance_init(Object *obj) +{ + PCIIPMIKCSDevice *pik = PCI_IPMI_KCS(obj); + + ipmi_bmc_find_and_link(obj, (Object **) &pik->kcs.bmc); +} + +static void *pci_ipmi_kcs_get_backend_data(IPMIInterface *ii) +{ + PCIIPMIKCSDevice *pik = PCI_IPMI_KCS(ii); + + return &pik->kcs; +} + +static void pci_ipmi_kcs_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); + IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); + + pdc->vendor_id = PCI_VENDOR_ID_QEMU; + pdc->device_id = PCI_DEVICE_ID_QEMU_IPMI; + pdc->revision = 1; + pdc->class_id = PCI_CLASS_SERIAL_IPMI; + + dc->vmsd = &vmstate_PCIIPMIKCSDevice; + dc->desc = "PCI IPMI KCS"; + pdc->realize = pci_ipmi_kcs_realize; + + iic->get_backend_data = pci_ipmi_kcs_get_backend_data; + ipmi_kcs_class_init(iic); +} + +static const TypeInfo pci_ipmi_kcs_info = { + .name = TYPE_PCI_IPMI_KCS, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIIPMIKCSDevice), + .instance_init = pci_ipmi_kcs_instance_init, + .class_init = pci_ipmi_kcs_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_IPMI_INTERFACE }, + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { } + } +}; + +static void pci_ipmi_kcs_register_types(void) +{ + type_register_static(&pci_ipmi_kcs_info); +} + +type_init(pci_ipmi_kcs_register_types) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 1b840e61a2..f3f0ffd5fb 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -55,6 +55,7 @@ extern bool pci_available; /* QEMU/Bochs VGA (0x1234) */ #define PCI_VENDOR_ID_QEMU 0x1234 #define PCI_DEVICE_ID_QEMU_VGA 0x1111 +#define PCI_DEVICE_ID_QEMU_IPMI 0x1112 /* VMWare (0x15ad) */ #define PCI_VENDOR_ID_VMWARE 0x15ad From patchwork Thu Sep 19 21:39:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164920 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PvWyjs77"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46ZB3b44zJz9sPk for ; Fri, 20 Sep 2019 08:14:51 +1000 (AEST) Received: from localhost ([::1]:49060 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4hN-0004t0-6J for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:14:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56405) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49t-0001g3-QV for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49h-0006Fz-1Z for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:10 -0400 Received: from mail-ot1-x343.google.com ([2607:f8b0:4864:20::343]:35899) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49f-0006Cc-Rs for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:00 -0400 Received: by mail-ot1-x343.google.com with SMTP id 67so4471096oto.3 for ; Thu, 19 Sep 2019 14:39:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=HuIlwjKgrYEWVysrX6UaajuLncKSjIW4O4CwrkB0y4Y=; b=PvWyjs77AR/GCV9MoxR3KPs9pIIv64biuBt1NPwYGTVmt52LKUc2wtyl8h4bpE+QQb A3c0tRd0OvozF6tefKImb8Ta3DdbzefYTgHbGy7fAn6+LsDk81jU33EpLHKcvnan+nAo hCOCCfEvrdI1U+a7U6UtZafdL3ezGNFniWrwVLAHuc0MMcUkpr33zK4kwmZLllBPcwJ2 wUTMK3OyvXlPCYQiCofiKfc5BWznugqH52OUTUL6vZFFv5z7tNpMegpRi3hrEQBuy1uH QyD82N9kTRzfeOAO8I3AS8oohx3VL7rd1cBEaYNlFYaNpDokBGKBqI3ZR3yOlQOI3Qzd ci6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=HuIlwjKgrYEWVysrX6UaajuLncKSjIW4O4CwrkB0y4Y=; b=cX5IQB5klOZMauwlhiNfVY/ayT0A35jd7E5peZZwrc5TUzdE/2xJ3xf57hgI4qXTwi G/bh7k+tDi5Lefd4jbFikuVV8vJiax3R2YP0ragVEtTG5mL6eHSU6lbRHN5J3peUStnb 9LRCovOuu2d/P5+HuPyw+mXz5JH66G7s1dzXrIJgJ1YOG7Wclnu5B1cVJEV9NLrjrhpm wKkmevQ6z6yOA6pyyX5LtCXZLB9lc8gTOQySBJ3J6ZdemE/vGERnkOvDcaSY72Z62IX0 dWEwUK3tTlG6FwEOtdCtTEfEOWEQFKLtQym5SBDlGa3AZ5rQYnQqmnbrkgGPlpxA2g/t 0WNw== X-Gm-Message-State: APjAAAV8azjykqOYPyk9c03ZL4Lz7ZLZMFnbjglk8Ft2OWa+lwRhf4p4 GU+AP5Z8tMS/V4q4DUCkgg== X-Google-Smtp-Source: APXvYqyeIX6yy/oitmkSzrYZnNOmZuVIEqGRE18sOrLz8zikNST3+a16geQfsdRQqUuN9TGAqft37Q== X-Received: by 2002:a9d:962:: with SMTP id 89mr4800417otp.261.1568929186957; Thu, 19 Sep 2019 14:39:46 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id e9sm29432oie.58.2019.09.19.14.39.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:40 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 560DD1805A3; Thu, 19 Sep 2019 21:39:37 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 12/15] ipmi: Add an SMBus IPMI interface Date: Thu, 19 Sep 2019 16:39:21 -0500 Message-Id: <20190919213924.31852-13-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::343 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Signed-off-by: Corey Minyard --- default-configs/i386-softmmu.mak | 1 + hw/i386/Kconfig | 1 + hw/ipmi/Kconfig | 5 + hw/ipmi/Makefile.objs | 1 + hw/ipmi/smbus_ipmi.c | 384 +++++++++++++++++++++++++++++++ 5 files changed, 392 insertions(+) create mode 100644 hw/ipmi/smbus_ipmi.c diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 2294c0be5a..4229900f57 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -12,6 +12,7 @@ #CONFIG_ISA_IPMI_KCS=n #CONFIG_PCI_IPMI_KCS=n #CONFIG_PCI_IPMI_BT=n +#CONFIG_IPMI_SSIF=n #CONFIG_PCI_DEVICES=n #CONFIG_PVPANIC=n #CONFIG_QXL=n diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index d10f4e3e8b..c5c9d4900e 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -10,6 +10,7 @@ config PC imply ISA_IPMI_BT imply PCI_IPMI_KCS imply PCI_IPMI_BT + imply IPMI_SSIF imply ISA_DEBUG imply PARALLEL imply PCI_DEVICES diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig index 12db4e81ad..9befd4f422 100644 --- a/hw/ipmi/Kconfig +++ b/hw/ipmi/Kconfig @@ -30,3 +30,8 @@ config PCI_IPMI_BT bool depends on PCI select IPMI + +config IPMI_SSIF + bool + depends on I2C + select IPMI diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 2d7f080a86..3cca10bc50 100644 --- a/hw/ipmi/Makefile.objs +++ b/hw/ipmi/Makefile.objs @@ -5,3 +5,4 @@ common-obj-$(CONFIG_ISA_IPMI_KCS) += isa_ipmi_kcs.o common-obj-$(CONFIG_PCI_IPMI_KCS) += pci_ipmi_kcs.o common-obj-$(CONFIG_ISA_IPMI_BT) += isa_ipmi_bt.o common-obj-$(CONFIG_PCI_IPMI_BT) += pci_ipmi_bt.o +common-obj-$(CONFIG_IPMI_SSIF) += smbus_ipmi.o diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c new file mode 100644 index 0000000000..2a9470d9df --- /dev/null +++ b/hw/ipmi/smbus_ipmi.c @@ -0,0 +1,384 @@ +/* + * QEMU IPMI SMBus (SSIF) emulation + * + * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC + * + * 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 "migration/vmstate.h" +#include "hw/i2c/smbus_slave.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "hw/ipmi/ipmi.h" + +#define TYPE_SMBUS_IPMI "smbus-ipmi" +#define SMBUS_IPMI(obj) OBJECT_CHECK(SMBusIPMIDevice, (obj), TYPE_SMBUS_IPMI) + +#define SSIF_IPMI_REQUEST 2 +#define SSIF_IPMI_MULTI_PART_REQUEST_START 6 +#define SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE 7 +#define SSIF_IPMI_MULTI_PART_REQUEST_END 8 +#define SSIF_IPMI_RESPONSE 3 +#define SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE 9 +#define SSIF_IPMI_MULTI_PART_RETRY 0xa + +#define MAX_SSIF_IPMI_MSG_SIZE 255 +#define MAX_SSIF_IPMI_MSG_CHUNK 32 + +#define IPMI_GET_SYS_INTF_CAP_CMD 0x57 + +typedef struct SMBusIPMIDevice { + SMBusDevice parent; + + IPMIBmc *bmc; + + uint8_t outmsg[MAX_SSIF_IPMI_MSG_SIZE]; + uint32_t outlen; + uint32_t currblk; + + /* Holds the SMBUS message currently being sent to the host. */ + uint8_t outbuf[MAX_SSIF_IPMI_MSG_CHUNK + 1]; /* len + message. */ + uint32_t outpos; + + uint8_t inmsg[MAX_SSIF_IPMI_MSG_SIZE]; + uint32_t inlen; + + /* + * This is a response number that we send with the command to make + * sure that the response matches the command. + */ + uint8_t waiting_rsp; + + uint32_t uuid; +} SMBusIPMIDevice; + +static void smbus_ipmi_handle_event(IPMIInterface *ii) +{ + /* No interrupts, so nothing to do here. */ +} + +static void smbus_ipmi_handle_rsp(IPMIInterface *ii, uint8_t msg_id, + unsigned char *rsp, unsigned int rsp_len) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(ii); + + if (sid->waiting_rsp == msg_id) { + sid->waiting_rsp++; + + if (rsp_len > MAX_SSIF_IPMI_MSG_SIZE) { + rsp[2] = IPMI_CC_REQUEST_DATA_TRUNCATED; + rsp_len = MAX_SSIF_IPMI_MSG_SIZE; + } + memcpy(sid->outmsg, rsp, rsp_len); + sid->outlen = rsp_len; + sid->outpos = 0; + sid->currblk = 0; + } +} + +static void smbus_ipmi_set_atn(IPMIInterface *ii, int val, int irq) +{ + /* This is where PEC would go. */ +} + +static void smbus_ipmi_set_irq_enable(IPMIInterface *ii, int val) +{ +} + +static void smbus_ipmi_send_msg(SMBusIPMIDevice *sid) +{ + uint8_t *msg = sid->inmsg; + uint32_t len = sid->inlen; + IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(sid->bmc); + + sid->outlen = 0; + sid->outpos = 0; + sid->currblk = 0; + + if (msg[0] == (IPMI_NETFN_APP << 2) && msg[1] == IPMI_GET_SYS_INTF_CAP_CMD) + { + /* We handle this ourself. */ + sid->outmsg[0] = (IPMI_NETFN_APP + 1) << 2; + sid->outmsg[1] = msg[1]; + if (len < 3) { + sid->outmsg[2] = IPMI_CC_REQUEST_DATA_LENGTH_INVALID; + sid->outlen = 3; + } else if ((msg[2] & 0x0f) != 0) { + sid->outmsg[2] = IPMI_CC_INVALID_DATA_FIELD; + sid->outlen = 3; + } else { + sid->outmsg[2] = 0; + sid->outmsg[3] = 0; + sid->outmsg[4] = (2 << 6); /* Multi-part supported. */ + sid->outmsg[5] = MAX_SSIF_IPMI_MSG_SIZE; + sid->outmsg[6] = MAX_SSIF_IPMI_MSG_SIZE; + sid->outlen = 7; + } + return; + } + + bk->handle_command(sid->bmc, sid->inmsg, sid->inlen, sizeof(sid->inmsg), + sid->waiting_rsp); +} + +static uint8_t ipmi_receive_byte(SMBusDevice *dev) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(dev); + + if (sid->outpos >= sizeof(sid->outbuf)) { + return 0xff; + } + + return sid->outbuf[sid->outpos++]; +} + +static int ipmi_load_readbuf(SMBusIPMIDevice *sid) +{ + unsigned int block = sid->currblk, pos, len; + + if (sid->outlen == 0) { + return -1; + } + + if (sid->outlen <= 32) { + if (block != 0) { + return -1; + } + sid->outbuf[0] = sid->outlen; + memcpy(sid->outbuf + 1, sid->outmsg, sid->outlen); + sid->outpos = 0; + return 0; + } + + if (block == 0) { + sid->outbuf[0] = 32; + sid->outbuf[1] = 0; + sid->outbuf[2] = 1; + memcpy(sid->outbuf + 3, sid->outmsg, 30); + sid->outpos = 0; + return 0; + } + + /* + * Calculate the position in outmsg. 30 for the first block, 31 + * for the rest of the blocks. + */ + pos = 30 + (block - 1) * 31; + + if (pos >= sid->outlen) { + return -1; + } + + len = sid->outlen - pos; + if (len > 31) { + /* More chunks after this. */ + len = 31; + /* Blocks start at 0 for the first middle transaction. */ + sid->outbuf[1] = block - 1; + } else { + sid->outbuf[1] = 0xff; /* End of message marker. */ + } + + sid->outbuf[0] = len + 1; + memcpy(sid->outbuf + 2, sid->outmsg + pos, len); + sid->outpos = 0; + return 0; +} + +static int ipmi_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(dev); + bool send = false; + uint8_t cmd; + int ret = 0; + + /* length is guaranteed to be >= 1. */ + cmd = *buf++; + len--; + + /* Handle read request, which don't have any data in the write part. */ + switch (cmd) { + case SSIF_IPMI_RESPONSE: + sid->currblk = 0; + ret = ipmi_load_readbuf(sid); + break; + + case SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE: + sid->currblk++; + ret = ipmi_load_readbuf(sid); + break; + + case SSIF_IPMI_MULTI_PART_RETRY: + if (len >= 1) { + sid->currblk = buf[0]; + ret = ipmi_load_readbuf(sid); + } else { + ret = -1; + } + break; + + default: + break; + } + + /* This should be a message write, make the length is there and correct. */ + if (len >= 1) { + if (*buf != len - 1 || *buf > MAX_SSIF_IPMI_MSG_CHUNK) { + return -1; /* Bogus message */ + } + buf++; + len--; + } + + switch (cmd) { + case SSIF_IPMI_REQUEST: + send = true; + /* FALLTHRU */ + case SSIF_IPMI_MULTI_PART_REQUEST_START: + if (len < 2) { + return -1; /* Bogus. */ + } + memcpy(sid->inmsg, buf, len); + sid->inlen = len; + break; + + case SSIF_IPMI_MULTI_PART_REQUEST_END: + send = true; + /* FALLTHRU */ + case SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE: + if (!sid->inlen) { + return -1; /* Bogus. */ + } + if (sid->inlen + len > MAX_SSIF_IPMI_MSG_SIZE) { + sid->inlen = 0; /* Discard the message. */ + return -1; /* Bogus. */ + } + if (len < 32) { + /* + * Special hack, a multi-part middle that is less than 32 bytes + * marks the end of a message. The specification is fairly + * confusing, so some systems to this, even sending a zero + * length end message to mark the end. + */ + send = true; + } + memcpy(sid->inmsg + sid->inlen, buf, len); + sid->inlen += len; + break; + } + + if (send && sid->inlen) { + smbus_ipmi_send_msg(sid); + } + + return ret; +} + +static const VMStateDescription vmstate_smbus_ipmi = { + .name = TYPE_SMBUS_IPMI, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_SMBUS_DEVICE(parent, SMBusIPMIDevice), + VMSTATE_UINT8(waiting_rsp, SMBusIPMIDevice), + VMSTATE_UINT32(outlen, SMBusIPMIDevice), + VMSTATE_UINT32(currblk, SMBusIPMIDevice), + VMSTATE_UINT8_ARRAY(outmsg, SMBusIPMIDevice, MAX_SSIF_IPMI_MSG_SIZE), + VMSTATE_UINT32(outpos, SMBusIPMIDevice), + VMSTATE_UINT8_ARRAY(outbuf, SMBusIPMIDevice, + MAX_SSIF_IPMI_MSG_CHUNK + 1), + VMSTATE_UINT32(inlen, SMBusIPMIDevice), + VMSTATE_UINT8_ARRAY(inmsg, SMBusIPMIDevice, MAX_SSIF_IPMI_MSG_SIZE), + VMSTATE_END_OF_LIST() + } +}; + +static void smbus_ipmi_realize(DeviceState *dev, Error **errp) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(dev); + IPMIInterface *ii = IPMI_INTERFACE(dev); + + if (!sid->bmc) { + error_setg(errp, "IPMI device requires a bmc attribute to be set"); + return; + } + + sid->uuid = ipmi_next_uuid(); + + sid->bmc->intf = ii; +} + +static void smbus_ipmi_init(Object *obj) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(obj); + + ipmi_bmc_find_and_link(OBJECT(obj), (Object **) &sid->bmc); +} + +static void smbus_ipmi_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) +{ + SMBusIPMIDevice *sid = SMBUS_IPMI(ii); + + info->interface_name = "smbus"; + info->interface_type = IPMI_SMBIOS_SSIF; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->i2c_slave_address = sid->bmc->slave_addr; + info->base_address = sid->parent.i2c.address; + info->memspace = IPMI_MEMSPACE_SMBUS; + info->register_spacing = 1; + info->uuid = sid->uuid; +} + +static void smbus_ipmi_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); + SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(oc); + + sc->receive_byte = ipmi_receive_byte; + sc->write_data = ipmi_write_data; + dc->vmsd = &vmstate_smbus_ipmi; + dc->realize = smbus_ipmi_realize; + iic->set_atn = smbus_ipmi_set_atn; + iic->handle_rsp = smbus_ipmi_handle_rsp; + iic->handle_if_event = smbus_ipmi_handle_event; + iic->set_irq_enable = smbus_ipmi_set_irq_enable; + iic->get_fwinfo = smbus_ipmi_get_fwinfo; +} + +static const TypeInfo smbus_ipmi_info = { + .name = TYPE_SMBUS_IPMI, + .parent = TYPE_SMBUS_DEVICE, + .instance_size = sizeof(SMBusIPMIDevice), + .instance_init = smbus_ipmi_init, + .class_init = smbus_ipmi_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_IPMI_INTERFACE }, + { } + } +}; + +static void smbus_ipmi_register_types(void) +{ + type_register_static(&smbus_ipmi_info); +} + +type_init(smbus_ipmi_register_types) From patchwork Thu Sep 19 21:39:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Jagi61QT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9r41PHtz9sCJ for ; Fri, 20 Sep 2019 08:04:52 +1000 (AEST) Received: from localhost ([::1]:48918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4Xh-0002Cz-4G for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:04:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56397) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49s-0001fw-D4 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49g-0006Fr-SS for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:09 -0400 Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:43006) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49f-0006DA-RG for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:00 -0400 Received: by mail-ot1-x342.google.com with SMTP id c10so4431073otd.9 for ; Thu, 19 Sep 2019 14:39:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=PNIkOVUyVGiMnom4futjhqgQ2wG4j2xkwRrNLbLlk8M=; b=Jagi61QTNzp6AtNXoD1gkdVjMm6ezElun6mOdTDnHvD6Df28DCd7XroItmwtsQMp32 KgWnAEiaYP52TvkVdvJ4JNhb+5YNwseOd4uCYLY07cjTvPFjMAEQLns/Yo4viANFcd7X 9LktLk0sZcoFZUA7FEli09wMDmcSs3GAGkECU3DtSGMC1UeuJZBzBoP6iOXU0uyqTNR2 xyjA/5LQUrtQvo9Z/CMMbsCri998vzWQ5NNIBY39jV2b+rzI6+gbLHBzGhR3V/QTJYD7 +mLrKh62dQganRJLTvlsciAYA0lhEsZygwvnUnPZqxliWnJnXqk5u4XFBxVzOMNWA8u6 iWRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=PNIkOVUyVGiMnom4futjhqgQ2wG4j2xkwRrNLbLlk8M=; b=Vy0IOhVoIHVDaTLctABfQ9Fa9NJ0UJyvSw+9auXmXMO/3kzAfjoFErUM52+9JqqrRw MuXqyq86rmSwl2B30UcGRS4CyTAuYfDRVlmtp26sFfSe6FvKwXFf74WDhsolpQOV1b2Y fGZAV3EpAhZ8bEgPnm6L7oLxDqBwyzxQsGXq1N+4mGc6CI0ueQaY71AIKBmvt2qXI7H1 1Xb2EODDXzYxVX+jxDZ0IzHY7+qyVdbotNw33B81uLfz+R4S35D+QNQ0466V1dPbC2Bz PN9wwa2R9+VvaH40i2NTewasThmguRkhywVX4s4nKlaMJi9QlkQig5Mc+ioJ/H6Vl1Aj rUbA== X-Gm-Message-State: APjAAAWkuVGzmNz2kH9RvDQHlzc2anOSvdR80SXmZAqgMcrFsk+yL2nn zC8pM0rrhsOqiPy8dl7aFg== X-Google-Smtp-Source: APXvYqyzQovPBWd2mH6wc0MbRe3R9zXOhIhKBQFhfj86dQCfRn4NmCIX6MahtvAGYx5WCWupb/c1jA== X-Received: by 2002:a05:6830:4a5:: with SMTP id l5mr7778730otd.150.1568929189270; Thu, 19 Sep 2019 14:39:49 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id y30sm33572oix.36.2019.09.19.14.39.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:47 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id 848071805A5; Thu, 19 Sep 2019 21:39:37 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 13/15] acpi: Add i2c serial bus CRS handling Date: Thu, 19 Sep 2019 16:39:22 -0500 Message-Id: <20190919213924.31852-14-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::342 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard This will be required for getting IPMI SSIF (SMBus interface) into the ACPI tables. Cc: Michael S. Tsirkin Cc: Igor Mammedov Signed-off-by: Corey Minyard --- hw/acpi/aml-build.c | 40 +++++++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 18 +++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 78aee1a2f9..2c3702b882 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1874,3 +1874,43 @@ build_hdr: build_header(linker, tbl, (void *)(tbl->data + fadt_start), "FACP", tbl->len - fadt_start, f->rev, oem_id, oem_table_id); } + +/* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */ +static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags, + uint16_t type_flags, + uint8_t revid, uint16_t data_length, + uint16_t resource_source_len) +{ + Aml *var = aml_alloc(); + uint16_t length = data_length + resource_source_len + 9; + + build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */ + build_append_int_noprefix(var->buf, length, sizeof(length)); + build_append_byte(var->buf, 1); /* Revision ID */ + build_append_byte(var->buf, 0); /* Resource Source Index */ + build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */ + build_append_byte(var->buf, flags); /* General Flags */ + build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */ + sizeof(type_flags)); + build_append_byte(var->buf, revid); /* Type Specification Revision ID */ + build_append_int_noprefix(var->buf, data_length, sizeof(data_length)); + + return var; +} + +/* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */ +Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source) +{ + uint16_t resource_source_len = strlen(resource_source) + 1; + Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1, + 6, resource_source_len); + + /* Connection Speed. Just set to 100K for now, it doesn't really matter. */ + build_append_int_noprefix(var->buf, 100000, 4); + build_append_int_noprefix(var->buf, address, sizeof(address)); + + /* This is a string, not a name, so just copy it directly in. */ + g_array_append_vals(var->buf, resource_source, resource_source_len); + + return var; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 991cf05134..de4a406568 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -223,6 +223,23 @@ struct AcpiBuildTables { BIOSLinker *linker; } AcpiBuildTables; +/* + * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors + * Serial Bus Type + */ +#define AML_SERIAL_BUS_TYPE_I2C 1 +#define AML_SERIAL_BUS_TYPE_SPI 2 +#define AML_SERIAL_BUS_TYPE_UART 3 + +/* + * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors + * General Flags + */ +/* Slave Mode */ +#define AML_SERIAL_BUS_FLAG_MASTER_DEVICE (1 << 0) +/* Consumer/Producer */ +#define AML_SERIAL_BUS_FLAG_CONSUME_ONLY (1 << 1) + /** * init_aml_allocator: * @@ -347,6 +364,7 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed, Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz, uint8_t channel); Aml *aml_sleep(uint64_t msec); +Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From patchwork Thu Sep 19 21:39:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164911 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Fu416awU"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Z9k50Rt4z9sCJ for ; Fri, 20 Sep 2019 07:59:41 +1000 (AEST) Received: from localhost ([::1]:48870 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4Sg-0005PN-Jg for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 17:59:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56407) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49t-0001g5-QY for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49i-0006GT-1z for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:11 -0400 Received: from mail-ot1-x341.google.com ([2607:f8b0:4864:20::341]:39889) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49h-0006DF-Jj for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:01 -0400 Received: by mail-ot1-x341.google.com with SMTP id s22so4450541otr.6 for ; Thu, 19 Sep 2019 14:39:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=hEnRsnkhBw6lClljHVlxLoL/kUii/7QYP2uJtyHbCs0=; b=Fu416awUVxtLYIL6GI06ro3NY8xprgTY3iqYgJ1JyybCI47y9fYEQsDfJzO2plTVtD +908OKUzx73bHNmHn7lMLrlAxgx0qOk4KOkYtKvLYnSDhfH2J2DvmAu7LW51vPgBLzTM geBw7sHZRs7rgX+bWADf0NPGRkMrS2utFXwxeaahcCoJw75LwxmEhTZ4M3qTe5pcJTWl vEHNGSDTxstWGK/k1UsxLOWPIodwNwLyGMk7xIDQVRqD2Iuv8gZXJVTwtRM13LkB4eVG +JjHuMrv812PHP/yYVcs5UF9Ew6+guHcxoC/dCOYwUiTReYyfth+qHK2vFsKt5sMBfJ8 CtUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=hEnRsnkhBw6lClljHVlxLoL/kUii/7QYP2uJtyHbCs0=; b=Lyn4OTwR0Kmj5kZyZMEk9qR/JVfuzdFsPYVWc1R8+ZN1qVpyQbBiNUjvzr4kOb3ln8 dGDE2cip54RgwHNBL8cMtdCf354LoVSL386tKDYHqa7hd4BDKqe5sHRfb0Stl66xBNkQ kNNAiANDVJNibpirKOH+2wa02fAT+kVsE5pw5urCcc9OdckWFOpIGAZ7he+BhEIRH4qL RLbAht4aZIXOkmx74J/F6TY3iOgMow0lUGvV4/Ghr0C+BPgx3mCA7IT6v36JJESl+joW 56RUG0BZUVSEC8G3/kp9KvJzemL/K/Nahg8ErSfLETG3IJdd0H0fJGp00JMKcbozDh4L InHw== X-Gm-Message-State: APjAAAVNL7UEFyTG1nT8mY6i+QABSZpFjY+NUvZ4PDRwFsygrjML+CMe atMjyTQrr8W2bFAunQThLA== X-Google-Smtp-Source: APXvYqyqc2LNrxt1WgxBsh5zxAbunutABK8MPaoVQx755YdH9AtZD8o/O0kQON+3IxCyKu45mCHwHg== X-Received: by 2002:a9d:5a06:: with SMTP id v6mr8634768oth.250.1568929189790; Thu, 19 Sep 2019 14:39:49 -0700 (PDT) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id 88sm37376otb.63.2019.09.19.14.39.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:47 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id A3F631805B1; Thu, 19 Sep 2019 21:39:37 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 14/15] ipmi: Fix SSIF ACPI handling to use the right CRS Date: Thu, 19 Sep 2019 16:39:23 -0500 Message-Id: <20190919213924.31852-15-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::341 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Pass in the CRS so that it can be set to the SMBus for IPMI later. Cc: Michael S. Tsirkin Cc: Igor Mammedov Signed-off-by: Corey Minyard --- hw/acpi/ipmi-stub.c | 2 +- hw/acpi/ipmi.c | 13 +++++++------ hw/i386/acpi-build.c | 2 +- include/hw/acpi/ipmi.h | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/acpi/ipmi-stub.c b/hw/acpi/ipmi-stub.c index f525f71c2d..8634fb325c 100644 --- a/hw/acpi/ipmi-stub.c +++ b/hw/acpi/ipmi-stub.c @@ -10,6 +10,6 @@ #include "qemu/osdep.h" #include "hw/acpi/ipmi.h" -void build_acpi_ipmi_devices(Aml *table, BusState *bus) +void build_acpi_ipmi_devices(Aml *table, BusState *bus, const char *resource) { } diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c index 651e2e94ea..96e48eba15 100644 --- a/hw/acpi/ipmi.c +++ b/hw/acpi/ipmi.c @@ -13,7 +13,7 @@ #include "hw/acpi/acpi.h" #include "hw/acpi/ipmi.h" -static Aml *aml_ipmi_crs(IPMIFwInfo *info) +static Aml *aml_ipmi_crs(IPMIFwInfo *info, const char *resource) { Aml *crs = aml_resource_template(); @@ -48,7 +48,8 @@ static Aml *aml_ipmi_crs(IPMIFwInfo *info) info->register_spacing, info->register_length)); break; case IPMI_MEMSPACE_SMBUS: - aml_append(crs, aml_return(aml_int(info->base_address))); + aml_append(crs, aml_i2c_serial_bus_device(info->base_address, + resource)); break; default: abort(); @@ -61,7 +62,7 @@ static Aml *aml_ipmi_crs(IPMIFwInfo *info) return crs; } -static Aml *aml_ipmi_device(IPMIFwInfo *info) +static Aml *aml_ipmi_device(IPMIFwInfo *info, const char *resource) { Aml *dev; uint16_t version = ((info->ipmi_spec_major_revision << 8) @@ -74,14 +75,14 @@ static Aml *aml_ipmi_device(IPMIFwInfo *info) aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s", info->interface_name))); aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid))); - aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info))); + aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info, resource))); aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type))); aml_append(dev, aml_name_decl("_SRV", aml_int(version))); return dev; } -void build_acpi_ipmi_devices(Aml *scope, BusState *bus) +void build_acpi_ipmi_devices(Aml *scope, BusState *bus, const char *resource) { BusChild *kid; @@ -101,6 +102,6 @@ void build_acpi_ipmi_devices(Aml *scope, BusState *bus) iic = IPMI_INTERFACE_GET_CLASS(obj); memset(&info, 0, sizeof(info)); iic->get_fwinfo(ii, &info); - aml_append(scope, aml_ipmi_device(&info)); + aml_append(scope, aml_ipmi_device(&info, resource)); } } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e54e571a75..8acf12df9a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1290,7 +1290,7 @@ static void build_isa_devices_aml(Aml *table) } else if (!obj) { error_report("No ISA bus, unable to define IPMI ACPI data"); } else { - build_acpi_ipmi_devices(scope, BUS(obj)); + build_acpi_ipmi_devices(scope, BUS(obj), "\\_SB.PCI0.ISA"); } aml_append(table, scope); diff --git a/include/hw/acpi/ipmi.h b/include/hw/acpi/ipmi.h index c38483565c..c14ad682ac 100644 --- a/include/hw/acpi/ipmi.h +++ b/include/hw/acpi/ipmi.h @@ -16,6 +16,6 @@ * bus matches the given bus. The resource is the ACPI resource that * contains the IPMI device, this is required for the I2C CRS. */ -void build_acpi_ipmi_devices(Aml *table, BusState *bus); +void build_acpi_ipmi_devices(Aml *table, BusState *bus, const char *resource); #endif /* HW_ACPI_IPMI_H */ From patchwork Thu Sep 19 21:39:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 1164919 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TJbxOARo"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46ZB0G2cHXz9sQp for ; Fri, 20 Sep 2019 08:11:58 +1000 (AEST) Received: from localhost ([::1]:49012 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB4ea-00013h-61 for incoming@patchwork.ozlabs.org; Thu, 19 Sep 2019 18:11:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56403) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iB49t-0001g1-Q7 for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iB49i-0006GZ-3B for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:10 -0400 Received: from mail-oi1-x241.google.com ([2607:f8b0:4864:20::241]:41645) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iB49h-0006DL-Jf for qemu-devel@nongnu.org; Thu, 19 Sep 2019 17:40:01 -0400 Received: by mail-oi1-x241.google.com with SMTP id w17so13263oiw.8 for ; Thu, 19 Sep 2019 14:39:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=WgyVtq9w6PvClORTpivvOhmxn0kbUdDtW15cfLnsIag=; b=TJbxOARoZ0uYDI7F+ZBw/2P1mA/mfxoitGUNvTQztvEi5l4fK2PevTGq6I1CvhrS3G McPR/nsQDFNi1/XQULBQoJuQW2ZHm3YNPiwAATFWnG2MFyE0CMP1dPT6ZG7avY69lmR/ T+ljxj3/TAo26K+Qje4UssGPm5IZdRd+VA3CYbNff8DVcL6u/RxseXdI+4Rzp3aD8J+a UITA96QA+EkVyehFMlfED69TPDkRL1o7zyIdPDF4UPmFbb1uuBHl8Y4I6WrxLYxni8nR 6Xx1co7dbo9up/zxLPf3qvWQ4vOgFyiKlcxdqXvnICaDbUdq1WgefZicsX+dNUh24NfV ejEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=WgyVtq9w6PvClORTpivvOhmxn0kbUdDtW15cfLnsIag=; b=BcGfCwK5DV4aC/wCQF0rFV+ofzuGnaKowXP37xVNOWNwIAW1DweM4O4uPUubqRtUEu g7tfUkbT6w/b8Zh4K/Aiq2xKWhJRkCg2mumimA+4fiL6IA+xDrY8giFZQYq5m4BCL8Wr w0P8kwKz+idTFmZcSELNLoxSVjYJdbdX3Oq/HHP6U64JiUUAfMjnMbvN8O/FSqwJ4n/O kyYrAgDNjEGbAvNZvMnO9iMR9ljqV5tW2qFALdHWOJT2jKtXId517Lblr7xyuryGhgyb gWgoU5O44Y2PQX0o33vYDbyub9av1B2N9zDFcaO6BuYrByBdDEbdub1jSxr4RQvuAjSR KDiw== X-Gm-Message-State: APjAAAUTqpZYd2ospWuGj+j1hBnnqHCr7Xp29vlmeWM2EUBGu0QZ3KXi QIysxRrGHSO4FWSs6MKwPA== X-Google-Smtp-Source: APXvYqwq1G1VJ4q62ElrN/BsbVMNVBn1Cql/EANQH7UAnUEcCE8s2MU1qhALhDZgDrt9dnytuEjxJQ== X-Received: by 2002:aca:50c2:: with SMTP id e185mr48033oib.152.1568929190461; Thu, 19 Sep 2019 14:39:50 -0700 (PDT) Received: from serve.minyard.net ([47.184.136.59]) by smtp.gmail.com with ESMTPSA id x140sm34370oix.42.2019.09.19.14.39.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2019 14:39:48 -0700 (PDT) Received: from t560.minyard.net (unknown [192.168.27.180]) by serve.minyard.net (Postfix) with ESMTPA id C596C1805B3; Thu, 19 Sep 2019 21:39:37 +0000 (UTC) From: minyard@acm.org To: Peter Maydell Subject: [PATCH 15/15] pc: Add an SMB0 ACPI device to q35 Date: Thu, 19 Sep 2019 16:39:24 -0500 Message-Id: <20190919213924.31852-16-minyard@acm.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919213924.31852-1-minyard@acm.org> References: <20190919213924.31852-1-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::241 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard , Fam Zheng , "Michael S . Tsirkin" , QEMU Developers , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?C=C3=A9dric_Le_Goater?= , Paolo Bonzini , Igor Mammedov , David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard This is so I2C devices can be found in the ACPI namespace. Currently that's only IPMI, but devices can be easily added now. Adding the devices required some PCI information, and the bus itself to be added to the PCMachineState structure. Note that this only works on Q35, the ACPI for PIIX4 is not capable of handling an SMBus device. Cc: Michael S. Tsirkin Cc: Igor Mammedov Signed-off-by: Corey Minyard --- hw/i386/acpi-build.c | 15 +++++++++++++++ hw/i386/pc_piix.c | 12 ++++++------ hw/i386/pc_q35.c | 9 +++++---- include/hw/i386/pc.h | 2 ++ tests/data/acpi/q35/DSDT | Bin 7841 -> 7879 bytes tests/data/acpi/q35/DSDT.bridge | Bin 7858 -> 7896 bytes tests/data/acpi/q35/DSDT.cphp | Bin 8304 -> 8342 bytes tests/data/acpi/q35/DSDT.dimmpxm | Bin 9494 -> 9532 bytes tests/data/acpi/q35/DSDT.ipmibt | Bin 7916 -> 7954 bytes tests/data/acpi/q35/DSDT.memhp | Bin 9200 -> 9238 bytes tests/data/acpi/q35/DSDT.mmio64 | Bin 8971 -> 9009 bytes tests/data/acpi/q35/DSDT.numamem | Bin 7847 -> 7885 bytes 12 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT index f9f36d1645c9b57aea38350d67dfaa143845697d..77ea60ffed421c566138fe6341421f579129a582 100644 GIT binary patch delta 62 zcmZ2zd)$`GCD=)CDW690Qk}0eJT(JhZ diff --git a/tests/data/acpi/q35/DSDT.bridge b/tests/data/acpi/q35/DSDT.bridge index 29176832ca9842c6654273ae1246321aa38b2821..fbc2d40000428b402586ea9302b5ccf36ef8de1e 100644 GIT binary patch delta 62 zcmdmFd&8E?CD? delta 24 fcmbQ{_`!k8CDh%4&?v< delta 24 fcmdnvHO-65CDZvE=4t$(!5&ShNQA diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt index 9634930e6125de4375d87a56a353f636985599d4..c3fca0a71efa7b55c958a49f305389426fbe7922 100644 GIT binary patch delta 62 zcmaE3JIRjACDI?2uJBvV)cXHo~& diff --git a/tests/data/acpi/q35/DSDT.memhp b/tests/data/acpi/q35/DSDT.memhp index dad5dc8db2f13bdb0de001da42c13b18286c3061..2abd0e36cd1344cbca3fa4ab59c5db2ea326d125 100644 GIT binary patch delta 62 zcmez1KFx#6CDsmbus && !pcmc->do_not_add_smb_acpi) { + build_smb0(dsdt, pcms->smbus, ICH9_SMB_DEV, ICH9_SMB_FUNC); + } } if (pcmc->legacy_cpu_hotplug) { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 2362675149..6824b72124 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -283,15 +283,14 @@ else { if (pcmc->pci_enabled && acpi_enabled) { DeviceState *piix4_pm; - I2CBus *smbus; smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0); /* TODO: Populate SPD eeprom data. */ - smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, - pcms->gsi[9], smi_irq, - pc_machine_is_smm_enabled(pcms), - &piix4_pm); - smbus_eeprom_init(smbus, 8, NULL, 0); + pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, + pcms->gsi[9], smi_irq, + pc_machine_is_smm_enabled(pcms), + &piix4_pm); + smbus_eeprom_init(pcms->smbus, 8, NULL, 0); object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP, TYPE_HOTPLUG_HANDLER, @@ -476,6 +475,7 @@ static void pc_i440fx_3_1_machine_options(MachineClass *m) pc_i440fx_4_0_machine_options(m); m->is_default = 0; + pcmc->do_not_add_smb_acpi = true; m->smbus_no_migration_support = true; m->alias = NULL; pcmc->pvh_enabled = false; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index d4e8a1cb9f..8fad20f314 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -316,10 +316,10 @@ static void pc_q35_init(MachineState *machine) if (pcms->smbus_enabled) { /* TODO: Populate SPD eeprom data. */ - smbus_eeprom_init(ich9_smb_init(host_bus, - PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC), - 0xb100), - 8, NULL, 0); + pcms->smbus = ich9_smb_init(host_bus, + PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC), + 0xb100); + smbus_eeprom_init(pcms->smbus, 8, NULL, 0); } pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state); @@ -421,6 +421,7 @@ static void pc_q35_3_1_machine_options(MachineClass *m) pc_q35_4_0_machine_options(m); m->default_kernel_irqchip_split = false; + pcmc->do_not_add_smb_acpi = true; m->smbus_no_migration_support = true; m->alias = NULL; pcmc->pvh_enabled = false; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 062feeb69e..6df4f4b6fb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -38,6 +38,7 @@ struct PCMachineState { HotplugHandler *acpi_dev; ISADevice *rtc; PCIBus *bus; + I2CBus *smbus; FWCfgState *fw_cfg; qemu_irq *gsi; PFlashCFI01 *flash[2]; @@ -117,6 +118,7 @@ typedef struct PCMachineClass { bool rsdp_in_ram; int legacy_acpi_table_size; unsigned acpi_data_size; + bool do_not_add_smb_acpi; /* SMBIOS compat: */ bool smbios_defaults;