From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web09.32440.1606121029474778335 for ; Mon, 23 Nov 2020 00:43:49 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=W94XGC20; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: jiewen.yao@intel.com) IronPort-SDR: iQfhvDNuqDjbScP20r5Zh5Ynm4JNQSp1fLgoXXEQBV83qk5hAIrqN6GqzB8Hd8eIEnQIRUKdNy N5BuYehHVg4A== X-IronPort-AV: E=McAfee;i="6000,8403,9813"; a="169159584" X-IronPort-AV: E=Sophos;i="5.78,361,1599548400"; d="scan'208";a="169159584" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2020 00:43:48 -0800 IronPort-SDR: Jnht951nfL95JbD6un/FasFfoxBUzc76/WOTzOPA7obJ+diMpjw/xoPICB2oB+4y85Gno3rfmu aA1O/syqaDaA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,361,1599548400"; d="scan'208";a="364583140" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by fmsmga002.fm.intel.com with ESMTP; 23 Nov 2020 00:43:48 -0800 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 23 Nov 2020 00:43:48 -0800 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 23 Nov 2020 00:43:47 -0800 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Mon, 23 Nov 2020 00:43:47 -0800 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (104.47.57.173) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Mon, 23 Nov 2020 00:43:47 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OXNQquXL81n5PYUNRP7qV9LL63lyctTZeayilLYplfTwgNPBx4mugeR/a2zJ4Ya+mMHmJASk5GHqfU9QhqBNlEnov6Sne3Pu/Zh81flk4rT7y+hBoEhyTX6ggj7MHC6xh7yfcDlbVCVO3H1CeSMVTZmBOou3vFbuK0WqAUcuKVIX6SupUVb7biEqOdvoWBkKB7CaLgLLBMY8jq1nHQSfLRVc8GMNRAJSa0FoM47XYBmyBsPq310VV5Y8jrbsU/tLhqH/JKfilMzCKnprTxFNFn6Nn0ppJ1N9WOwgwjUJcewFhrbeYN6p95H5xdXfrq3f5JnXQHAA2L/V5SJRzbKmWQ== 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=tNBoBYRL++ERSLJR4gaAll9nSvefTsk21PAtf42S+/8=; b=ILiuQdHArD2nao9Og+8V+iTxMMU+RY+yuswr5RbmZRg3uAQ+PZOqRxE26RC8JFZIpFoi/0lU/WbVHzt7mHrRRtTL2DuvMOO2SyAwbSHC+3nUnrmJNuh8BxxHsL/61TPbpiLrZUW/XJsVW7foGBUqambcGzXLy8xvLREcDT6AFqClwDFsrtePhRkhLw/lruJ14uzh6JCssdNUrxiCNKR3Zgo67/bnI2lvr0/mKswmVxqOd6HPnn3oxGO8uGwMJ9ZCGP+X27qoAdVSNIgyNOO/lyDth3QHvgfwkUPBogcMncRb2JsnvruzMBM6ORANwOIDOR3GO47VwQ5yceNVGqGauA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tNBoBYRL++ERSLJR4gaAll9nSvefTsk21PAtf42S+/8=; b=W94XGC20ngdYb38P3774xATfznWit7nMCa9qZrzA+pgxgBM+VEGJgKdoEaAvk0XYAvFwsjuZR4MohVFfnxyjhfqCdJ9E19YkmoMCkuV+fh9C/1+8qcCirgCCbYgox1ccuYO3f0QoldiocSjCeijfh22efBX46vMvSlY5fn+AYw4= Received: from CY4PR11MB1288.namprd11.prod.outlook.com (2603:10b6:903:23::8) by CY4PR11MB1286.namprd11.prod.outlook.com (2603:10b6:903:2e::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3589.22; Mon, 23 Nov 2020 08:43:45 +0000 Received: from CY4PR11MB1288.namprd11.prod.outlook.com ([fe80::a188:2994:6c14:aad7]) by CY4PR11MB1288.namprd11.prod.outlook.com ([fe80::a188:2994:6c14:aad7%12]) with mapi id 15.20.3589.029; Mon, 23 Nov 2020 08:43:45 +0000 From: "Yao, Jiewen" To: "Sheng, W" , "devel@edk2.groups.io" CC: "Ni, Ray" , "Chaganty, Rangasai V" , "Huang, Jenny" Subject: Re: [PATCH v4] IntelSiliconPkg/VTd: Add iommu 5 level paging support Thread-Topic: [PATCH v4] IntelSiliconPkg/VTd: Add iommu 5 level paging support Thread-Index: AQHWwW8xSr9g5vPNRkSjbzyv1VuVZanVZKtQ Date: Mon, 23 Nov 2020 08:43:45 +0000 Message-ID: References: <20201123080345.21772-1-w.sheng@intel.com> In-Reply-To: <20201123080345.21772-1-w.sheng@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-product: dlpe-windows dlp-reaction: no-action authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [101.80.124.211] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 2660ebda-d408-4d60-5d18-08d88f8be3dc x-ms-traffictypediagnostic: CY4PR11MB1286: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: IywCmGnLbs2sbsQ2QMPkZwqsQtZLesUDuXtV91Gw0bN5WCI2m6s8VEtCXUu7xkqMZKOUC7A40xpXvbLBs1nLQpNLwQ1XxI+C9TlM0csERbzKJPFSD6mnFLZKY360e0etYdEvaLzx/lo7NnUb1LAjOSr2ZT52Or6Hczf87o8ER++iD1rs3qRVhZkRoDOJBPL6knaFsytdoJFO27fFyONXMnLIzfc6aGLJ2gqX2xo4UPJA9ociwNaOXiNhRCuxo9OrVN+hyAtkeIV2Oq+F4biLBQ9aFzpdxqlvKJ5uHdPLEa3TClhrMXSnkhm1ma5YpGqZnXh7/f2Jf+H8+d9/6aEv9pdMHgKgdQcvee/r6k4lPmf1Fbu2fEYSIiW5LvesZBVgbIxIQsP+tRFbQET/pFCgOQ== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY4PR11MB1288.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(346002)(376002)(39860400002)(396003)(136003)(366004)(71200400001)(9686003)(5660300002)(8676002)(107886003)(55016002)(4326008)(30864003)(33656002)(966005)(76116006)(66946007)(478600001)(64756008)(66476007)(66446008)(8936002)(66556008)(86362001)(6506007)(316002)(54906003)(52536014)(26005)(110136005)(186003)(2906002)(7696005)(53546011)(83380400001)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: ULsWd/0WSBXhWJYCyVPF3BYLt6tqXPLcRF2g9AeJ/mXZJJjTqMnCrIWvzYJ2Y4KGwLgxejxXS2+iBMj7AuyPI5E0WZeFuKE9exM5h3gqTzJnKMe2xkd57vt5zWTCDz54DJA8EDrcs6IkjbkOKHCXUa6taa5amo+b1bKJaZUCz5inSH2rp10G81Bko9LAiCexhTbsnzR804R+MDtg4xzEuO9H6hXVuzIQ4dGLak4A2LzEYQPUKIZj9eFMtrIg5GEv5yXOh4x0FLbI45LrWlOZyLLfe0+rW+065WAVzTlt3R4sUultSFCEAsQi7TNng+gLPaL+id38H7w/Rnxwtr89QFJQ+1+ESHpj/wC7+4nHbjV9nQDumI0kGGea/ewXnjq9312l4jE+GEK1781p9SkS7A/RLDFkjci9iBsVDZSwnEY7tLRyBhJC6W7rympENAatskLjkC9GuQpGWOt6XLJ2Eai9q3GpcRMGDigix9yuH8qUUwY8S2al+pjCaImgk0M6ZguIXkmFh/unbUiyKiSnrlGuzH6Y3kWKFzkKlH+rXCGqxopdFRXzFADpF2s3KcVvYmyKVosHE0lJlues9e1ptX+5vQboLxSlr8yO+nq2uMX7y2TFT79ImplAsmINptTKOMVx7kyQ3qRy+I85DMAlcw== MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR11MB1288.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2660ebda-d408-4d60-5d18-08d88f8be3dc X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Nov 2020 08:43:45.8161 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: w4T5kLPZuCcJrW76XPtP1YG5bDYvouf670kbrzbSJxQdvs45ToPhkPGgOALR7TLEr+Qoce/ovy9rqbj2+tGGSA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1286 Return-Path: jiewen.yao@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Thanks. I only reviewed the policy part. Comment below: 1) I recommend you can merge below 2 if into one - if ((mAcpiDmarTable->Hos= tAddressWidth <=3D 48) && (mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW = & BIT2) !=3D 0)) { You can use 2 lines, but there is no need to use 2 if. + if (mAcpiDmarTable->HostAddressWidth <=3D 48) { + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) !=3D = 0) { + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; + } + } 2) I think below code has typo. The DEBUG message about 4-level and 5-level should be reversed. Also we should use DEBUG_INFO instead of DEBUG_ERROR. + if (mVtdUnitInformation[VtdIndex].Is5LevelPaging) { + ContextEntry->Bits.AddressWidth =3D 0x3; + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", VtdIndex= )); + } else { + ContextEntry->Bits.AddressWidth =3D 0x2; + DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", VtdIndex= )); + } > -----Original Message----- > From: Sheng, W > Sent: Monday, November 23, 2020 4:04 PM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Chaganty, Rangasai V > ; Yao, Jiewen ; > Huang, Jenny > Subject: [PATCH v4] IntelSiliconPkg/VTd: Add iommu 5 level paging support >=20 > Support iommu 5 level paging for translation table. >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3067 >=20 > Signed-off-by: Sheng Wei > Cc: Ray Ni > Cc: Rangasai V Chaganty > Cc: Jiewen Yao > Cc: Jenny Huang > --- > .../Feature/VTd/IntelVTdDxe/DmaProtection.c | 4 +- > .../Feature/VTd/IntelVTdDxe/DmaProtection.h | 19 +- > .../Feature/VTd/IntelVTdDxe/TranslationTable.c | 281 +++++++++++++++= -- > ---- > .../Feature/VTd/IntelVTdDxe/TranslationTableEx.c | 31 ++- > .../Feature/VTd/IntelVTdDxe/VtdReg.c | 10 +- > 5 files changed, 245 insertions(+), 100 deletions(-) >=20 > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > index 9b6135ef..628565ee 100644 > --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection= .c > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > @@ -523,10 +523,10 @@ SetupVtd ( > for (Index =3D 0; Index < mVtdUnitNumber; Index++) { > DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, > mVtdUnitInformation[Index].Segment)); > if (mVtdUnitInformation[Index].ExtRootEntryTable !=3D NULL) { > - DumpDmarExtContextEntryTable > (mVtdUnitInformation[Index].ExtRootEntryTable); > + DumpDmarExtContextEntryTable > (mVtdUnitInformation[Index].ExtRootEntryTable, > mVtdUnitInformation[Index].Is5LevelPaging); > } > if (mVtdUnitInformation[Index].RootEntryTable !=3D NULL) { > - DumpDmarContextEntryTable > (mVtdUnitInformation[Index].RootEntryTable); > + DumpDmarContextEntryTable > (mVtdUnitInformation[Index].RootEntryTable, > mVtdUnitInformation[Index].Is5LevelPaging); > } > } >=20 > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > index a3331db8..f641cea0 100644 > --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection= .h > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > @@ -77,6 +77,7 @@ typedef struct { > BOOLEAN HasDirtyContext; > BOOLEAN HasDirtyPages; > PCI_DEVICE_INFORMATION PciDeviceInfo; > + BOOLEAN Is5LevelPaging; > } VTD_UNIT_INFORMATION; >=20 > // > @@ -375,31 +376,37 @@ ParseDmarAcpiTableRmrr ( > /** > Dump DMAR context entry table. >=20 > - @param[in] RootEntry DMAR root entry. > + @param[in] RootEntry DMAR root entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpDmarContextEntryTable ( > - IN VTD_ROOT_ENTRY *RootEntry > + IN VTD_ROOT_ENTRY *RootEntry, > + IN BOOLEAN Is5LevelPaging > ); >=20 > /** > Dump DMAR extended context entry table. >=20 > - @param[in] ExtRootEntry DMAR extended root entry. > + @param[in] ExtRootEntry DMAR extended root entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpDmarExtContextEntryTable ( > - IN VTD_EXT_ROOT_ENTRY *ExtRootEntry > + IN VTD_EXT_ROOT_ENTRY *ExtRootEntry, > + IN BOOLEAN Is5LevelPaging > ); >=20 > /** > Dump DMAR second level paging entry. >=20 > - @param[in] SecondLevelPagingEntry The second level paging entry. > + @param[in] SecondLevelPagingEntry The second level paging entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpSecondLevelPagingEntry ( > - IN VOID *SecondLevelPagingEntry > + IN VOID *SecondLevelPagingEntry, > + IN BOOLEAN Is5LevelPaging > ); >=20 > /** > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > index 201d663d..6c786b40 100644 > --- > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > @@ -128,11 +128,26 @@ CreateContextEntry ( >=20 > DEBUG ((DEBUG_INFO,"Source: S%04x B%02x D%02x F%02x\n", > mVtdUnitInformation[VtdIndex].Segment, SourceId.Bits.Bus, > SourceId.Bits.Device, SourceId.Bits.Function)); >=20 > - if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) =3D=3D = 0) { > - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on > VTD %d !!!!\n", VtdIndex)); > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; > + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) !=3D 0)= { > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + if (mAcpiDmarTable->HostAddressWidth <=3D 48) { > + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) != =3D 0) { > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; > + } > + } > + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = =3D=3D > 0) { > + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on > VTD %d !!!!\n", VtdIndex)); > return EFI_UNSUPPORTED; > } > - ContextEntry->Bits.AddressWidth =3D 0x2; > + > + if (mVtdUnitInformation[VtdIndex].Is5LevelPaging) { > + ContextEntry->Bits.AddressWidth =3D 0x3; > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + } else { > + ContextEntry->Bits.AddressWidth =3D 0x2; > + DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", > VtdIndex)); > + } > } >=20 > FlushPageTableMemory (VtdIndex, > (UINTN)mVtdUnitInformation[VtdIndex].RootEntryTable, > EFI_PAGES_TO_SIZE(EntryTablePages)); > @@ -148,6 +163,7 @@ CreateContextEntry ( > @param[in] MemoryBase The base of the memory. > @param[in] MemoryLimit The limit of the memory. > @param[in] IoMmuAccess The IOMMU access. > + @param[in] Is5LevelPaging If it is the 5 level paging. >=20 > @return The second level paging entry. > **/ > @@ -157,16 +173,23 @@ CreateSecondLevelPagingEntryTable ( > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN UINT64 MemoryBase, > IN UINT64 MemoryLimit, > - IN UINT64 IoMmuAccess > + IN UINT64 IoMmuAccess, > + IN BOOLEAN Is5LevelPaging > ) > { > + UINTN Index5; > UINTN Index4; > UINTN Index3; > UINTN Index2; > + UINTN Lvl5Start; > + UINTN Lvl5End; > + UINTN Lvl4PagesStart; > + UINTN Lvl4PagesEnd; > UINTN Lvl4Start; > UINTN Lvl4End; > UINTN Lvl3Start; > UINTN Lvl3End; > + VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry; > @@ -184,7 +207,7 @@ CreateSecondLevelPagingEntryTable ( > if (SecondLevelPagingEntry =3D=3D NULL) { > SecondLevelPagingEntry =3D AllocateZeroPages (1); > if (SecondLevelPagingEntry =3D=3D NULL) { > - DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 PT. \n")); > + DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 or LVL5 PT. \n")); > return NULL; > } > FlushPageTableMemory (VtdIndex, (UINTN)SecondLevelPagingEntry, > EFI_PAGES_TO_SIZE(1)); > @@ -197,66 +220,109 @@ CreateSecondLevelPagingEntryTable ( > return SecondLevelPagingEntry; > } >=20 > - Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; > - Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; > + if (Is5LevelPaging) { > + Lvl5Start =3D RShiftU64 (BaseAddress, 48) & 0x1FF; > + Lvl5End =3D RShiftU64 (EndAddress - 1, 48) & 0x1FF; > + DEBUG ((DEBUG_INFO," Lvl5Start - 0x%x, Lvl5End - 0x%x\n", Lvl5Start= , > Lvl5End)); >=20 > - DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start, > Lvl4End)); > + Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; > + Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; >=20 > - Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > - for (Index4 =3D Lvl4Start; Index4 <=3D Lvl4End; Index4++) { > - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > - Lvl4PtEntry[Index4].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages (1= ); > - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > - DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL > (0x%x)!!!!!!\n", Index4)); > - ASSERT(FALSE); > - return NULL; > - } > - FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint64, > SIZE_4KB); > - SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > - } > + Lvl4PagesStart =3D (Lvl5Start<<9) | Lvl4Start; > + Lvl4PagesEnd =3D (Lvl5End<<9) | Lvl4End; > + DEBUG ((DEBUG_INFO," Lvl4PagesStart - 0x%x, Lvl4PagesEnd - 0x%x\n", > Lvl4PagesStart, Lvl4PagesEnd)); >=20 > - Lvl3Start =3D RShiftU64 (BaseAddress, 30) & 0x1FF; > - if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <=3D > EndAddress) { > - Lvl3End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1; > - } else { > - Lvl3End =3D RShiftU64 (EndAddress - 1, 30) & 0x1FF; > + Lvl5PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > + } else { > + Lvl5Start =3D RShiftU64 (BaseAddress, 48) & 0x1FF; > + Lvl5End =3D Lvl5Start; > + > + Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; > + Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; > + DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start= , > Lvl4End)); > + > + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > + } > + > + for (Index5 =3D Lvl5Start; Index5 <=3D Lvl5End; Index5++) { > + if (Is5LevelPaging) { > + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { > + Lvl5PtEntry[Index5].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages = (1); > + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { > + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL > (0x%x)!!!!!!\n", Index5)); > + ASSERT(FALSE); > + return NULL; > + } > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl5PtEntry[Index5].Uint6= 4, > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute (&Lvl5PtEntry[Index5], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + } > + Lvl4Start =3D Lvl4PagesStart & 0x1FF; > + if (((Index5+1)<<9) > Lvl4PagesEnd) { > + Lvl4End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1;; > + Lvl4PagesStart =3D (Index5+1)<<9; > + } else { > + Lvl4End =3D Lvl4PagesEnd & 0x1FF; > + } > + DEBUG ((DEBUG_INFO," Lvl5(0x%x): Lvl4Start - 0x%x, Lvl4End - 0x%x= \n", > Index5, Lvl4Start, Lvl4End)); > + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, > Lvl5PtEntry[Index5].Bits.AddressHi); > } > - DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x\n= ", > Index4, Lvl3Start, Lvl3End)); >=20 > - Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > - for (Index3 =3D Lvl3Start; Index3 <=3D Lvl3End; Index3++) { > - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > - Lvl3PtEntry[Index3].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages = (1); > - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > - DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, > 0x%x)!!!!!!\n", Index4, Index3)); > + for (Index4 =3D Lvl4Start; Index4 <=3D Lvl4End; Index4++) { > + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > + Lvl4PtEntry[Index4].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages = (1); > + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL > (0x%x)!!!!!!\n", Index4)); > ASSERT(FALSE); > return NULL; > } > - FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uint6= 4, > SIZE_4KB); > - SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint6= 4, > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + } > + > + Lvl3Start =3D RShiftU64 (BaseAddress, 30) & 0x1FF; > + if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <=3D > EndAddress) { > + Lvl3End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1; > + } else { > + Lvl3End =3D RShiftU64 (EndAddress - 1, 30) & 0x1FF; > } > + DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x= \n", > Index4, Lvl3Start, Lvl3End)); >=20 > - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > - for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > - Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; > - SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], > IoMmuAccess); > - Lvl2PtEntry[Index2].Bits.PageSize =3D 1; > - BaseAddress +=3D SIZE_2MB; > + Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > + for (Index3 =3D Lvl3Start; Index3 <=3D Lvl3End; Index3++) { > + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > + Lvl3PtEntry[Index3].Uint64 =3D (UINT64)(UINTN)AllocateZeroPage= s (1); > + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, > 0x%x)!!!!!!\n", Index4, Index3)); > + ASSERT(FALSE); > + return NULL; > + } > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uin= t64, > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + } > + > + Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > + for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > + Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; > + SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], > IoMmuAccess); > + Lvl2PtEntry[Index2].Bits.PageSize =3D 1; > + BaseAddress +=3D SIZE_2MB; > + if (BaseAddress >=3D MemoryLimit) { > + break; > + } > + } > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); > if (BaseAddress >=3D MemoryLimit) { > break; > } > } > - FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); > + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], > (UINTN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); > if (BaseAddress >=3D MemoryLimit) { > break; > } > } > - FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], > (UINTN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); > - if (BaseAddress >=3D MemoryLimit) { > - break; > - } > + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], > (UINTN)&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); > } > - FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], > (UINTN)&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); > + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl5PtEntry[Lvl5Start], > (UINTN)&Lvl5PtEntry[Lvl5End + 1] - (UINTN)&Lvl5PtEntry[Lvl5Start]); >=20 > return SecondLevelPagingEntry; > } > @@ -266,26 +332,28 @@ CreateSecondLevelPagingEntryTable ( >=20 > @param[in] VtdIndex The index of the VTd engine. > @param[in] IoMmuAccess The IOMMU access. > + @param[in] Is5LevelPaging If it is the 5 level paging. >=20 > @return The second level paging entry. > **/ > VTD_SECOND_LEVEL_PAGING_ENTRY * > CreateSecondLevelPagingEntry ( > IN UINTN VtdIndex, > - IN UINT64 IoMmuAccess > + IN UINT64 IoMmuAccess, > + IN BOOLEAN Is5LevelPaging > ) > { > VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; >=20 > SecondLevelPagingEntry =3D NULL; > - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex= , > SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess); > + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex= , > SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess, > Is5LevelPaging); > if (SecondLevelPagingEntry =3D=3D NULL) { > return NULL; > } >=20 > if (mAbove4GMemoryLimit !=3D 0) { > ASSERT (mAbove4GMemoryLimit > BASE_4GB); > - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdInd= ex, > SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess); > + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdInd= ex, > SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess, > Is5LevelPaging); > if (SecondLevelPagingEntry =3D=3D NULL) { > return NULL; > } > @@ -326,11 +394,13 @@ SetupTranslationTable ( > /** > Dump DMAR context entry table. >=20 > - @param[in] RootEntry DMAR root entry. > + @param[in] RootEntry DMAR root entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpDmarContextEntryTable ( > - IN VTD_ROOT_ENTRY *RootEntry > + IN VTD_ROOT_ENTRY *RootEntry, > + IN BOOLEAN Is5LevelPaging > ) > { > UINTN Index; > @@ -359,7 +429,7 @@ DumpDmarContextEntryTable ( > if (ContextEntry[Index2].Bits.Present =3D=3D 0) { > continue; > } > - DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPage > TranslationPointerLo, > ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi)); > + DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPage > TranslationPointerLo, > ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi), > Is5LevelPaging); > } > } > DEBUG ((DEBUG_INFO,"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D\n")); > @@ -368,17 +438,22 @@ DumpDmarContextEntryTable ( > /** > Dump DMAR second level paging entry. >=20 > - @param[in] SecondLevelPagingEntry The second level paging entry. > + @param[in] SecondLevelPagingEntry The second level paging entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpSecondLevelPagingEntry ( > - IN VOID *SecondLevelPagingEntry > + IN VOID *SecondLevelPagingEntry, > + IN BOOLEAN Is5LevelPaging > ) > { > + UINTN Index5; > UINTN Index4; > UINTN Index3; > UINTN Index2; > UINTN Index1; > + UINTN Lvl5IndexEnd; > + VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry; > VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry; > @@ -386,38 +461,53 @@ DumpSecondLevelPagingEntry ( >=20 > DEBUG ((DEBUG_VERBOSE,"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D\n")); > DEBUG ((DEBUG_VERBOSE,"DMAR Second Level Page Table:\n")); > + DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x, > Is5LevelPaging - %d\n", SecondLevelPagingEntry, Is5LevelPaging)); >=20 > - DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x\n", > SecondLevelPagingEntry)); > + Lvl5IndexEnd =3D Is5LevelPaging ? > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) : 1; > Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > - for (Index4 =3D 0; Index4 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index4++) { > - if (Lvl4PtEntry[Index4].Uint64 !=3D 0) { > - DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", Index= 4, > Lvl4PtEntry[Index4].Uint64)); > - } > - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > - continue; > - } > - Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > - for (Index3 =3D 0; Index3 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index3++) { > - if (Lvl3PtEntry[Index3].Uint64 !=3D 0) { > - DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", > Index3, Lvl3PtEntry[Index3].Uint64)); > + Lvl5PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > + > + for (Index5 =3D 0; Index5 < Lvl5IndexEnd; Index5++) { > + if (Is5LevelPaging) { > + if (Lvl5PtEntry[Index5].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl5Pt Entry(0x%03x) - 0x%016lx\n", > Index5, Lvl5PtEntry[Index5].Uint64)); > } > - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { > continue; > } > + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, > Lvl5PtEntry[Index5].Bits.AddressHi); > + } >=20 > - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > - for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > - if (Lvl2PtEntry[Index2].Uint64 !=3D 0) { > - DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n= ", > Index2, Lvl2PtEntry[Index2].Uint64)); > + for (Index4 =3D 0; Index4 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index4++) { > + if (Lvl4PtEntry[Index4].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", > Index4, Lvl4PtEntry[Index4].Uint64)); > + } > + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { > + continue; > + } > + Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > + for (Index3 =3D 0; Index3 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index3++) { > + if (Lvl3PtEntry[Index3].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", > Index3, Lvl3PtEntry[Index3].Uint64)); > } > - if (Lvl2PtEntry[Index2].Uint64 =3D=3D 0) { > + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { > continue; > } > - if (Lvl2PtEntry[Index2].Bits.PageSize =3D=3D 0) { > - Lvl1PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, > Lvl2PtEntry[Index2].Bits.AddressHi); > - for (Index1 =3D 0; Index1 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) { > - if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { > - DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%0= 16lx\n", > Index1, Lvl1PtEntry[Index1].Uint64)); > + > + Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > + for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > + if (Lvl2PtEntry[Index2].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n= ", > Index2, Lvl2PtEntry[Index2].Uint64)); > + } > + if (Lvl2PtEntry[Index2].Uint64 =3D=3D 0) { > + continue; > + } > + if (Lvl2PtEntry[Index2].Bits.PageSize =3D=3D 0) { > + Lvl1PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, > Lvl2PtEntry[Index2].Bits.AddressHi); > + for (Index1 =3D 0; Index1 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) { > + if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%0= 16lx\n", > Index1, Lvl1PtEntry[Index1].Uint64)); > + } > } > } > } > @@ -510,6 +600,7 @@ PageAttributeToLength ( > @param[in] VtdIndex The index used to identify a VTd= engine. > @param[in] SecondLevelPagingEntry The second level paging entry in > VTd table for the device. > @param[in] Address The address to be checked. > + @param[in] Is5LevelPaging If it is the 5 level paging. > @param[out] PageAttributes The page attribute of the page e= ntry. >=20 > @return The page entry. > @@ -519,6 +610,7 @@ GetSecondLevelPageTableEntry ( > IN UINTN VtdIndex, > IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, > IN PHYSICAL_ADDRESS Address, > + IN BOOLEAN Is5LevelPaging, > OUT PAGE_ATTRIBUTE *PageAttribute > ) > { > @@ -526,17 +618,38 @@ GetSecondLevelPageTableEntry ( > UINTN Index2; > UINTN Index3; > UINTN Index4; > + UINTN Index5; > UINT64 *L1PageTable; > UINT64 *L2PageTable; > UINT64 *L3PageTable; > UINT64 *L4PageTable; > + UINT64 *L5PageTable; >=20 > + Index5 =3D ((UINTN)RShiftU64 (Address, 48)) & PAGING_VTD_INDEX_MASK; > Index4 =3D ((UINTN)RShiftU64 (Address, 39)) & PAGING_VTD_INDEX_MASK; > Index3 =3D ((UINTN)Address >> 30) & PAGING_VTD_INDEX_MASK; > Index2 =3D ((UINTN)Address >> 21) & PAGING_VTD_INDEX_MASK; > Index1 =3D ((UINTN)Address >> 12) & PAGING_VTD_INDEX_MASK; >=20 > - L4PageTable =3D (UINT64 *)SecondLevelPagingEntry; > + if (Is5LevelPaging) { > + L5PageTable =3D (UINT64 *)SecondLevelPagingEntry; > + if (L5PageTable[Index5] =3D=3D 0) { > + L5PageTable[Index5] =3D (UINT64)(UINTN)AllocateZeroPages (1); > + if (L5PageTable[Index5] =3D=3D 0) { > + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL5 PAGE FAIL > (0x%x)!!!!!!\n", Index4)); > + ASSERT(FALSE); > + *PageAttribute =3D PageNone; > + return NULL; > + } > + FlushPageTableMemory (VtdIndex, (UINTN)L5PageTable[Index5], > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute > ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&L5PageTable[Index5], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)&L5PageTable[Index5], > sizeof(L5PageTable[Index5])); > + } > + L4PageTable =3D (UINT64 *)(UINTN)(L5PageTable[Index5] & > PAGING_4K_ADDRESS_MASK_64); > + } else { > + L4PageTable =3D (UINT64 *)SecondLevelPagingEntry; > + } > + > if (L4PageTable[Index4] =3D=3D 0) { > L4PageTable[Index4] =3D (UINT64)(UINTN)AllocateZeroPages (1); > if (L4PageTable[Index4] =3D=3D 0) { > @@ -785,7 +898,7 @@ SetSecondLevelPagingAttribute ( > } >=20 > while (Length !=3D 0) { > - PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, > SecondLevelPagingEntry, BaseAddress, &PageAttribute); > + PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, > SecondLevelPagingEntry, BaseAddress, > mVtdUnitInformation[VtdIndex].Is5LevelPaging, &PageAttribute); > if (PageEntry =3D=3D NULL) { > DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n")); > return RETURN_UNSUPPORTED; > @@ -913,7 +1026,7 @@ SetAccessAttribute ( >=20 > if (ExtContextEntry !=3D NULL) { > if (ExtContextEntry->Bits.Present =3D=3D 0) { > - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex,= 0); > + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex,= 0, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x > B%02x D%02x F%02x) New\n", SecondLevelPagingEntry, Segment, > SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)); > Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 1= 2); >=20 > @@ -922,7 +1035,7 @@ SetAccessAttribute ( > ExtContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ExtContextEntry->Bits.Present =3D 1; > FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, > sizeof(*ExtContextEntry)); > - DumpDmarExtContextEntryTable > (mVtdUnitInformation[VtdIndex].ExtRootEntryTable); > + DumpDmarExtContextEntryTable > (mVtdUnitInformation[VtdIndex].ExtRootEntryTable, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry- > >Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry- > >Bits.SecondLevelPageTranslationPointerHi); > @@ -930,7 +1043,7 @@ SetAccessAttribute ( > } > } else if (ContextEntry !=3D NULL) { > if (ContextEntry->Bits.Present =3D=3D 0) { > - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex,= 0); > + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex,= 0, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x > B%02x D%02x F%02x) New\n", SecondLevelPagingEntry, Segment, > SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)); > Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 1= 2); >=20 > @@ -939,7 +1052,7 @@ SetAccessAttribute ( > ContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ContextEntry->Bits.Present =3D 1; > FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, > sizeof(*ContextEntry)); > - DumpDmarContextEntryTable > (mVtdUnitInformation[VtdIndex].RootEntryTable); > + DumpDmarContextEntryTable > (mVtdUnitInformation[VtdIndex].RootEntryTable, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry- > >Bits.SecondLevelPageTranslationPointerLo, ContextEntry- > >Bits.SecondLevelPageTranslationPointerHi); > @@ -1000,7 +1113,7 @@ AlwaysEnablePageAttribute ( >=20 > if (mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D=3D 0= ) { > DEBUG((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", > VtdIndex)); > - mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D > CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | > EDKII_IOMMU_ACCESS_WRITE); > + mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D > CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | > EDKII_IOMMU_ACCESS_WRITE, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > } >=20 > SecondLevelPagingEntry =3D > mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry; > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > index 0ed9e3ca..a4466891 100644 > --- > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > @@ -78,11 +78,28 @@ CreateExtContextEntry ( >=20 > DEBUG ((DEBUG_INFO,"DOMAIN: S%04x, B%02x D%02x F%02x\n", > mVtdUnitInformation[VtdIndex].Segment, SourceId.Bits.Bus, > SourceId.Bits.Device, SourceId.Bits.Function)); >=20 > - if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) =3D=3D = 0) { > - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on > VTD %d !!!!\n", VtdIndex)); > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; > + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) !=3D 0)= { > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + if (mAcpiDmarTable->HostAddressWidth <=3D 48) { > + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) != =3D 0) { > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; > + } > + } > + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = =3D=3D > 0) { > + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on > VTD %d !!!!\n", VtdIndex)); > return EFI_UNSUPPORTED; > } > - ExtContextEntry->Bits.AddressWidth =3D 0x2; > + > + if (mVtdUnitInformation[VtdIndex].Is5LevelPaging) { > + ExtContextEntry->Bits.AddressWidth =3D 0x3; > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + } else { > + ExtContextEntry->Bits.AddressWidth =3D 0x2; > + DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", > VtdIndex)); > + } > + > + > } >=20 > FlushPageTableMemory (VtdIndex, > (UINTN)mVtdUnitInformation[VtdIndex].ExtRootEntryTable, > EFI_PAGES_TO_SIZE(EntryTablePages)); > @@ -93,11 +110,13 @@ CreateExtContextEntry ( > /** > Dump DMAR extended context entry table. >=20 > - @param[in] ExtRootEntry DMAR extended root entry. > + @param[in] ExtRootEntry DMAR extended root entry. > + @param[in] Is5LevelPaging If it is the 5 level paging. > **/ > VOID > DumpDmarExtContextEntryTable ( > - IN VTD_EXT_ROOT_ENTRY *ExtRootEntry > + IN VTD_EXT_ROOT_ENTRY *ExtRootEntry, > + IN BOOLEAN Is5LevelPaging > ) > { > UINTN Index; > @@ -127,7 +146,7 @@ DumpDmarExtContextEntryTable ( > if (ExtContextEntry[Index2].Bits.Present =3D=3D 0) { > continue; > } > - DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPa > geTranslationPointerLo, > ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi)); > + DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPa > geTranslationPointerLo, > ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi), > Is5LevelPaging); > } >=20 > if (ExtRootEntry[Index].Bits.UpperPresent =3D=3D 0) { > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg= .c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c > index 699639ba..686d235f 100644 > --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c > @@ -174,8 +174,14 @@ PrepareVtdConfig ( > if ((mVtdUnitInformation[Index].CapReg.Bits.SLLPS & BIT0) =3D=3D 0) = { > DEBUG((DEBUG_WARN, "!!!! 2MB super page is not supported on > VTD %d !!!!\n", Index)); > } > - if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) =3D=3D 0) = { > - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on > VTD %d !!!!\n", Index)); > + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT3) !=3D 0) { > + DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n", > Index)); > + } > + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) !=3D 0) { > + DEBUG((DEBUG_INFO, "Support 4-level page-table on VTD %d\n", > Index)); > + } > + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) = =3D=3D 0) > { > + DEBUG((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on > VTD %d !!!!\n", Index, mVtdUnitInformation[Index].CapReg.Bits.SAGAW)); > return ; > } >=20 > -- > 2.16.2.windows.1