121 lines
5.9 KiB
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;
|
|
}
|