/** @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 #include #include #include "Register/PchRegsLpc.h" #include //#include #include //[-start-191225-IB16740000-add]// for PCI_BUS_NUMBER_PCH_XHCI define #include //[-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; }