From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (EUR05-VI1-obe.outbound.protection.outlook.com [40.107.21.80]) by mx.groups.io with SMTP id smtpd.web12.7681.1601039921790880565 for ; Fri, 25 Sep 2020 06:18:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@armh.onmicrosoft.com header.s=selector2-armh-onmicrosoft-com header.b=7h0P7p8/; spf=pass (domain: arm.com, ip: 40.107.21.80, mailfrom: sami.mujawar@arm.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qIcmQzBxBK7nJQCe/24pDwq485qfMhfKBvkxamA5sqM=; b=7h0P7p8/ef+dW73iKFPpIkDdmnEz3ptswpqAGEntbaf4hXFeLFZxc0ATEj0E0BCntFWw/4LjZH7lRFD2t0fUHAIkc1yfRVsZzNuHJIQtszv8fYg/mwy41nvgSncn95dHbokSlUl32CKwC4jjGI3PuoVTqD16xNP8DYnZ6mfnFFE= Received: from AM6PR10CA0014.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:89::27) by AM5PR0801MB1779.eurprd08.prod.outlook.com (2603:10a6:203:2f::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3391.14; Fri, 25 Sep 2020 13:18:38 +0000 Received: from VE1EUR03FT047.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:89:cafe::83) by AM6PR10CA0014.outlook.office365.com (2603:10a6:209:89::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.21 via Frontend Transport; Fri, 25 Sep 2020 13:18:38 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; edk2.groups.io; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;edk2.groups.io; dmarc=bestguesspass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT047.mail.protection.outlook.com (10.152.19.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.21 via Frontend Transport; Fri, 25 Sep 2020 13:18:38 +0000 Received: ("Tessian outbound 7fc8f57bdedc:v64"); Fri, 25 Sep 2020 13:18:37 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 091a0bfd1a9f8bf5 X-CR-MTA-TID: 64aa7808 Received: from e9c4e5bd9da0.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 1B0F6095-3B87-433D-99B1-53BDF649A31C.1; Fri, 25 Sep 2020 13:18:32 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id e9c4e5bd9da0.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Fri, 25 Sep 2020 13:18:32 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eoU8jXw7HWt0Q0HS6Dde0y9PYi+/Ry/SxFFHJCT3U6DZ7xswLOm/50yKif/eZE1ZjjE32CDFGOVbThQSqDgJkRTt5/woBGYDgOChy4ROko2bFAcOt/fLSgU8o5S+GNNfeoxGRcIiviv9ga0pTgF/CM4HAO/fGP5wq/4o2yttoeDQQBzdpyVDYlj3vGpiiCnfDDwDwgbVk+hAzjjES6p9xSBhGjf0j2R56w9pXG5+P1/oWWpxIASME8kCZKr9Z3BGOnARycc8Re/cHGXk4HvvQgQLltdVcTmWkGqb8mZ1NV6bMw0XAqfE883RknEQU+w2zE/k9mNhoVHy2dUeZUxDew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qIcmQzBxBK7nJQCe/24pDwq485qfMhfKBvkxamA5sqM=; b=IdNMHGd8ZSZ6S7VR63Tzahh1wnOiTCcShVpmxuOr84O11MT2jVCzL8Ucw+QAINk5rumwh9SizfRFEEHnSKoDj5ohA82ygsx2rWVJHSCxI+ZVz/ER6cdGwP93g/ofbSjx70LQc0v3sFVE50XiG2l6G7hObO72cMtuWet8zKgt1ZpfsFWTUL+b8hwT4O4sQimMIEG4lQtmio0vMvTzJEH4HCQpUaEFRN9J72g5GkZ19jCfSSqTu7jX31vkdDm3nTTRYEdq/GGey5dMPAKwOxl/+GMpxf1TGDbDhJUBZdkm95OIqfE+B3nCeI2wtRtJvaPpjqYSkiGggFTfovKNfv4keg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=arm.com; dmarc=bestguesspass action=none header.from=arm.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qIcmQzBxBK7nJQCe/24pDwq485qfMhfKBvkxamA5sqM=; b=7h0P7p8/ef+dW73iKFPpIkDdmnEz3ptswpqAGEntbaf4hXFeLFZxc0ATEj0E0BCntFWw/4LjZH7lRFD2t0fUHAIkc1yfRVsZzNuHJIQtszv8fYg/mwy41nvgSncn95dHbokSlUl32CKwC4jjGI3PuoVTqD16xNP8DYnZ6mfnFFE= Received: from AM6P193CA0051.EURP193.PROD.OUTLOOK.COM (2603:10a6:209:8e::28) by DB6PR0801MB2023.eurprd08.prod.outlook.com (2603:10a6:4:75::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3391.15; Fri, 25 Sep 2020 13:18:28 +0000 Received: from VE1EUR03FT025.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:8e:cafe::12) by AM6P193CA0051.outlook.office365.com (2603:10a6:209:8e::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.22 via Frontend Transport; Fri, 25 Sep 2020 13:18:28 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=bestguesspass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; Received: from nebula.arm.com (40.67.248.234) by VE1EUR03FT025.mail.protection.outlook.com (10.152.18.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.3412.21 via Frontend Transport; Fri, 25 Sep 2020 13:18:28 +0000 Received: from AZ-NEU-EX04.Arm.com (10.251.24.32) by AZ-NEU-EX03.Arm.com (10.251.24.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Fri, 25 Sep 2020 13:18:25 +0000 Received: from E107187.Arm.com (10.57.53.22) by mail.arm.com (10.251.24.32) with Microsoft SMTP Server id 15.1.2044.4 via Frontend Transport; Fri, 25 Sep 2020 13:18:24 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , , , Subject: [PATCH v2 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator Date: Fri, 25 Sep 2020 14:18:22 +0100 Message-ID: <20200925131822.94148-3-sami.mujawar@arm.com> X-Mailer: git-send-email 2.11.0.windows.3 In-Reply-To: <20200925131822.94148-1-sami.mujawar@arm.com> References: <20200925131822.94148-1-sami.mujawar@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-Office365-Filtering-HT: Tenant X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 39e5ef2d-38aa-413a-9cb3-08d8615583ad X-MS-TrafficTypeDiagnostic: DB6PR0801MB2023:|AM5PR0801MB1779: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:1417;OLM:1417; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: dnHfFIKHt5kR9k3O5UcCBVEG0/YqEsYqJiJsfZMNHVNKKplWXI/EgHU0zicnapvydAvToMxW35O2i9gMDAhiPYcD2f26UC7TSmuqkhAjkVTsGkkT5QddczanMp7MTZsmlYuA7nQ6DKpeQ+3fFdc4Xuz6p3D55lxvo7J/Agnaw/mpsO75rnh1wFM6eSwng3Cdy/z+Aq0MQ6J6e1+ubKGxYFbisEiIocWxFodZVOXbSy41BB6oTPQotQPAu3F7Ifn34gJ0Bm/zoiOYY8x2APBhfbfvi2gWAikaUL0S45r0cQ7vFsDKdeSy3WZIqeObbb0xmCfQ2Yna7SERzxnM8houLuNctgzPeeb//W2qvalqimjsNLMHmPp3YjT2VezNOR1LbmK2WuvGSl+t9P5ABgGW8TkRc4lZ7ZSKijxee8H9ZUXwD+xJS4OpldIZLsZjb/+hHpD5zQimSYM1iBrd5IDTdA== X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:nebula.arm.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(4636009)(39860400002)(346002)(376002)(396003)(136003)(46966005)(4326008)(478600001)(186003)(2906002)(26005)(19627235002)(47076004)(36756003)(6916009)(70206006)(8936002)(70586007)(316002)(8676002)(5660300002)(7696005)(30864003)(83380400001)(1076003)(356005)(86362001)(2616005)(81166007)(82740400003)(82310400003)(426003)(336012)(54906003)(44832011)(21314003);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB2023 Return-Path: Sami.Mujawar@arm.com X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT047.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 763e90fb-d9e0-4fb2-6d65-08d861557dc1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bglWd2MyeopD8LEx216zXZaPehJsTZMSDuNFzokP+Be2snBGvNqTIvZVSblrY7z5CKlptv3N58QAD1DAOp58zM+zVXob8O0f9Z9SYZx5Z3ac+9H1HBK9tancz2ge236/g+3t1vQFKgvH2F1SAc3miWBi9IAiI6CfYCUpp9WsHXxn9QaAHc0dIxT6MBoHzsHGpJ40X/gn9IT8xO45JsGWt3Csy8uID8wZ9pJLAT3N1bHrc/iC4MFCNou2j33kLjdoJwPBBH3CUprQ45vcSF33DSPEEKPZ/mXrD6OhHyPEOt0MoGMJpUrSSk38lDMo0cq/gVKG+SkUBMIDxT8VoZzOFy5zXhOwpX66g+bQLO/IUsSfjGlNDWqTKg7pMLnyhmzD1N2WTSkdpVIBXKb7+42TFZXneYrn8jpV0TIauNxR1Gr8HwWY5dYQ/MEfG20bkETHXHpKE0X/61JF/v0PvJlMYQ== X-Forefront-Antispam-Report: CIP:63.35.35.123;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:64aa7808-outbound-1.mta.getcheckrecipient.com;PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com;CAT:NONE;SFS:(4636009)(136003)(346002)(376002)(396003)(39860400002)(46966005)(82740400003)(1076003)(4326008)(8936002)(2906002)(5660300002)(47076004)(8676002)(83380400001)(70586007)(30864003)(36756003)(81166007)(70206006)(2616005)(478600001)(36906005)(26005)(86362001)(186003)(54906003)(316002)(426003)(7696005)(336012)(6916009)(82310400003)(44832011)(19627235002)(21314003);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Sep 2020 13:18:38.0723 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 39e5ef2d-38aa-413a-9cb3-08d8615583ad X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VE1EUR03FT047.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1779 Content-Type: text/plain From: Pierre Gondois The Generic ACPI for Arm Components 1.0 Platform Design Document, s2.6.4 "ASL code examples" provides information to describe an Arm CoreLink CMN-600 Coherent Mesh Network using an ASL definition block table. The SSDT CMN-600 Table Generator uses the Configuration Manager protocol to obtain the following information about the CMN-600 device on the platform: - the PERIPHBASE address location and address range; - the ROOTNODEBASE address location; - the number of Debug and Trace Controller (DTC) and their respective interrupt number; The CMN-600 mesh is described using the CM_ARM_CMN_600_INFO and CM_ARM_EXTENDED_INTERRUPT structures in the Configuration Manager. The SSDT CMN-600 Table generator: - gets the CMN-600 hardware information from the configuration manager. - uses the AmlLib interfaces to parse the AML template BLOB and construct an AML tree. - uses the AmlLib to update: - the "_UID" value; - the address location and range of the PERIPHBASE; - the address location of the ROOTNODEBASE; - the number of Debug and Trace Controller (DTC) and their respective interrupt number; - serializes the AML tree to an output buffer. This output buffer contains the fixed-up AML code, which is then installed as an ACPI SSDT table. Signed-off-by: Pierre Gondois Co-authored-by: Sami Mujawar --- Notes: v2: - Updates corresponding to changes done in Acpi10.h based on [SAMI] review comments for [PATCH v1 1/1]. DynamicTablesPkg/DynamicTables.dsc.inc | 2 + DynamicTablesPkg/DynamicTablesPkg.ci.yaml | 4 + DynamicTablesPkg/Include/AcpiTableGenerator.h | 5 + DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 64 +- DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | 708 ++++++++++++++++++++ DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h | 51 ++ DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf | 34 + DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl | 81 +++ 8 files changed, 943 insertions(+), 6 deletions(-) diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 7fb14d8d1463f7d4502fd3a7708bc94bc336357d..fa33b7ee67e615e236cb13224c859594566df19f 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -34,6 +34,7 @@ [Components.common] # AML Fixup DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf + DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf # # Dynamic Table Factory Dxe @@ -53,6 +54,7 @@ [Components.common] # AML Fixup NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf + NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf } # diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml index c0d09e79fdf7f6003b5bbda45abc82a0caf4e53f..52c8c2ab4aefb21bea0289a4fd02209ae937a221 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml +++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml @@ -70,6 +70,7 @@ # in matching files "ExtendWords": [ "ARMHB", # ARMHB000 + "ARMHC", # ARMHC600 "ARMLTD", "EISAID", "CCIDX", @@ -81,8 +82,11 @@ "lgreater", "lless", "MPIDR", + "PERIPHBASE", "pytool", "Roadmap", + "ROOTNODEBASE", + "ssdtcmn", "ssdtserialporttemplate", "SMMUV", "standardised", diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index ef5018c312c1abbc205a06b037ffd6063cf02f0a..352331d6dc957b664d31d55b50efcce5b90d8ada 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -59,6 +59,10 @@ The Dynamic Tables Framework implements the following ACPI table generators: The SSDT Serial generator collates the Serial port information from the Configuration Manager and patches the SSDT Serial Port template to build the SSDT Serial port table. + - SSDT CMN-600: + The SSDT CMN-600 generator collates the CMN-600 information + from the Configuration Manager and patches the SSDT CMN-600 + template to build the SSDT CMN-600 table. */ /** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID. @@ -83,6 +87,7 @@ typedef enum StdAcpiTableId { EStdAcpiTableIdPptt, ///< PPTT Generator EStdAcpiTableIdSrat, ///< SRAT Generator EStdAcpiTableIdSsdtSerialPort, ///< SSDT Serial-Port Generator + EStdAcpiTableIdSsdtCmn600, ///< SSDT Cmn-600 Generator EStdAcpiTableIdMax } ESTD_ACPI_TABLE_ID; diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index b2534a6505d6fb695f0751bbb09d365bd93d092e..f0654866444e5497a010f7e7177199604f5d32b6 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -57,6 +57,7 @@ typedef enum ArmObjectID { EArmObjDeviceHandlePci, ///< 33 - Device Handle Pci EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info + EArmObjCmn600Info, ///< 36 - CMN-600 Info EArmObjMax } EARM_OBJECT_ID; @@ -653,18 +654,37 @@ typedef struct CmArmIdMapping { UINT32 Flags; } CM_ARM_ID_MAPPING; -/** A structure that describes the - SMMU interrupts for the Platform. - - ID: EArmObjSmmuInterruptArray +/** A structure that describes the Arm + Generic Interrupts. */ -typedef struct CmArmSmmuInterrupt { +typedef struct CmArmGenericInterrupt { /// Interrupt number UINT32 Interrupt; /// Flags UINT32 Flags; -} CM_ARM_SMMU_INTERRUPT; +} CM_ARM_GENERIC_INTERRUPT; + +/** A structure that describes the SMMU interrupts for the Platform. + + Interrupt Interrupt number. + Flags Interrupt flags as defined for SMMU node. + + ID: EArmObjSmmuInterruptArray +*/ +typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT; + +/** A structure that describes the AML Extended Interrupts. + + Interrupt Interrupt number. + Flags Interrupt flags as defined by the Interrupt + Vector Flags (Byte 3) of the Extended Interrupt + resource descriptor. + See EFI_ACPI_EXTENDED_INTERRUPT_FLAG_xxx in Acpi10.h + + ID: EArmObjExtendedInterruptInfo +*/ +typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT; /** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT @@ -825,6 +845,38 @@ typedef struct CmArmGenericInitiatorAffinityInfo { CM_OBJECT_TOKEN DeviceHandleToken; } CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO; +/** A structure that describes the CMN-600 hardware. + + ID: EArmObjCmn600Info +*/ +typedef struct CmArmCmn600Info { + /// The PERIPHBASE address. + /// Corresponds to the Configuration Node Region (CFGR) base address. + UINT64 PeriphBaseAddress; + + /// The PERIPHBASE address length. + /// Corresponds to the CFGR base address length. + UINT64 PeriphBaseAddressLength; + + /// The ROOTNODEBASE address. + /// Corresponds to the Root node (ROOT) base address. + UINT64 RootNodeBaseAddress; + + /// The Debug and Trace Logic Controller (DTC) count. + /// CMN-600 can have maximum 4 DTCs. + UINT8 DtcCount; + + /// DTC Interrupt list. + /// The first interrupt resource descriptor pertains to + /// DTC[0], the second to DTC[1] and so on. + /// DtcCount determines the number of DTC Interrupts that + /// are populated. If DTC count is 2 then DtcInterrupt[2] + /// and DtcInterrupt[3] are ignored. + /// Note: The size of CM_ARM_CMN_600_INFO structure remains + /// constant and does not vary with the DTC count. + CM_ARM_EXTENDED_INTERRUPT DtcInterrupt[4]; +} CM_ARM_CMN_600_INFO; + #pragma pack() #endif // ARM_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c new file mode 100644 index 0000000000000000000000000000000000000000..97a5c55fa3f60b6885862a76223994ab5c3daa26 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c @@ -0,0 +1,708 @@ +/** @file + SSDT CMN-600 AML Table Generator. + + Copyright (c) 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0 + - Generic ACPI for Arm Components 1.0 Platform Design Document +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include "SsdtCmn600Generator.h" + +/** C array containing the compiled AML template. + This symbol is defined in the auto generated C file + containing the AML bytecode array. +*/ +extern CHAR8 ssdtcmn600template_aml_code[]; + +/** SSDT CMN-600 Table Generator. + + Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjCmn600Info +*/ + +/** This macro expands to a function that retrieves the CMN-600 + Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjCmn600Info, + CM_ARM_CMN_600_INFO + ); + +/** Check the CMN-600 Information. + + @param [in] Cmn600InfoList Array of CMN-600 information structure. + @param [in] Cmn600Count Count of CMN-600 information structure. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +ValidateCmn600Info ( + IN CONST CM_ARM_CMN_600_INFO * Cmn600InfoList, + IN CONST UINT32 Cmn600Count + ) +{ + UINT32 Index; + UINT32 DtcIndex; + CONST CM_ARM_CMN_600_INFO * Cmn600Info; + CONST CM_ARM_GENERIC_INTERRUPT * DtcInterrupt; + + if ((Cmn600InfoList == NULL) || + (Cmn600Count == 0)) { + return EFI_INVALID_PARAMETER; + } + + // Validate each Cmn600Info structure. + for (Index = 0; Index < Cmn600Count; Index++) { + Cmn600Info = &Cmn600InfoList[Index]; + + // At least one DTC is required. + if ((Cmn600Info->DtcCount == 0) || + (Cmn600Info->DtcCount > MAX_DTC_COUNT)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid DTC configuration:\n" + )); + goto error_handler; + } + + // Check PERIPHBASE and ROOTNODEBASE address spaces are initialized. + if ((Cmn600Info->PeriphBaseAddress == 0) || + (Cmn600Info->RootNodeBaseAddress == 0)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid PERIPHBASE or ROOTNODEBASE.\n" + )); + goto error_handler; + } + + // The PERIPHBASE address must be 64MB aligned for a (X < 4) && (Y < 4) + // dimension mesh, and 256MB aligned otherwise. + // Check it is a least 64MB aligned. + if ((Cmn600Info->PeriphBaseAddress & + (PERIPHBASE_MIN_ADDRESS_LENGTH - 1)) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: PERIPHBASE address must be 64MB aligned.\n" + )); + goto error_handler; + } + + // The PERIPHBASE address is at most 64MB for a (X < 4) && (Y < 4) + // dimension mesh, and 256MB otherwise. Check it is not more than 256MB. + if (Cmn600Info->PeriphBaseAddressLength > PERIPHBASE_MAX_ADDRESS_LENGTH) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: PERIPHBASE address range must be < 256MB.\n" + )); + goto error_handler; + } + + // Check the 16 KB alignment of the ROOTNODEBASE address. + if ((Cmn600Info->PeriphBaseAddress & + (ROOTNODEBASE_ADDRESS_LENGTH - 1)) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Root base address must be 16KB aligned.\n" + )); + goto error_handler; + } + + // The ROOTNODEBASE address space should be included in the PERIPHBASE + // address space. + if ((Cmn600Info->PeriphBaseAddress > Cmn600Info->RootNodeBaseAddress) || + ((Cmn600Info->PeriphBaseAddress + Cmn600Info->PeriphBaseAddressLength) < + (Cmn600Info->RootNodeBaseAddress + ROOTNODEBASE_ADDRESS_LENGTH))) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600:" + " ROOTNODEBASE address space not in PERIPHBASE address space.\n" + )); + goto error_handler; + } + + for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) { + DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex]; + if (((DtcInterrupt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) == 0)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: DTC Interrupt must be consumer.\n" + )); + goto error_handler; + } + } // for DTC Interrupt + + } //for Cmn600InfoList + + return EFI_SUCCESS; + +error_handler: + + DEBUG (( + DEBUG_ERROR, + "PeriphBaseAddress = 0x%llx\n" + "PeriphBaseAddressLength = 0x%llx\n" + "RootNodeBaseAddress = 0x%llx\n" + "DtcCount = %u\n", + Cmn600Info->PeriphBaseAddress, + Cmn600Info->PeriphBaseAddressLength, + Cmn600Info->RootNodeBaseAddress, + Cmn600Info->DtcCount + )); + + DEBUG_CODE ( + for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) { + DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex]; + DEBUG (( + DEBUG_ERROR, + " DTC[%d]:\n", + DtcIndex + )); + DEBUG (( + DEBUG_ERROR, + " Interrupt = 0x%lx\n", + DtcInterrupt->Interrupt + )); + DEBUG (( + DEBUG_ERROR, + " Flags = 0x%lx\n", + DtcInterrupt->Flags + )); + } // for + ); + + return EFI_INVALID_PARAMETER; +} + +/** Build a SSDT table describing the CMN-600 device. + + The table created by this function must be freed by FreeSsdtCmn600Table. + + @param [in] Cmn600Info Pointer to a Cmn600 structure. + @param [in] Name The Name to give to the Device. + Must be a NULL-terminated ASL NameString + e.g.: "DEV0", "DV15.DEV0", etc. + @param [in] Uid UID for the CMN600 device. + @param [out] Table If success, pointer to the created SSDT table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. +**/ +STATIC +EFI_STATUS +EFIAPI +FixupCmn600Info ( + IN CONST CM_ARM_CMN_600_INFO * Cmn600Info, + IN CONST CHAR8 * Name, + IN CONST UINT64 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER ** Table + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + UINT8 Index; + CONST CM_ARM_GENERIC_INTERRUPT * DtcInt; + + EFI_ACPI_DESCRIPTION_HEADER * SsdtCmn600Template; + AML_ROOT_NODE_HANDLE RootNodeHandle; + AML_OBJECT_NODE_HANDLE NameOpIdNode; + AML_OBJECT_NODE_HANDLE NameOpCrsNode; + AML_DATA_NODE_HANDLE CmnPeriphBaseRdNode; + AML_DATA_NODE_HANDLE CmnRootNodeBaseRdNode; + AML_OBJECT_NODE_HANDLE DeviceNode; + + // Parse the Ssdt CMN-600 Template. + SsdtCmn600Template = (EFI_ACPI_DESCRIPTION_HEADER*) + ssdtcmn600template_aml_code; + + RootNodeHandle = NULL; + Status = AmlParseDefinitionBlock ( + SsdtCmn600Template, + &RootNodeHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to parse SSDT CMN-600 Template." + " Status = %r\n", + Status + )); + return Status; + } + + // Get the _UID NameOp object defined by the "Name ()" statement, + // and update its value. + Status = AmlFindNode ( + RootNodeHandle, + "\\_SB_.CMN0._UID", + &NameOpIdNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + Status = AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the _CRS object defined by the "Name ()" statement. + Status = AmlFindNode ( + RootNodeHandle, + "\\_SB.CMN0._CRS", + &NameOpCrsNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the first Rd node in the "_CRS" object. + // This is the PERIPHBASE node. + Status = AmlNameOpCrsGetFirstRdNode (NameOpCrsNode, &CmnPeriphBaseRdNode); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + if (CmnPeriphBaseRdNode == NULL) { + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + // Update the PERIPHBASE base address and length. + Status = AmlUpdateRdQWord ( + CmnPeriphBaseRdNode, + Cmn600Info->PeriphBaseAddress, + Cmn600Info->PeriphBaseAddressLength + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the QWord node corresponding to the ROOTNODEBASE. + // It is the second Resource Data element in the BufferNode's + // variable list of arguments. + Status = AmlNameOpCrsGetNextRdNode ( + CmnPeriphBaseRdNode, + &CmnRootNodeBaseRdNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + if (CmnRootNodeBaseRdNode == NULL) { + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + // Update the ROOTNODEBASE base address and length. + Status = AmlUpdateRdQWord ( + CmnRootNodeBaseRdNode, + Cmn600Info->RootNodeBaseAddress, + ROOTNODEBASE_ADDRESS_LENGTH + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Add the Interrupt node(s). + // Generate Resource Data node(s) corresponding to the "Interrupt ()" + // ASL function and add it at the last position in the list of + // Resource Data nodes. + for (Index = 0; Index < Cmn600Info->DtcCount; Index++) { + DtcInt = &Cmn600Info->DtcInterrupt[Index]; + Status = AmlCodeGenCrsAddRdInterrupt ( + NameOpCrsNode, + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0), + (UINT32*)&DtcInt->Interrupt, + 1 + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + } // for + + // Fixup the CMN600 device name. + // This MUST be done at the end, otherwise AML paths won't be valid anymore. + // Get the CMN0 variable defined by the "Device ()" statement. + Status = AmlFindNode (RootNodeHandle, "\\_SB_.CMN0", &DeviceNode); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Update the CMN600 Device's name. + Status = AmlDeviceOpUpdateName (DeviceNode, (CHAR8*)Name); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Serialise the definition block + Status = AmlSerializeDefinitionBlock ( + RootNodeHandle, + Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to Serialize SSDT Table Data." + " Status = %r\n", + Status + )); + } + +error_handler: + // Cleanup + if (RootNodeHandle != NULL) { + Status1 = AmlDeleteTree (RootNodeHandle); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to cleanup AML tree." + " Status = %r\n", + Status1 + )); + // If Status was success but we failed to delete the AML Tree + // return Status1 else return the original error code, i.e. Status. + if (!EFI_ERROR (Status)) { + return Status1; + } + } + } + + return Status; +} + +/** Free any resources allocated for constructing the SSDT tables for CMN-600. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeSsdtCmn600TableResourcesEx ( + IN CONST ACPI_TABLE_GENERATOR * CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER *** CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_ACPI_DESCRIPTION_HEADER ** TableList; + UINTN Index; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount == 0)) { + DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CMN-600: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + + for (Index = 0; Index < TableCount; Index++) { + if ((TableList[Index] != NULL) && + (TableList[Index]->Signature == + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) { + FreePool (TableList[Index]); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Could not free SSDT table at index %d." + " Status = %r\n", + Index, + EFI_INVALID_PARAMETER + )); + return EFI_INVALID_PARAMETER; + } + } //for + + // Free the table list. + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** Construct SSDT tables for describing CMN-600 meshes. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Could not find information. + @retval EFI_OUT_OF_RESOURCES Could not allocate memory. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtCmn600TableEx ( + IN CONST ACPI_TABLE_GENERATOR * This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER *** Table, + OUT UINTN * CONST TableCount + ) +{ + EFI_STATUS Status; + UINT64 Index; + CM_ARM_CMN_600_INFO * Cmn600Info; + UINT32 Cmn600Count; + CHAR8 NewName[5]; + EFI_ACPI_DESCRIPTION_HEADER ** TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + *Table = NULL; + + // Get CMN-600 information. + Status = GetEArmObjCmn600Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &Cmn600Info, + &Cmn600Count + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to get the CMN-600 information." + " Status = %r\n", + Status + )); + return Status; + } + + if ((Cmn600Count == 0) || (Cmn600Count > MAX_CMN600_DEVICES_SUPPORTED)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: CMN600 peripheral count = %d." + " This must be between 1 to 16.\n", + Cmn600Count + )); + return EFI_INVALID_PARAMETER; + } + + // Validate the CMN-600 Info. + Status = ValidateCmn600Info (Cmn600Info, Cmn600Count); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid CMN600 information. Status = %r\n", + Status + )); + return Status; + } + + // Allocate a table to store pointers to the SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER**) + AllocateZeroPool ( + (sizeof (EFI_ACPI_DESCRIPTION_HEADER*) * Cmn600Count) + ); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to allocate memory for Table List." + " Status = %r\n", + Status + )); + return Status; + } + + // Setup the table list early so that that appropriate cleanup + // can be done in case of failure. + *Table = TableList; + + NewName[0] = 'C'; + NewName[1] = 'M'; + NewName[2] = 'N'; + NewName[4] = '\0'; + for (Index = 0; Index < Cmn600Count; Index++) { + NewName[3] = AsciiFromHex ((UINT8)(Index)); + + // Build a SSDT table describing the CMN600 device. + Status = FixupCmn600Info ( + &Cmn600Info[Index], + NewName, + Index, + &TableList[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to build associated SSDT table." + " Status = %r\n", + Status + )); + break; + } + + // Increment the table count here so that appropriate clean-up + // can be done in case of failure. + *TableCount += 1; + } // for + + // Note: Table list and CMN600 device count has been setup. The + // framework will invoke FreeSsdtCmn600TableResourcesEx() even + // on failure, so appropriate clean-up will be done. + return Status; +} + +/** This macro defines the Raw Generator revision. +*/ +#define SSDT_CMN_600_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the Raw Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SsdtCmn600Generator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCmn600), + // Generator Description + L"ACPI.STD.SSDT.CMN600.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SSDT_CMN_600_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Build Table function + BuildSsdtCmn600TableEx, + // Free Resource function + FreeSsdtCmn600TableResourcesEx +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCmn600LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SsdtCmn600Generator); + DEBUG (( + DEBUG_INFO, + "SSDT-CMN-600: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCmn600LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SsdtCmn600Generator); + DEBUG (( + DEBUG_INFO, + "SSDT-CMN-600: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h new file mode 100644 index 0000000000000000000000000000000000000000..ab03b72236e78c28a5e36452bb5d7e93e957332d --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h @@ -0,0 +1,51 @@ +/** @file + + Copyright (c) 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object + - Std or STD - Standard + + @par Reference(s): + - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0 + - Generic ACPI for Arm Components 1.0 Platform Design Document +**/ + +#ifndef SSDT_CMN600_GENERATOR_H_ +#define SSDT_CMN600_GENERATOR_H_ + +/** PeriphBase maximum address length is 256MB (0x10000000) + for a (X >= 4) || (Y >= 4) dimensions mesh. +*/ +#define PERIPHBASE_MAX_ADDRESS_LENGTH SIZE_256MB + +/** PeriphBase minimum address length is 64MB (0x04000000) + for a (X < 4) && (Y < 4) dimensions mesh. +*/ +#define PERIPHBASE_MIN_ADDRESS_LENGTH SIZE_64MB + +/** RootNodeBase address length is 16KB (0x00004000). +*/ +#define ROOTNODEBASE_ADDRESS_LENGTH SIZE_16KB + +/** Maximum number of CMN-600 Debug and Trace Logic Controllers (DTC). +*/ +#define MAX_DTC_COUNT 4 + +/** Starting value for the UID to represent the CMN600 devices. +*/ +#define CMN600_DEVICE_START_UID 0 + +/** Maximum CMN-600 devices supported by this generator. + This generator supports a maximum of 16 CMN-600 devices. + Note: This is not a hard limitation and can be extended if needed. + Corresponding changes would be needed to support the Name and + UID fields describing the serial port. + +*/ +#define MAX_CMN600_DEVICES_SUPPORTED 16 + +#endif // SSDT_CMN600_GENERATOR_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf new file mode 100644 index 0000000000000000000000000000000000000000..821c0d531b983e19278062a11317bba83fdc141a --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf @@ -0,0 +1,34 @@ +## @file +# Ssdt CMN-600 Table Generator +# +# Copyright (c) 2020, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SsdtCmn600LibArm + FILE_GUID = CEDB450D-8F0E-4ACC-8FB7-F72EC7D216A4 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSsdtCmn600LibConstructor + DESTRUCTOR = AcpiSsdtCmn600LibDestructor + +[Sources] + SsdtCmn600Generator.c + SsdtCmn600Generator.h + SsdtCmn600Template.asl + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + AmlLib + BaseLib + diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl new file mode 100644 index 0000000000000000000000000000000000000000..023a89e2ab3d753cb1cdb8c423766294b0ea3fab --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl @@ -0,0 +1,81 @@ +/** @file + SSDT CMN-600 Template + + Copyright (c) 2020, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0 + - Generic ACPI for Arm Components 1.0 Platform Design Document + + @par Glossary: + - {template} - Data fixed up using AML Fixup APIs. + - {codegen} - Data generated using AML Codegen APIs. +**/ + +DefinitionBlock ("SsdtCmn600.aml", "SSDT", 2, "ARMLTD", "CMN-600", 1) { + Scope (_SB) { + // CMN-600 device object for a X * Y mesh, where (X >= 4) || (Y >= 4). + Device (CMN0) { // {template} + Name (_HID, "ARMHC600") + Name (_UID, 0x0) // {template} + + Name (_CRS, ResourceTemplate () { + // Descriptor for 256 MB of the CFG region at offset PERIPHBASE. + QWordMemory ( + ResourceConsumer, // bit 0 of general flags is 0. + PosDecode, + MinFixed, // Range is fixed. + MaxFixed, // Range is Fixed. + NonCacheable, + ReadWrite, + 0x00000000, // Granularity + 0xA0000000, // MinAddress // {template} + 0xAFFFFFFF, // MaxAddress // {template} + 0x00000000, // Translation + 0x10000000, // RangeLength // {template} + , // ResourceSourceIndex + , // ResourceSource + CFGR // DescriptorName + ) // QWordMemory + + // Descriptor for the root node. This is a 16 KB region at offset + // ROOTNODEBASE. In this example, ROOTNODEBASE starts at the 16 KB + // aligned offset of PERIPHBASE. + QWordMemory ( + ResourceConsumer, // bit 0 of general flags is 0. + PosDecode, + MinFixed, // Range is fixed. + MaxFixed, // Range is Fixed. + NonCacheable, + ReadWrite, + 0x00000000, // Granularity + 0xA0000000, // MinAddress // {template} + 0xAFFFFFFF, // MaxAddress // {template} + 0x00000000, // Translation + 0x10000000, // RangeLength // {template} + , // ResourceSourceIndex + , // ResourceSource + ROOT // DescriptorName + ) // QWordMemory + + // The Interrupt information is generated using AmlCodegen. + // Interrupt on PMU0 overflow, attached to DTC [0], with GSIV = . + // + // Interrupt ( // {codegen} + // ResourceConsumer, // ResourceUsage + // Level, // EdgeLevel + // ActiveHigh, // ActiveLevel + // Exclusive, // Shared + // , // ResourceSourceIndex + // , // ResourceSource + // // DescriptorName + // ) { + // 0xA5 // + // } // Interrupt + + }) // Name + } // Device + } // _SB +} // DefinitionBlock -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'