From patchwork Tue Jul 24 07:09:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Huang X-Patchwork-Id: 142723 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp6935637ljj; Tue, 24 Jul 2018 00:17:54 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcMbsRbsZKzRlJT9xQ0b8XWYzoCqJsDDEQXxDnehVei4saj+GS8/keRmR4W+b1CY9uVb9Ln X-Received: by 2002:a63:1d3:: with SMTP id 202-v6mr15077737pgb.136.1532416674643; Tue, 24 Jul 2018 00:17:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532416674; cv=none; d=google.com; s=arc-20160816; b=vMZHNY130h7kta3S0qFtkEharYs7PPW/Vmtr82+4KIvTIY9iXYwovFMx5p/OqlSgTx xpB61wmZVN93EYZF0kVU2rUTFHgjvNRfGkZzWgMwue5zityr++f/b43d/mLhLe5w3//x tZTYGRJmKuP1U+sNcarSAKz9MdtgF92JWEfKgIWGXhjbZ5AUKXCFslOdu5RVNMstgt70 dsLq9lAD6CK1bzmPbJcUFhhqJ2ctpLpshZZYLC0BavHnFxdd0Q0LpF9xOyMOWtM88wuO h/pIYQd+v+LPfDmiJrhpXwiSg9MzwMGAIsO0PIKwvyV7VdQaExj04c46/AcNPClPxmiF AiYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version: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:delivered-to:arc-authentication-results; bh=4li9O4fob1Xq+q/d6fV3W/fPvZsS1LC9b++hXFl6AWY=; b=WjkwyZ6SMWfAJJtd+0R1rdqeRwuXTuhuukIjWsXrUYb2X8QjTdkCwlYXHkIjKXsQk2 EAGEaZIhZjxqb4SmJQ1J53ezfOLzwiCpDsEPNDKVBRc1GRhQCHTb/DsPWl7n9FQxKuZ+ TZC7EtDvPDwcpELKuflL8s7DiDPHqpYDVBcJq2mjztNNQAVESJJr1NUl1e3IiF4NDmlY wdibsgYBvgw23MUo8f4GPKckScKQNV9kYMWPxroBXG9VBoE3LaNK1WWuPh21lpTDGQcd HfYepiwvaBU/wujIkR2N4vEEY3IQqdLOi7W3RonAmwvtczv06A3j8t2h33bdU5vt7eDT 1JKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=UwVzjI0R; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id 190-v6si10959081pfy.293.2018.07.24.00.17.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Jul 2018 00:17:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=UwVzjI0R; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 48148210C124E; Tue, 24 Jul 2018 00:17:54 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c01::244; helo=mail-pl0-x244.google.com; envelope-from=ming.huang@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-pl0-x244.google.com (mail-pl0-x244.google.com [IPv6:2607:f8b0:400e:c01::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A3AF2210C123B for ; Tue, 24 Jul 2018 00:17:52 -0700 (PDT) Received: by mail-pl0-x244.google.com with SMTP id z7-v6so1349226plo.9 for ; Tue, 24 Jul 2018 00:17:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xEU0XyFdgULCrfJx6vOsc5k1Ee9FpBPDfKeW2FEyTw4=; b=UwVzjI0Rvy0Gx28YZ0BmHtGz77U2D7N9AChcb/0SgmMLREzKgfS1ZNuCdMChPfbK4T fb7izMIl1DPxEJ+222qVo0oV4YjY7Jv5xwn24mbOCGY/ilzWBXZB/CI0OemPesCSiNAO 8TQjkNzRInA+v4Xc3fq+lk9mdOU5B/6ZLZl/s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xEU0XyFdgULCrfJx6vOsc5k1Ee9FpBPDfKeW2FEyTw4=; b=GddFm2mQfJSP48rhdepa5+TMgFFUKNgQZqExXoL3S0FGKKs1GjVEqb0thl4ZSakVa5 lLTAYPjGdHoE9BA7Jg9a6JH6WGd1Y57L75+t9TOiPbxp3EedLd++QwcorqkxXkhmuQQq TMwCDfNQVpRDuknU4s1EOwF5bSzFvNmHYEQ6W+dq95m+p+JdcAlz8Iunw7itDJerd6Hm HFlqv0Y0nj+Ia2SfrONLO+eymKJREH1bNEUdJEA+06msnbAWdQ46uAEH+eHRyRu5hFXN CiGvLIb7ieYjbuwmM02OUbKlV8Ifp2QTjJiwbOUBUK//s3Y1oTVEyB2aLh3GVZx9q1mq KdlA== X-Gm-Message-State: AOUpUlGMnDFb8/7AvFmvC6kbq2xJdXPn/+VFUBmxkJn0+EWO9QtY4kiX V2ILOjPNp8h2ru+jXfeilln1+Q== X-Received: by 2002:a17:902:42e4:: with SMTP id h91-v6mr15729068pld.27.1532416672110; Tue, 24 Jul 2018 00:17:52 -0700 (PDT) Received: from localhost.localdomain ([120.31.149.194]) by smtp.gmail.com with ESMTPSA id t14-v6sm11449788pgu.0.2018.07.24.00.17.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Jul 2018 00:17:51 -0700 (PDT) From: Ming Huang To: leif.lindholm@linaro.org, linaro-uefi@lists.linaro.org, edk2-devel@lists.01.org, graeme.gregory@linaro.org Date: Tue, 24 Jul 2018 15:09:03 +0800 Message-Id: <20180724070922.63362-20-ming.huang@linaro.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180724070922.63362-1-ming.huang@linaro.org> References: <20180724070922.63362-1-ming.huang@linaro.org> Subject: [edk2] [PATCH edk2-platforms v1 19/38] Hisilicon/Hi1620: Add ACPI PPTT table X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: huangming23@huawei.com, xinliang.liu@linaro.org, john.garry@huawei.com, zhangjinsong2@huawei.com, huangdaode@hisilicon.com, guoheyi@huawei.com, wanghuiqiang@huawei.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" From: Heyi Guo This driver fetches information from MADT, so it is adaptable for partial good and 1P/2P, since MADT is updated for different configurations by certain mechanism. Since L2 cache is also private resource of core, so we need to set the next level of cache for L1I and L1D, which is important for OS to parse cache hierarchy. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Heyi Guo Signed-off-by: Ming Huang --- Silicon/Hisilicon/Hi1620/Pptt/Pptt.c | 543 ++++++++++++++++++++ Silicon/Hisilicon/Hi1620/Pptt/Pptt.h | 69 +++ Silicon/Hisilicon/Hi1620/Pptt/Pptt.inf | 48 ++ 3 files changed, 660 insertions(+) -- 2.17.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/Silicon/Hisilicon/Hi1620/Pptt/Pptt.c b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.c new file mode 100644 index 0000000000..944b4b9507 --- /dev/null +++ b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.c @@ -0,0 +1,543 @@ +/** @file +* +* Copyright (c) 2018, Hisilicon Limited. All rights reserved. +* Copyright (c) 2018, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +* Based on the files under Platform/ARM/JunoPkg/AcpiTables/ +* +**/ + +#include "Pptt.h" + +typedef EFI_ACPI_5_1_GIC_STRUCTURE ACPI_GIC_STRUCTURE; +typedef EFI_ACPI_5_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER ACPI_MADT_TABLE_HEADER; + +EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL; +EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol = NULL; + +EFI_ACPI_DESCRIPTION_HEADER mPpttHeader = + ARM_ACPI_HEADER ( + EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, + EFI_ACPI_DESCRIPTION_HEADER, + EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION + ); + +EFI_ACPI_6_2_PPTT_STRUCTURE_ID mPpttSocketType2[PPTT_SOCKET_COMPONENT_NO] = +{ + {2, sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID), {0, 0}, PPTT_VENDOR_ID, 0, 0, 0, 0, 0} +}; + +EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE mPpttCacheType1[PPTT_CACHE_NO]; + +STATIC UINT32 mSocketOffset[MAX_SOCKET]; +STATIC UINT32 mScclOffset[MAX_SCL]; +STATIC UINT32 mClusterOffset[MAX_SCL][MAX_CLUSTER_PER_SCL]; + +STATIC +VOID +InitCacheInfo ( + VOID + ) +{ + UINT8 Index; + EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES Type1Attributes; + CSSELR_DATA CsselrData; + CCSIDR_DATA CcsidrData; + + for (Index = 0; Index < PPTT_CACHE_NO; Index++) { + CsselrData.Data = 0; + CcsidrData.Data = 0; + SetMem ( + &Type1Attributes, + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES), + 0 + ); + + if (Index == 0) { //L1I + CsselrData.Bits.InD = 1; + CsselrData.Bits.Level = 0; + Type1Attributes.CacheType = 1; + } else if (Index == 1) { + Type1Attributes.CacheType = 0; + CsselrData.Bits.Level = Index - 1; + } else { + Type1Attributes.CacheType = 2; + CsselrData.Bits.Level = Index - 1; + } + + CcsidrData.Data = ReadCCSIDR (CsselrData.Data); + + if (CcsidrData.Bits.Wa == 1) { + Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_WRITE; + if (CcsidrData.Bits.Ra == 1) { + Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE; + } + } + + if (CcsidrData.Bits.Wt == 1) { + Type1Attributes.WritePolicy = 1; + } + DEBUG ((DEBUG_INFO, + "[Acpi PPTT] Level = %x!CcsidrData = %x!\n", + CsselrData.Bits.Level, + CcsidrData.Data)); + + mPpttCacheType1[Index].Type = EFI_ACPI_6_2_PPTT_TYPE_CACHE; + mPpttCacheType1[Index].Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE); + mPpttCacheType1[Index].Reserved[0] = 0; + mPpttCacheType1[Index].Reserved[1] = 0; + mPpttCacheType1[Index].Flags.SizePropertyValid = 1; + mPpttCacheType1[Index].Flags.NumberOfSetsValid = 1; + mPpttCacheType1[Index].Flags.AssociativityValid = 1; + mPpttCacheType1[Index].Flags.AllocationTypeValid = 1; + mPpttCacheType1[Index].Flags.CacheTypeValid = 1; + mPpttCacheType1[Index].Flags.WritePolicyValid = 1; + mPpttCacheType1[Index].Flags.LineSizeValid = 1; + mPpttCacheType1[Index].Flags.Reserved = 0; + mPpttCacheType1[Index].NextLevelOfCache = 0; + + if (Index != PPTT_CACHE_NO - 1) { + mPpttCacheType1[Index].NumberOfSets = (UINT16)CcsidrData.Bits.NumSets + 1; + mPpttCacheType1[Index].Associativity = (UINT16)CcsidrData.Bits.Associativity + 1; + mPpttCacheType1[Index].LineSize = (UINT16)( 1 << (CcsidrData.Bits.LineSize + 4)); + mPpttCacheType1[Index].Size = mPpttCacheType1[Index].LineSize * \ + mPpttCacheType1[Index].Associativity * \ + mPpttCacheType1[Index].NumberOfSets; + CopyMem ( + &mPpttCacheType1[Index].Attributes, + &Type1Attributes, + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES) + ); + } else { + // L3 cache + mPpttCacheType1[Index].Size = 0x2000000; // 32MB + mPpttCacheType1[Index].NumberOfSets = 0x800; + mPpttCacheType1[Index].Associativity = 0x0F; // CacheAssociativity16Way + SetMem ( + &mPpttCacheType1[Index].Attributes, + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES), + 0x0A + ); + mPpttCacheType1[Index].LineSize = 0x80; // 128byte + } + } +} + +STATIC +EFI_STATUS +AddCoreTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable, + IN OUT UINT32 *PpttTableLengthRemain, + IN UINT32 Parent, + IN UINT32 ResourceNo, + IN UINT32 ProcessorId + ) +{ + EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0; + EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *PpttType1; + UINT32 *PrivateResource; + UINT8 Index; + UINT32 NextLevelCacheOffset; + + if (*PpttTableLengthRemain < + (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) { + return EFI_OUT_OF_RESOURCES; + } + PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable + + PpttTable->Length); + PpttType0->Type = 0; + SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0); + PpttType0->Flags.AcpiProcessorIdValid = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID; + PpttType0->Parent= Parent; + PpttType0->AcpiProcessorId = ProcessorId; + PpttType0->NumberOfPrivateResources = ResourceNo; + PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + + ResourceNo * 4; + + *PpttTableLengthRemain -= (UINTN)PpttType0->Length; + PpttTable->Length += PpttType0->Length; + PrivateResource = (UINT32 *)((UINT8 *)PpttType0 + + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)); + + // Add cache type structure + for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) { + if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) { + return EFI_OUT_OF_RESOURCES; + } + *PrivateResource = PpttTable->Length; + PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable + + PpttTable->Length); + gBS->CopyMem ( + PpttType1, + &mPpttCacheType1[Index], + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE) + ); + *PpttTableLengthRemain -= PpttType1->Length; + PpttTable->Length += PpttType1->Length; + } + + NextLevelCacheOffset = *(PrivateResource - 1); + PrivateResource = (UINT32 *)(PpttType0 + 1); + // Set the next level to L2 for L1I and L1D + PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *) PpttTable + *PrivateResource++); + PpttType1->NextLevelOfCache = NextLevelCacheOffset; + PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *) PpttTable + *PrivateResource++); + PpttType1->NextLevelOfCache = NextLevelCacheOffset; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +AddClusterTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable, + IN OUT UINT32 *PpttTableLengthRemain, + IN UINT32 Parent, + IN UINT32 ResourceNo + ) +{ + EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0; + + if ((*PpttTableLengthRemain) < + (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) { + return EFI_OUT_OF_RESOURCES; + } + PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable + + PpttTable->Length); + PpttType0->Type = 0; + SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0); + PpttType0->Parent= Parent; + PpttType0->NumberOfPrivateResources = ResourceNo; + PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + + ResourceNo * 4; + + *PpttTableLengthRemain -= PpttType0->Length; + PpttTable->Length += PpttType0->Length; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +AddScclTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable, + IN OUT UINT32 *PpttTableLengthRemain, + IN UINT32 Parent, + IN UINT32 ResourceNo + ) +{ + EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0; + EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *PpttType1; + UINT32 *PrivateResource; + + if (*PpttTableLengthRemain < + (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) { + return EFI_OUT_OF_RESOURCES; + } + PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable + + PpttTable->Length); + PpttType0->Type = 0; + SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0); + PpttType0->Parent= Parent; + PpttType0->NumberOfPrivateResources = ResourceNo; + PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + + ResourceNo * 4; + + *PpttTableLengthRemain -= PpttType0->Length; + PpttTable->Length += PpttType0->Length; + PrivateResource = (UINT32 *)((UINT8 *)PpttType0 + + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)); + + // Add cache type structure + if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) { + return EFI_OUT_OF_RESOURCES; + } + *PrivateResource = PpttTable->Length; + PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable + + PpttTable->Length); + gBS->CopyMem ( + PpttType1, + &mPpttCacheType1[3], + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE) + ); + *PpttTableLengthRemain -= PpttType1->Length; + PpttTable->Length += PpttType1->Length; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +AddSocketTable ( + IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable, + IN OUT UINT32 *PpttTableLengthRemain, + IN UINT32 Parent, + IN UINT32 ResourceNo + ) +{ + EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0; + EFI_ACPI_6_2_PPTT_STRUCTURE_ID *PpttType2; + UINT32 *PrivateResource; + UINT8 Index; + + if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)) { + return EFI_OUT_OF_RESOURCES; + } + PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable + + PpttTable->Length); + PpttType0->Type = 0; + SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0); + PpttType0->Flags.PhysicalPackage = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID; + PpttType0->Parent= Parent; + PpttType0->NumberOfPrivateResources = ResourceNo; + PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + + ResourceNo * 4; + PpttTable->Length += PpttType0->Length; + + *PpttTableLengthRemain -= PpttType0->Length; + if (*PpttTableLengthRemain < ResourceNo * 4) { + return EFI_OUT_OF_RESOURCES; + } + PrivateResource = (UINT32 *)((UINT8 *)PpttType0 + + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)); + DEBUG ((DEBUG_INFO, + "[Acpi PPTT] sizeof(EFI_ACPI_6_2_PPTT_STRUCTURE_ID) = %x!\n", + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID))); + + for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) { + if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)) { + return EFI_OUT_OF_RESOURCES; + } + *PrivateResource = PpttTable->Length; + PpttType2 = (EFI_ACPI_6_2_PPTT_STRUCTURE_ID *)((UINT8 *)PpttTable + + PpttTable->Length); + gBS->CopyMem ( + PpttType2, + &mPpttSocketType2[Index], + sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID) + ); + *PpttTableLengthRemain -= PpttType2->Length; + PpttTable->Length += PpttType2->Length; + } + + return EFI_SUCCESS; +} + +STATIC +VOID +GetAffLvl ( + IN UINT64 Mpidr, + IN OUT UINT8 *Level3, + IN OUT UINT8 *Level2, + IN OUT UINT8 *Level1, + IN OUT UINT8 *Level0 + ) +{ + *Level3 = BitFieldRead64 (Mpidr, 32, 39); + *Level2 = BitFieldRead64 (Mpidr, 16, 23); + *Level1 = BitFieldRead64 (Mpidr, 8, 15); + *Level0 = BitFieldRead64 (Mpidr, 0, 7); +} + + +STATIC +VOID +GetApic ( + IN ACPI_MADT_TABLE_HEADER *ApicTable, + IN OUT EFI_ACPI_DESCRIPTION_HEADER *PpttTable, + IN UINT32 PpttTableLengthRemain +) +{ + UINT32 Parent = 0; + UINT32 ResourceNo = 0; + ACPI_GIC_STRUCTURE *Ptr; + UINT8 AffLvl3 = 0; + UINT8 AffLvl2 = 0; + UINT8 AffLvl1 = 0; + UINT8 AffLvl0 = 0; + UINTN SocketIndex; + + for (Ptr = (ACPI_GIC_STRUCTURE *) (ApicTable + 1); + (UINTN) Ptr < (UINTN) ApicTable + ApicTable->Header.Length; + Ptr = (ACPI_GIC_STRUCTURE *) ((UINTN) Ptr + Ptr->Length)) { + + // Avoid dead loop due to corrupted MADT + if (Ptr->Length == 0) { + DEBUG ((DEBUG_ERROR, "[%a:%d] - Invalid MADT sub structure at 0x%x\n", + __FUNCTION__, __LINE__, (UINTN) Ptr - (UINTN) ApicTable)); + break; + } + + if (Ptr->Type != EFI_ACPI_5_1_GIC || + (Ptr->Flags & EFI_ACPI_5_1_GIC_ENABLED) == 0) { + continue; + } + GetAffLvl (Ptr->MPIDR, &AffLvl3, &AffLvl2, &AffLvl1, &AffLvl0); + // AffLvl3 is not used for Hi1620 + // And socket index is calculated by AffLvl2 + + SocketIndex = AffLvl2 / MAX_SCL_PER_SOCKET; + if (mSocketOffset[SocketIndex] == 0) { + //Add socket for type0 table + ResourceNo = PPTT_SOCKET_COMPONENT_NO; + mSocketOffset[SocketIndex] = PpttTable->Length; + Parent = 0; + AddSocketTable ( + PpttTable, + &PpttTableLengthRemain, + Parent, + ResourceNo + ); + } + + if (mScclOffset[AffLvl2] == 0) { + //Add SCCL for type0 table + ResourceNo = 1; + mScclOffset[AffLvl2] = PpttTable->Length ; + Parent = mSocketOffset[SocketIndex]; + AddScclTable ( + PpttTable, + &PpttTableLengthRemain, + Parent, + ResourceNo + ); + } + + if (mClusterOffset[AffLvl2][AffLvl1] == 0) { + // Add cluster for type0 table + // No private resource for cluster on Hi1620 + ResourceNo = 0; + mClusterOffset[AffLvl2][AffLvl1] = PpttTable->Length ; + Parent = mScclOffset[AffLvl2]; + AddClusterTable ( + PpttTable, + &PpttTableLengthRemain, + Parent, + ResourceNo + ); + } + + //Add core for type0 table + ResourceNo = 3; + Parent = mClusterOffset[AffLvl2][AffLvl1]; + AddCoreTable ( + PpttTable, + &PpttTableLengthRemain, + Parent, + ResourceNo, + Ptr->AcpiProcessorUid + ); + } +} + + +STATIC +VOID +PpttSetAcpiTable( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN AcpiTableHandle; + EFI_STATUS Status; + UINT8 Checksum; + EFI_ACPI_SDT_HEADER *Table; + ACPI_MADT_TABLE_HEADER *ApicTable; + EFI_ACPI_TABLE_VERSION TableVersion; + EFI_ACPI_DESCRIPTION_HEADER *PpttTable; + UINTN TableKey; + UINT32 Index0; + UINT32 PpttTableLengthRemain = 0; + + gBS->CloseEvent (Event); + + InitCacheInfo (); + + PpttTable = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (PPTT_TABLE_MAX_LEN); + gBS->CopyMem ( + (VOID *)PpttTable, + &mPpttHeader, + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ); + PpttTableLengthRemain = PPTT_TABLE_MAX_LEN - sizeof (EFI_ACPI_DESCRIPTION_HEADER); + + for (Index0 = 0; Index0 < EFI_ACPI_MAX_NUM_TABLES; Index0++) { + Status = mAcpiSdtProtocol->GetAcpiTable ( + Index0, + &Table, + &TableVersion, + &TableKey + ); + if (EFI_ERROR (Status)) { + break; + } + + // Find APIC table + if (Table->Signature == EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) { + break; + } + + } + + if (!EFI_ERROR (Status) && (Index0 != EFI_ACPI_MAX_NUM_TABLES)) { + ApicTable = (ACPI_MADT_TABLE_HEADER *)Table; + + GetApic (ApicTable, PpttTable, PpttTableLengthRemain); + + Checksum = CalculateCheckSum8 ((UINT8 *)(PpttTable), PpttTable->Length); + PpttTable->Checksum = Checksum; + + AcpiTableHandle = 0; + Status = mAcpiTableProtocol->InstallAcpiTable ( + mAcpiTableProtocol, + PpttTable, + PpttTable->Length, + &AcpiTableHandle); + } + + FreePool (PpttTable); + return ; +} + +EFI_STATUS +EFIAPI +PpttEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + + Status = gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **)&mAcpiTableProtocol); + ASSERT_EFI_ERROR (Status); + + Status = gBS->LocateProtocol ( + &gEfiAcpiSdtProtocolGuid, + NULL, + (VOID **)&mAcpiSdtProtocol); + ASSERT_EFI_ERROR (Status); + + Status = EfiCreateEventReadyToBootEx ( + TPL_NOTIFY, + PpttSetAcpiTable, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Acpi Pptt init done.\n")); + + return Status; +} diff --git a/Silicon/Hisilicon/Hi1620/Pptt/Pptt.h b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.h new file mode 100644 index 0000000000..07e4d89fed --- /dev/null +++ b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.h @@ -0,0 +1,69 @@ +/** @file +* +* Copyright (c) 2018, Hisilicon Limited. All rights reserved. +* Copyright (c) 2018, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +* Based on the files under Platform/ARM/JunoPkg/AcpiTables/ +* +**/ + +#ifndef _PPTT_H_ +#define _PPTT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../Hi1620AcpiTables/Hi1620Platform.h" + +#define PPTT_VENDOR_ID SIGNATURE_32('H', 'I', 'S', 'I') + +#define EFI_ACPI_MAX_NUM_TABLES 20 + +#define MAX_SCL_PER_SOCKET MAX_DIE +#define MAX_SCL (MAX_SOCKET * MAX_SCL_PER_SOCKET) +#define MAX_CLUSTER_PER_SCL 8 + +#define PPTT_TABLE_MAX_LEN 0x6000 +#define PPTT_SOCKET_COMPONENT_NO 0x1 +#define PPTT_CACHE_NO 0x4 + +typedef union { + struct { + UINT32 InD :1; + UINT32 Level :3; + UINT32 Reserved :28; + } Bits; + UINT32 Data; +} CSSELR_DATA; + +typedef union { + struct { + UINT32 LineSize :3; + UINT32 Associativity :10; + UINT32 NumSets :15; + UINT32 Wa :1; + UINT32 Ra :1; + UINT32 Wb :1; + UINT32 Wt :1; + } Bits; + UINT32 Data; +} CCSIDR_DATA; + +#endif // _PPTT_H_ + diff --git a/Silicon/Hisilicon/Hi1620/Pptt/Pptt.inf b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.inf new file mode 100644 index 0000000000..f8a5ed33a4 --- /dev/null +++ b/Silicon/Hisilicon/Hi1620/Pptt/Pptt.inf @@ -0,0 +1,48 @@ +/** @file +* +* Copyright (c) 2018, Hisilicon Limited. All rights reserved. +* Copyright (c) 2018, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +* Based on the files under Platform/ARM/JunoPkg/AcpiTables/ +* +**/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = AcpiPptt + FILE_GUID = 65766562-49e7-11e8-817f-286ed489ee9b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = PpttEntryPoint + +[Sources.common] + Pptt.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + Silicon/Hisilicon/HisiPkg.dec + +[LibraryClasses] + ArmLib + BaseMemoryLib + DebugLib + HobLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + +[Protocols] + gEfiAcpiSdtProtocolGuid ## PROTOCOL ALWAYS_CONSUMED + gEfiAcpiTableProtocolGuid ## PROTOCOL ALWAYS_CONSUMED + +[Depex] + gEfiAcpiTableProtocolGuid AND gEfiAcpiSdtProtocolGuid +