From patchwork Thu Dec 7 21:34:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121085 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8893674qgn; Thu, 7 Dec 2017 13:40:12 -0800 (PST) X-Google-Smtp-Source: AGs4zMbkWdwcuPkVTAy53CdlNs1a7BKGDNAe9R/cTqIhkw4X3ek6Eb/FAOPrr7cbWMe+tqTzHDZQ X-Received: by 10.13.243.195 with SMTP id c186mr19102664ywf.170.1512682812362; Thu, 07 Dec 2017 13:40:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512682812; cv=none; d=google.com; s=arc-20160816; b=Z08+/xaAK+PZ4QyPQTxi+SgMJNLbcTYE1K+cE8qJ+8p/j8ff33MxueLllrfYRbKBll f0fBr4DqlkHw4Qjw23UJVVmFCCfGANNz1SseX4McsuvbEPWJg4/x+yMI384Jrz1mYs5S 5+3uSt6x8KJEEcAtBLd6562B7om9C0T4TDEUbTaINIymje3Oox9gwI7WJqZO5DP6R93J i51Uqlpr9LMHLvqMzHa17XhC1n7APV1//7CD6JGDWonNm5L8ZBuQs2SVf7vOxuviVZLS LHqkSN5U8bcuy6BiDHU4wca7RMuailMJvVwh2Q9hcWyrE4Rh1qvd1Ai88DmvCI6yfIp5 HxCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=IIsa0k4TSzytd1gcdXeGvAL79/YvEgP8Bz5UukWutHE=; b=d4lLTg29KPjlPhU0gssZhWX8kOY8vJ/Vf7H8fExA4m0PxuPJvbrcZp8aUwUvygj25R tCOpuoHevPerlXMgUKSWNWleEOUNxoY5JA357XjksUHcNFWgq+NNqLNpP+pFu6zrlW04 hYyUhT56SO2xBcD4pXFxcCx1taZMjUat1Odt2p3hAoT/wgZSE5JdyDWxZvZ9s/EqSL/A YR1c2PPCkxVg5QjQHsVSd9PTC8KF6FUn/CQN54gjFvFc64W2PN2fiqdcFV8AC7j1ebE0 zj6eC717lHzMi0Q7WOyqcGQbAxJ4WrJ7IYMvpH4Upu52MaMX5Q7ftTYHzkcOiKeoSsnV p0nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=Tup79Wem; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m125si215727ybm.322.2017.12.07.13.40.12 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:40:12 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=Tup79Wem; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34455 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3tr-0006wx-S9 for patch@linaro.org; Thu, 07 Dec 2017 16:40:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3op-0001rJ-82 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3oo-00052F-7M for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:59 -0500 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]:39787) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3on-00051q-UP for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:58 -0500 Received: by mail-pg0-x244.google.com with SMTP id w7so5364854pgv.6 for ; Thu, 07 Dec 2017 13:34:57 -0800 (PST) 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=IIsa0k4TSzytd1gcdXeGvAL79/YvEgP8Bz5UukWutHE=; b=Tup79WemppZ4zHOePPRRPYtMXJEhaAsgvDwNVPxhChSB4UTjReqaRQRLnZnR3JKHiE t57v99kNvuFBX2hWqeZn93FVxP6A5tKrSNSotCLmpQbTErjB9N43Op/qBf3HgpEAFa9P q/a8NFfWi2bJsryNsMMjV3ZxmDvOWe12ssmnawI/IuKlm3+OL2OBsZSM298jPRF3XgVt qOw4U3ex0uLbsuiLBYAa8vZLyLLf4uZX+DRwlDcL714eAQVCA/QCn+o5MEb+C1yV3ixi 6J2LCS330m98PplBob57ypmUNvKaQwfTw8nIZnQsYrHZFVkOLRZUSHr/1xzTvmhEBeVn WLZg== 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=IIsa0k4TSzytd1gcdXeGvAL79/YvEgP8Bz5UukWutHE=; b=hUEjfH/960aCj1Es+bi/eAlomslZWCESPKo4KLRm/5uiQfsojyIcztGfAp0wps7xHl ROKr76KtTQ5IsZoSLENNWn/SEzl/29LId0YpFZnmiE0NHidnGACxG/V4XtlLssHGo2HK 4OTsv0nZ3raqQyYlDh/ufAUdMXKdGWXUv3MD393Kp6VHxM/np6lnYUcWxnxrttbHtE5D FvXcdLma7tkkJV2OqdJrLPjBi2aZCSbJvRk1AzunTxUJGv/IlH4bsByqwDENRJdARHyS yszoAi4IA/jRjNi83o8S9MZEwBMSK5ibjGW7sy+6rrFxkgzuAifyv4Pnda+ASo4I6q8d dj1A== X-Gm-Message-State: AJaThX6iaawCQGc5XsYVcAszqr+p3HvLLI1AeL7rS5XYs+HUwZ3yGBUW hK2BVqHPJPunumEDWaD3gfrHg2s= X-Received: by 10.99.108.5 with SMTP id h5mr27735360pgc.113.1512682496933; Thu, 07 Dec 2017 13:34:56 -0800 (PST) Received: from serve.minyard.net ([47.184.168.85]) by smtp.gmail.com with ESMTPSA id t23sm12014797pfg.97.2017.12.07.13.34.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:55 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id 2E2FA901; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id F1E3A300082; Thu, 7 Dec 2017 15:34:51 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:43 -0600 Message-Id: <1512682489-4474-2-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::244 Subject: [Qemu-devel] [PATCH 1/7] ipmi: Use proper struct reference for KCS vmstate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard The vmstate for isa_ipmi_kcs was referencing into the kcs structure, instead create a kcs structure separate and use that. There was also some issues in the state transfer. The inlen field was not being transferred, so if a transaction was in process during the transfer it would be messed up. And the use_irq field was transferred, but that should come from the configuration. This also fixes those issues and is tested under heavy load. Signed-off-by: Corey Minyard --- hw/ipmi/isa_ipmi_kcs.c | 75 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 15 deletions(-) -- 2.7.4 diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 8044497..c887251 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -423,24 +423,69 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); } -const VMStateDescription vmstate_ISAIPMIKCSDevice = { - .name = TYPE_IPMI_INTERFACE, +static const VMStateDescription vmstate_IPMIKCS = { + .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_BOOL(kcs.obf_irq_set, ISAIPMIKCSDevice), - VMSTATE_BOOL(kcs.atn_irq_set, ISAIPMIKCSDevice), - VMSTATE_BOOL(kcs.use_irq, ISAIPMIKCSDevice), - VMSTATE_BOOL(kcs.irqs_enabled, ISAIPMIKCSDevice), - VMSTATE_UINT32(kcs.outpos, ISAIPMIKCSDevice), - VMSTATE_UINT8_ARRAY(kcs.outmsg, ISAIPMIKCSDevice, MAX_IPMI_MSG_SIZE), - VMSTATE_UINT8_ARRAY(kcs.inmsg, ISAIPMIKCSDevice, MAX_IPMI_MSG_SIZE), - VMSTATE_BOOL(kcs.write_end, ISAIPMIKCSDevice), - VMSTATE_UINT8(kcs.status_reg, ISAIPMIKCSDevice), - VMSTATE_UINT8(kcs.data_out_reg, ISAIPMIKCSDevice), - VMSTATE_INT16(kcs.data_in_reg, ISAIPMIKCSDevice), - VMSTATE_INT16(kcs.cmd_reg, ISAIPMIKCSDevice), - VMSTATE_UINT8(kcs.waiting_rsp, ISAIPMIKCSDevice), + VMSTATE_BOOL(obf_irq_set, IPMIKCS), + VMSTATE_BOOL(atn_irq_set, IPMIKCS), + VMSTATE_BOOL(use_irq, IPMIKCS), + VMSTATE_BOOL(irqs_enabled, IPMIKCS), + VMSTATE_UINT32(outpos, IPMIKCS), + VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), + VMSTATE_UINT32(inlen, IPMIKCS), + 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 int isa_ipmi_kcs_load_old(QEMUFile *f, void *opaque, int version_id) +{ + ISAIPMIKCSDevice *iik = opaque; + IPMIKCS *k = &iik->kcs; + unsigned int i; + + if (version_id != 1) { + return -EINVAL; + } + + k->obf_irq_set = qemu_get_byte(f); + k->atn_irq_set = qemu_get_byte(f); + qemu_get_byte(f); /* Used to be use_irq, but that's not a good idea. */ + k->irqs_enabled = qemu_get_byte(f); + k->outpos = qemu_get_be32(f); + for (i = 0; i < MAX_IPMI_MSG_SIZE; i++) { + k->outmsg[i] = qemu_get_byte(f); + } + k->inlen = 0; /* This was forgotten on version 1, just reset it. */ + for (i = 0; i < MAX_IPMI_MSG_SIZE; i++) { + k->inmsg[i] = qemu_get_byte(f); + } + k->write_end = qemu_get_byte(f); + k->status_reg = qemu_get_byte(f); + k->data_out_reg = qemu_get_byte(f); + k->data_in_reg = qemu_get_be16(f); + k->cmd_reg = qemu_get_be16(f); + k->waiting_rsp = qemu_get_byte(f); + + return 0; +} + +static const VMStateDescription vmstate_ISAIPMIKCSDevice = { + .name = TYPE_IPMI_INTERFACE_PREFIX "isa-kcs", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 1, + .load_state_old = isa_ipmi_kcs_load_old, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(kcs, ISAIPMIKCSDevice, 1, vmstate_IPMIKCS, IPMIKCS), VMSTATE_END_OF_LIST() } }; From patchwork Thu Dec 7 21:34:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121084 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8890633qgn; Thu, 7 Dec 2017 13:36:39 -0800 (PST) X-Google-Smtp-Source: AGs4zMZwg2zQ8EMdW5UQfpHEiPDCAEJq60jVeIFYejdbHUFuheewy9cyLs2oTz7jhd7ahelE3avu X-Received: by 10.129.77.195 with SMTP id a186mr19619974ywb.363.1512682599000; Thu, 07 Dec 2017 13:36:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512682598; cv=none; d=google.com; s=arc-20160816; b=fd8s+zH+A+exPPyrz53NkedsRYzR0coEYv/FYiObTDqD+JaXaa7I0leRuS/my2TziZ G87rhlgIoD1G4A3n0OEUuvVd4ofHtLvTG/6LuwuUGbtDKkQPI4OJKbtGDsMqP0DaPCOz 5xlldPuLwZubIJG0itqOqvgVSnc9kFTxgnla7Wvlw3w+I0NhLKyXW/DqLBulkNbzmB/n xlt2f/hlvuJ+7EL5UsHonA9ZKl4rWDW4jndR3XfaxcqB8xWPGw0tGzYDlgv64ZrtogyY Jzrrv2WTAeQd36klQ+7UE6Hc7LjkAluRAnh+uYlGjO7tc7/M5b0geVPqpmtY94KtW8LY WhHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=4RoVAwc71qYqgGS7jwFyZQoajATDmjeCv/3UnmOYBk4=; b=NJTRfjAJQdXO+QGBoovEexoK8iKAMO9rxonoW6Kp7CPWoynpSTO6rvZezjatzqX+p4 //c+OJbRPSxSUQKSRzP1yqIDUu/vCdEPlY6mRKEcrk2p+ZAsz7xpE4UZiR2itEuYDlnd y1Qrh/IetIM7YLzZCLGs1k6ojTb6CGRcPEWQ3Q5IoZNjqj0mUtvE4OE7yGbREZEs2Sl0 DThfZofxPdN4JHbtgfhVRpQiuMaWUpWziCQf60RkJiSI8We6H/3Hb2BUjn8YH89/SsAq huA7QcjXmMd1KzNkeVm4Re1uBYXTkZCRWA+iiQ0V2cXrBlcyz1hGj86qorQXCZRcSHDa cmzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=D6cj/azy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id x3si33366ybf.287.2017.12.07.13.36.38 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:36:38 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=D6cj/azy; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34438 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3qQ-0002xf-Gl for patch@linaro.org; Thu, 07 Dec 2017 16:36:38 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46631) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3on-0001q7-Sw for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3om-00051S-U0 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:57 -0500 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]:41056) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3om-00051F-NO for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:56 -0500 Received: by mail-pg0-x244.google.com with SMTP id o2so5362295pgc.8 for ; Thu, 07 Dec 2017 13:34:56 -0800 (PST) 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=4RoVAwc71qYqgGS7jwFyZQoajATDmjeCv/3UnmOYBk4=; b=D6cj/azyW3gA2xa+UoA3zeJogfnN4pA5VIYsBjv88Sg+0/I+KXNih3bHc+nGkV9bqI e+/tRNmuIPmH1gyRWDAJVWN0MtLC5lt3lhzwXVrEW+HxixuGO5gGIME9y/Ar5Ve7whm0 /fkrcwG2w2B8wgDYjM3AOhK9TJDkXPmqHP7eJBmXjx1wrE7B2v69jUUPmmUNOTJ8B5Yp Le/jEdjO7v45OOQcggBEjqxtY98dqBY6hOuX6aBi+crcykjliIsCSbYwblbfUHpVUgsw LXe7wdiP0Eb4R2ToTXKcemuMq08mS56L7y6gsjE1ix2KEujsDefPEob4DWd6Hf4LflCT ot6w== 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=4RoVAwc71qYqgGS7jwFyZQoajATDmjeCv/3UnmOYBk4=; b=Sows9hTIwLM2d3xpXLAltFGOTUhPZ0P7J03w1e2ty7GNHCuKA9+F2dFROkBSQpF46l AJCSZv/loDXrAtKv8YjQm12vGClw9lGR6QbyZpDr+3KqKv8jCpLJvxOJvX/j9u3s6a1p KPAUdfKFAM3Kpwz9xNDkwYIELL2I+AnGDyz0POfgJyUS+NkZiUd2XoBXHNfdUgsLD1YN MqRsd3gCW62fsn/i2bMC391VoRerAzUOdBx7/3nftS8YuB0PSny2t15KnP9So05/ENlq xaiH5JsiW8bYXx99gI8KYhpPEAMH6FvN1uJ5n2jqLYBz9eE/SA3eNuyDZON8RUEjGoKw A0PA== X-Gm-Message-State: AJaThX5EIQcjeuYyMZuxZ6X1atG1FdDbScPGccsSYBqE0chmkp/IiZt4 3H3gcN5S1CmMmgy91Ysx+Q== X-Received: by 10.101.100.24 with SMTP id a24mr27291298pgv.239.1512682495513; Thu, 07 Dec 2017 13:34:55 -0800 (PST) Received: from serve.minyard.net ([47.184.168.85]) by smtp.gmail.com with ESMTPSA id i20sm10993250pfj.58.2017.12.07.13.34.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:54 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id 965D88F4; Thu, 7 Dec 2017 15:34:52 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id E35F230000E; Thu, 7 Dec 2017 15:34:51 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:44 -0600 Message-Id: <1512682489-4474-3-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::244 Subject: [Qemu-devel] [PATCH 2/7] ipmi: Use proper struct reference for BT vmstate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard The vmstate for isa_ipmi_bt was referencing into the bt structure, instead create a bt structure separate and use that. The version 1 of the BT transfer was fairly broken, if a migration occured during an IPMI operation, it is likely the migration would be corrupted because I misunderstood the VMSTATE_VBUFFER_UINT32() handling, I thought it handled transferring the length field, too. So I just remove support for that. I doubt anyone is using it at this point. This also removes the transfer of use_irq, since that should come from configuration. Signed-off-by: Corey Minyard --- hw/ipmi/isa_ipmi_bt.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) -- 2.7.4 diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index 13a8c09..c78ec6d 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -451,22 +451,39 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base); } -static const VMStateDescription vmstate_ISAIPMIBTDevice = { - .name = TYPE_IPMI_INTERFACE, + +const VMStateDescription vmstate_IPMIBT = { + .name = TYPE_IPMI_INTERFACE_PREFIX "bt", .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_BOOL(bt.obf_irq_set, ISAIPMIBTDevice), - VMSTATE_BOOL(bt.atn_irq_set, ISAIPMIBTDevice), - VMSTATE_BOOL(bt.use_irq, ISAIPMIBTDevice), - VMSTATE_BOOL(bt.irqs_enabled, ISAIPMIBTDevice), - VMSTATE_UINT32(bt.outpos, ISAIPMIBTDevice), - VMSTATE_VBUFFER_UINT32(bt.outmsg, ISAIPMIBTDevice, 1, NULL, bt.outlen), - VMSTATE_VBUFFER_UINT32(bt.inmsg, ISAIPMIBTDevice, 1, NULL, bt.inlen), - VMSTATE_UINT8(bt.control_reg, ISAIPMIBTDevice), - VMSTATE_UINT8(bt.mask_reg, ISAIPMIBTDevice), - VMSTATE_UINT8(bt.waiting_rsp, ISAIPMIBTDevice), - VMSTATE_UINT8(bt.waiting_seq, ISAIPMIBTDevice), + 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, + .minimum_version_id = 2, + /* + * Version 1 had messed up the array transfer, it's not even usable + * because it used VMSTATE_VBUFFER_UINT32, but it did not transfer + * the buffer length, so random things would happen. + */ + .fields = (VMStateField[]) { + VMSTATE_STRUCT(bt, ISAIPMIBTDevice, 1, vmstate_IPMIBT, IPMIBT), VMSTATE_END_OF_LIST() } }; From patchwork Thu Dec 7 21:34:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121089 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8897783qgn; Thu, 7 Dec 2017 13:45:08 -0800 (PST) X-Google-Smtp-Source: AGs4zMZjCP+EBzkVTZ2geP/EtWlbpDH2Ur+zW4H1GMtzAO0O06T9jssUlCO0eYIkUxNSHYVwJaDm X-Received: by 10.129.177.131 with SMTP id p125mr18415321ywh.282.1512683108588; Thu, 07 Dec 2017 13:45:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512683108; cv=none; d=google.com; s=arc-20160816; b=uTcKd1AHlUIzVHxvujvV4MCLDGZQmM9lzueetX1CxMYUiJ1CwDWfWT9ILRJZyCDBsa GlBy3besyLhHdTSqi/6be3pIfdPryC4oFhVIKr9VZHYpS4U/pjjXgVc9O8zwtzTMXTnw kOfdzHOM1JOUA0b1v4oKf/AgMI4RFKkOLB3oFmTO2GXGlSRkLA4fp2wDFnDdfdiG6zGD AhP58NKZFPWaDvLOzA7yxwR90ygt0SZ6SU0il4oNbZkybgewD7XapMWgPGdl/hM/TtBR PNO1/zTKOc7MTdWBUPkU9oAYuhcA7+IUysgADJ+w7bVwZlRiAZn1EQpASmsMWetjiRF9 8v+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=SixkL63jep4feub0NCcjBQGzpCafM79AgG/LSrItlnU=; b=cxxS24vnhOXo6moCMochT0YVVh8GAL6PHsHACcl8eHu7TQexGFwu8BInQas7k+1O0U 54gY2fKFimMZr92b/YS64x2mT1Yd3OGq/9k2oX+bx6VVVnaWqd21AdkRsb5EdcaeS0rn j97Z3kD+bMJ6K6OsbQWH0HjBfbd300M5FE1vof2wXx1AIahP2V5v2frtCA0VKi39l8bi wnX6xA2xG0kcT9LhXqhTcpnZxYh6WsZ+xWF3LVwkCp9DuGhm48uCtz4XiS3f/xgYOA/c Zz26xcNA0CVhlfDxLs8SHiCSJzx5hC6BQQvKHPlvNciUlgF9YVdvxCDG3dPbQ6PASVLd geLA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=hIEzPTKi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d189si1267691ybh.407.2017.12.07.13.45.08 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:45:08 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=hIEzPTKi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34476 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ye-0002Mq-3G for patch@linaro.org; Thu, 07 Dec 2017 16:45:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46757) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ot-0001vr-D2 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3oq-00053V-6E for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:03 -0500 Received: from mail-pg0-x22b.google.com ([2607:f8b0:400e:c05::22b]:38285) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3op-00052w-RY for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:00 -0500 Received: by mail-pg0-x22b.google.com with SMTP id f12so5368379pgo.5 for ; Thu, 07 Dec 2017 13:34:59 -0800 (PST) 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=SixkL63jep4feub0NCcjBQGzpCafM79AgG/LSrItlnU=; b=hIEzPTKi2+nnwknSFRu//COZkxZxQ8yuDpJ46vbQ3yFPZjA8L/5iJ0G9Pzd70az71o ldBmUuLflVOz3lCVlrBseemXPL2yBGGTEKyEcP6m4al/GkALEVBpcvNv/c6CrYRJelIA LbTdfBE24Xc0y1FQ5gOHjsYRHpFo23TesJz1Zyk12DWoCIoTqHjNomGTMGJvarqF9DTv b1O7nclyBwBWZT/HPG1qvN5yjGRtkNlQIxdxOh0rgwCKN7HAU7Nvws+LQr3j5RDoodp6 7xG7w/mnsNp3KDBZqQo+LCG8dWK0WloVPcgsZtE/6+SZBmyroCr9jbDsR3w7nMfOZ5tF y+yQ== 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=SixkL63jep4feub0NCcjBQGzpCafM79AgG/LSrItlnU=; b=RYzxMrO3Mg8ihCiBELWg3HgpGImVLC4mp7LkNe5/1snJGL32PpIE4WqqXQrzo2KS35 vAFppn3V2QrDOO+GpVnNQEFKKAwKK4RVkGVznNTOI69SjfhjtynIixzSdkllytQ8fFwI PNQ7bIKJIt22FPNkWaZuIRp+vR2ZLt7C4iOxmBRFauzUJ2zXqXUV05JAgfg0ssWn4CR0 FWLQ5bPnT77sZYMxYgiXTG/+Jw1CEM68OtXaWVjdiGVfUqbEBLSj0ATdGGhXIaQHKin1 4miuZXIrPZEuxpae9sDRg3LVMvmMWtQZPNO41NbLgp0iNAG4TwEZjx778K47GjeNOVtK Wo0g== X-Gm-Message-State: AJaThX6WAFxflLydXP4W+KJBN/pEhALvNspF0ectFrlDBlMy3V9VKbhd EmmNOFRkCOk87z9gPcsGGsQJdbI= X-Received: by 10.99.114.82 with SMTP id c18mr26897325pgn.221.1512682498409; Thu, 07 Dec 2017 13:34:58 -0800 (PST) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id f15sm9574843pgu.83.2017.12.07.13.34.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:56 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id 7E739BD7; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id 2083D300092; Thu, 7 Dec 2017 15:34:51 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:45 -0600 Message-Id: <1512682489-4474-4-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::22b Subject: [Qemu-devel] [PATCH 3/7] ipmi: Split out KCS-specific code from ISA KCS code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Get ready for PCI and other KCS interfaces. Signed-off-by: Corey Minyard --- hw/ipmi/Makefile.objs | 2 +- hw/ipmi/ipmi_kcs.c | 375 ++++++++++++++++++++++++++++++++++++++++++ hw/ipmi/isa_ipmi_kcs.c | 394 +++------------------------------------------ include/hw/ipmi/ipmi_kcs.h | 75 +++++++++ 4 files changed, 473 insertions(+), 373 deletions(-) create mode 100644 hw/ipmi/ipmi_kcs.c create mode 100644 include/hw/ipmi/ipmi_kcs.h -- 2.7.4 diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 1b422bb..6835d2f 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 0000000..cb22dee --- /dev/null +++ b/hw/ipmi/ipmi_kcs.c @@ -0,0 +1,375 @@ +/* + * 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 "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); +} + +const VMStateDescription vmstate_IPMIKCS = { + .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL(obf_irq_set, IPMIKCS), + VMSTATE_BOOL(atn_irq_set, IPMIKCS), + VMSTATE_BOOL(use_irq, IPMIKCS), + VMSTATE_BOOL(irqs_enabled, IPMIKCS), + VMSTATE_UINT32(outpos, IPMIKCS), + VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), + VMSTATE_UINT32(inlen, IPMIKCS), + 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 c887251..d1a5956 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 @@ -21,339 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include "qemu/osdep.h" #include "qapi/error.h" -#include "hw/hw.h" -#include "hw/ipmi/ipmi.h" +#include "hw/ipmi/ipmi_kcs.h" #include "hw/isa/isa.h" #include "hw/i386/pc.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) @@ -361,36 +34,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) @@ -408,14 +77,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); @@ -423,29 +95,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); } -static const VMStateDescription vmstate_IPMIKCS = { - .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_BOOL(obf_irq_set, IPMIKCS), - VMSTATE_BOOL(atn_irq_set, IPMIKCS), - VMSTATE_BOOL(use_irq, IPMIKCS), - VMSTATE_BOOL(irqs_enabled, IPMIKCS), - VMSTATE_UINT32(outpos, IPMIKCS), - VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), - VMSTATE_UINT32(inlen, IPMIKCS), - 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 int isa_ipmi_kcs_load_old(QEMUFile *f, void *opaque, int version_id) { ISAIPMIKCSDevice *iik = opaque; @@ -522,6 +171,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 0000000..af596be --- /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/hw.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; + +#endif /* HW_IPMI_KCS_H */ From patchwork Thu Dec 7 21:34:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121090 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8899421qgn; Thu, 7 Dec 2017 13:47:12 -0800 (PST) X-Google-Smtp-Source: AGs4zMbJvUrhPoKgpUrOunb2X/wL/zFZxfjz4ONKn1OjtF5qOxbaXkwqxVTs0tSG56nUJdZjg9lf X-Received: by 10.129.182.92 with SMTP id h28mr20226107ywk.402.1512683232121; Thu, 07 Dec 2017 13:47:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512683232; cv=none; d=google.com; s=arc-20160816; b=X7Abh0MNg8e4twT4VjaljGylljp4EvQ2FPXk6dN/+9TjcpNr/agsBHLgjD0kLOD0w3 dglYVq5x3SUQ4KSE3XUl7o2JebPiEJkbgxxvNecgAhuxekepYU0EQJKg0/Cv/oCE+1Pf lK1H+xr1EKMd9E7oI0hSP9ldLSfGnaU5W5qKRNlZckkLjF1YhaAb2Hk50XnIm6X5o2Me RsHmtUxV+vD++22Zn0bWt4MR03bBtuht+aANiETGatdHq0BAtAXLe7eFmPgecsIA4sdU 4YqZKUywONVd6kbcPvzAkKp7rJDpkK6iXapsG0g03eXvce0XmyydlvG2upkn0TF4agZn /uRQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=1qQ4hOGQ9ZS/COSobywP+2kYSRvjCKIrXKNN/lL9gLY=; b=saI++MNlLx5iYBrG8DOMaCl15PJEi2rTu7qONxoFuD0UQo1PbwBgyYD/E0cKt7+YMx ZtYxoPjIBzFz1ZZ0Qtyo6/pCuKqO8Z4eZkSilwTqL+9b2JqgrTCg6xC8xcQThWEE3eqm Hf08fQiT/H8w8aQMco88QpgITGwwPtp1P9JQoTHc+oYpJjPIMppnDuIoBd0YMrpDlVwL gjiEuuUnblANM9ubn9MZaiWrzPy4XGPmkRPFsKDnHuTVi00MAV6KfIAyvfFcu9s0Us52 fpx7pVXML/FYz7t6MpVgurcLA+TYtZTo81iUZiHkLHiLDTrOqbPfNOFQPrI+skA+A5T6 ghgA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=KadUmBd/; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id i5si1347450ywe.572.2017.12.07.13.47.11 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:47:12 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=KadUmBd/; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34487 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN40d-0003Yo-K3 for patch@linaro.org; Thu, 07 Dec 2017 16:47:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46751) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ot-0001vi-67 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3op-00053D-J4 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:03 -0500 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]:36716) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3op-00052a-7j for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:34:59 -0500 Received: by mail-pg0-x241.google.com with SMTP id k134so5382663pga.3 for ; Thu, 07 Dec 2017 13:34:59 -0800 (PST) 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=1qQ4hOGQ9ZS/COSobywP+2kYSRvjCKIrXKNN/lL9gLY=; b=KadUmBd/ziVvuCQpyapkJz6A67GdRQ//MUMKZ9ZYA2glYjpdVlqQJJfJK6k7hCnOWO ahhrU7V5ruO4oXFtOCjmM6NGBFYhbb+PezPN+05MwrDEfVm9szDu1AvrPX8D6cUZAlCP lkFRSW1r5fTd0YHy4c0/QbIQ9byK586U+E0cQ7KfOAhKhU35o4Khi0gHbnVAASAIG29Y XkHDTEQTPcgKcpgEvAwXkOTnWynTLHBmzuLP/n9Ib0e5ZOus5YMCXfukkYpzr73PW7v0 dxyOQPHDcZJWxpeNQ/H7fhNUNBquAR6y5wxh19FsOPG9Bq0TlfnR1y+CLuly5WCnup6t nZyw== 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=1qQ4hOGQ9ZS/COSobywP+2kYSRvjCKIrXKNN/lL9gLY=; b=fmwfxdRW3thO/CopBHFQzEpBFlA40ldAAA/Ggd/rxfTzv4wMW3dA6Edq7c56T1jzZV KT6De3fHZQWMaodf/RU7ByaH+Vm3DsRXLX/kH/Q0BzIdnieigYn4Szkozc8Y4bmODJ+T CVQNT9i3zpw56bwnDO2dwC4+s3v1p7k0YM/U3UfqsCVv9BySOisAJzk0Xls/x2GN0orG jCEQtcP0YaPcN63Yzi05K1UNX5yB40gC0l5ZDaZKlbJ/mZ+u1I91uTG4j4JMz1EMKmm/ oLDTxAR6CGmcuCrxFJaczyAOzVFNoDHiPmqeA1Gl3F3YRDoj0AToAhX/UgtO2pgtCqss zhkQ== X-Gm-Message-State: AKGB3mLaqp1zIgDgAZPuKNR10tFB+43ctmniNNr8AOdUCHCZfMZ1m8w0 iBUS/jGlwWZRKDMS+Q36wdx3eQE= X-Received: by 10.159.205.135 with SMTP id v7mr6801942plo.371.1512682497753; Thu, 07 Dec 2017 13:34:57 -0800 (PST) Received: from serve.minyard.net ([47.184.168.85]) by smtp.gmail.com with ESMTPSA id s65sm11714884pfk.7.2017.12.07.13.34.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:56 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id 4419DB76; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id 0A0ED30007F; Thu, 7 Dec 2017 15:34:52 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:46 -0600 Message-Id: <1512682489-4474-5-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::241 Subject: [Qemu-devel] [PATCH 4/7] ipmi: Split out BT-specific code from ISA BT code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Get ready for PCI and other BT interfaces. Signed-off-by: Corey Minyard --- hw/ipmi/Makefile.objs | 2 +- hw/ipmi/ipmi_bt.c | 399 +++++++++++++++++++++++++++++++++++++++++++ hw/ipmi/isa_ipmi_bt.c | 418 +++------------------------------------------- include/hw/ipmi/ipmi_bt.h | 72 ++++++++ 4 files changed, 493 insertions(+), 398 deletions(-) create mode 100644 hw/ipmi/ipmi_bt.c create mode 100644 include/hw/ipmi/ipmi_bt.h -- 2.7.4 diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 6835d2f..4ffa45a 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 0000000..e07e10a --- /dev/null +++ b/hw/ipmi/ipmi_bt.c @@ -0,0 +1,399 @@ +/* + * 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 "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); +} + +const VMStateDescription vmstate_IPMIBT = { + .name = TYPE_IPMI_INTERFACE_PREFIX "bt", + .version_id = 1, + .minimum_version_id = 1, + .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 c78ec6d..b711eca 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -23,402 +23,44 @@ */ #include "qemu/osdep.h" #include "qapi/error.h" -#include "hw/hw.h" -#include "hw/ipmi/ipmi.h" +#include "hw/ipmi/ipmi_bt.h" #include "hw/isa/isa.h" #include "hw/i386/pc.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) +{ + ISAIPMIBTDevice *iib = ib->opaque; + + qemu_irq_raise(iib->irq); +} + +static void isa_ipmi_bt_lower_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_lower(iib->irq); } static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) @@ -436,14 +78,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); @@ -451,28 +96,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base); } - -const VMStateDescription vmstate_IPMIBT = { - .name = TYPE_IPMI_INTERFACE_PREFIX "bt", - .version_id = 1, - .minimum_version_id = 1, - .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, @@ -520,6 +143,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 0000000..16066a7 --- /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/hw.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; + +#endif /* HW_IPMI_BT_H */ From patchwork Thu Dec 7 21:34:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121086 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8893744qgn; Thu, 7 Dec 2017 13:40:17 -0800 (PST) X-Google-Smtp-Source: AGs4zMaI5lTJ+E9e9JgtwoydXj367e90xt2xEO2fPSmsMm6LL2jPVOAlVOVf+JhLdzw0dWG/sqOz X-Received: by 10.129.75.22 with SMTP id y22mr19205502ywa.100.1512682817432; Thu, 07 Dec 2017 13:40:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512682817; cv=none; d=google.com; s=arc-20160816; b=0qH2V2QkEUVGvwW4watx47NxV/82fmTaWhOnvLl0gAMifEzZeVEUEw7n5XWJVMs1Tu 2RcxQEl0e+COEilDIvrzjpyundKhAPQ7NV7R2tco9ubH9jwHJgIcfWeriv8R+Xd8sPNa LOcmJJgDUlGiS7qg88+Iev6erUgerBZ9RH2GzEwsFXQqeTEtEmHXHJr/ro2qfjgrTpxJ DVTYMUTWzAzflCK8LsEL/r9qPvfpYZGERWIGH7axbMyb9uRNEw8XjQph1HbEdtUawMa4 ZQ2tIF5e0qR9ejG93Q74xJ/JGWQSJwZ7T4pFgORY0yME2hPKylr1B7XFS66RTMmEGI6G Girg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=ba92l3LFx1+Ht8sl7OUzFvrBVOExWKkqYB6FsoZgV1c=; b=KuuNrdEtIJuX65bNeMzE+WEWK78wbAvOKJ6eCFUoZwb+xMuMjw2z82D9NQf1zTl4ZA euDPphXZqy4Dm+NlXXPg20R2hLtt05Ns7ZIttTOlOIL+nZEIAV9fpSuTqHv9UqWR8i40 SJ3uqaG1NmJ/fzqwKapm/4YGjNYZueYBB0g8/RQjpekLIu2nLFhBOPSzYq5I1SzX4WL+ K+9FbhVgUQECWLzQzfeDFuXactrr47U9VJJzOX97loKIsRCXd4RTD0LLQ2zFv0aEEy57 4z8GJywF64WEH4Ue3CnffUdGbKby/tD9jjpbySDxVLLh4kF3BqPQRNzp+vmejcSvfX/S 1F/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=mzvmT0TV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id n20si1406278ywm.146.2017.12.07.13.40.17 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:40:17 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=mzvmT0TV; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34450 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3tw-0006Y0-Uv for patch@linaro.org; Thu, 07 Dec 2017 16:40:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46759) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ot-0001vx-Fd for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3or-00054h-8x for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:03 -0500 Received: from mail-pg0-x242.google.com ([2607:f8b0:400e:c05::242]:42392) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3or-00053r-0A for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:01 -0500 Received: by mail-pg0-x242.google.com with SMTP id e14so5366255pgr.9 for ; Thu, 07 Dec 2017 13:35:00 -0800 (PST) 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=ba92l3LFx1+Ht8sl7OUzFvrBVOExWKkqYB6FsoZgV1c=; b=mzvmT0TVMUmmrKZI6cEmEngWR0+kiAixsXXrIBiLZMxajzAR7zlkTKdw182FIP6Etw MHKuTmYbJdx6zdlxDY/vVppDq2iOnbsAqEfA96JFBmH5hIWEGPqoxVqnSrgSXUmfwdyU PwgRYyRMY5prb86Hr6iJ1khqxuNoNulNjcAALowSKyPE71aS2uuzLlN+RYgS9zxSNUvY Y321pDYSikLsTMIUStyKHb7qwcWrtAxj2hQX/TENQgEGwfb5gSeulPIaHkfkf9wfvIgF P70+C/iuXJCS0lhDymLlJ2XGSDzuqBUwluDF4/x0lMYkdftJqFk9tfLI4V+cOGMXAIs4 sT/w== 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=ba92l3LFx1+Ht8sl7OUzFvrBVOExWKkqYB6FsoZgV1c=; b=b5mcyGa7IAQO7p43QHVOqZb6vfUa1v08+sq9Wh7QT8znQwWysOThVyegdOfslGqsV1 EXHLH/9qn2qZ1K6d5qHxKOf9R9qOBJky2feW8HimBa8D0SR6M2UmeZ8VSkZpvSK9sILR MIvJhlwwEWUqgmIIpMxkzgJcecH2WUHIYqeHbwp31auHYLzZAs6ovm0qk241LQAzvLJc eds+o3YM9V59V7CWQ3msgnQLsrwZo+KyFIl2q0Ej096ZvjBBNJzJh999dXIck7yghjmQ fm/dg3auSKkzcCZz4Rmz6RYfBunRjt4Re80QMrzknva1U262vmj8YxQ4NIwImlYt1wjd ekTw== X-Gm-Message-State: AJaThX5S2T8zdF+DcMlMjN/PjjhpGj1e6/JghMPOAQEZdsKEoQXPlXVA A398hyWYBWJtggaVvy06mqhIrBA= X-Received: by 10.101.90.8 with SMTP id y8mr26733417pgs.21.1512682499863; Thu, 07 Dec 2017 13:34:59 -0800 (PST) Received: from serve.minyard.net ([47.184.168.85]) by smtp.gmail.com with ESMTPSA id s184sm1772017pfb.9.2017.12.07.13.34.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:57 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id B33F4CF0; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id 3D42D30008F; Thu, 7 Dec 2017 15:34:52 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:47 -0600 Message-Id: <1512682489-4474-6-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::242 Subject: [Qemu-devel] [PATCH 5/7] ipmi: Allow a size value to be passed for I/O space X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.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(-) -- 2.7.4 diff --git a/hw/ipmi/ipmi_bt.c b/hw/ipmi/ipmi_bt.c index e07e10a..130ef24 100644 --- a/hw/ipmi/ipmi_bt.c +++ b/hw/ipmi/ipmi_bt.c @@ -187,7 +187,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; @@ -206,6 +206,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; } @@ -228,7 +231,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; @@ -283,6 +286,9 @@ static void ipmi_bt_ioport_write(void *opaque, hwaddr addr, uint64_t val, ipmi_bt_lower_irq(ib); } break; + default: + /* Ignore. */ + break; } } @@ -344,14 +350,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); } const VMStateDescription vmstate_IPMIBT = { diff --git a/hw/ipmi/ipmi_kcs.c b/hw/ipmi/ipmi_kcs.c index cb22dee..ec6dc39 100644 --- a/hw/ipmi/ipmi_kcs.c +++ b/hw/ipmi/ipmi_kcs.c @@ -230,7 +230,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); @@ -241,6 +241,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) { @@ -250,6 +251,9 @@ static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) } } break; + + default: + ret = 0xff; } return ret; } @@ -265,7 +269,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; @@ -273,6 +277,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); @@ -319,13 +327,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); } const VMStateDescription vmstate_IPMIKCS = { diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index b711eca..a98e0ea 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -80,7 +80,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 d1a5956..ab6f62e 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -79,7 +79,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 0affe5a..0f62ea3 100644 --- a/include/hw/ipmi/ipmi.h +++ b/include/hw/ipmi/ipmi.h @@ -121,7 +121,12 @@ typedef struct 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 16066a7..d1e2abe 100644 --- a/include/hw/ipmi/ipmi_bt.h +++ b/include/hw/ipmi/ipmi_bt.h @@ -57,6 +57,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 af596be..8c75e86 100644 --- a/include/hw/ipmi/ipmi_kcs.h +++ b/include/hw/ipmi/ipmi_kcs.h @@ -60,6 +60,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 Dec 7 21:34:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121087 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8895112qgn; Thu, 7 Dec 2017 13:41:54 -0800 (PST) X-Google-Smtp-Source: AGs4zMa0qnr7PHjJEBebm+Os2c7ArqWuqvjOEcrZ096eeV1LV09e7zD/V8vgRQ9F0UVZhi7l6E07 X-Received: by 10.129.25.212 with SMTP id 203mr19539795ywz.261.1512682914323; Thu, 07 Dec 2017 13:41:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512682914; cv=none; d=google.com; s=arc-20160816; b=J1N9DaTKtC7wRQBn/7635wZllHaa2CtgLRDBx137Y1NvuLQpFk51jqaJJSPAF/hNeM V8msWC5X60TCuiQSD7/z7Uu5c/2D42TRzmbkFkKjbYVuuzYy6QSGzxtkHxszAHB3bkK3 6AyjwAlYG5nP2Dg+YqNz0W6Y5YYFD0YPQp8gY9iyHLoJzQt0ZWICzsG5RtXsHK15R9ST Z6ChYKn0o87aMEzft9vkcgj7WI60RbZtGE40Nz23wLBjIjjQpjXeQh6Z5FYaJ6z/08vF dA+s9mRz1npuf9LnWt55ZWNpYpOUJs7CPvr2JBOqur4UdqxJNp2FM3Yq2Wg3mNAn5Gjb JEnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=uRSobrHjxqieEnAdlolrJj1OZXyQ6+ruX8a9cfbGsE0=; b=Zx/ZnMqdGqePMwkl71qyCUoX20cBCskRSC0CCRLzKS1+LdL6fgjUkRThqd8X2Mbu1u jEbYFovsZyXDRlImAnVPdsRlEbXI8g8wDHtof8I9b2FAgl3HeWHHFDagqskeDRqDGGC/ +ble9+wg76V3oa2xuVHAH4jKdcfvelP1uQYTX3uzz+HlHAPIuXYvS8AKNX7AFkT2ARa0 C/54uQ8fn/mY+cEhpwfu0+HqY0imcit3QkdTe4hchy65GFarGgZVHmSNMCfGMH7CDBom TQT97qF44G1MFSECBtXua9e0mzE7XDfhs9rsfbKRrscL2LPO/s/CqPHrOMmeXWrHi83Q lIfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=pAkcwFj7; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c190si1303685ybh.532.2017.12.07.13.41.54 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:41:54 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=pAkcwFj7; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3vV-0008O8-Un for patch@linaro.org; Thu, 07 Dec 2017 16:41:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46761) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ot-0001w1-H5 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3oq-00053n-CG for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:03 -0500 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:45766) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3oq-00053I-5W for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:00 -0500 Received: by mail-pf0-x242.google.com with SMTP id u19so5641408pfa.12 for ; Thu, 07 Dec 2017 13:35:00 -0800 (PST) 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=uRSobrHjxqieEnAdlolrJj1OZXyQ6+ruX8a9cfbGsE0=; b=pAkcwFj7GUPsMSWQ8qeOKKJvZpKhfHXBrQ3iMVizumWRx4R0y2Jx29vPjmhmpipnZD CNmaCxbF0WCjrSQpMbYDIQ+GOZrGeZKz/HRPoV0gNzKJh7ljy8B8/XwVaFe4XOdFFRnX iAEi+Ukzd319M540pIpqVRaBKjtDMvet4HvCTIXURQOtoqjM1xEzIjPthL3bAxiHyBH/ mC6xWHHuyvKiPPjC9srmjCt2XLgPRKstvavuEeBNVJC2wnKDMCKihooZbZMTUCVJi1Ze EZVoF+8X8ZoLafQuRU8NoXTJ2LBERLSSof1ijdjTkh5Pi9P2abCG4tyEu+eEOjDL7Oie ke6Q== 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=uRSobrHjxqieEnAdlolrJj1OZXyQ6+ruX8a9cfbGsE0=; b=GFgTewNmfWd0eosLCfXnViIARN3SiUj9II+uE1HZnXxHtpRZDF+0tDRYWHLMcdTVD/ FZYLWWecgiNk845t2zSnboW/m9BqcmV3ftkUcFLEgbSMYE8Y6enaL3TV+AmKjzRzV4/S jk0rEOaxG/s22P0xy2VO55pcH3x/oBCebfwrKiGMRT7RLQhOe/svbmjyM9cLfXjjQGqo o1pmBK0ZrXk2AjYxetM23fgeOeAyDFZW4+YatTYF3a3c4sZuZjC7LoDAkVuNGltbhppp XJZhfLMsSW/Prz0V1cknWbBPBvVGI+NOGMUbkorAbJeqrPg8YhPi7YYUo2VHx7+1A9Uh vp5A== X-Gm-Message-State: AJaThX5O1h2OvlJLuIoV9YWrZrx0IIvVdKxUcH59LlC9QAOJCMIUHxwE Mz7BE1zDYZ+NiwVwsdNgdudJvJ8= X-Received: by 10.101.101.208 with SMTP id y16mr26974073pgv.159.1512682499106; Thu, 07 Dec 2017 13:34:59 -0800 (PST) Received: from serve.minyard.net ([47.184.168.85]) by smtp.gmail.com with ESMTPSA id u18sm10965021pgn.72.2017.12.07.13.34.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:57 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id CF89EDF0; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id 4F9CE302366; Thu, 7 Dec 2017 15:34:52 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:48 -0600 Message-Id: <1512682489-4474-7-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [PATCH 6/7] smbios:ipmi: Ignore IPMI devices with no fwinfo function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.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. Signed-off-by: Corey Minyard --- hw/smbios/smbios_type_38.c | 3 +++ 1 file changed, 3 insertions(+) -- 2.7.4 diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c index 56e8609..5475323 100644 --- a/hw/smbios/smbios_type_38.c +++ b/hw/smbios/smbios_type_38.c @@ -95,6 +95,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 Dec 7 21:34:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 121088 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp8896063qgn; Thu, 7 Dec 2017 13:43:01 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ1SJe6UZF/6aY2aqfnwh/F5EaKbnxVeYgd7vKzTX/UmKFcVbG0xNlz7l3iHLxefBoyqOaf X-Received: by 10.129.96.86 with SMTP id u83mr20366530ywb.19.1512682981721; Thu, 07 Dec 2017 13:43:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512682981; cv=none; d=google.com; s=arc-20160816; b=xdST7yK5R+91LQOUw6Yb0kQoSED5wCfvc90M5PpIEMBtNxZNcOAbnWWJ3eWuTRrb56 sRFeGazgCbBvvHO3iN/OAnpJmgUEj0EfUcKcvw7pHX/+fnUa81BhgmHTE2nBGJalVBeN nN8j1+RhTbbT23eM5Qirj+OzH23A+5C0OlU2XECV/CUK3WkNwdnyL8QgWTSm992FFk1F CUcshstqKulAAvYI9nr2IRSbmJQw+swN9YYGEW6V0wZePeOWo2hmi98H0DbXWEVdavQK T8MyuXYz4Swc9lZMpDVfIRa+ALQi8Fs6NpcAnlpOZv2zXUdcnwxF4P+W6Z2LBVwoyDOt SkuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=ujLV4jbcitAaR94nQzk+fl1zfmlMCfpFIiwI3Q0f7H0=; b=T+bPkPPBMFobK6uWJ4g84r3tQsMB46FOk7CtE/GB0/TOpXtV8ONAeA5Eqy310WwPtx TSIfEucel+7jDoKOT33CRLSAaGegBzGtFnMkgkcv5YCnGiMZBAATkVZlubYzi+jyRXzQ TTqL4XmcgY8fKBFu9GQigjZmTWzR9aVGSni3SWxGZHKW70iy/mY0mwDyPA9Crekc8p0Z aKhh4WeX4XSjEBKoY5e3HMRJ7hLZ5AqqCYXVV6AABpnfsEk9YYdcu5GTE67KGOEExzwm BED/wDYAYiQcYyM03WLm4yHPlZARTRJbySOoNoqxke1GXOdyWNT3I2DIyehELV6jdkM8 wnFQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=QGvCF3v4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id j184si1307598ywb.247.2017.12.07.13.43.01 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Dec 2017 13:43:01 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=QGvCF3v4; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org Received: from localhost ([::1]:34471 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3wb-0000Zj-A5 for patch@linaro.org; Thu, 07 Dec 2017 16:43:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46766) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eN3ot-0001wG-QI for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eN3or-00056U-Ui for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:03 -0500 Received: from mail-pg0-x242.google.com ([2607:f8b0:400e:c05::242]:38729) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eN3or-00054T-M0 for qemu-devel@nongnu.org; Thu, 07 Dec 2017 16:35:01 -0500 Received: by mail-pg0-x242.google.com with SMTP id f12so5368431pgo.5 for ; Thu, 07 Dec 2017 13:35:01 -0800 (PST) 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=ujLV4jbcitAaR94nQzk+fl1zfmlMCfpFIiwI3Q0f7H0=; b=QGvCF3v4L+D3IV+Tpo3XBQgdgdRe7D3WA8B75ssbt4lVYv4360HSzbQS9DmGyI7b2v jtbSeO4u65V+HEDMVrvjHJxaF2MPwwEt3+VsC+xpLJ2zeisazCgT722Thuf99ek33COh YwV8KNk6JKvRNBY3xJS5vn3zZKT8HxTHbhrKiooDcWM+2di7+8KNvfxGPBpOHapZhmvR +em4/awHf1Z0aOWnIHuUgqaXzo2CO5IW5APHH9cqY1qRiF0yxHfSgRcwW+XdBuLU5AtP nmI8NTaTeKfR7W7N1OPxO+pLQ9yY1xC+O/U6U/Hvg9DesrPWjVpznq335bFt+mrmBGk1 vZKg== 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=ujLV4jbcitAaR94nQzk+fl1zfmlMCfpFIiwI3Q0f7H0=; b=G+9TiB4h+KoXVras8ylBkq7X6dav7L0fMg0Ph9dWvUMvE34OyVFsiRWshN21ICCNdg cwMg2PnIWecndkgC49MHTg7cES+SBPNjjm2LgWgPlsM7/mRFpDoz+HJ11nUVkaAoZ06D Kz9SsoVfxIQsYVBiFaWPegEE6w9XlJtVltBVOWxwvWMwrXUa/StR7Iwui11VSVzveItc G62PtZn6u44XBt54aQeLsO58I0lfOKkyLAlPeg0yfRMsJu6PM8iErtf54NWRDdnGD/Bm RDE2Ip/4fpug6D/UGLmiAYL4VxtCtzJMMtorUsqo0MsNbuObwCQyQFRIE5S6wPgCQige 7oMw== X-Gm-Message-State: AJaThX512lMLZu7sorGbRwdEJOyxtBJaPLSdIdCBd2O4hyU4P+tGZb50 ugs5tpsrCUgHD1Ma29IbrQ== X-Received: by 10.99.124.88 with SMTP id l24mr27584356pgn.355.1512682500612; Thu, 07 Dec 2017 13:35:00 -0800 (PST) Received: from serve.minyard.net (serve.minyard.net. [2001:470:b8f6:1b::1]) by smtp.gmail.com with ESMTPSA id c191sm12618793pfg.24.2017.12.07.13.34.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Dec 2017 13:34:58 -0800 (PST) Received: from t430.minyard.net (t430m.minyard.net [192.168.27.3]) by serve.minyard.net (Postfix) with ESMTPA id E2ADAEB7; Thu, 7 Dec 2017 15:34:53 -0600 (CST) Received: by t430.minyard.net (Postfix, from userid 1000) id 5BFB8302367; Thu, 7 Dec 2017 15:34:52 -0600 (CST) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Thu, 7 Dec 2017 15:34:49 -0600 Message-Id: <1512682489-4474-8-git-send-email-minyard@acm.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512682489-4474-1-git-send-email-minyard@acm.org> References: <1512682489-4474-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::242 Subject: [Qemu-devel] [PATCH 7/7] ipmi: Add PCI IPMI interfaces X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Corey Minyard Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Corey Minyard Signed-off-by: Corey Minyard --- default-configs/i386-softmmu.mak | 2 + default-configs/x86_64-softmmu.mak | 2 + hw/ipmi/Makefile.objs | 2 + hw/ipmi/pci_ipmi_bt.c | 145 +++++++++++++++++++++++++++++++++++++ hw/ipmi/pci_ipmi_kcs.c | 145 +++++++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + 6 files changed, 297 insertions(+) create mode 100644 hw/ipmi/pci_ipmi_bt.c create mode 100644 hw/ipmi/pci_ipmi_kcs.c -- 2.7.4 diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 95ac4b4..07aaf77 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -14,7 +14,9 @@ CONFIG_IPMI=y CONFIG_IPMI_LOCAL=y CONFIG_IPMI_EXTERN=y CONFIG_ISA_IPMI_KCS=y +CONFIG_PCI_IPMI_KCS=y CONFIG_ISA_IPMI_BT=y +CONFIG_PCI_IPMI_BT=y CONFIG_SERIAL=y CONFIG_SERIAL_ISA=y CONFIG_PARALLEL=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 0221236..179ca35 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -14,7 +14,9 @@ CONFIG_IPMI=y CONFIG_IPMI_LOCAL=y CONFIG_IPMI_EXTERN=y CONFIG_ISA_IPMI_KCS=y +CONFIG_PCI_IPMI_KCS=y CONFIG_ISA_IPMI_BT=y +CONFIG_PCI_IPMI_BT=y CONFIG_SERIAL=y CONFIG_SERIAL_ISA=y CONFIG_PARALLEL=y diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs index 4ffa45a..2d7f080 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 0000000..8002027 --- /dev/null +++ b/hw/ipmi/pci_ipmi_bt.c @@ -0,0 +1,145 @@ +/* + * 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 "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 0000000..02bd52f --- /dev/null +++ b/hw/ipmi/pci_ipmi_kcs.c @@ -0,0 +1,145 @@ +/* + * 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 "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 8d02a0a..e8c3e4b 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -56,6 +56,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