From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by mx.groups.io with SMTP id smtpd.web08.75037.1656957201602219395 for ; Mon, 04 Jul 2022 10:53:22 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=kqWVsiHN; spf=pass (domain: kernel.org, ip: 145.40.68.75, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 00552B811F8; Mon, 4 Jul 2022 17:53:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4B812C341CB; Mon, 4 Jul 2022 17:53:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1656957199; bh=Yw6+yEriQchOO3Nxpk2mtCmrCV3NZIMHJ3/N8zemEk8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kqWVsiHNXmDrL+5eXgfZ0yWfAfnNsmcrlwJgLyMw24rhYotEz+N0NBcRB0CYw/bcU XmSI18lSOYUlHrd+6pVocNZZNxzxyB5LK+5Gq+MfzOzBOm5Tau5jjm0rBl24sXINLH XiDRBJd78EoOLxHDpYYs+46hKVeiMzmz9kO5pHnvC6JMRONPGygztoDIznCc9kZgST nYInFbU3XuvhnXvjMDdGwQlykUJZjuneEu5lS/QQaRr6tw5nsyizrPm4uZRqFYnmN2 8uruL/1AaIEAxJJeUOnRHEjo94UwHfE8xaAdarGWUocqQe4lEBSBiSFnVDRsQq2MmZ l9cafuHO4YraA== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: quic_llindhol@quicinc.com, sami.mujawar@arm.com, Ard Biesheuvel , Marc Zyngier , Alexander Graf Subject: [PATCH 5/7] ArmVirtPkg/ArmVirtQemu: implement ArmPlatformLib with static ID map Date: Mon, 4 Jul 2022 19:52:50 +0200 Message-Id: <20220704175252.4015120-6-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220704175252.4015120-1-ardb@kernel.org> References: <20220704175252.4015120-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To substantially reduce the amount of processing that takes place with the MMU and caches off, implemnt a version of ArmPlatformLib specific for QEMU/mach-virt in AArch64 mode that carries a statically allocated and populated ID map that covers the NOR flash and device region, and 128 MiB of DRAM at the base of memory (0x4000_0000). Note that 128 MiB has always been the minimum amount of DRAM we support for this configuration, and the existing code already ASSERT()s in DEBUG mode when booting with less. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S | 111 ++= ++++++++++++++++++ ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.c | 36 ++= +++++ ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf | 36 ++= +++++ ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S | 57 ++= ++++++++ 4 files changed, 240 insertions(+) diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelpe= r.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S new file mode 100644 index 000000000000..7b78e2928710 --- /dev/null +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S @@ -0,0 +1,111 @@ +//=0D +// Copyright (c) 2022, Google LLC. All rights reserved.=0D +//=0D +// SPDX-License-Identifier: BSD-2-Clause-Patent=0D +//=0D +//=0D +=0D +#include =0D +=0D + .macro mov_i, reg:req, imm:req=0D + movz \reg, :abs_g3:\imm=0D + movk \reg, :abs_g2_nc:\imm=0D + movk \reg, :abs_g1_nc:\imm=0D + movk \reg, :abs_g0_nc:\imm=0D + .endm=0D +=0D + .set MAIR_DEV_nGnRnE, 0x00=0D + .set MAIR_MEM_NC, 0x44=0D + .set MAIR_MEM_WT, 0xbb=0D + .set MAIR_MEM_WBWA, 0xff=0D + .set mairval, MAIR_DEV_nGnRnE | (MAIR_MEM_NC << 8) | (MAIR_MEM_WT << 1= 6) | (MAIR_MEM_WBWA << 24)=0D +=0D + .set TCR_TG0_4KB, 0x0 << 14=0D + .set TCR_TG1_4KB, 0x2 << 30=0D + .set TCR_IPS_SHIFT, 32=0D + .set TCR_EPD1, 0x1 << 23=0D + .set TCR_SH_INNER, 0x3 << 12=0D + .set TCR_RGN_OWB, 0x1 << 10=0D + .set TCR_RGN_IWB, 0x1 << 8=0D + .set tcrval, TCR_TG0_4KB | TCR_TG1_4KB | TCR_EPD1 | TCR_RGN_OWB=0D + .set tcrval, tcrval | TCR_RGN_IWB | TCR_SH_INNER=0D +=0D + .set SCTLR_ELx_I, 0x1 << 12=0D + .set SCTLR_ELx_SA, 0x1 << 3=0D + .set SCTLR_ELx_C, 0x1 << 2=0D + .set SCTLR_ELx_M, 0x1 << 0=0D + .set SCTLR_EL1_SPAN, 0x1 << 23=0D + .set SCTLR_EL1_WXN, 0x1 << 19=0D + .set SCTLR_EL1_SED, 0x1 << 8=0D + .set SCTLR_EL1_ITD, 0x1 << 7=0D + .set SCTLR_EL1_RES1, (0x1 << 11) | (0x1 << 20) | (0x1 << 22) | (0= x1 << 28) | (0x1 << 29)=0D + .set sctlrval, SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_EL1_IT= D | SCTLR_EL1_SED=0D + .set sctlrval, sctlrval | SCTLR_ELx_I | SCTLR_EL1_SPAN | SCTLR_EL1_RES= 1=0D +=0D +=0D +ASM_FUNC(ArmPlatformPeiBootAction)=0D + mov_i x0, mairval=0D + mov_i x1, tcrval=0D + adrp x2, idmap=0D + orr x2, x2, #0xff << 48 // set non-zero ASID=0D + mov_i x3, sctlrval=0D +=0D + mrs x6, id_aa64mmfr0_el1 // get the supported PA range=0D + and x6, x6, #0xf // isolate PArange bits=0D + cmp x6, #6 // 0b0110 =3D=3D 52 bits=0D + sub x6, x6, #1 // subtract 1=0D + cinc x6, x6, ne // add back 1 unless PArange =3D=3D 52 bi= ts=0D + bfi x1, x6, #32, #3 // copy updated PArange into TCR_EL1.IPS= =0D +=0D + cmp x6, #3 // 0b0011 =3D=3D 42 bits=0D + sub x6, x6, #1 // subtract 1=0D + cinc x6, x6, lt // add back 1 unless VA range >=3D 42=0D +=0D + mov x7, #32=0D + sub x6, x7, x6, lsl #2 // T0SZ for PArange !=3D 42=0D + mov x7, #64 - 42 // T0SZ for PArange =3D=3D 42=0D + csel x6, x6, x7, ne=0D + orr x1, x1, x6 // set T0SZ field in TCR=0D +=0D + cmp x6, #64 - 40 // VA size < 40 bits?=0D + add x4, x2, #0x1000 // advance to level 1 descriptor=0D + csel x2, x4, x2, gt=0D +=0D + msr mair_el1, x0 // set up the 1:1 mapping=0D + msr tcr_el1, x1=0D + msr ttbr0_el1, x2=0D + isb=0D +=0D + tlbi vmalle1 // invalidate any cached translations=0D + ic iallu // invalidate the I-cache=0D + dsb nsh=0D + isb=0D +=0D + msr sctlr_el1, x3 // enable MMU and caches=0D + isb=0D + ret=0D +=0D +//UINTN=0D +//ArmPlatformGetCorePosition (=0D +// IN UINTN MpId=0D +// );=0D +// With this function: CorePos =3D (ClusterId * 4) + CoreId=0D +ASM_FUNC(ArmPlatformGetCorePosition)=0D + mov x0, xzr=0D + ret=0D +=0D +//UINTN=0D +//ArmPlatformGetPrimaryCoreMpId (=0D +// VOID=0D +// );=0D +ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)=0D + MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore))=0D + ret=0D +=0D +//UINTN=0D +//ArmPlatformIsPrimaryCore (=0D +// IN UINTN MpId=0D +// );=0D +ASM_FUNC(ArmPlatformIsPrimaryCore)=0D + mov x0, #1=0D + ret=0D diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.c b/A= rmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.c new file mode 100644 index 000000000000..4a5ea82ef5e2 --- /dev/null +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.c @@ -0,0 +1,36 @@ +/** @file=0D +=0D + Copyright (c) 2011-2012, ARM Limited. All rights reserved.=0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +=0D +EFI_BOOT_MODE=0D +ArmPlatformGetBootMode (=0D + VOID=0D + )=0D +{=0D + return BOOT_WITH_FULL_CONFIGURATION;=0D +}=0D +=0D +RETURN_STATUS=0D +ArmPlatformInitialize (=0D + IN UINTN MpId=0D + )=0D +{=0D + return RETURN_SUCCESS;=0D +}=0D +=0D +VOID=0D +ArmPlatformGetPlatformPpiList (=0D + OUT UINTN *PpiListSize,=0D + OUT EFI_PEI_PPI_DESCRIPTOR **PpiList=0D + )=0D +{=0D + *PpiListSize =3D 0;=0D + *PpiList =3D NULL;=0D +}=0D diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf b= /ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf new file mode 100644 index 000000000000..d2eaa6be6586 --- /dev/null +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/ArmPlatformLibQemu.inf @@ -0,0 +1,36 @@ +#/* @file=0D +# Copyright (c) 2011-2012, ARM Limited. All rights reserved.=0D +# Copyright (c) 2022, Google LLC. All rights reserved.=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +#*/=0D +=0D +[Defines]=0D + INF_VERSION =3D 1.27=0D + BASE_NAME =3D ArmPlatformLibQemu=0D + FILE_GUID =3D 40af3a25-f02c-4aef-94ef-7ac0282d21d4= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D ArmPlatformLib=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + ArmPkg/ArmPkg.dec=0D + ArmPlatformPkg/ArmPlatformPkg.dec=0D +=0D +[LibraryClasses]=0D + ArmLib=0D + DebugLib=0D +=0D +[Sources.common]=0D + ArmPlatformLibQemu.c=0D + IdMap.S=0D +=0D +[Sources.AArch64]=0D + AArch64/ArmPlatformHelper.S=0D +=0D +[FixedPcd]=0D + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask=0D + gArmTokenSpaceGuid.PcdArmPrimaryCore=0D diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S b/ArmVirtPkg/Lib= rary/ArmPlatformLibQemu/IdMap.S new file mode 100644 index 000000000000..9c174bb81dc2 --- /dev/null +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/IdMap.S @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +// Copyright 2022 Google LLC +// Author: Ard Biesheuvel + + .set TT_TYPE_BLOCK, 0x1 + .set TT_TYPE_PAGE, 0x3 + .set TT_TYPE_TABLE, 0x3 + + .set TT_AF, 0x1 << 10 + .set TT_NG, 0x1 << 11 + .set TT_RO, 0x2 << 6 + .set TT_XN, 0x3 << 53 + + .set TT_MT_DEV, 0x0 << 2 // MAIR #0 + .set TT_MT_MEM, (0x3 << 2) | (0x3 << 8) // MAIR #3 + + .set PAGE_XIP, TT_TYPE_PAGE | TT_MT_MEM | TT_AF | TT_R= O | TT_NG + .set BLOCK_DEV, TT_TYPE_BLOCK | TT_MT_DEV | TT_AF | TT_X= N | TT_NG + .set BLOCK_MEM, TT_TYPE_BLOCK | TT_MT_MEM | TT_AF | TT_X= N | TT_NG + + .globl idmap + .section ".rodata.idmap", "a", %progbits + .align 12 + + /* level 0 */ +idmap: .quad 1f + TT_TYPE_TABLE + .fill 511, 8, 0x0 + + /* level 1 */ +1: .quad 20f + TT_TYPE_TABLE // 1 GB of flash an= d device mappings + .quad 21f + TT_TYPE_TABLE // up to 1 GB of DR= AM + .fill 510, 8, 0x0 // 510 GB of remain= ing VA space + + /* level 2 */ +20: .quad 3f + TT_TYPE_TABLE // up to 2 MB of fl= ash + .fill 63, 8, 0x0 // 126 MB of unused= flash + .set idx, 64 + .rept 448 + .quad BLOCK_DEV | (idx << 21) // 896 MB of RW- de= vice mappings + .set idx, idx + 1 + .endr + + /* level 2 */ +21: .set idx, 0x40000000 >> 21 + .rept 64 + .quad BLOCK_MEM | (idx << 21) // 128 MB of RW- me= mory mappings + .set idx, idx + 1 + .endr + .fill 448, 8, 0x0 + + /* level 3 */ +3: .quad 0x0 // omit first 4k pa= ge + .set idx, 1 + .rept 511 + .quad PAGE_XIP | (idx << 12) // 2044 KiB of R-X = flash mappings + .set idx, idx + 1 + .endr --=20 2.35.1