From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=jiewen.yao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 158222034A891 for ; Fri, 27 Oct 2017 05:26:54 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP; 27 Oct 2017 05:30:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,304,1505804400"; d="scan'208";a="914419097" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by FMSMGA003.fm.intel.com with ESMTP; 27 Oct 2017 05:30:41 -0700 Received: from fmsmsx123.amr.corp.intel.com (10.18.125.38) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 27 Oct 2017 05:30:40 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by fmsmsx123.amr.corp.intel.com (10.18.125.38) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 27 Oct 2017 05:30:40 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.175]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.159]) with mapi id 14.03.0319.002; Fri, 27 Oct 2017 20:30:38 +0800 From: "Yao, Jiewen" To: "Zeng, Star" , "edk2-devel@lists.01.org" Thread-Topic: [edk2] [PATCH V2 2/2] IntelSiliconPkg/VtdPeiSample: Add premem support. Thread-Index: AQHTTuYtZb1oWE4ECUuhB97iYEsELaL2vUgAgAAfMoCAAMP7MA== Date: Fri, 27 Oct 2017 12:30:37 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AA07475@shsmsx102.ccr.corp.intel.com> References: <1509082830-17824-1-git-send-email-jiewen.yao@intel.com> <1509082830-17824-3-git-send-email-jiewen.yao@intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B9AEEAB@shsmsx102.ccr.corp.intel.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B9AEF1A@shsmsx102.ccr.corp.intel.com> In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B9AEF1A@shsmsx102.ccr.corp.intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiOGVjODRmOTAtMGE2MS00NDczLWIzYjMtMmExNTdiZTYyNzY1IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjIuNS4xOCIsIlRydXN0ZWRMYWJlbEhhc2giOiJsU1FSeUd1cU1wdDErbWU4bUlJb3FaNWJuXC9HNW9zNVdwTHgzMkl4d1wvQktUXC96amRCUHF1NzYxYUgyUTVHbnNhIn0= x-ctpclassification: CTP_IC dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH V2 2/2] IntelSiliconPkg/VtdPeiSample: Add premem support. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Oct 2017 12:26:54 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Good feedback. I fixed all these in V3. Why the wrong size does not cause problem? The reason is that the garbage data is skipped in the while loop of DRHD or= RMRR structure. Thank you Yao Jiewen > -----Original Message----- > From: Zeng, Star > Sent: Friday, October 27, 2017 4:47 PM > To: Yao, Jiewen ; edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: RE: [edk2] [PATCH V2 2/2] IntelSiliconPkg/VtdPeiSample: Add prem= em > support. >=20 > Another comment. >=20 > sizeof(MY_VTD_INFO_PPI) is used in mPlatformVTdNoIgdSample, that seems > wrong and should be sizeof(MY_VTD_INFO_NO_IGD_PPI), right? > Why it does not cause problem with the code. >=20 >=20 > Thanks, > Star > -----Original Message----- > From: Zeng, Star > Sent: Friday, October 27, 2017 2:56 PM > To: Yao, Jiewen ; edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: RE: [edk2] [PATCH V2 2/2] IntelSiliconPkg/VtdPeiSample: Add prem= em > support. >=20 > Could you update the function comments of InitDmar() and > SiliconInitializedPpiNotifyCallback()? > There are two lines of " DEBUG ((DEBUG_INFO, "MchBar - %x\n", MchBar)) " = in > InitDmar(), are they added on purpose? >=20 > Thanks, > Star > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ji= ewen > Yao > Sent: Friday, October 27, 2017 1:41 PM > To: edk2-devel@lists.01.org > Cc: Zeng, Star > Subject: [edk2] [PATCH V2 2/2] IntelSiliconPkg/VtdPeiSample: Add premem > support. >=20 > Before memory is ready, this sample produces one VTd engine. > After memory and silicon is initialized, this sample produces both IGD VT= d engine > and all-rest VTd engine by reinstall the FV_INFO_PPI. >=20 > This update is to demonstrate how to support pre-mem VTd usage. >=20 > Cc: Star Zeng > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Jiewen Yao > --- >=20 > IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSampl= e > Pei.c | 234 +++++++++++++++++--- >=20 > IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSampl= e > Pei.inf | 2 +- > 2 files changed, 202 insertions(+), 34 deletions(-) >=20 > diff --git > a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.c > b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.c > index 6267da7..921daef 100644 > --- > a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.c > +++ b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdIn > +++ foSamplePei.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include >=20 > #define R_SA_MCHBAR (0x48) > #define R_SA_GGC (0x50) > @@ -33,6 +34,8 @@ > #define R_SA_MCHBAR_VTD1_OFFSET 0x5400 ///< HW UNIT for IGD > #define R_SA_MCHBAR_VTD2_OFFSET 0x5410 ///< HW UNIT for all other - > PEG, USB, SATA etc >=20 > +EFI_GUID gEdkiiSiliconInitializedPpiGuid =3D {0x82a72dc8, 0x61ec, 0x403e= , > +{0xb1, 0x5a, 0x8d, 0x7a, 0x3a, 0x71, 0x84, 0x98}}; > + > typedef struct { > EFI_ACPI_DMAR_HEADER DmarHeader; > // > @@ -131,50 +134,190 @@ EFI_PEI_PPI_DESCRIPTOR > mPlatformVTdInfoSampleDesc =3D { > &mPlatformVTdSample > }; >=20 > +typedef struct { > + EFI_ACPI_DMAR_HEADER DmarHeader; > + // > + // VTd engine 2 - all rest > + // > + EFI_ACPI_DMAR_DRHD_HEADER Drhd2; > +} MY_VTD_INFO_NO_IGD_PPI; > + > +MY_VTD_INFO_NO_IGD_PPI mPlatformVTdNoIgdSample =3D { > + { // DmarHeader > + { // Header > + EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE, > + sizeof(MY_VTD_INFO_PPI), > + EFI_ACPI_DMAR_REVISION, > + }, > + 0x26, // HostAddressWidth > + }, > + > + { // Drhd2 > + { // Header > + EFI_ACPI_DMAR_TYPE_DRHD, > + sizeof(EFI_ACPI_DMAR_DRHD_HEADER) > + }, > + EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL, // Flags > + 0, // Reserved > + 0, // SegmentNumber > + 0xFED91000 // RegisterBaseAddress -- TO BE PATCHED > + }, > +}; > + > +EFI_PEI_PPI_DESCRIPTOR mPlatformVTdNoIgdInfoSampleDesc =3D { > + (EFI_PEI_PPI_DESCRIPTOR_PPI | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > + &gEdkiiVTdInfoPpiGuid, > + &mPlatformVTdNoIgdSample > +}; > + > /** > Patch Graphic UMA address in RMRR and base address. > **/ > VOID > -PatchDmar ( > +InitDmar ( > VOID > ) > { > UINT32 MchBar; > - UINT16 IgdMode; > - UINT16 GttMode; > - UINT32 IgdMemSize; > - UINT32 GttMemSize; > - > - /// > - /// Calculate IGD memsize > - /// > - IgdMode =3D ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & > B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF; > - if (IgdMode < 0xF0) { > - IgdMemSize =3D IgdMode * 32 * (1024) * (1024); > + > + DEBUG ((DEBUG_INFO, "InitDmar\n")); > + > + MchBar =3D PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; > + DEBUG ((DEBUG_INFO, "MchBar - %x\n", MchBar)); > + > + PciWrite32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR), 0xFED10000 | > + BIT0); DEBUG ((DEBUG_INFO, "MchBar - %x\n", MchBar)); > + > + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + > +R_SA_MCHBAR_VTD2_OFFSET) &~1))); > + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, > +(UINT32)mPlatformVTdSample.Drhd2.RegisterBaseAddress | 1); > + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + > +R_SA_MCHBAR_VTD2_OFFSET) &~1))); } > + > +/** > + Patch Graphic UMA address in RMRR and base address. > +**/ > +EFI_PEI_PPI_DESCRIPTOR * > +PatchDmar ( > + VOID > + ) > +{ > + UINT32 MchBar; > + UINT16 IgdMode; > + UINT16 GttMode; > + UINT32 IgdMemSize; > + UINT32 GttMemSize; > + MY_VTD_INFO_PPI *PlatformVTdSample; > + EFI_PEI_PPI_DESCRIPTOR *PlatformVTdInfoSampleDesc; > + MY_VTD_INFO_NO_IGD_PPI *PlatformVTdNoIgdSample; > + EFI_PEI_PPI_DESCRIPTOR *PlatformVTdNoIgdInfoSampleDesc; > + > + DEBUG ((DEBUG_INFO, "PatchDmar\n")); > + > + if (PciRead16 (PCI_LIB_ADDRESS(0, 2, 0, 0)) !=3D 0xFFFF) { > + PlatformVTdSample =3D AllocateCopyPool (sizeof(MY_VTD_INFO_PPI), > &mPlatformVTdSample); > + ASSERT(PlatformVTdSample !=3D NULL); > + PlatformVTdInfoSampleDesc =3D AllocateCopyPool > (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdInfoSampleDesc); > + ASSERT(PlatformVTdInfoSampleDesc !=3D NULL); > + PlatformVTdInfoSampleDesc->Ppi =3D PlatformVTdSample; > + > + /// > + /// Calculate IGD memsize > + /// > + IgdMode =3D ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & > B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF; > + if (IgdMode < 0xF0) { > + IgdMemSize =3D IgdMode * 32 * (1024) * (1024); > + } else { > + IgdMemSize =3D 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024); > + } > + > + /// > + /// Calculate GTT mem size > + /// > + GttMemSize =3D 0; > + GttMode =3D (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & > B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET; > + if (GttMode <=3D V_SKL_SA_GGC_GGMS_8MB) { > + GttMemSize =3D (1 << GttMode) * (1024) * (1024); > + } > + > + PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress =3D > (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize= - > GttMemSize; > + PlatformVTdSample->Rmrr1.ReservedMemoryRegionLimitAddress =3D > + PlatformVTdSample->Rmrr1.ReservedMemoryRegionBaseAddress + > IgdMemSize > + + GttMemSize - 1; > + > + /// > + /// Update DRHD structures of DmarTable > + /// > + MchBar =3D PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0= ; > + > + DEBUG ((DEBUG_INFO, "VTd1 - %x\n", (MmioRead32 (MchBar + > R_SA_MCHBAR_VTD1_OFFSET)))); > + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1) !=3D 0) { > + PlatformVTdSample->Drhd1.RegisterBaseAddress =3D (MmioRead32 > (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1); > + } else { > + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET, > (UINT32)PlatformVTdSample->Drhd1.RegisterBaseAddress | 1); > + } > + > + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + > R_SA_MCHBAR_VTD2_OFFSET)))); > + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) !=3D 0) { > + PlatformVTdSample->Drhd2.RegisterBaseAddress =3D (MmioRead32 > (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1); > + } else { > + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, > (UINT32)PlatformVTdSample->Drhd2.RegisterBaseAddress | 1); > + } > + > + return PlatformVTdInfoSampleDesc; > } else { > - IgdMemSize =3D 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024); > - } > + PlatformVTdNoIgdSample =3D AllocateCopyPool > (sizeof(MY_VTD_INFO_NO_IGD_PPI), &mPlatformVTdNoIgdSample); > + ASSERT(PlatformVTdNoIgdSample !=3D NULL); > + PlatformVTdNoIgdInfoSampleDesc =3D AllocateCopyPool > (sizeof(EFI_PEI_PPI_DESCRIPTOR), &mPlatformVTdNoIgdInfoSampleDesc); > + ASSERT(PlatformVTdNoIgdInfoSampleDesc !=3D NULL); > + PlatformVTdNoIgdInfoSampleDesc->Ppi =3D PlatformVTdNoIgdSample; > + > + /// > + /// Update DRHD structures of DmarTable > + /// > + MchBar =3D PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0= ; >=20 > - /// > - /// Calculate GTT mem size > - /// > - GttMemSize =3D 0; > - GttMode =3D (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & > B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET; > - if (GttMode <=3D V_SKL_SA_GGC_GGMS_8MB) { > - GttMemSize =3D (1 << GttMode) * (1024) * (1024); > + DEBUG ((DEBUG_INFO, "VTd2 - %x\n", (MmioRead32 (MchBar + > R_SA_MCHBAR_VTD2_OFFSET)))); > + if ((MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1) !=3D 0) { > + PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress =3D (MmioRead32 > (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1); > + } else { > + MmioWrite32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET, > (UINT32)PlatformVTdNoIgdSample->Drhd2.RegisterBaseAddress | 1); > + } > + > + return PlatformVTdNoIgdInfoSampleDesc; > } > +} >=20 > - mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress =3D > (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize= - > GttMemSize; > - mPlatformVTdSample.Rmrr1.ReservedMemoryRegionLimitAddress =3D > mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress + > IgdMemSize + GttMemSize - 1; > +/** > + Install Firmware Volume Hob's once there is main memory >=20 > - /// > - /// Update DRHD structures of DmarTable > - /// > - MchBar =3D PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0; > - mPlatformVTdSample.Drhd1.RegisterBaseAddress =3D (MmioRead32 (MchBar + > R_SA_MCHBAR_VTD1_OFFSET) &~1); > - mPlatformVTdSample.Drhd2.RegisterBaseAddress =3D (MmioRead32 (MchBar + > R_SA_MCHBAR_VTD2_OFFSET) &~1); > + @param[in] PeiServices General purpose services available to ev= ery > PEIM. > + @param[in] NotifyDescriptor Notify that this module published. > + @param[in] Ppi PPI that was installed. > + > + @retval EFI_SUCCESS The function completed successfully. > +**/ > +EFI_STATUS > +EFIAPI > +SiliconInitializedPpiNotifyCallback ( > + IN CONST EFI_PEI_SERVICES **PeiServices, > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, > + IN VOID *Ppi > + ) > +{ > + EFI_STATUS Status; > + EFI_PEI_PPI_DESCRIPTOR *PpiDesc; > + > + PpiDesc =3D PatchDmar (); > + > + Status =3D PeiServicesReInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc, > + PpiDesc); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; > } >=20 > +EFI_PEI_NOTIFY_DESCRIPTOR mSiliconInitializedNotifyList =3D { > + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > +EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > + &gEdkiiSiliconInitializedPpiGuid, > + (EFI_PEIM_NOTIFY_ENTRY_POINT) SiliconInitializedPpiNotifyCallback > +}; > + > /** > Platform VTd Info sample driver. >=20 > @@ -190,12 +333,37 @@ PlatformVTdInfoSampleInitialize ( > IN CONST EFI_PEI_SERVICES **PeiServices > ) > { > - EFI_STATUS Status; > + EFI_STATUS Status; > + BOOLEAN SiliconInitialized; > + VOID *SiliconInitializedPpi; > + EFI_PEI_PPI_DESCRIPTOR *PpiDesc; > + > + SiliconInitialized =3D FALSE; > + // > + // Check if silicon is initialized. > + // > + Status =3D PeiServicesLocatePpi ( > + &gEdkiiSiliconInitializedPpiGuid, > + 0, > + NULL, > + &SiliconInitializedPpi > + ); > + if (!EFI_ERROR(Status)) { > + SiliconInitialized =3D TRUE; > + } > + DEBUG ((DEBUG_INFO, "SiliconInitialized - %x\n", > + SiliconInitialized)); if (!SiliconInitialized) { > + Status =3D PeiServicesNotifyPpi (&mSiliconInitializedNotifyList); > + InitDmar (); >=20 > - PatchDmar (); > + Status =3D PeiServicesInstallPpi (&mPlatformVTdNoIgdInfoSampleDesc); > + ASSERT_EFI_ERROR (Status); > + } else { > + PpiDesc =3D PatchDmar (); >=20 > - Status =3D PeiServicesInstallPpi (&mPlatformVTdInfoSampleDesc); > - ASSERT_EFI_ERROR (Status); > + Status =3D PeiServicesInstallPpi (PpiDesc); > + ASSERT_EFI_ERROR (Status); > + } >=20 > return Status; > } > diff --git > a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.inf > b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.inf > index 96adb70..a4ffe51 100644 > --- > a/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSam > plePei.inf > +++ b/IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdIn > +++ foSamplePei.inf > @@ -47,7 +47,7 @@ > gEdkiiVTdInfoPpiGuid ## PRODUCES >=20 > [Depex] > - gEfiPeiMemoryDiscoveredPpiGuid > + gEfiPeiMasterBootModePpiGuid >=20 > [UserExtensions.TianoCore."ExtraFiles"] > PlatformVTdInfoSamplePeiExtra.uni > -- > 2.7.4.windows.1 >=20 > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel