alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/ChipsetSvcDxe/IoDecodeControl.c

121 lines
5.9 KiB
C

/** @file
DXE Chipset Services Library.
This file contains only one function that is DxeCsSvcIoDecodeControl().
The function DxeCsSvcIoDecodeControl() use chipset services to set
IO decode region.
;***************************************************************************
;* Copyright (c) 2017, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Protocol/H2ODxeChipsetServices.h>
#include <Library/IoLib.h>
#include <Register/PchRegs.h>
#include "Register/PchRegsLpc.h"
#include <ChipsetAccess.h>
//#include <Library/PchPlatformLib.h>
#include <Library/PchCycleDecodingLib.h>
//[-start-191225-IB16740000-add]// for PCI_BUS_NUMBER_PCH_XHCI define
#include <PchBdfAssignment.h>
//[-end-191225-IB16740000-add]//
typedef struct {
IO_DECODE_TYPE IoType;
IO_DECODE_ADDRESS IoAddress;
UINT16 IoDecMask;
UINT16 IoDecValue;
UINT16 IoDecEn;
} IO_DECODE_CONTROL_TABLE;
IO_DECODE_CONTROL_TABLE mIoDecConTable[] = {
// {IoType, IoAddress, IoDecMask, IoDecValue, IoDecEn}
{IoDecodeFdd, AddressFdd3F0, B_LPC_CFG_IOD_FDD, 0x0000, B_LPC_CFG_IOE_FDE},
{IoDecodeFdd, AddressFdd370, B_LPC_CFG_IOD_FDD, B_LPC_CFG_IOD_FDD, B_LPC_CFG_IOE_FDE},
{IoDecodeLpt, AddressLpt378, B_LPC_CFG_IOD_LPT, 0x0000, B_LPC_CFG_IOE_PPE},
{IoDecodeLpt, AddressLpt278, B_LPC_CFG_IOD_LPT, 0x0100, B_LPC_CFG_IOE_PPE},
{IoDecodeLpt, AddressLpt3BC, B_LPC_CFG_IOD_LPT, 0x0200, B_LPC_CFG_IOE_PPE},
{IoDecodeComA, AddressCom3F8, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_3F8 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom2F8, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_2F8 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom220, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_220 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom228, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_228 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom238, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_238 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom2E8, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_2E8 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom338, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_338 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComA, AddressCom3E8, B_LPC_CFG_IOD_COMA, V_LPC_CFG_IOD_COMA_3E8 << N_LPC_CFG_IOD_COMA, B_LPC_CFG_IOE_CAE},
{IoDecodeComB, AddressCom3F8, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_3F8 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom2F8, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_2F8 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom220, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_220 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom228, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_228 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom238, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_238 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom2E8, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_2E8 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom338, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_338 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeComB, AddressCom3E8, B_LPC_CFG_IOD_COMB, V_LPC_CFG_IOD_COMB_3E8 << N_LPC_CFG_IOD_COMB, B_LPC_CFG_IOE_CBE},
{IoDecodeCnf2, AddressCnf24E4F, 0, 0, B_LPC_CFG_IOE_ME2},
{IoDecodeCnf1, AddressCnf12E2F, 0, 0, B_LPC_CFG_IOE_SE},
{IoDecodeMc, AddressMc6266, 0, 0, B_LPC_CFG_IOE_ME1},
{IoDecodeKbc, AddressKbc6064, 0, 0, B_LPC_CFG_IOE_KE},
{IoDecodeGameh, AddressGameh208, 0, 0, B_LPC_CFG_IOE_HGE},
{IoDecodeGamel, AddressGamel200, 0, 0, B_LPC_CFG_IOE_LGE},
};
/**
IO address decode
@param[in] Type Decode type
@param[in] Address Decode address
@param[in] Length Decode length
@retval EFI_SUCCESS Function returns successfully
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
1. Type has invalid value
2. Address big then 0xFFFF
3. Length need to be 4-byte aligned
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to set IO decode
*/
EFI_STATUS
IoDecodeControl (
IN IO_DECODE_TYPE Type,
IN IO_DECODE_ADDRESS Address,
IN UINT16 Length
)
{
EFI_STATUS Status;
UINTN Index;
UINT16 IoDecodeRangesReg,IoDecodeRangesEnable;
Status = EFI_INVALID_PARAMETER;
if (Type == IoDecodeGenericIo) {
Status = PchLpcGenIoRangeSet ((UINT16)Address, (UINTN) Length);
} else {
if ((Type < IoDecodeTypeMaximum) && (Address < IoDecodeAddressMaximum)) {
IoDecodeRangesReg = PchLpcPciCfg16 (R_LPC_CFG_IOD);
IoDecodeRangesEnable = PchLpcPciCfg16 (R_LPC_CFG_IOE);
for (Index = 0; Index < sizeof (mIoDecConTable) / sizeof (IO_DECODE_CONTROL_TABLE); Index++) {
if ((Type == mIoDecConTable[Index].IoType) && (Address == mIoDecConTable[Index].IoAddress)) {
IoDecodeRangesReg &= (~(mIoDecConTable[Index].IoDecMask));
IoDecodeRangesReg |= (mIoDecConTable[Index].IoDecValue);
if (Length == 0) {
IoDecodeRangesEnable &= (~mIoDecConTable[Index].IoDecEn);
} else {
IoDecodeRangesEnable |= mIoDecConTable[Index].IoDecEn;
}
Status = EFI_SUCCESS;
break;
}
}
PchLpcIoDecodeRangesSet (IoDecodeRangesReg);
PchLpcIoEnableDecodingSet (IoDecodeRangesEnable);
}
}
return Status;
}