//************************************************************************* //************************************************************************* //** ** //** (C)Copyright 1985-2010, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** //** ** //** Phone: (770)-246-8600 ** //** ** //************************************************************************* //************************************************************************* //************************************************************************* // $Header: /Alaska/SOURCE/Core/Library/AcpiRes.c 32 12/22/11 12:26p Felixp $ // // $Revision: 32 $ // // $Date: 12/22/11 12:26p $ //************************************************************************* // Revision History // ---------------- // $Log: /Alaska/SOURCE/Core/Library/AcpiRes.c $ // // 32 12/22/11 12:26p Felixp // Bug fix in GetRbAmlPackagePointer. // Wrong pointer math in the first paramater of the first GetAslObj call. // // 31 11/15/11 11:59a Felixp // [TAG] EIP73021 // [Category] Improvement // [Description] LibGetDsdt: initialize Status variable with default // value (EFI_NOT_FOUND) // // 30 11/11/11 3:14p Artems // PI 1.2 support: Use ACPI_SDT protocol in PI 1.2 mode // // 29 4/08/11 2:26p Yakovlevs // [TAG] EIP55537 // [Category] New Feature // [Description] Request for ACPI library function to dynamically modify // Package objects // [Files] AcpiRes.c; AcpiRes.h // // 28 4/05/11 2:01p Yakovlevs // [TAG] EIP38174 // [Category] New Feature // [Description] Generic support to handle PCI OUT OF RESOURDCES added. // AmiPciOutOfRes() function added. // [Files] AcpiRes.h // // 27 4/28/10 2:31p Oleksiyy // EIP 35563 LibGetDsdt fixed for only ACPI 1.1 tables case. // // 26 2/23/10 11:23p Felixp // // 25 2/19/10 11:37a Oleksiyy // EIP 35099: HideAslMethodFromOs function added, which replace // leading '_' in method name with 'X'. // // 24 8/21/09 3:47p Yakovlevs // A new function - UpdateAslNameOfDevice() was added. // Some ASL update functions was changed to support newly added one. // // 23 7/10/09 4:01p Felixp // Function headers added // // 22 10/21/08 3:27p Felixp // LibGetDsdt updated to be backward compatible // // 21 10/14/08 4:36p Yakovlevs // Support for EFI_ACPI_TABLE_VERSION_3_0 added in LibGetDsdt() function. // // 20 10/01/08 12:57p Yakovlevs // ValidateDescriptorBlock() function implementation changed to accomodate // recent PciBus Driver changes // // 19 3/30/07 3:44p Felixp // Comments added // // 18 3/29/07 11:01a Yakovlevs // Added LibGetDsdt() function implementation; file header fixed. //************************************************************************* // // // Name: AcpiRes.c // // Description: // Implementation of ASL MACROs for ResourceTemplate. See ACPI 2.0 // specification section 16.2.4. // // //************************************************************************* #include #include #include //************************************************************************* // // // Name: ASLM_IRQ // // Description: // VOID* ASLM_IRQ(IN UINT8 dsc_cnt, IN UINT8 ll, IN UINT8 he, // IN UINT8 shr, IN ...) generates a short IRQ descriptor and returns its // address. User is responsible for freeing the returned memory. // // Input: // IN UINT8 dsc_cnt // Number of IRQ numbers in the list. // // IN UINT8 ll // IRQ flag. 0 = active-high, 1 = active-low. // // IN UINT8 he // IRQ flag. 0 = level-triggered, 1 = edge-triggered. // // IN UINT8 shr // IRQ flag. 0 = not interrupt shareable, 1 = interrupt shareable. // // IN ... // List of IRQ numbers. Valid values: 0-15. // // Output: // VOID* address of the created IRQ descriptor. User is responsible for // freeing the returned memory. // // Modified: // // Referrals: // Malloc // va_start // va_arg // va_end // // Notes: // // //************************************************************************* VOID *ASLM_IRQ(UINT8 dsc_cnt, UINT8 ll, UINT8 he, UINT8 shr, ... ) { UINT8 i; UINT16 irq=0; va_list marker; UINT32 sz=sizeof(ASLR_IRQ); ASLR_IRQ *rb=(ASLR_IRQ*)Malloc(sz); //------------------------------ if (!rb)return NULL; pBS->SetMem(rb,sz,0); //Update descriptor Header rb->Hdr.Length=3;//sizeof(ASLR_IRQ)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_IRQ; rb->Hdr.Type=ASLV_SMALL_RES; //Update descriptor Body rb->Flags._LL=ll; rb->Flags._HE=he; rb->Flags._SHR=shr; va_start(marker, shr); for (i=0; i_INT=irq; return rb; } //************************************************************************* // // // Name: ASLM_IRQNoFlags // // Description: // VOID* ASLM_IRQNoFlags(IN UINT8 dsc_cnt, IN ...) generates a short IRQ // descriptor without an optional IRQ information byte and returns its // address. User is responsible for freeing the returned memory. // // Input: // IN UINT8 dsc_cnt // Number of IRQ numbers in the list. // // IN ... // List of IRQ numbers. Valid values: 0-15. // // Output: // VOID* address of the created IRQ descriptor. User is responsible for // freeing the returned memory. // // Modified: // // Referrals: // Malloc // va_start // va_arg // va_end // // Notes: // // //************************************************************************* VOID *ASLM_IRQNoFlags(UINT8 dsc_cnt, ... ) { UINT8 i; va_list marker; UINT16 irq=0; UINT32 sz=sizeof(ASLR_IRQNoFlags); ASLR_IRQNoFlags *rb=(ASLR_IRQNoFlags*)Malloc(sz); //------------------------------ if (!rb)return NULL; pBS->SetMem(rb,sz,0); //Update descriptor Header rb->Hdr.Length=2;//sizeof(ASLR_IRQNoFlags)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_IRQ; rb->Hdr.Type=ASLV_SMALL_RES; va_start(marker, dsc_cnt); for (i=0; i_INT=irq; return rb; } //************************************************************************* // // // Name: ASLM_DMA // // Description: // VOID* ASLM_DMA(IN UINT8 dsc_cnt, IN UINT8 typ, IN UINT8 bm, IN UINT8 siz, // IN ...) generates a short DMA descriptor and returns its address. User is // responsible for freeing the returned memory. // // Input: // IN UINT8 dsc_cnt // Number of channel numbers in the list. // // IN UINT8 typ // DMA channel speed. Valid values are: // ASLV_Compatibility, ASLV_TypeA, ASLV_TypeB, ASLV_TypeF // // IN UINT8 bm // BusMaster or NotBusMaster. 0 defaults to BusMaster. // // IN UINT8 siz // Transfer size. Valid values are: // Transfer8, Transfer16, Transfer8_16 // // IN ... // List of channel numbers. Valid values are 0-7. // // Output: // VOID* address of the created DMA descriptor. User is responsible for // freeing the returned memory. // // Modified: // // Referrals: // Malloc // va_start // va_arg // va_end // // Notes: // // //************************************************************************* VOID *ASLM_DMA(UINT8 dsc_cnt, UINT8 typ, UINT8 bm, UINT8 siz, ... ) { UINT8 i, dma=0; va_list marker; UINT32 sz=sizeof(ASLR_DMA); ASLR_DMA *rb=(ASLR_DMA*)Malloc(sz); //------------------------------ if (!rb)return NULL; pBS->SetMem(rb,sz,0); //Update descriptor Header rb->Hdr.Length=sizeof(ASLR_DMA)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_DMA; rb->Hdr.Type=ASLV_SMALL_RES; //Update descriptor Body rb->Flags._TYP=typ; rb->Flags._BM=bm; rb->Flags._SIZ=siz; va_start(marker, siz); for (i=0; i_DMA=dma; return rb; } //************************************************************************* // // // Name: ASLM_StartDependentFn // // Description: // VOID* ASLM_StartDependentFn(IN UINT8 dsc_cnt, IN UINT8 pComp, // IN UINT8 pPerf, IN ...) generates a Start-Dependent Function descriptor // with the optional priority byte and returns its address. User is // responsible for freeing the returned memory. // // Input: // IN UINT8 dsc_cnt // Number of items in the descriptor list. // // IN UINT8 pComp // Compatibility priority. Valid values are 0-2. // // IN UINT8 pPerf // Performance/robustness priority. Valid values are 0-2. // // IN ... // List of descriptors for this dependent function. // // Output: // VOID* address of the created Start-Dependent Function descriptor. User // is responsible for freeing the returned memory. // // Modified: // // Referrals: // MallocZ // Malloc // va_start // va_arg // // Notes: // // //************************************************************************* VOID *ASLM_StartDependentFn(UINT8 dsc_cnt,UINT8 pComp,UINT8 pPerf, ...) { UINT8 i; va_list marker; UINT32 sz=sizeof(EFI_ASL_DepFn)+sizeof(ASLR_StartDependentFn); EFI_ASL_DepFn *rb=(EFI_ASL_DepFn*)MallocZ(sz); //-------------------------------------------- if (!rb)return NULL; rb->DepFn=(rb+1); ((ASLR_StartDependentFn*)rb->DepFn)->Hdr.Length=sizeof(ASLR_StartDependentFn)-sizeof(ASLRF_S_HDR); ((ASLR_StartDependentFn*)rb->DepFn)->Hdr.Name=ASLV_RT_StartDependentFn; ((ASLR_StartDependentFn*)rb->DepFn)->Hdr.Type=ASLV_SMALL_RES; ((ASLR_StartDependentFn*)rb->DepFn)->_PRI._CMP=pComp; ((ASLR_StartDependentFn*)rb->DepFn)->_PRI._PRF=pPerf; rb->DepRes.Items=Malloc(sizeof(ASLR_HDR*)*dsc_cnt); if (!rb->DepRes.Items) return NULL; rb->DepRes.InitialCount=dsc_cnt; rb->DepRes.ItemCount=dsc_cnt; va_start(marker, pPerf); for (i=0; iDepRes.Items[i]=va_arg(marker, VOID*); return rb; } //************************************************************************* // // // Name: ASLM_StartDependentFnNoPri // // Description: // VOID* ASLM_StartDependentFnNoPri(IN UINT8 dsc_cnt, IN ...) generates a // Start-Dependent Function descriptor without the optional priority byte and // returns its address. User is responsible for freeing the returned memory. // // Input: // IN UINT8 dsc_cnt // Number of items in the descriptor list. // // IN ... // List of descriptors for this dependent function. // // Output: // VOID* address of the created Start-Dependent Function descriptor. User // is responsible for freeing the returned memory. // // Modified: // // Referrals: // MallocZ // Malloc // va_start // va_arg // // Notes: // // //************************************************************************* VOID *ASLM_StartDependentFnNoPri(UINT8 dsc_cnt, ...) { UINT8 i; va_list marker; UINT32 sz=sizeof(EFI_ASL_DepFn)+sizeof(ASLR_StartDependentFnNoPri); EFI_ASL_DepFn *rb=(EFI_ASL_DepFn*)MallocZ(sz); //-------------------------------------------- if (!rb)return NULL; rb->DepFn=(rb+1); ((ASLR_StartDependentFnNoPri*)rb->DepFn)->Length=sizeof(ASLR_StartDependentFnNoPri)-sizeof(ASLRF_S_HDR); ((ASLR_StartDependentFnNoPri*)rb->DepFn)->Name=ASLV_RT_StartDependentFn; ((ASLR_StartDependentFnNoPri*)rb->DepFn)->Type=ASLV_SMALL_RES; rb->DepRes.Items=Malloc(sizeof(ASLR_HDR*)*dsc_cnt); if (!rb->DepRes.Items) return NULL; rb->DepRes.InitialCount=dsc_cnt; rb->DepRes.ItemCount=dsc_cnt; va_start(marker, dsc_cnt); for (i=0; iDepRes.Items[i]=va_arg(marker, VOID*); return rb; } //************************************************************************* // // // Name: ASLM_IO // // Description: // VOID* ASLM_IO(IN UINT8 dec, IN UINT16 min, IN UINT16 max, IN UINT8 aln, // IN UINT8 len) generates a short I/O descriptor and returns its address. // User is responsible for freeing the returned memory. // // Input: // IN UINT8 dec // Decode value. Valid values are: ASLV_Decode16, ASLV_Decode10. // // IN UINT16 min // Address minimum. // // IN UINT16 max // Address maximum. // // IN UINT8 aln // Base alignment. // // IN UINT8 len // Range length. // // Output: // VOID* address of the created I/O descriptor. User is responsible for // freeing the returned memory. // // Modified: // // Referrals: // MallocZ // // Notes: // // //************************************************************************* VOID *ASLM_IO(UINT8 dec,UINT16 min,UINT16 max,UINT8 aln,UINT8 len) { ASLR_IO *rb=(ASLR_IO*)MallocZ(sizeof(ASLR_IO)); //------------------------------------------ if (!rb)return NULL; rb->Hdr.Length=sizeof(ASLR_IO)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_IO; rb->Hdr.Type=ASLV_SMALL_RES; rb->_DEC=dec; rb->_MIN=min; rb->_MAX=max; rb->_ALN=aln; rb->_LEN=len; return rb; } //************************************************************************* // // // Name: ASLM_FixedIO // // Description: // VOID* ASLM_FixedIO(IN UINT16 bas, IN UINT8 len) generates a short fixed // I/O descriptor and returns its address. User is responible for freeing // the returned memory. // // Input: // IN UINT16 bas // Address base. // // IN UINT8 len // Range length. // // Output: // VOID* address of the created fixed I/O descriptor. User is responsible // for freeing the returned memory. // // Modified: // // Referrals: // MallocZ // // Notes: // // //************************************************************************* VOID *ASLM_FixedIO(UINT16 bas, UINT8 len) { ASLR_FixedIO *rb=(ASLR_FixedIO*)MallocZ(sizeof(ASLR_FixedIO)); //------------------------------------------ if (!rb)return NULL; rb->Hdr.Length=sizeof(ASLR_FixedIO)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_FixedIO; rb->Hdr.Type=ASLV_SMALL_RES; rb->_BAS=bas; rb->_LEN=len; return rb; } //************************************************************************* // // // Name: ASLM_VendorShort // // Description: // VOID* ASLM_VendorShort(IN UINT8 byte_cnt, IN ...) generates a short // Vendor-Defined descriptor and returns its address. User is responsible // for freeing the returned memory. // // Input: // IN UINT8 byte_cnt // Number of bytes in the list. Must be less than 8. // // IN ... // List of byte expressions for the descriptor. Must be less than 8 // elements. // // Output: // VOID* address of the created Vendor-Defined descriptor. User is // responsible for freeing the returned memory. // // Modified: // // Referrals: // MallocZ // va_start // va_arg // va_end // // Notes: // // //************************************************************************* VOID *ASLM_VendorShort(UINT8 byte_cnt, ...) { UINT8 i; va_list marker; UINT32 sz= sizeof(ASLR_VendorShort)+byte_cnt; ASLR_VendorShort *rb=(ASLR_VendorShort*)MallocZ(sz); UINT8 *bb=(UINT8*)rb+1; //------------------------------ if (!rb)return NULL; rb->Length=byte_cnt; rb->Name=ASLV_RT_VendorShort; rb->Type=ASLV_SMALL_RES; va_start(marker, byte_cnt); //Update descriptor Body for (i=0; i // // Name: ASLM_Memory24 // // Description: // VOID* ASLM_Memory24(IN UINT8 rw, IN UINT8 min, IN UINT8 max, // IN UINT8 aln, IN UINT8 len) generates a long 24-bit memory descriptor and // returns its address. User is responsible for freeing the returned memory. // // Input: // IN UINT8 rw // Write protection flag. Valid values: ASLV_ReadOnly, ASLV_ReadWrite. // // IN UINT8 min // Minimum base memory address [23:8]. // // IN UINT8 max // Maximum base memory address [23:8]. // // IN UINT8 aln // Base alignment. // // IN UINT8 len // Range length. // // Output: // VOID* address of the created long 24-bit memory descriptor. User is // responsible for freeing the returned memory. // // Modified: // // Referrals: // MallocZ // // Notes: // // //************************************************************************* VOID *ASLM_Memory24(UINT8 rw,UINT8 min, UINT8 max, UINT8 aln, UINT8 len) { ASLR_Memory24 *rb=(ASLR_Memory24*)MallocZ(sizeof(ASLR_Memory24)); //------------------------------------------ if (!rb)return NULL; rb->Hdr.Length=sizeof(ASLR_Memory24)-sizeof(ASLRF_S_HDR); rb->Hdr.Name=ASLV_RT_Memory24; rb->Hdr.Type=ASLV_SMALL_RES; rb->_RW=rw; rb->_MIN=min; rb->_MAX=max; rb->_ALN=aln; rb->_LEN=len; return rb; } //---------------------------------------------------------------------- // Methods Implementation for T_ITEM_LIST object //---------------------------------------------------------------------- #define LST_INIT_COUNT 10 //initial value //************************************************************************* // // // Name: reallocItemLst // // Description: // EFI_STATUS reallocItemLst(IN T_ITEM_LIST *Lst) is an internal worker // function which reallocates space for a T_ITEM_LIST.Items[] array. // // Input: // IN T_ITEM_LIST *Lst // List which needs its Items array reallocated. // // Output: // EFI_OUT_OF_RESOURCES, if allocation failed. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // MallocZ // // Notes: // // //************************************************************************* EFI_STATUS reallocItemLst(T_ITEM_LIST *Lst) { UINTN sz=0; VOID *nrl=NULL; //new resource list pointer; //--------------------------------------------- // if Initial count has not been initialized; if (Lst->InitialCount==0) sz=LST_INIT_COUNT*sizeof(VOID*); else { //or Initial Count was initialized but memory fot Items[] array was not allocated if (Lst->InitialCount && !Lst->Items) sz=Lst->InitialCount*sizeof(VOID*); else { //or if we at the end or near the end of the Items[] array list if ((INTN)Lst->ItemCount > (INTN)(Lst->InitialCount-1)) sz=(Lst->InitialCount+LST_INIT_COUNT)*sizeof(VOID*); } } if (sz) { nrl=MallocZ(sz); if (!nrl) return EFI_OUT_OF_RESOURCES; pBS->CopyMem((VOID*)nrl,(VOID*)Lst->Items,sizeof(VOID*)*Lst->ItemCount); //Free Buffer of previouse ChildList... pBS->FreePool((VOID*)Lst->Items); //Make it point to a new ChildList Lst->Items=nrl; Lst->InitialCount=sz/sizeof(VOID*); } return EFI_SUCCESS; } //************************************************************************* // // // Name: InsertItemLst // // Description: // EFI_STATUS InsertItemLst(IN T_ITEM_LIST *Lst, IN VOID *pRes, // IN UINTN ItemIndex) inserts the provided item pointed to by pRes into the // provided Lst at index ItemIndex. // // Input: // IN T_ITEM_LIST *Lst // List to be inserted into. // // IN VOID *pRes // Pointer to object to place in list. // // IN UINTN ItemIndex // Index in list to place the object pointed to by pRes. // // Output: // EFI_INVALID_PARAMETER, if the ItemIndex value is invalid. // EFI_OUT_OF_RESOURCES, if there is not enough memory for the new object. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // reallocItemLst // // Notes: // // //************************************************************************* EFI_STATUS InsertItemLst(T_ITEM_LIST *Lst, VOID* pRes, UINTN ItemIndex) { INTN i; //---------------- if (!Lst->ItemCount && Lst->ItemCountItemCount-1; i>=(INTN)ItemIndex; i--) Lst->Items[i+1]=Lst->Items[i]; //fill Item address we are inserting Lst->Items[ItemIndex]=pRes; //Adjust Item Count Lst->ItemCount++; return EFI_SUCCESS; } //************************************************************************* // // // Name: DeleteItemLst // // Description: // EFI_STATUS DeleteItemLst(IN T_ITEM_LIST *Lst, IN UINTN ItemIndex, // IN BOOLEAN FreeData) deletes the object stored at the provided ItemIndex // in Lst. Frees the memory associated with the object pointer if FreeData // is TRUE. // // Input: // IN T_ITEM_LIST *Lst // List to be deleted from. // // IN UINTN ItemIndex // Index inside Lst->Items to be deleted. // // IN BOOLEAN FreeData // TRUE will free the memory associated with the deleted object. // // Output: // EFI_INVALID_PARAMETER, if the provided ItemIndex is invalid. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* EFI_STATUS DeleteItemLst(T_ITEM_LIST *Lst, UINTN ItemIndex, BOOLEAN FreeData) { UINTN i; //---------------- if (!Lst->ItemCount || Lst->ItemCount<=ItemIndex) return EFI_INVALID_PARAMETER; //Free Data associated with Iterm if requested; if (FreeData)pBS->FreePool(Lst->Items[ItemIndex]); //Shift items after ItemIndex backwards for (i=ItemIndex; iItemCount-1; i++) Lst->Items[i]=Lst->Items[i+1]; //Adjust Item Count Lst->ItemCount--; return EFI_SUCCESS; } //************************************************************************* // // // Name: AppendItemLst // // Description: // EFI_STATUS AppendItemLst(IN T_ITEM_LIST *Lst, IN VOID *pRes) appends the // provided object to Lst. // // Input: // IN T_ITEM_LIST *Lst // List to be appended to. // // IN VOID *pRes // Object to be appended. // // Output: // EFI_OUT_OF_RESOURCES, if memory allocation fails. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // reallocItemLst // // Notes: // // //************************************************************************* EFI_STATUS AppendItemLst(T_ITEM_LIST *Lst, VOID* pRes ) { //Check if Items[] array can accomodate a new child... if (EFI_ERROR(reallocItemLst(Lst)))return EFI_OUT_OF_RESOURCES; Lst->Items[Lst->ItemCount]=pRes; Lst->ItemCount++; return EFI_SUCCESS; } //************************************************************************* // // // Name: ClearItemLst // // Description: // VOID ClearItemLst(IN T_ITEM_LIST *Lst, IN BOOLEAN FreeData) clears all // the items of Lst. If FreeData is TRUE, frees all the memory associated // with the stored objects. // // Input: // IN T_ITEM_LIST *Lst // List to be cleared. // // IN BOOLEAN FreeData // If TRUE, all objects are freed. // // Output: // VOID. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* VOID ClearItemLst(T_ITEM_LIST *Lst, BOOLEAN FreeData) { UINTN i; //----------------------------------------- if (FreeData)for (i=0; iItemCount; i++) { if (Lst->Items[i])pBS->FreePool(Lst->Items[i]); } if (Lst->Items) pBS->FreePool(Lst->Items); Lst->Items=NULL; Lst->ItemCount=0; Lst->InitialCount=0; } //************************************************************************* // // // Name: CopyItemLst // // Description: // EFI_STATUS CopyItemLst(IN T_ITEM_LIST *Lst, OUT T_ITEM_LIST **NewLstPtr) // copies Lst into a new list and provides the address of the copy in // NewLstPtr. // // Input: // IN T_ITEM_LIST *Lst // List to be copied. // // OUT T_ITEM_LIST **NewLstPtr // Location to store the address of the new copy. // // Output: // EFI_OUT_OF_RESOURCES, if memory allocation fails. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // MallocZ // // Notes: // // //************************************************************************* EFI_STATUS CopyItemLst(T_ITEM_LIST *Lst, T_ITEM_LIST **NewLstPtr) { UINTN i = 0; T_ITEM_LIST *NewLst = NULL; *NewLstPtr = NULL; *NewLstPtr = MallocZ(sizeof(T_ITEM_LIST)); if (!*NewLstPtr) { return EFI_OUT_OF_RESOURCES; } NewLst = *NewLstPtr; NewLst->InitialCount = Lst->InitialCount; NewLst->ItemCount = Lst->ItemCount; if (Lst->ItemCount == 0) { return EFI_SUCCESS; } NewLst->Items = MallocZ( Lst->ItemCount * sizeof(VOID*) ); if (!NewLst->Items) { return EFI_OUT_OF_RESOURCES; } for (i = 0; i < Lst->ItemCount; i++) { NewLst->Items[i] = NULL; if (Lst->Items[i]) { NewLst->Items[i] = MallocZ( sizeof(Lst->Items[i]) ); if (!NewLst->Items[i]) { return EFI_OUT_OF_RESOURCES; } pBS->CopyMem(NewLst->Items[i], Lst->Items[i], sizeof(Lst->Items[i])); } } return EFI_SUCCESS; } //************************************************************************* // // // Name: ValidateDescriptor // // Description: // BOOLEAN ValidateDescriptor(IN ASLR_QWORD_ASD *Descriptor, // IN ASLR_TYPE_ENUM ResType, IN BOOLEAN Fixed) validates a ASLV_LARGE_RES // descriptor. // // Input: // IN ASLR_QWORD_ASD *Descriptor // Descriptor to be validated. // // IN ASLR_TYPE_ENUM ResType // The resource type of the descriptor. Valid values are: // tResAll, tResIoMem, tResBus // // IN BOOLEAN Fixed // If TRUE, checks the general flags for consistancy. // // Output: // TRUE if a valid ASLR_QWORD_ASD descriptor. Otherwise, FALSE. // // Modified: // // Referrals: // // Notes: // Helper function for ValidateDescriptorBlock. // // //************************************************************************* BOOLEAN ValidateDescriptor(ASLR_QWORD_ASD *Descriptor,ASLR_TYPE_ENUM ResType,BOOLEAN Fixed) { //Check ASL Resource Descriptor Header consistancy if ( (Descriptor->Hdr.Name!=ASLV_RT_QWORD_ASD) || (Descriptor->Hdr.Type!=ASLV_LARGE_RES) || (Descriptor->Hdr.Length!=sizeof(ASLR_QWORD_ASD)-sizeof(ASLRF_L_HDR) ) )return FALSE; //Check ASL Resource Descriptor General Flags Consistancy if (Fixed) { if ( (!Descriptor->GFlags._MIF) || (!Descriptor->GFlags._MAF) )return FALSE; } if (Descriptor->Type>2) return FALSE; //Check ASL Resource Descriptor Resource Type switch (ResType) { case tResBus: if (Descriptor->Type!=ASLRV_SPC_TYPE_BUS) return FALSE; if ((Descriptor->_MIN+Descriptor->_LEN)>0x100)return FALSE; break; case tResIoMem: if (Descriptor->Type>=ASLRV_SPC_TYPE_BUS) return FALSE; break; case tResAll: if (Descriptor->Type>ASLRV_SPC_TYPE_BUS) return FALSE; break; default : return FALSE; } return TRUE; } //************************************************************************* // // // Name: ValidateDescriptorBlock // // Description: // UINTN ValidateDescriptorBlock(IN ASLR_QWORD_ASD *DscStart, // IN ASLR_TYPE_ENUM ResType, IN BOOLEAN Fixed) validates the consistancy of // the provided ACPI QWORD resource descriptors block which contains some // number of ASLR_QWORD_ASDs in memory terminated by an ASLR_EndTag. Returns // the total size of the resource descriptors plus the size of the // ASLR_EndTag. // // Input: // IN ASLR_QWORD_ASD *DscStart // Pointer to the first descriptor in the block to be validated. // // IN ASLR_TYPE_ENUM ResType // The resource type of the descriptors. Valid values are: // tResAll, tResIoMem, tResBus // // IN BOOLEAN Fixed // If TRUE, checks the general flags for consistancy. // // Output: // UINTN size of the resource descriptor block plus the size of the // ASLR_EndTag. // // Modified: // // Referrals: // ValidateDescriptor // // Notes: // // //************************************************************************* UINTN ValidateDescriptorBlock(ASLR_QWORD_ASD* DscStart, ASLR_TYPE_ENUM ResType, BOOLEAN Fixed) { ASLR_QWORD_ASD *qwd=DscStart; UINTN len=0; ASLR_EndTag *endtag=(ASLR_EndTag*)DscStart; //----------------------------------- //resource descriptor is empty... if (endtag->Hdr.HDR==ASLV_END_TAG_HDR) return sizeof(ASLR_EndTag); while (endtag->Hdr.HDR!=ASLV_END_TAG_HDR) { if (!ValidateDescriptor(qwd, ResType, Fixed)) return 0; else len+=sizeof(ASLR_QWORD_ASD); qwd++; endtag=(ASLR_EndTag*)qwd; } len+=sizeof(ASLR_EndTag); return len; } //************************************************************************* // // // Name: CheckDsdt // // Description: // BOOLEAN CheckDsdt(IN ACPI_HDR *Dsdt) checks the signature of the provided // ACPI header for the DSDT signature. // // Input: // IN ACPI_HDR *Dsdt // Pointer to the ACPI header to be checked for the DSDT signature. // // Output: // TRUE if the header signature is that of the DSDT. Otherwise, FALSE. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* BOOLEAN CheckDsdt(ACPI_HDR *Dsdt) { if (Dsdt->Signature!=DSDT_SIG) return FALSE; return TRUE; } // //---------------------------------------------------------------------------- // // Name: GetRbAmlPackagePointer // // Description: // This function returns a pointer to a named AML Package object in the // specified root bridge scope along with information necessary to // dynamically read and/or modify its data. // // This function also serves as an example of how a named Package object // pointer can be obtained, if the scope path is known. // // Input: // IN ACPI_HDR **Dsdt // - This pointer is either NULL or the pointer to the DSDT. // (If it is NULL, LibGetDsdt is called to obtain the // pointer.) // IN CHAR8 *RbName // - This string specifies the name of the root bridge // device for which the Package object is to be found. // IN CHAR8 *PackageName // - This string specifies the name of the Package object // to be found. // OUT ASL_OBJ_INFO *Package // - This parameter is updated to contain the address of // the ASL_OBJ_INFO structure associated with the // located Package object. // OUT PACKAGE_ELEMENT *Elements // - This parameter is updated to contain the address // of the first element of the located Package object. // OUT UINT8 *ElementCount // - This parameter is updated to contain the number // of elements in the located Package object. // // Output: // EFI_STATUS (Return Value) // = EFI_SUCCESS if successful // = or valid EFI error code // // Modified: // None // // Referrals: // LibGetDsdt() // GetAslObj() // // Notes: // Package objects are aggregate arrays of elements that can be of // different size and type. This function assumes the caller // understands the structure of the package object associated with the // PackageName paramenter and can iterate through the elements. // // Prototypes for several element types are provided in AcpiRes.h // (see PACKAGE_ELEMENT). Additional types can be supported by // typecasting PACKAGE_ELEMENT.Ptr. // // Example: Supported ASL Package Declarations (must be initialized) // // Scope(\_SB.PCI0) { // Name (PAK1, Package () // { // 0x0123, // 0x0123, // 0x0123, // 0x0123, // }) // } // // Scope(\_SB.PCI1) { // Name (PAK1, Package () // { // 0x0123, // 0x0123, // 0x0123, // 0x0123, // }) // } // // Example: Usage // // VOID Function(){ // ASL_OBJ_INFO Package; // PACKAGE_ELEMENT Element; // UINT8 ElementCount; // // Status = GetRbAmlPackagePointer( "PCI1", "PAK1", // &Package, &Element, &ElementCount); // ... // } // // //-------------------------------------------------------------------------- // EFI_STATUS GetRbAmlPackagePointer( IN ACPI_HDR **Dsdt, IN CHAR8 *RbName, IN CHAR8 *PackageName, OUT ASL_OBJ_INFO *Package, OUT PACKAGE_ELEMENT *Elements, OUT UINT8 *ElementCount ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Address; ASL_OBJ_INFO RbScope; AML_PACKAGE_HEADER *Pkg; if (*Dsdt == NULL){ Status = LibGetDsdt(&Address, EFI_ACPI_TABLE_VERSION_ALL); if (EFI_ERROR(Status)) { return Status; } else { *Dsdt = (ACPI_HDR*)Address; } } // Get a pointer to this root bridge's device scope Status = GetAslObj( (UINT8*)(*Dsdt + 1), (*Dsdt)->Length - sizeof(ACPI_HDR) - 1, RbName, otDevice, &RbScope ); // Get a pointer to the AML Package object if (!EFI_ERROR(Status)){ Status = GetAslObj( (UINT8*)RbScope.DataStart, RbScope.Length, PackageName, otName, Package ); } // Parse the Package object to get a pointer to the first element and // number of elements. if (!EFI_ERROR(Status)){ Pkg = Package->DataStart; // Check ByteCount to determine the encoding and obtain a pointer // to the first element and the element count. switch (Pkg->Encoding.Small.ByteCount) { case 0: (*Elements).Ptr = &Pkg->Encoding.Small.Element; *ElementCount = Pkg->Encoding.Small.ElementCount; break; case 1: (*Elements).Ptr = &Pkg->Encoding.Large1.Element; *ElementCount = Pkg->Encoding.Large1.ElementCount; break; case 2: (*Elements).Ptr = &Pkg->Encoding.Large2.Element; *ElementCount = Pkg->Encoding.Large2.ElementCount; break; case 3: (*Elements).Ptr = &Pkg->Encoding.Large3.Element; *ElementCount = Pkg->Encoding.Large3.ElementCount; } } return Status; } //************************************************************************* // // // Name: GetPackageLen // // Description: // UINTN GetPackageLen(IN AML_PACKAGE_LBYTE *Pck, OUT UINT8 *BytesCnt) // determines the length in bytes of an AML package. // // Input: // IN AML_PACKAGE_LBYTE *Pck // AML package to be measured. // // OUT UINT8 *BytesCnt // The ByteCount value of the package. // // Output: // UINTN size of the AML package in bytes. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* //will determine length in bytes of a package UINTN GetPackageLen(AML_PACKAGE_LBYTE *Pck, UINT8 *BytesCnt) { UINTN len=0; UINT8 *p=(UINT8*)Pck; //------------------ if (BytesCnt)*BytesCnt=0; if (!Pck->ByteCount) len=Pck->Length; else { len|=(Pck->Length&0x0F); if (BytesCnt)*BytesCnt=Pck->ByteCount; switch (Pck->ByteCount) { case 1: { UINT8 b=*(p+1); len|=(b<<4); } break; case 2: { UINT16 w=(UINT16)(*((UINT16*)(p+1))); len|=(w<<4); } break; case 3: { UINT32 d=(UINT32)(*((UINT32*)(p+1))); d&=0xffffff; len|=(d<<4); } break; } //switch } return len; } //************************************************************************* // // // Name: ConvertAslName // // Description: // UINT32 ConvertAslName(IN UINT8 *AslName) converts an ASL name into a // UINT32 value and returns it. // // Input: // IN UINT8 *AslName // Pointer to the ASL name string. // // Output: // UINT32 translation of the ASL name. // // Modified: // // Referrals: // Strlen // MemCpy // // Notes: // Helper function for FindAslObjectName. // // //************************************************************************* UINT32 ConvertAslName(UINT8 *AslName) { AML_NAME_SEG n; UINTN l=Strlen(AslName); //------------------------- n.NAME=0x5F5F5F5F; MemCpy(&n.Name[0],AslName,l); return n.NAME; } //************************************************************************* // // // Name: FindAslObjectName // // Description: // VOID* FindAslObjectName(IN UINT8 *Start, IN UINT8 *ObjName, IN UINTN Len) // finds an ASL object by its name string and returns its location. // // Input: // IN UINT8 *Start // Location to begin scanning for the ASL object. // // IN UINT8 *ObjName // Name of the ASL object to be located. // // IN UINTN Len // Maximum length of bytes to scan for the ASL object. // // Output: // VOID* pointer to the start of the ASL name string in memory. // // Modified: // // Referrals: // ConvertAslName // // Notes: // Helper function for GetAslObj. // // //************************************************************************* VOID* FindAslObjectName(UINT8 *Start, UINT8 *ObjName, UINTN Len) { unsigned int i; UINT8 *p; AML_NAME_SEG *obj,nm; //------------------------------ nm.NAME=ConvertAslName(ObjName); p=Start; for (i=0; iNAME!=nm.NAME)continue; return &p[i]; } return NULL; } //************************************************************************* // // // Name: HideAslMethodFromOs // // Description: // Destroys Method passed as MethodName parameter if it is present in ASL object // described by AslObj parameter // // Input: // IN ASL_OBJ_INFO *AslObj // Pointer to ASL_OBJ_INFO structure, which discribes ASL object to modify // // UINT8 *MethodName // Name of the ASL Method to be destroyed. // // // Referrals: // ConvertAslName // // //************************************************************************* VOID HideAslMethodFromOs (ASL_OBJ_INFO *AslObj, UINT8 *MethodName) { UINT32 AslMethodName = ConvertAslName(MethodName), i, Position; //*(UINT32*)MethodName UINT8 *Start = AslObj->DataStart; // TRACE ((-1,"AslMethodNameHex = %X, Str=%s; Start= %lX\n", AslMethodName, MethodName, (UINT64) Start)); for (i = 0; i < AslObj->Length; i++) { Position =*(UINT32*)(Start+i); if (Position == AslMethodName) // If method is found { // TRACE ((-1,"METHOD FOUND = %x,\n", Position)); Start[i] = 'X'; //Replace leading _ with X return; } } } //************************************************************************* // // // Name: CheckOpCode // // Description: // BOOLEAN CheckOpCode(IN UINT8 *NameStart, IN UINT8 OpCode, // IN UINT8 ExtOpCode, OUT ASL_OBJ_INFO *ObjInfo) checks an ASL object for // the user provided op code and extended op code and returns the op code // location in a user allocated ASL_OBJ_INFO structure. // // Input: // IN UINT8 *NameStart // Pointer to the start of the ASL object's name. // // IN UINT8 OpCode // Op code to be checked. // // IN UINT8 ExtOpCode // Extended op code to be checked. If set as 0, only checks for OpCode. // // OUT ASL_OBJ_INFO *ObjInfo // Pointer to a user allocated ASL_OBJ_INFO structure which will be updated // with the associated information if the op codes are located. If an // extended op code is specified, ObjInfo->Object is filled with the location // of the extended op code; otherwise ObjInfo->Object refers to the location // of the op code. // // Output: // TRUE if the op code and extended op code (if specified) are located; // otherwise, FALSE. // // Modified: // // Referrals: // GetPackageLen // // Notes: // Helper function for GetAslObj. // // //************************************************************************* BOOLEAN CheckOpCode(UINT8 *NameStart, UINT8 OpCode, UINT8 ExtOpCode, ASL_OBJ_INFO *ObjInfo) { UINT8 *p, *p1; INTN i; //--------------------- //Maximum number of bytes in PackageLength is 4 if ( (*(NameStart-1))==AML_PR_ROOT || (*(NameStart-1))==AML_PR_PARENT) NameStart--; //if we Looking For ASL Name Object its a special case. if (OpCode==AML_OP_NAME && !ExtOpCode) { p=NameStart-1; if (*p==OpCode) { ObjInfo->Object=p; ObjInfo->ObjName=NameStart; ObjInfo->Length=0; return TRUE; } return FALSE; } //if we Looking For ASL Name Object its a special case. if (OpCode==AML_OP_OPREG && ExtOpCode) { p=NameStart-2; if (*p==ExtOpCode && *(p+1)==OpCode) { ObjInfo->Object=p; ObjInfo->ObjName=NameStart; ObjInfo->Length=0; return TRUE; } return FALSE; } for (i=2; i<6; i++) { p=NameStart-i; if (ExtOpCode) p1=p-1; else p1=NULL; if (p1)if (*p1!=ExtOpCode) continue; if (*p!=OpCode) continue; if (p1)ObjInfo->Object=p1; else ObjInfo->Object=p; ObjInfo->Length=GetPackageLen((AML_PACKAGE_LBYTE*)(p+1),NULL); ObjInfo->ObjName=NameStart; return TRUE; } return FALSE; } //************************************************************************* // // // Name: GetAslObj // // Description: // EFI_STATUS GetAslObj(IN UINT8 *Start, IN UINTN Length, IN UINT8 *Name, // IN ASL_OBJ_TYPE ObjType, OUT ASL_OBJ_INFO *ObjInfo) // // Input: // IN UINT8 *Start // Starting location in memory to begin scanning for the desired ASL object. // // IN UINTN Length // Maximum number of bytes in memory to be scanned starting from Start for // the ASL object. // // IN UINT8 *Name // Pointer to the name of the ASL object to be located. // // IN ASL_OBJ_TYPE ObjType // Type of the ASL object to be located. Supports: otScope, otName, otProc, // otTermal, otDevice, otMethod, otPwrRes, otOpReg // // OUT ASL_OBJ_INFO *ObjInfo // Returns completed ASL_OBJ_INFO structure, if the ASL object is found. // // Output: // EFI_NOT_FOUND, if object not found or invalid type. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // FindAslObjectName // CheckOpCode // // Notes: // // //************************************************************************* //Since the search is done by locating the OBJECT name. //Caller must know what ASL Object Type he is looking for. EFI_STATUS GetAslObj(UINT8 *Start, UINTN Length, UINT8 *Name, ASL_OBJ_TYPE ObjType, ASL_OBJ_INFO *ObjInfo) { UINT8 *pn, *s, eop,op; UINTN l, i; BOOLEAN objfound=FALSE; // ASL_OBJ_INFO objinf; //--------------------------- //if(!CheckDsdt(PDsdt)) return FALSE; //s=((UINT8*)PDsdt)+sizeof(ACPI_HDR); s=Start; //l=PDsdt->Length-sizeof(ACPI_HDR)-1; l=Length; while (!objfound) { pn=FindAslObjectName(s,Name,l); if (!pn) return EFI_NOT_FOUND; //If we found the name let's check if it is the Object we are looking for //it could be just object referance, or field definition inside the object, //or double name, or multiple name definition we must filter such situations // and make sure we have got the actual object but not its reference instance switch (ObjType) { case otScope : i=0; eop=0; op=AML_OP_SCOPE; break; case otName : i=0; eop=0; op=AML_OP_NAME; break; case otProc : i=6; eop=AML_PR_EXTOP; op=AML_OP_PROC; break; case otTermal : i=0; eop=AML_PR_EXTOP; op=AML_OP_THERMAL; break; case otDevice : i=0; eop=AML_PR_EXTOP; op=AML_OP_DEVICE; break; case otMethod : i=1; eop=0; op=AML_OP_METHOD; break; case otPwrRes : i=3; eop=AML_PR_EXTOP; op=AML_OP_PWRRES; break; case otOpReg : i=0; eop=AML_PR_EXTOP; op=AML_OP_OPREG; break; default: return EFI_NOT_FOUND; } //switch objfound=CheckOpCode(pn, op, eop, ObjInfo); if (!objfound) { l-=(UINTN)(pn-s)-4; s=pn+4; continue; } ObjInfo->ObjType=ObjType; ObjInfo->DataStart=pn+i+4; return EFI_SUCCESS; } //while () return EFI_NOT_FOUND; } //************************************************************************* // // // Name: UpdateAslNameBuffer // // Description: // EFI_STATUS UpdateAslNameBuffer(UINT8 *BufferStart, UINTN BufferLen, // IN UINT8 *ObjName, IN UINT64 Value) locates an ASL object by its name, // ObjName, in Memory Buffer specified by BufferStart, and BufferLen // and updates its data start with the user provided Value. // // Input: // IN UINT8 *BufferStart // Pointer to the DSDT. // // UINTN BufferLen // Length of the Buffer // // IN UINT8 *ObjName // Name of the ASL object to be updated. // // IN UINT64 Value // New value for the ASL object's data entry. // // Output: // EFI_INVALID_PARAMETER, if the DSDT pointer, ObjName or Value are invalid. // EFI_NOT_FOUND, if object specified by ObjName not present. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // GetAslObj // // Notes: // // //************************************************************************* EFI_STATUS UpdateAslNameBuffer(UINT8 *BufferStart, UINTN BufferLen, UINT8 *ObjName, UINT64 Value) { EFI_STATUS Status; ASL_OBJ_INFO obj; //--------------- Status=GetAslObj(BufferStart,BufferLen, ObjName, otName, &obj); if EFI_ERROR(Status) return Status; switch (*((UINT8*)obj.DataStart)) { case AML_PR_BYTE: { UINT8 *p = (UINT8*)((UINT8*)obj.DataStart+1); //---------------------------------- *p=(UINT8)Value; } break; case AML_PR_WORD: { UINT16 *p = (UINT16*)((UINT8*)obj.DataStart+1); //---------------------------------- *p=(UINT16)Value; } break; case AML_PR_DWORD: { UINT32 *p = (UINT32*)((UINT8*)obj.DataStart+1); //---------------------------------- *p=(UINT32)Value; } break; case AML_PR_QWORD: { UINT64 *p = (UINT64*)((UINT8*)obj.DataStart+1); //---------------------------------- *p=(UINT64)Value; } break; case AML_ZERO_OP: case AML_ONE_OP: { if ((Value == 0) || (Value == 1)) { UINT8 *p = (UINT8*)((UINT8*)obj.DataStart); *p = (UINT8)Value; } else { return EFI_INVALID_PARAMETER; } } break; default: { return EFI_INVALID_PARAMETER; } } return EFI_SUCCESS; } //************************************************************************* // // // Name: UpdateAslNameOfDevice // // Description: // EFI_STATUS UpdateAslNameOfDevice(IN ACPI_HDR *PDsdt, IN CHAR8 *DeviceName, // CHAR8 *ObjName, IN UINT64 Value) locates an ASL Device Object by its name, // DeviceName, and then In the scope of this Device Object, trys to locate a // Name Object, ObjName, in the DSDT. If found it updates its data place holder // with user provided Value. // // Input: // IN ACPI_HDR *PDsdt // Pointer to the DSDT. // // IN CHAR8 *DeviceName // Name of the ASL Device object having in it's scope Name Object to be updated. // // IN CHAR8 *ObjName // Name of the ASL Name Object to be updated. // // IN UINT64 Value // New value for the ASL object's data entry. // // Output: // EFI_INVALID_PARAMETER, if the DSDT pointer, ObjName or Value are invalid. // EFI_NOT_FOUND, if object specified by Device Name Or ObjName not present. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // CheckDsdt // GetAslObj // // Notes: // // //************************************************************************* EFI_STATUS UpdateAslNameOfDevice(ACPI_HDR *PDsdt, CHAR8 *DeviceName, CHAR8 *ObjName, UINT64 Value) { EFI_STATUS Status; ASL_OBJ_INFO obj; //--------------- if (!CheckDsdt(PDsdt)) return EFI_INVALID_PARAMETER; Status=GetAslObj((UINT8*)(PDsdt+1),PDsdt->Length-sizeof(ACPI_HDR)-1, DeviceName, otDevice, &obj); if EFI_ERROR(Status) return Status; Status=UpdateAslNameBuffer((UINT8*)obj.DataStart, obj.Length, ObjName, Value); return Status; } //************************************************************************* // // // Name: UpdateAslNameObject // // Description: // EFI_STATUS UpdateAslNameObject(IN ACPI_HDR *PDsdt, IN UINT8 *ObjName, // IN UINT64 Value) locates an ASL object by its name, ObjName, in the DSDT // and updates its data start with the user provided Value. // // Input: // IN ACPI_HDR *PDsdt // Pointer to the DSDT. // // IN UINT8 *ObjName // Name of the ASL object to be updated. // // IN UINT64 Value // New value for the ASL object's data entry. // // Output: // EFI_INVALID_PARAMETER, if the DSDT pointer, ObjName or Value are invalid. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // CheckDsdt // GetAslObj // // Notes: // // //************************************************************************* EFI_STATUS UpdateAslNameObject(ACPI_HDR *PDsdt, UINT8 *ObjName, UINT64 Value) { //------------------------------------ if (!CheckDsdt(PDsdt)) return EFI_INVALID_PARAMETER; return UpdateAslNameBuffer((UINT8*)(PDsdt+1),PDsdt->Length-sizeof(ACPI_HDR)-1, ObjName, Value); } //************************************************************************* // // // Name: ChsumTbl // // Description: // UINT8 ChsumTbl(IN UINT8 *TblStart, IN UINT32 BytesCount) calculates the // checksum of a table starting at TblStart of length BytesCount and returns // the checksum value. // // Input: // IN UINT8 *TblStart // Starting address of the memory area to checksum. // // IN UINT32 BytesCount // Length in bytes of the memory area to checksum. // // Output: // UINT8 checksum value starting from TblStart and ending at // TblStart + BytesCount. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* UINT8 ChsumTbl(UINT8* TblStart, UINT32 BytesCount) { UINTN i; UINT8 res=*TblStart; for (i=1; i // // Name: AmiIsaIrqMask // // Description: // EFI_STATUS AmiIsaIrqMask(IN OUT UINT16 *IsaIrqMask, IN BOOLEAN Get) sets // or retrieves the ISA IRQ mask from NVRAM depending upon the Get input. // // Input: // IN OUT UINT16 *IsaIrqMask // If Get is TRUE, returns an address to the ISA IRQ mask. If Get is FALSE, // used to update the ISA IRQ mask NVRAM variable. User is responsible for // allocating and managing this memory. // // IN BOOLEAN Get // If TRUE, causes function to return an address to the ISA IRQ mask. // If FALSE, causes function to use the user provided ISA IRQ mask to update // the NVRAM variable with its value. // // Output: // EFI_NOT_FOUND, if the ISA IRQ mask NVRAM variable is not found. // EFI_DEVICE_ERROR, if the ISA IRQ mask NVRAM variable could not be // accessed due to a hardware error. // EFI_SECURITY_VIOLATION, if the ISA IRQ mask NVRAM variable could be not // be accessed due to a authentication failure. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* EFI_STATUS AmiIsaIrqMask(UINT16 *IsaIrqMask, BOOLEAN Get) { UINTN sz=sizeof(UINT16); EFI_STATUS Status; //----------------------- if (Get) Status = pRS->GetVariable(L"IsaIrqMask", &gAmiIsaDmaIrqMaskVarGuid, NULL, &sz, IsaIrqMask); else Status=pRS->SetVariable(L"IsaIrqMask",&gAmiIsaDmaIrqMaskVarGuid,EFI_VARIABLE_BOOTSERVICE_ACCESS, sz, IsaIrqMask); return Status; } //************************************************************************* // // // Name: AmiIsaDmaMask // // Description: // EFI_STATUS AmiIsaDmaMask(IN OUT UINT8 *IsaDmaMask, IN BOOLEAN Get) sets // or retrieves the ISA DMA mask from NVRAM depending upon the Get input. // // Input: // IN OUT UINT8 *IsaDmaMask // If Get is TRUE, returns an address to the ISA DMA mask. If Get is FALSE, // used to update the ISA DMA mask NVRAM variable. User is responsible for // allocating and managing this memory. // // IN BOOLEAN Get // If TRUE, causes function to return an address to the ISA DMA mask. // If FALSE, causes function to use the user provided ISA DMA mask to update // the NVRAM variable with its value. // // Output: // EFI_NOT_FOUND, if the ISA DMA mask NVRAM variable is not found. // EFI_DEVICE_ERROR, if the ISA DMA mask NVRAM variable could not be // accessed due to a hardware error. // EFI_SECURITY_VIOLATION, if the ISA DMA mask NVRAM variable could be not // be accessed due to a authentication failure. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* EFI_STATUS AmiIsaDmaMask(UINT8 *IsaDmaMask, BOOLEAN Get) { UINTN sz=sizeof(UINT8); EFI_STATUS Status; //----------------------- if (Get) Status = pRS->GetVariable(L"IsaDmaMask", &gAmiIsaDmaIrqMaskVarGuid, NULL, &sz, IsaDmaMask); else Status=pRS->SetVariable(L"IsaDmaMask",&gAmiIsaDmaIrqMaskVarGuid,EFI_VARIABLE_BOOTSERVICE_ACCESS, sz, IsaDmaMask); return Status; } static EFI_GUID gAmiPciOutOfResVarGuid = AMI_PCI_OUT_OF_RESOURCES_GUID; //************************************************************************* // // // Name: AmiPciOutOfRes // // Description: // EFI_STATUS AmiPciOutOfRes(AMI_OUT_OF_RES_VAR *AmiOutOfResData, IN BOOLEAN Get) sets // or retrieves the AMI_OUT_OF_RES_DATA from NVRAM depending upon the Get input. // // Input: // AMI_OUT_OF_RES_VAR *AmiOutOfResData // If Get is TRUE, returns an address to the AMI_OUT_OF_RES_VAR. If Get is FALSE, // used to update the AMI_OUT_OF_RES_VAR data NVRAM variable. User is responsible for // allocating and managing this memory. // // IN BOOLEAN Get // If TRUE, causes function to return an address to the ISA DMA mask. // If FALSE, causes function to use the user provided ISA DMA mask to update // the NVRAM variable with its value. // // Output: // EFI_NOT_FOUND, if the NVRAM variable is not found. // EFI_DEVICE_ERROR, if the NVRAM variable could not be // accessed due to a hardware error. // EFI_SECURITY_VIOLATION, if the NVRAM variable could be not // be accessed due to a authentication failure. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* EFI_STATUS AmiPciOutOfRes(AMI_OUT_OF_RES_VAR *AmiOutOfResData, BOOLEAN Get) { AMI_OUT_OF_RES_VAR orv; UINTN sz=sizeof(AMI_OUT_OF_RES_VAR); EFI_STATUS Status; //----------------------- if(!Get && AmiOutOfResData==NULL) return EFI_INVALID_PARAMETER; if (Get) Status = pRS->GetVariable(L"AmiOutOfRes", &gAmiPciOutOfResVarGuid, NULL, &sz, &orv); else Status=pRS->SetVariable(L"AmiOutOfRes",&gAmiPciOutOfResVarGuid,EFI_VARIABLE_BOOTSERVICE_ACCESS, sz, AmiOutOfResData); if(Get && AmiOutOfResData!=NULL) *AmiOutOfResData=orv; return Status; } //************************************************************************* // // // Name: LibGetDsdt // // Description: // EFI_STATUS LibGetDsdt(OUT EFI_PHYSICAL_ADDRESS *DsdtAddr, // IN EFI_ACPI_TABLE_VERSION Version) retrieves a pointer to the DSDT ACPI // table for the user requested Version of ACPI. // // Input: // OUT EFI_PHYSICAL_ADDRESS *DsdtAddr // Address of the DSDT associated with the user provided Version. // // IN EFI_ACPI_TABLE_VERSION Version // Which version of ACPI's DSDT to return. Valid values include: // EFI_ACPI_TABLE_VERSION_1_0B, EFI_ACPI_TABLE_VERSION_X, // EFI_ACPI_TABLE_VERSION_NONE // // Output: // EFI_NOT_AVAILABLE_YET, if ACPI support protocol not installed yet. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* EFI_STATUS LibGetDsdt(EFI_PHYSICAL_ADDRESS *DsdtAddr, EFI_ACPI_TABLE_VERSION Version) { static EFI_PHYSICAL_ADDRESS Dsdt1 = 0; static EFI_PHYSICAL_ADDRESS Dsdt2 = 0; #if PI_SPECIFICATION_VERSION < 0x10014 ACPI_HDR *tbl = NULL; EFI_ACPI_SUPPORT_PROTOCOL *as; #else EFI_ACPI_SDT_HEADER *tbl = NULL; EFI_ACPI_SDT_PROTOCOL *as; #endif EFI_STATUS Status = EFI_NOT_FOUND; UINTN i; EFI_ACPI_TABLE_VERSION ver; UINTN AcpiHandle; //--------------------------- if (!(Dsdt1 && Dsdt2)) { #if PI_SPECIFICATION_VERSION < 0x10014 Status=pBS->LocateProtocol(&gEfiAcpiSupportGuid, NULL, &as); #else Status=pBS->LocateProtocol(&gEfiAcpiSdtProtocolGuid, NULL, &as); #endif if (EFI_ERROR(Status)) { TRACE((-1,"AcpiResLib: LibGetDsdt(): LocateProtocol(ACPISupport) returned %r \n", Status)); return EFI_NOT_AVAILABLE_YET; } else { for (i=0; ; i++) { #if PI_SPECIFICATION_VERSION < 0x10014 Status = as->GetAcpiTable(as, i, &tbl, &ver, &AcpiHandle); #else Status = as->GetAcpiTable(i, &tbl, &ver, &AcpiHandle); #endif if (EFI_ERROR(Status)) { TRACE((-1,"Can't find FADT table -> %r search %d Tables\n", Status, i)); break; } if (tbl->Signature == FACP_SIG) { if (ver == EFI_ACPI_TABLE_VERSION_1_0B) { Dsdt1 = (EFI_PHYSICAL_ADDRESS)(((FACP_20 *)tbl)->DSDT); TRACE((-1,"AcpiResLib: LibGetDsdt(): Found v1.0b RSDT->DSDT @ 0x%lX; -> %r \n", Dsdt1, Status)); } if ((ver & EFI_ACPI_TABLE_VERSION_X)!= 0) { Dsdt2 = (EFI_PHYSICAL_ADDRESS)(((FACP_20 *)tbl)->X_DSDT); TRACE((-1,"AcpiResLib: LibGetDsdt(): Found v2.0&UP XSDT->DSDT @ 0x%lX; -> %r \n", Dsdt2, Status)); } } pBS->FreePool((VOID *)tbl); if (Dsdt1 && Dsdt2) break; } } } if (Dsdt2 && ((Version & EFI_ACPI_TABLE_VERSION_X) || (Version & EFI_ACPI_TABLE_VERSION_NONE))) { *DsdtAddr = Dsdt2; Status = EFI_SUCCESS; } else { if (Dsdt1 && ((Version & EFI_ACPI_TABLE_VERSION_1_0B) || (Version & EFI_ACPI_TABLE_VERSION_NONE))) { *DsdtAddr = Dsdt1; Status = EFI_SUCCESS; } } return Status; } //---------------------------------------------------------------------- //---------------------------------------------------------------------- //---------------------------------------------------------------------- //************************************************************************* //************************************************************************* //** ** //** (C)Copyright 1985-2010, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** //** ** //** Phone: (770)-246-8600 ** //** ** //************************************************************************* //*************************************************************************