From nobody Sat Nov 15 07:40:53 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=stgolabs.net) ARC-Seal: i=2; a=rsa-sha256; t=1753811894; cv=pass; d=zohomail.com; s=zohoarc; b=csVrG6ZVYAEso4LMyei+2Ic7VoenRaI1p3+/jAJI+7OVbAVHCbURTgTgL/PhnRWySB/0YLT88k/+6BRTiEczKM27m3XygeYGgqFlawJIv4opaDaS6nLpUvITYJ2+0HNqt15Ei8+7oYBsjHjC6ClpquBMyMPw1t3eiuWZ5PRklqw= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753811894; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=m3zmudrbJi3rUAWruVPmWJ/JHGSWiiguedxKVAHxwYo=; b=eOww0ddEWyYFwHM3DgYjEqf5cfVFnov96Lv4uxf/5bWnDN8Hv1nx7yqTT84tC8EyxOcQXYlILH7QmvWVxmfBi000zDFCJrgRaOS6mkEMY6gMXdUufT4PpTQRpXV4evv0je+3hRt34ZC1sCJVZLiSqQ6S/kjBfiha0LQuWQZw3MA= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=stgolabs.net) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1753811894842835.8943409843895; Tue, 29 Jul 2025 10:58:14 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ugoaF-0002ZL-C1; Tue, 29 Jul 2025 13:57:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ugnbY-0003A3-AA for qemu-devel@nongnu.org; Tue, 29 Jul 2025 12:55:10 -0400 Received: from bonobo.aspen.relay.mailchannels.net ([23.83.221.22]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ugnbU-0006BR-7R for qemu-devel@nongnu.org; Tue, 29 Jul 2025 12:55:07 -0400 Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 687F18A3E58; Tue, 29 Jul 2025 16:54:59 +0000 (UTC) Received: from pdx1-sub0-mail-a208.dreamhost.com (trex-blue-4.trex.outbound.svc.cluster.local [100.126.137.26]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id BCCDE8A36F9; Tue, 29 Jul 2025 16:54:58 +0000 (UTC) Received: from pdx1-sub0-mail-a208.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.126.137.26 (trex/7.1.3); Tue, 29 Jul 2025 16:54:59 +0000 Received: from offworld.lan (syn-076-167-199-067.res.spectrum.com [76.167.199.67]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: dave@stgolabs.net) by pdx1-sub0-mail-a208.dreamhost.com (Postfix) with ESMTPSA id 4bs1fp19SKzJl; Tue, 29 Jul 2025 09:54:58 -0700 (PDT) X-Sender-Id: dreamhost|x-authsender|dave@stgolabs.net ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1753808098; a=rsa-sha256; cv=none; b=lsBv49TCAGMBaDC9TPz1ykJc5u5Uhs02Wmbg5NlVlKy6jh1UMN73AGF+IMelxmjHxtV/T8 aVR++Toijt6SlM5MPYzm/ohkLYs2IEhIEUSQsEzbG+zLSZI8Ibs1oOapkcuZXwDVFhzc7r StrAay8KO8EdTY57UZGGVxjRNA6y15j5LIFqh7q1zEuwx8q7DGTjvOHoSJvo/rTx3Uv/I0 RPJ8higPIoL1kJ9jM/f7ZgpUICh6/CWCjQ/4Iup1FoeqrXRz34sjBFGWFAzpqD27Njnm/z tTzioIX+0/CVRgz/YRDQ/mvKk2Lu2+lvhu9nXW4ATPhYKMNROZlHj/7sHOKtPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1753808098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=m3zmudrbJi3rUAWruVPmWJ/JHGSWiiguedxKVAHxwYo=; b=5es03teX/DKlrRhWGb/iHFTlx7GZFqQWZScBeSuL/FmWGx3WudLcMaY3R2vv8BySBTS+ca K3MqsKuZfgqbQdziDP52QF2u8ZZ/OlewmowFslyYqMLN4784bCSHxFMXqrBNUL5b7GlGhV RW3awTyYRr/o+Z5PAP0YrZSfuV0FC+iK65NyEyYyLpFhXGF2xNjJPa3/0dTLQGc2rqKRmv 6vO0gAC8ZPuuBn+nGZa8fAOhhdx0et2XqnwApU86/lX/BPsP4YWzu9ay4o+7xDkFhqO8tZ +EYN45Gm0u4FrFpPTTW37ejZoOGIUvPs7zU4392tDotdi1JgMLZQA138C0oe6Q== ARC-Authentication-Results: i=1; rspamd-696f8998d-ps5xn; auth=pass smtp.auth=dreamhost smtp.mailfrom=dave@stgolabs.net X-Sender-Id: dreamhost|x-authsender|dave@stgolabs.net X-MC-Relay: Bad X-MailChannels-SenderId: dreamhost|x-authsender|dave@stgolabs.net X-MailChannels-Auth-Id: dreamhost X-Thoughtful-Trail: 58e523057b06f1b2_1753808099062_3055446933 X-MC-Loop-Signature: 1753808099062:1942783069 X-MC-Ingress-Time: 1753808099062 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=stgolabs.net; s=dreamhost; t=1753808098; bh=m3zmudrbJi3rUAWruVPmWJ/JHGSWiiguedxKVAHxwYo=; h=From:To:Cc:Subject:Date:Content-Transfer-Encoding; b=iUerdZrID4hh9DkAxqdSFTvoaS2hdUskmlvYbPH4IzPa5Ohc+k/NBZAoUJtbPV6pk Hyx9Pqkic1lukPDELa8kAbtyngh8VzopCdh74iDeASXid6CGEAwlF9jyUBEmU21HfW t5IZxyNzp5UgGcGpzw2Su+GeJW/2l2Vhu58o/+uuW3T9NwVdQZ8hLlcGRiuuGr9w2Y CB6UOHFeV+Lr98DHIrCaQ46h0oJDhzW+5hFlNkwEEGIHT3bq2KvQ9B7n980d0ETEbt Zo89h65tX70cp+IMJSpHgXTTy9tY4Mc2Eh9qnNu9LCf4d43ZLyJ0TO6rcvggx/IiOd kAV2q6sc92MFA== From: Davidlohr Bueso To: jonathan.cameron@huawei.com Cc: ira.weiny@intel.com, alucerop@amd.com, a.manzanares@samsung.com, linux-cxl@vger.kernel.org, qemu-devel@nongnu.org, Davidlohr Bueso Subject: [PATCH 1/2] hw/cxl: Refactor component register initialization Date: Tue, 29 Jul 2025 09:54:40 -0700 Message-Id: <20250729165441.1898150-2-dave@stgolabs.net> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250729165441.1898150-1-dave@stgolabs.net> References: <20250729165441.1898150-1-dave@stgolabs.net> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=23.83.221.22; envelope-from=dave@stgolabs.net; helo=bonobo.aspen.relay.mailchannels.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @stgolabs.net) X-ZM-MESSAGEID: 1753811899245116600 Content-Type: text/plain; charset="utf-8" From: Ira Weiny CXL 3.2 8.2.4 Table 8-22 defines which capabilities are mandatory, not permitted, or optional for each type of device. cxl_component_register_init_common() uses a rather odd 'fall through' mechanism to define each component register set. This assumes that any device or capability being added builds on the previous devices capabilities. This is not true as there are mutually exclusive capabilities defined. For example, downstream ports can not have snoop but it can have Back Invalidate capable decoders. Refactor this code to make it easier to add individual capabilities as defined by a device type. Any capability which is not specified by the type is left NULL'ed out which complies with the packed nature of the register array. Update all spec references to 3.2. No functional changes should be seen with this patch. Signed-off-by: Ira Weiny [rebased, no RAS for HBs, r3.2 references] Signed-off-by: Davidlohr Bueso --- hw/cxl/cxl-component-utils.c | 75 +++++++++++----------------------- include/hw/cxl/cxl_component.h | 33 ++++++++++----- 2 files changed, 46 insertions(+), 62 deletions(-) diff --git a/hw/cxl/cxl-component-utils.c b/hw/cxl/cxl-component-utils.c index ce42fa4a2946..a43d227336ca 100644 --- a/hw/cxl/cxl-component-utils.c +++ b/hw/cxl/cxl-component-utils.c @@ -289,32 +289,6 @@ void cxl_component_register_init_common(uint32_t *reg_= state, { int caps =3D 0; =20 - /* - * In CXL 2.0 the capabilities required for each CXL component are such - * that, with the ordering chosen here, a single number can be used to - * define which capabilities should be provided. - */ - switch (type) { - case CXL2_DOWNSTREAM_PORT: - case CXL2_DEVICE: - /* RAS, Link */ - caps =3D 2; - break; - case CXL2_UPSTREAM_PORT: - case CXL2_TYPE3_DEVICE: - case CXL2_LOGICAL_DEVICE: - /* + HDM */ - caps =3D 3; - break; - case CXL2_ROOT_PORT: - case CXL2_RC: - /* + Extended Security, + Snoop */ - caps =3D 5; - break; - default: - abort(); - } - memset(reg_state, 0, CXL2_COMPONENT_CM_REGION_SIZE); =20 /* CXL Capability Header Register */ @@ -322,11 +296,12 @@ void cxl_component_register_init_common(uint32_t *reg= _state, ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, VERSION, CXL_CAPABILITY_VERSION); ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, = 1); - ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps); =20 #define init_cap_reg(reg, id, version) = \ do { = \ - int which =3D R_CXL_##reg##_CAPABILITY_HEADER; = \ + int which =3D CXL_##reg##_CAP_HDR_IDX; = \ + if (CXL_##reg##_CAP_HDR_IDX > caps) = \ + caps =3D CXL_##reg##_CAP_HDR_IDX; = \ reg_state[which] =3D FIELD_DP32(reg_state[which], = \ CXL_##reg##_CAPABILITY_HEADER, ID, i= d); \ reg_state[which] =3D = \ @@ -337,37 +312,35 @@ void cxl_component_register_init_common(uint32_t *reg= _state, CXL_##reg##_REGISTERS_OFFSET); = \ } while (0) =20 + /* CXL r3.2 8.2.4 Table 8-22 */ switch (type) { - case CXL2_DEVICE: - case CXL2_TYPE3_DEVICE: - case CXL2_LOGICAL_DEVICE: case CXL2_ROOT_PORT: + case CXL2_RC: + /* + Extended Security, + Snoop */ + init_cap_reg(EXTSEC, 6, 1); + init_cap_reg(SNOOP, 8, 1); + /* fallthrough */ case CXL2_UPSTREAM_PORT: + case CXL2_TYPE3_DEVICE: + case CXL2_LOGICAL_DEVICE: + /* + HDM */ + init_cap_reg(HDM, 5, 1); + hdm_init_common(reg_state, write_msk, type); + /* fallthrough */ case CXL2_DOWNSTREAM_PORT: - init_cap_reg(RAS, 2, CXL_RAS_CAPABILITY_VERSION); - ras_init_common(reg_state, write_msk); + case CXL2_DEVICE: + /* RAS, Link */ + if (type !=3D CXL2_RC) { + init_cap_reg(RAS, 2, 2); + ras_init_common(reg_state, write_msk); + } + init_cap_reg(LINK, 4, 2); break; default: - break; - } - - init_cap_reg(LINK, 4, CXL_LINK_CAPABILITY_VERSION); - - if (caps < 3) { - return; - } - - if (type !=3D CXL2_ROOT_PORT) { - init_cap_reg(HDM, 5, CXL_HDM_CAPABILITY_VERSION); - hdm_init_common(reg_state, write_msk, type); - } - if (caps < 5) { - return; + abort(); } =20 - init_cap_reg(EXTSEC, 6, CXL_EXTSEC_CAP_VERSION); - init_cap_reg(SNOOP, 8, CXL_SNOOP_CAP_VERSION); - + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps); #undef init_cap_reg } =20 diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h index b721333cb7aa..cd92cb02532a 100644 --- a/include/hw/cxl/cxl_component.h +++ b/include/hw/cxl/cxl_component.h @@ -32,10 +32,20 @@ enum reg_type { }; =20 /* - * Capability registers are defined at the top of the CXL.cache/mem region= and - * are packed. For our purposes we will always define the caps in the same - * order. - * CXL r3.1 Table 8-22: CXL_CAPABILITY_ID Assignment for details. + * CXL r3.2 - 8.2.4 Table 8-22 and 8-23 + * + * Capability registers are defined at the top of the CXL.cache/mem region. + * They are defined to be packed and at variable offsets. However, NULL + * capabilities can be added to the packed array. To facilitate easier ac= cess + * within the QEMU code, define these at specified offsets. Then NULL out= any + * capabilities for devices which don't (or can't) have a particular capab= ility + * (see cxl_component_register_init_common). NULL capabilities are to be + * ignored by software. + * + * 'offsets' are based on index's which can then be used to report the arr= ay + * size in CXL Capability Header Register (index/offset 0). + * + * See CXL r3.2 Table 8-25 for an example of allowing a 'NULL' header. */ =20 /* CXL r3.1 Section 8.2.4.1: CXL Capability Header Register */ @@ -46,16 +56,17 @@ REG32(CXL_CAPABILITY_HEADER, 0) FIELD(CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 20, 4) FIELD(CXL_CAPABILITY_HEADER, ARRAY_SIZE, 24, 8) =20 -#define CXLx_CAPABILITY_HEADER(type, offset) \ - REG32(CXL_##type##_CAPABILITY_HEADER, offset) \ +#define CXLx_CAPABILITY_HEADER(type, idx) \ + enum { CXL_##type##_CAP_HDR_IDX =3D idx }; \ + REG32(CXL_##type##_CAPABILITY_HEADER, (idx * 0x4)) \ FIELD(CXL_##type##_CAPABILITY_HEADER, ID, 0, 16) \ FIELD(CXL_##type##_CAPABILITY_HEADER, VERSION, 16, 4) \ FIELD(CXL_##type##_CAPABILITY_HEADER, PTR, 20, 12) -CXLx_CAPABILITY_HEADER(RAS, 0x4) -CXLx_CAPABILITY_HEADER(LINK, 0x8) -CXLx_CAPABILITY_HEADER(HDM, 0xc) -CXLx_CAPABILITY_HEADER(EXTSEC, 0x10) -CXLx_CAPABILITY_HEADER(SNOOP, 0x14) +CXLx_CAPABILITY_HEADER(RAS, 1) +CXLx_CAPABILITY_HEADER(LINK, 2) +CXLx_CAPABILITY_HEADER(HDM, 3) +CXLx_CAPABILITY_HEADER(EXTSEC, 4) +CXLx_CAPABILITY_HEADER(SNOOP, 5) =20 /* * Capability structures contain the actual registers that the CXL compone= nt --=20 2.39.5 From nobody Sat Nov 15 07:40:53 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=stgolabs.net) ARC-Seal: i=2; a=rsa-sha256; t=1753811913; cv=pass; d=zohomail.com; s=zohoarc; b=GcvqKmbm3N3AhLtP/QfK/oDlTaaLvZukQiFN1BSIISGw6wxdpZiflAI0KU7EUBF6rwgEDjoJpYHBFjOOwQvGDITpHwvbsn94J/6kCK+9Z0CgucEtDddubyV5o75Q98deW0GHVY71c5GT2j2XBzMfai1/jDcN6OtbTiPOKavzbIg= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753811913; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=SSKY9j0C8ik1w8HXeNrmP+gIjQnzzMnhn4wzueihAg0=; b=lz9osvamO1DWu/u+8LcRVugWV4r7itrRpBKbJS+aQZhfjg1TY+d1T6kHgdqZTLIX2K50WpZge8h2jurPE7jnfuddObDuPpn5TIRSLlsQ2Ad2g4S8l8U3BTFihGmV9YeQinw6OIgtfW2ZDpfsTtrp0UteB1oUYozwisOf4hgKsEg= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=pass (i=1 dmarc=pass fromdomain=stgolabs.net) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 175381191309292.9035403900732; Tue, 29 Jul 2025 10:58:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ugoae-0002u1-W2; Tue, 29 Jul 2025 13:58:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ugnbb-0003LS-La for qemu-devel@nongnu.org; Tue, 29 Jul 2025 12:55:12 -0400 Received: from azure.banana.relay.mailchannels.net ([23.83.217.7]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ugnbU-0006BW-5c for qemu-devel@nongnu.org; Tue, 29 Jul 2025 12:55:08 -0400 Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id BDFDE1A5FBE; Tue, 29 Jul 2025 16:54:59 +0000 (UTC) Received: from pdx1-sub0-mail-a208.dreamhost.com (trex-blue-0.trex.outbound.svc.cluster.local [100.97.47.152]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 6555B1A6A1B; Tue, 29 Jul 2025 16:54:59 +0000 (UTC) Received: from pdx1-sub0-mail-a208.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384) by 100.97.47.152 (trex/7.1.3); Tue, 29 Jul 2025 16:54:59 +0000 Received: from offworld.lan (syn-076-167-199-067.res.spectrum.com [76.167.199.67]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: dave@stgolabs.net) by pdx1-sub0-mail-a208.dreamhost.com (Postfix) with ESMTPSA id 4bs1fp5TNrzGy; Tue, 29 Jul 2025 09:54:58 -0700 (PDT) X-Sender-Id: dreamhost|x-authsender|dave@stgolabs.net ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1753808099; a=rsa-sha256; cv=none; b=BuFPeRsxwGZRhkSUyrmylF7LVAHBcFkJ4Um1ZYEAP3tXq0Rc1kAh6fyfOygr4rcKlsD5uz cKpKicgKnKzC22v+v6gjce7svrjMUqF/fLgF6WOWqKHQMnW8zcszoh+reZdk0NiloSHwct oNx0HtTb3J2z4MTMxT10u/vCjaWXTviUtlUEbnXmUVm1af8GcjmSkFf54x8oAhkiQu62Kr thNEf9uIbjNGjZNGvAYQFmKxp0+OG20hg1Kg55dpOl2pAA5LWtNy3IAziNGBZOufRGPcXX pJGinJ/m6oSgfzustNsefDJQdx+hzKzPrvKVWhUez2yhzOLjD3n+ani0b3whjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=mailchannels.net; s=arc-2022; t=1753808099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=SSKY9j0C8ik1w8HXeNrmP+gIjQnzzMnhn4wzueihAg0=; b=T6hDOoO9apiPvNkW/rRDf4GEpPxFl6XJ/jo6SKi80dhb1zYs3DlHU92QEh48nNyt6j/df+ l3hgCoWZqpHiDBdEdULIYco6YCSsxEgVakl+KUE+Jl89nCmFo0bWDkz5XaDYjeAL2qj+Mh +yKEccmRpPrtOp9XSGPzfx2Lq67x+HztTKsWnyEr+OsCJflRj0oN5l0KVLgsKX3maci0O7 DP8BbUelxlo/aIa161bqSPOrmzMlCpmDLlNYaDNqBhituT7O3wyO9WUGRw66KYuj75DUh+ e0+/2FqFQwPZEIntDyhi4EFg9VqshM2Nn1jdH321tkj9lXwNIroSNOG/xmPmgA== ARC-Authentication-Results: i=1; rspamd-696f8998d-ps5xn; auth=pass smtp.auth=dreamhost smtp.mailfrom=dave@stgolabs.net X-Sender-Id: dreamhost|x-authsender|dave@stgolabs.net X-MC-Relay: Bad X-MailChannels-SenderId: dreamhost|x-authsender|dave@stgolabs.net X-MailChannels-Auth-Id: dreamhost X-Eight-Stop: 23031a606d3abb61_1753808099700_315847281 X-MC-Loop-Signature: 1753808099700:1908830250 X-MC-Ingress-Time: 1753808099699 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=stgolabs.net; s=dreamhost; t=1753808099; bh=SSKY9j0C8ik1w8HXeNrmP+gIjQnzzMnhn4wzueihAg0=; h=From:To:Cc:Subject:Date:Content-Transfer-Encoding; b=E8m0Yrm27obCMhvFvHJK8gu48oXrcBGefHiWb8pd/JeA7rwBUu6m8eHjJlZum6y19 ryzn2xnwWw5ucWRjEpKKJrVgGyHV1aFizmIzs1eqvKk/3UMRgSAg5lkMgB9TuE40Fi 29Brh0lk9OGi3uhkbbUZtMG48EncmCtQzHhuaXYWSm0d4wsIgNm4TLtjSBbLCZBzJN C4U/SRuhql+F+gt/yNNPNhlH/KP9uIoTklcAg/cQUcSP+w9sl80055HuDLhm30yD7Y ZRP4igEc7Vif6EFXnDllsbN9HCc4hm9G/XtGfHIQMy0X7MDsdSvmlGFWcl+nUSO0Zu GJWGUmQZs67Wg== From: Davidlohr Bueso To: jonathan.cameron@huawei.com Cc: ira.weiny@intel.com, alucerop@amd.com, a.manzanares@samsung.com, linux-cxl@vger.kernel.org, qemu-devel@nongnu.org, Davidlohr Bueso Subject: [PATCH 2/2] hw/cxl: Support Type3 HDM-DB Date: Tue, 29 Jul 2025 09:54:41 -0700 Message-Id: <20250729165441.1898150-3-dave@stgolabs.net> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250729165441.1898150-1-dave@stgolabs.net> References: <20250729165441.1898150-1-dave@stgolabs.net> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=23.83.217.7; envelope-from=dave@stgolabs.net; helo=azure.banana.relay.mailchannels.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @stgolabs.net) X-ZM-MESSAGEID: 1753811915891116600 Content-Type: text/plain; charset="utf-8" Add basic plumbing for memory expander devices that support Back Invalidation. This introduces a 'hdm-db=3Don|off' parameter and exposes the relevant BI RT/Decoder component cachemem registers. Signed-off-by: Davidlohr Bueso --- hw/cxl/cxl-component-utils.c | 135 +++++++++++++++++++++++++++++++-- hw/mem/cxl_type3.c | 5 +- include/hw/cxl/cxl_component.h | 54 ++++++++++++- include/hw/cxl/cxl_device.h | 3 + 4 files changed, 188 insertions(+), 9 deletions(-) diff --git a/hw/cxl/cxl-component-utils.c b/hw/cxl/cxl-component-utils.c index a43d227336ca..dfdbf23a427c 100644 --- a/hw/cxl/cxl-component-utils.c +++ b/hw/cxl/cxl-component-utils.c @@ -71,10 +71,40 @@ static uint64_t cxl_cache_mem_read_reg(void *opaque, hw= addr offset, case 4: if (cregs->special_ops && cregs->special_ops->read) { return cregs->special_ops->read(cxl_cstate, offset, 4); - } else { - QEMU_BUILD_BUG_ON(sizeof(*cregs->cache_mem_registers) !=3D 4); - return cregs->cache_mem_registers[offset / 4]; } + + QEMU_BUILD_BUG_ON(sizeof(*cregs->cache_mem_registers) !=3D 4); + + if (offset =3D=3D A_CXL_BI_RT_STATUS || + offset =3D=3D A_CXL_BI_DECODER_STATUS) { + int type; + uint64_t started; + + type =3D (offset =3D=3D A_CXL_BI_RT_STATUS) ? + CXL_BISTATE_RT : CXL_BISTATE_DECODER; + started =3D cxl_cstate->bi_state[type].last_commit; + + if (started) { + uint32_t val, *cache_mem =3D cregs->cache_mem_registers; + uint64_t now; + int set; + + val =3D cregs->cache_mem_registers[offset / 4]; + now =3D qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + /* arbitrary 100 ms to do the commit */ + set =3D !!(now >=3D started + 100); + + if (offset =3D=3D A_CXL_BI_RT_STATUS) { + val =3D FIELD_DP32(val, CXL_BI_RT_STATUS, COMMITTED, s= et); + } else { + val =3D FIELD_DP32(val, CXL_BI_DECODER_STATUS, COMMITT= ED, + set); + } + stl_le_p((uint8_t *)cache_mem + offset, val); + } + } + + return cregs->cache_mem_registers[offset / 4]; case 8: qemu_log_mask(LOG_UNIMP, "CXL 8 byte cache mem registers not implemented\n"); @@ -123,6 +153,47 @@ static void dumb_hdm_handler(CXLComponentState *cxl_cs= tate, hwaddr offset, } } =20 +static void dumb_bi_handler(CXLComponentState *cxl_cstate, hwaddr offset, + uint32_t value) +{ + ComponentRegisters *cregs =3D &cxl_cstate->crb; + uint32_t sts, *cache_mem =3D cregs->cache_mem_registers; + bool to_commit =3D false; + int type; + + switch (offset) { + case A_CXL_BI_RT_CTRL: + to_commit =3D FIELD_EX32(value, CXL_BI_RT_CTRL, COMMIT); + if (to_commit) { + sts =3D cxl_cache_mem_read_reg(cxl_cstate, + R_CXL_BI_RT_STATUS, 4); + sts =3D FIELD_DP32(sts, CXL_BI_RT_STATUS, COMMITTED, 0); + stl_le_p((uint8_t *)cache_mem + R_CXL_BI_RT_STATUS, sts); + type =3D CXL_BISTATE_RT; + } + break; + case A_CXL_BI_DECODER_CTRL: + to_commit =3D FIELD_EX32(value, CXL_BI_DECODER_CTRL, COMMIT); + if (to_commit) { + sts =3D cxl_cache_mem_read_reg(cxl_cstate, + R_CXL_BI_DECODER_STATUS, 4); + sts =3D FIELD_DP32(sts, CXL_BI_DECODER_STATUS, COMMITTED, 0); + stl_le_p((uint8_t *)cache_mem + R_CXL_BI_DECODER_STATUS, sts); + type =3D CXL_BISTATE_DECODER; + } + break; + default: + break; + } + + if (to_commit) { + cxl_cstate->bi_state[type].last_commit =3D + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + } + + stl_le_p((uint8_t *)cache_mem + offset, value); +} + static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t = value, unsigned size) { @@ -146,6 +217,9 @@ static void cxl_cache_mem_write_reg(void *opaque, hwadd= r offset, uint64_t value, if (offset >=3D A_CXL_HDM_DECODER_CAPABILITY && offset <=3D A_CXL_HDM_DECODER3_TARGET_LIST_HI) { dumb_hdm_handler(cxl_cstate, offset, value); + } else if (offset =3D=3D A_CXL_BI_RT_CTRL || + offset =3D=3D A_CXL_BI_DECODER_CTRL) { + dumb_bi_handler(cxl_cstate, offset, value); } else { cregs->cache_mem_registers[offset / 4] =3D value; } @@ -248,7 +322,7 @@ static void hdm_init_common(uint32_t *reg_state, uint32= _t *write_msk, ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_4K,= 1); ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, POISON_ON_ERR_CAP, 0); - if (type =3D=3D CXL2_TYPE3_DEVICE) { + if (type =3D=3D CXL2_TYPE3_DEVICE || type =3D=3D CXL3_TYPE3_DEVICE) { ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, 3_6_12_WAY= , 1); ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, 16_WAY, 1); } else { @@ -260,7 +334,8 @@ static void hdm_init_common(uint32_t *reg_state, uint32= _t *write_msk, UIO_DECODER_COUNT, 0); ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, MEMDATA_NXM_CA= P, 0); ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, - SUPPORTED_COHERENCY_MODEL, 0); /* Unknown */ + SUPPORTED_COHERENCY_MODEL, + type =3D=3D CXL3_TYPE3_DEVICE ? 3:0); /* host+dev or = Unknown */ ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_GLOBAL_CONTROL, HDM_DECODER_ENABLE, 0); write_msk[R_CXL_HDM_DECODER_GLOBAL_CONTROL] =3D 0x3; @@ -271,7 +346,7 @@ static void hdm_init_common(uint32_t *reg_state, uint32= _t *write_msk, write_msk[R_CXL_HDM_DECODER0_SIZE_HI + i * hdm_inc] =3D 0xffffffff; write_msk[R_CXL_HDM_DECODER0_CTRL + i * hdm_inc] =3D 0x13ff; if (type =3D=3D CXL2_DEVICE || - type =3D=3D CXL2_TYPE3_DEVICE || + type =3D=3D CXL2_TYPE3_DEVICE || type =3D=3D CXL3_TYPE3_DEVICE= || type =3D=3D CXL2_LOGICAL_DEVICE) { write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * hdm_inc] =3D 0xf0000000; @@ -283,6 +358,37 @@ static void hdm_init_common(uint32_t *reg_state, uint3= 2_t *write_msk, } } =20 +static void bi_rt_init_common(uint32_t *reg_state, uint32_t *write_msk) +{ + /* switch usp must commit the new BI-ID, timeout of 2secs */ + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_CAPABILITY, EXPLICIT_COMMIT, 1); + + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_CTRL, COMMIT, 0); + write_msk[R_CXL_BI_RT_CTRL] =3D 0xffffffff; + + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_STATUS, COMMITTED, 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_STATUS, ERR_NOT_COMMITTED, 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_STATUS, COMMIT_TMO_SCALE, 0x6); + ARRAY_FIELD_DP32(reg_state, CXL_BI_RT_STATUS, COMMIT_TMO_BASE, 0x2); +} + +static void bi_decoder_init_common(uint32_t *reg_state, uint32_t *write_ms= k) +{ + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_CAPABILITY, HDM_D, 0); + /* switch dsp must commit the new BI-ID, timeout of 2secs */ + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_CAPABILITY, EXPLICIT_COMMIT= , 1); + + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_CTRL, BI_FW, 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_CTRL, BI_ENABLE, 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_CTRL, COMMIT, 0); + write_msk[R_CXL_BI_DECODER_CTRL] =3D 0xffffffff; + + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_STATUS, COMMITTED, 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_STATUS, ERR_NOT_COMMITTED, = 0); + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_STATUS, COMMIT_TMO_SCALE, 0= x6); + ARRAY_FIELD_DP32(reg_state, CXL_BI_DECODER_STATUS, COMMIT_TMO_BASE, 0x= 2); +} + void cxl_component_register_init_common(uint32_t *reg_state, uint32_t *write_msk, enum reg_type type) @@ -323,6 +429,7 @@ void cxl_component_register_init_common(uint32_t *reg_s= tate, case CXL2_UPSTREAM_PORT: case CXL2_TYPE3_DEVICE: case CXL2_LOGICAL_DEVICE: + case CXL3_TYPE3_DEVICE: /* + HDM */ init_cap_reg(HDM, 5, 1); hdm_init_common(reg_state, write_msk, type); @@ -340,6 +447,22 @@ void cxl_component_register_init_common(uint32_t *reg_= state, abort(); } =20 + /* back invalidate */ + switch (type) { + case CXL2_UPSTREAM_PORT: + init_cap_reg(BI_RT, 11, CXL_BI_RT_CAP_VERSION); + bi_rt_init_common(reg_state, write_msk); + break; + case CXL2_ROOT_PORT: + case CXL2_DOWNSTREAM_PORT: + case CXL3_TYPE3_DEVICE: + init_cap_reg(BI_DECODER, 12, CXL_BI_DECODER_CAP_VERSION); + bi_decoder_init_common(reg_state, write_msk); + break; + default: + break; + } + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps); #undef init_cap_reg } diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index c4658e0955d5..c0eb99519975 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -1501,8 +1501,10 @@ void ct3d_reset(DeviceState *dev) uint32_t *reg_state =3D ct3d->cxl_cstate.crb.cache_mem_registers; uint32_t *write_msk =3D ct3d->cxl_cstate.crb.cache_mem_regs_write_mask; =20 + pcie_cap_fill_link_ep_usp(PCI_DEVICE(dev), ct3d->width, ct3d->speed); - cxl_component_register_init_common(reg_state, write_msk, CXL2_TYPE3_DE= VICE); + cxl_component_register_init_common(reg_state, write_msk, + ct3d->hdmdb ? CXL3_TYPE3_DEVICE : CXL2_TYPE3_DE= VICE); cxl_device_register_init_t3(ct3d, CXL_T3_MSIX_MBOX); =20 /* @@ -1541,6 +1543,7 @@ static const Property ct3_props[] =3D { DEFINE_PROP_PCIE_LINK_WIDTH("x-width", CXLType3Dev, width, PCIE_LINK_WIDTH_16), DEFINE_PROP_UINT16("chmu-port", CXLType3Dev, cxl_dstate.chmu[0].port, = 0), + DEFINE_PROP_BOOL("hdm-db", CXLType3Dev, hdmdb, 0), }; =20 static uint64_t get_lsa_size(CXLType3Dev *ct3d) diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h index cd92cb02532a..4872ec5ead39 100644 --- a/include/hw/cxl/cxl_component.h +++ b/include/hw/cxl/cxl_component.h @@ -29,6 +29,7 @@ enum reg_type { CXL2_UPSTREAM_PORT, CXL2_DOWNSTREAM_PORT, CXL3_SWITCH_MAILBOX_CCI, + CXL3_TYPE3_DEVICE, /* hdm-db */ }; =20 /* @@ -67,6 +68,8 @@ CXLx_CAPABILITY_HEADER(LINK, 2) CXLx_CAPABILITY_HEADER(HDM, 3) CXLx_CAPABILITY_HEADER(EXTSEC, 4) CXLx_CAPABILITY_HEADER(SNOOP, 5) +CXLx_CAPABILITY_HEADER(BI_RT, 6) +CXLx_CAPABILITY_HEADER(BI_DECODER, 7) =20 /* * Capability structures contain the actual registers that the CXL compone= nt @@ -211,10 +214,56 @@ HDM_DECODER_INIT(3); (CXL_IDE_REGISTERS_OFFSET + CXL_IDE_REGISTERS_SIZE) #define CXL_SNOOP_REGISTERS_SIZE 0x8 =20 -QEMU_BUILD_BUG_MSG((CXL_SNOOP_REGISTERS_OFFSET + - CXL_SNOOP_REGISTERS_SIZE) >=3D 0x1000, +#define CXL_BI_RT_CAP_VERSION 1 +#define CXL_BI_RT_REGISTERS_OFFSET \ + (CXL_SNOOP_REGISTERS_OFFSET + CXL_SNOOP_REGISTERS_SIZE) +#define CXL_BI_RT_REGISTERS_SIZE 0xC + +REG32(CXL_BI_RT_CAPABILITY, CXL_BI_RT_REGISTERS_OFFSET) + FIELD(CXL_BI_RT_CAPABILITY, EXPLICIT_COMMIT, 0, 1) +REG32(CXL_BI_RT_CTRL, CXL_BI_RT_REGISTERS_OFFSET + 0x4) + FIELD(CXL_BI_RT_CTRL, COMMIT, 0, 1) +REG32(CXL_BI_RT_STATUS, CXL_BI_RT_REGISTERS_OFFSET + 0x8) + FIELD(CXL_BI_RT_STATUS, COMMITTED, 0, 1) + FIELD(CXL_BI_RT_STATUS, ERR_NOT_COMMITTED, 1, 1) + FIELD(CXL_BI_RT_STATUS, COMMIT_TMO_SCALE, 8, 4) + FIELD(CXL_BI_RT_STATUS, COMMIT_TMO_BASE, 12, 4) + +/* CXL r3.2 8.2.4.27 - CXL BI Decoder Capability Structure */ +#define CXL_BI_DECODER_CAP_VERSION 1 +#define CXL_BI_DECODER_REGISTERS_OFFSET \ + (CXL_BI_RT_REGISTERS_OFFSET + CXL_BI_RT_REGISTERS_SIZE) +#define CXL_BI_DECODER_REGISTERS_SIZE 0xC + +REG32(CXL_BI_DECODER_CAPABILITY, CXL_BI_DECODER_REGISTERS_OFFSET) + FIELD(CXL_BI_DECODER_CAPABILITY, HDM_D, 0, 1) + FIELD(CXL_BI_DECODER_CAPABILITY, EXPLICIT_COMMIT, 1, 1) +REG32(CXL_BI_DECODER_CTRL, CXL_BI_DECODER_REGISTERS_OFFSET + 0x4) + FIELD(CXL_BI_DECODER_CTRL, BI_FW, 0, 1) + FIELD(CXL_BI_DECODER_CTRL, BI_ENABLE, 1, 1) + FIELD(CXL_BI_DECODER_CTRL, COMMIT, 2, 1) +REG32(CXL_BI_DECODER_STATUS, CXL_BI_DECODER_REGISTERS_OFFSET + 0x8) + FIELD(CXL_BI_DECODER_STATUS, COMMITTED, 0, 1) + FIELD(CXL_BI_DECODER_STATUS, ERR_NOT_COMMITTED, 1, 1) + FIELD(CXL_BI_DECODER_STATUS, COMMIT_TMO_SCALE, 8, 4) + FIELD(CXL_BI_DECODER_STATUS, COMMIT_TMO_BASE, 12, 4) + +QEMU_BUILD_BUG_MSG((CXL_BI_DECODER_REGISTERS_OFFSET + + CXL_BI_DECODER_REGISTERS_SIZE) >=3D 0x1000, "No space for registers"); =20 +/* to track BI explicit commit handling */ +enum { + CXL_BISTATE_RT =3D 0, /* switch usp */ + CXL_BISTATE_DECODER, /* switch dsp */ + CXL_BISTATE_MAX +}; + +typedef struct bi_state { + /* last 0->1 transition */ + uint64_t last_commit; +} BIState; + typedef struct component_registers { /* * Main memory region to be registered with QEMU core. @@ -260,6 +309,7 @@ typedef struct cxl_component { =20 CDATObject cdat; CXLCompObject compliance; + BIState bi_state[CXL_BISTATE_MAX]; /* for ups+dsp switches */ } CXLComponentState; =20 void cxl_component_register_block_init(Object *obj, diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 068c20d61ebc..ee5bcf0652b9 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -840,6 +840,9 @@ struct CXLType3Dev { CXLMemSparingReadAttrs rank_sparing_attrs; CXLMemSparingWriteAttrs rank_sparing_wr_attrs; =20 + /* BI flows */ + bool hdmdb; + struct dynamic_capacity { HostMemoryBackend *host_dc; AddressSpace host_dc_as; --=20 2.39.5