1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609 |
- /** @file
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "TbtSmiHandler.h"
- #include <Library/IoLib.h>
- #include <Library/BaseLib.h>
- #include <Library/DebugLib.h>
- #include <Protocol/SmmVariable.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/SmmServicesTableLib.h>
- #include <Library/PciSegmentLib.h>
- #define MEM_PER_SLOT (DEF_RES_MEM_PER_DEV << 4)
- #define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
- #define IO_PER_SLOT (DEF_RES_IO_PER_DEV << 2)
- GLOBAL_REMOVE_IF_UNREFERENCED UINTN gDeviceBaseAddress;
- //
- //US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
- //
- GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG HrConfigs[MAX_CFG_PORTS];
- extern UINT8 gCurrentDiscreteTbtRootPort;
- extern UINT8 gCurrentDiscreteTbtRootPortType;
- BOOLEAN isLegacyDevice = FALSE;
- STATIC UINT8 TbtSegment = 0;
- STATIC
- VOID
- PortInfoInit (
- IN OUT PORT_INFO *PortInfo
- )
- {
- PortInfo->BusNumLimit = 4;
- }
- STATIC
- VOID
- UnsetVesc (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 Fun
- )
- {
- UINT8 Dbus;
- UINT32 Data32;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
- //
- // Check for abcence of DS bridge
- //
- if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
- return;
- }
- //
- // Unset vesc_reg2[23] bit (to have an option to access below DS)
- //
- Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
- Data32 &= 0xFF7FFFFF;
- PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
- //
- // Go to Device behind DS
- //
- Dbus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
- DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
- //
- // Check if there is something behind this Downstream Port (Up or Ep)
- // If there nothing behind Downstream Port Set vesc_reg2[23] bit -> this will flush all future MemWr
- //
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, 0x00, 0);
- if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET))
- {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
- Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
- Data32 |= 0x00800000;
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
- }
- }// Unset_VESC_REG2
- STATIC
- UINT16
- MemPerSlot (
- IN UINT16 CurrentUsage
- )
- {
- if (CurrentUsage == 0) {
- return 0;
- }
- if (CurrentUsage <= 16) {
- return 16;
- }
- if (CurrentUsage <= 64) {
- return 64;
- }
- if (CurrentUsage <= 128) {
- return 128;
- }
- if (CurrentUsage <= 256) {
- return 256;
- }
- if (CurrentUsage <= 512) {
- return 512;
- }
- if (CurrentUsage <= 1024) {
- return 1024;
- }
- return CurrentUsage;
- } // MemPerSlot
- STATIC
- UINT64
- PMemPerSlot (
- IN UINT64 CurrentUsage
- )
- {
- if (CurrentUsage == 0) {
- return 0;
- }
- if (CurrentUsage <= 1024ULL) {
- return 1024ULL;
- }
- if (CurrentUsage <= 4096ULL) {
- return 4096ULL;
- }
- return CurrentUsage;
- } // PMemPerSlot
- STATIC
- VOID
- SetPhyPortResources (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 SubBus,
- IN INT8 Depth,
- IN PORT_INFO *CurrentPi,
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 Cmd;
- UINT16 DeltaMem;
- UINT64 DeltaPMem;
- Cmd = CMD_BUS_MASTER;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x00, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
- DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
- if (isLegacyDevice) {
- if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
- PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
- }
- } else {
- if (DeltaMem < MemPerSlot (DeltaMem)) {
- PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
- }
- }
- if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10) <= PortInfo->MemLimit) {
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), CurrentPi->MemBase);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
- Cmd |= CMD_BM_MEM;
- } else {
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
- PortInfo->MemBase = CurrentPi->MemBase;
- }
- DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
- if (isLegacyDevice) {
- if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
- PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
- }
- } else {
- if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
- PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
- }
- }
- if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 & 0xFFFF));
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10) & 0xFFFF));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10) >> 16));
- Cmd |= CMD_BM_MEM;
- } else {
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
- PortInfo->PMemBase64 = CurrentPi->PMemBase64;
- }
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
- } // SetPhyPortResources
- STATIC
- UINT32
- SaveSetGetRestoreBar (
- IN UINTN Bar
- )
- {
- UINT32 BarReq;
- UINT32 OrigBar;
- OrigBar = PciSegmentRead32(Bar); // Save BAR
- PciSegmentWrite32(Bar, 0xFFFFFFFF); // Set BAR
- BarReq = PciSegmentRead32(Bar); // Get BAR
- PciSegmentWrite32(Bar, OrigBar); // Restore BAR
- return BarReq;
- } // SaveSetGetRestoreBar
- STATIC
- VOID
- SetIoBar (
- IN UINTN BAR,
- IN UINT32 BarReq,
- IN OUT UINT8 *Cmd,
- IN OUT IO_REGS *IoReg
- )
- {
- UINT16 Alignment;
- UINT16 Size;
- UINT16 NewBase;
- Alignment = ~(BarReq & 0xFFFC);
- Size = Alignment + 1;
- if (IoReg->Base > IoReg->Limit || !Size) {
- return ;
- }
- NewBase = BAR_ALIGN (IoReg->Base, Alignment);
- if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
- return ;
- }
- PciSegmentWrite16(BAR, NewBase);
- IoReg->Base = NewBase + Size; // Advance to new position
- *Cmd |= CMD_BM_IO; // Set Io Space Enable
- } // SetIoBar
- STATIC
- VOID
- SetMemBar (
- IN UINTN BAR,
- IN UINT32 BarReq,
- IN OUT UINT8 *Cmd,
- IN OUT MEM_REGS *MemReg
- )
- {
- UINT32 Alignment;
- UINT32 Size;
- UINT32 NewBase;
- Alignment = ~(BarReq & 0xFFFFFFF0);
- Size = Alignment + 1;
- if (MemReg->Base > MemReg->Limit || !Size) {
- return ;
- }
- NewBase = BAR_ALIGN (MemReg->Base, Alignment);
- if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
- return ;
- }
- PciSegmentWrite32(BAR, NewBase);
- MemReg->Base = NewBase + Size; // Advance to new position
- *Cmd |= CMD_BM_MEM; // Set Memory Space Enable
- } // SetMemBar
- STATIC
- VOID
- SetPMem64Bar (
- IN UINTN BAR,
- IN BOOLEAN IsMaxBar,
- IN UINT32 BarReq,
- IN OUT UINT8 *Cmd,
- IN OUT PMEM_REGS *MemReg
- )
- {
- UINT32 Alignment;
- UINT32 Size;
- UINT64 NewBase;
- Alignment = ~(BarReq & 0xFFFFFFF0);
- Size = Alignment + 1;
- if (MemReg->Base64 > MemReg->Limit64 || !Size) {
- return ;
- }
- NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
- if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64) {
- return ;
- }
- PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
- if (!IsMaxBar) {
- BAR++;
- PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
- }
- MemReg->Base64 = NewBase + Size; // Advance to new position
- *Cmd |= CMD_BM_MEM; // Set Memory Space Enable
- } // SetPMem64Bar
- STATIC
- VOID
- SetDevResources (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 MaxFun, // PCI_MAX_FUNC for devices, 1 for bridge
- IN UINT8 MaxBar, // PCI_BAR5 for devices, PCI_BAR1 for bridge
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 Fun;
- UINT8 Reg;
- UINT32 BarReq;
- IO_REGS Io;
- MEM_REGS Mem;
- PMEM_REGS PMem;
- UINT8 Cmd;
- Io.Base = PortInfo->IoBase << 8;
- Io.Limit = (PortInfo->IoLimit << 8) | 0xFF;
- Mem.Base = PortInfo->MemBase << 16;
- Mem.Limit = (PortInfo->MemLimit << 16) | 0xFFFF;
- PMem.Base64 = PortInfo->PMemBase64 << 16;
- PMem.Limit64 = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
- for (Fun = 0; Fun < MaxFun; ++Fun) {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
- Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
- if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
- continue;
- }
- for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
- BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform BAR sizing
- if (BarReq & BIT0) {
- //
- // I/O BAR
- //
- SetIoBar (
- (gDeviceBaseAddress + Reg),
- BarReq,
- &Cmd,
- &Io
- );
- continue;
- }
- if (BarReq & BIT3) {
- //
- // P-Memory BAR
- //
- SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq, &Cmd, &PMem);
- } else {
- SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
- }
- if (BIT2 == (BarReq & (BIT2 | BIT1))) {
- //
- // Base address is 64 bits wide
- //
- Reg += 4;
- if (!(BarReq & BIT3)) {
- //
- // 64-bit memory bar
- //
- PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
- }
- }
- }
- if (Cmd & BIT1) {
- //
- // If device uses I/O and MEM mapping use only MEM mepping
- //
- Cmd &= ~BIT0;
- }
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
- }
- //
- // Update PortInfo if any changes
- //
- if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
- PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
- }
- if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
- PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
- }
- if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
- PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
- }
- } // SetDevResources
- STATIC
- VOID
- InitARHRConfigs(
- IN HR_CONFIG *Hr_Config,
- IN UINT8 BusNumLimit,
- IN OUT BRDG_RES_CONFIG* HrResConf
- )
- {
- UINT8 i,j;
- //
- // DS port for USB device
- //
- HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
- HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
- HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
- HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
- HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
- HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
- //
- // CIO port
- //
- HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
- HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
- HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
- HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
- HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
- HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
- switch(Hr_Config->DeviceId)
- {
- //
- // HR with 1 DS and 1 USB
- //
- case AR_HR_2C:
- case AR_HR_LP:
- case AR_HR_C0_2C:
- case TR_HR_2C:
- Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
- Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
- Hr_Config->BridgeLoops = 4;
- break;
- //
- // HR with 2 DS and 1 USB
- //
- case AR_HR_4C:
- case TR_HR_4C:
- case AR_HR_C0_4C:
- Hr_Config->MinDSNumber = 1;
- Hr_Config->MaxDSNumber = 4;
- Hr_Config->BridgeLoops = 6;
- for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i)
- {
- HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
- HrConfigs[j].DevId.Dev = i;
- HrConfigs[j].DevId.Fun = 0;
- HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
- HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
- }
- break;
- }
- }//InitARHRConfigs
- STATIC
- VOID
- InitCommonHRConfigs (
- IN HR_CONFIG *Hr_Config,
- IN UINT8 BusNumLimit,
- IN OUT BRDG_RES_CONFIG *HrResConf
- )
- {
- UINT8 i;
- UINT8 j;
- for(i = 0; i < count(HrConfigs); ++i) {
- HrConfigs[i].IsDSBridge = TRUE;
- }
- //
- // US(HRBus:0:0)
- //
- HrConfigs[HR_US_PORT].DevId.Bus = Hr_Config->HRBus;
- HrConfigs[HR_US_PORT].DevId.Dev = 0;
- HrConfigs[HR_US_PORT].DevId.Fun = 0;
- HrConfigs[HR_US_PORT].Res = *HrResConf;
- HrConfigs[HR_US_PORT].Res.IoBase = 0xF1;
- HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
- HrConfigs[HR_US_PORT].PBus = HrConfigs[HR_US_PORT].DevId.Bus;
- HrConfigs[HR_US_PORT].SBus = HrConfigs[HR_US_PORT].PBus + 1;
- HrConfigs[HR_US_PORT].SubBus = BusNumLimit;
- HrConfigs[HR_US_PORT].IsDSBridge = FALSE;
- //
- // HIA resides here
- //
- HrConfigs[HR_DS_PORT0].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
- HrConfigs[HR_DS_PORT0].DevId.Dev = 0;
- HrConfigs[HR_DS_PORT0].DevId.Fun = 0;
- HrConfigs[HR_DS_PORT0].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[HR_DS_PORT0].Res.MemBase = HrResConf->MemLimit;
- HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
- HrResConf->MemLimit -= 0x10; //This 1 MB chunk will be used by HIA
- HrConfigs[HR_DS_PORT0].Res.Cmd = CMD_BM_MEM;
- HrConfigs[HR_DS_PORT0].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[HR_DS_PORT0].PBus = HrConfigs[HR_DS_PORT0].DevId.Bus;
- HrConfigs[HR_DS_PORT0].SBus = HrConfigs[HR_DS_PORT0].PBus + 1;
- HrConfigs[HR_DS_PORT0].SubBus = HrConfigs[HR_DS_PORT0].PBus + 1;
- switch (Hr_Config->DeviceId) {
- //
- // Alpine Ridge
- //
- case AR_HR_2C:
- case AR_HR_C0_2C:
- case AR_HR_LP:
- case AR_HR_4C:
- case AR_HR_C0_4C:
- //
- // Titan Ridge
- //
- case TR_HR_2C:
- case TR_HR_4C:
- InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
- break;
- default:
- //
- // DS(HRBus+2:3-6:0)
- //
- Hr_Config->MinDSNumber = 3;
- Hr_Config->MaxDSNumber = 6;
- Hr_Config->BridgeLoops = count (HrConfigs);
- for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i) {
- HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
- HrConfigs[j].DevId.Dev = i;
- HrConfigs[j].DevId.Fun = 0;
- HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
- HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
- }
- }
- } // InitCommonHRConfigs
- STATIC
- VOID
- InitHRDSPort_Disable (
- IN UINT8 id,
- IN OUT BRDG_CONFIG *BrdgConf
- )
- {
- HrConfigs[id].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[id].SBus = BrdgConf->SBus;
- HrConfigs[id].SubBus = BrdgConf->SBus;
- BrdgConf->SBus++;
- } // InitHRDSPort_Disable
- //AR only
- STATIC
- VOID
- InitARDSPort_1Port(
- IN OUT BRDG_CONFIG* BrdgConf
- )
- {
- UINT16 MemBase = BrdgConf->Res.MemBase & 0xFFF0;
- UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
- UINT8 BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
- HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
- HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
- HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
- HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
- HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
- HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
- HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
- BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
- HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
- HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
- HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
- HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
- HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
- BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
- }//InitARDSPort_1Port
- STATIC
- VOID
- InitARDSPort_2Port(
- IN OUT BRDG_CONFIG* BrdgConf
- )
- {
- UINT16 MemBase = BrdgConf->Res.MemBase & 0xFFF0;
- UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
- UINT8 BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
- // Busses are split between ports 1 and 4
- BusRange /= 2;
- HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
- HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
- HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
- HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
- HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
- HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
- HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
- BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
- HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
- HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
- HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
- HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
- HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
- BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
- HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
- HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
- HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
- HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
- HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
- HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
- HrConfigs[AR_DS_PORT4].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
- HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
- HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
- BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
- }//InitARDSPort_2Port
- STATIC
- BOOLEAN
- CheckLimits (
- IN BOOLEAN Is2PortDev,
- IN BRDG_RES_CONFIG *HrResConf,
- IN UINT8 BusRange
- )
- {
- UINT16 MemBase;
- UINT16 MemLimit;
- UINT64 PMemBase64;
- UINT64 PMemLimit64;
- MemBase = HrResConf->MemBase & 0xFFF0;
- MemLimit = HrResConf->MemLimit & 0xFFF0;
- PMemBase64 = HrResConf->PMemBase64 & 0xFFF0;
- PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
- //
- // Check memoty alignment
- //
- if (MemBase & 0x3FF) {
- DEBUG((DEBUG_INFO, "M alig\n"));
- return FALSE;
- }
- if (PMemBase64 & 0xFFF) {
- DEBUG((DEBUG_INFO, "PM alig\n"));
- return FALSE;
- }
- if (Is2PortDev) {
- //
- // Check mem size
- //
- if (MemLimit + 0x10 - MemBase < 0x2E00) {
- DEBUG((DEBUG_INFO, "M size\n"));
- return FALSE;
- }
- //
- // Check P-mem size
- //
- if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
- DEBUG((DEBUG_INFO, "PM size\n"));
- return FALSE;
- }
- //
- // Check bus range
- //
- if (BusRange < 106) {
- DEBUG((DEBUG_INFO, "Bus range\n"));
- return FALSE;
- }
- } else {
- //
- // Check mem size
- //
- if (MemLimit + 0x10 - MemBase < 0x1600) {
- DEBUG((DEBUG_INFO, "M size\n"));
- return FALSE;
- }
- //
- // Check P-mem size
- //
- if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
- DEBUG((DEBUG_INFO, "PM size\n"));
- return FALSE;
- }
- //
- // Check bus range
- //
- if (BusRange < 56) {
- DEBUG((DEBUG_INFO, "Bus range\n"));
- return FALSE;
- }
- }
- return TRUE;
- } // CheckLimits
- STATIC
- BOOLEAN
- InitHRResConfigs (
- IN OUT HR_CONFIG *Hr_Config,
- IN UINT8 BusNumLimit,
- IN OUT BRDG_RES_CONFIG*HrResConf
- )
- {
- BRDG_CONFIG BrdgConf = { { 0 } };
- InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
- BrdgConf.PBus = Hr_Config->HRBus + 2;// Take into account busses
- BrdgConf.SBus = Hr_Config->HRBus + 3;// for US and DS of HIA
- BrdgConf.SubBus = BusNumLimit;
- BrdgConf.Res = *HrResConf;
- while (TRUE) {
- switch (Hr_Config->DeviceId) {
- case AR_HR_4C:
- case TR_HR_4C:
- case AR_HR_C0_4C:
- //
- // 2 Port host
- //
- if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
- InitARDSPort_2Port(&BrdgConf);
- DEBUG((DEBUG_INFO, "AR2\n"));
- return TRUE;
- } else {
- return FALSE;
- }
- // AR only
- case AR_HR_2C: // 1 port host
- case AR_HR_C0_2C:
- case AR_HR_LP:
- case TR_HR_2C:
- DEBUG((DEBUG_INFO, "AR1\n"));
- InitARDSPort_1Port(&BrdgConf);
- return TRUE;
- default:
- InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
- InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
- InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
- InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
- return FALSE;
- }
- }
- } // InitHRResConfigs
- STATIC
- BOOLEAN
- InitializeHostRouter (
- OUT HR_CONFIG *Hr_Config,
- IN UINTN RpSegment,
- IN UINTN RpBus,
- IN UINTN RpDevice,
- IN UINTN RpFunction
- )
- {
- UINT8 BusNumLimit;
- BRDG_RES_CONFIG HrResConf = { 0 };
- UINT8 i;
- BOOLEAN Ret;
- Ret = TRUE;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
- Hr_Config->HRBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->HRBus, 0x00, 0x00, 0);
- Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
- return FALSE;
- }
- TbtSegment = (UINT8)RpSegment;
- HrResConf.Cmd = CMD_BM_MEM;
- HrResConf.Cls = DEF_CACHE_LINE_SIZE;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
- HrResConf.IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
- HrResConf.IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
- HrResConf.MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
- HrResConf.MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
- HrResConf.PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
- HrResConf.PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
- HrResConf.PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
- HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
- BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
- Ret = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
- for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
- UINT8 Bus;
- UINT8 Dev;
- UINT8 Fun;
- Bus = HrConfigs[i].DevId.Bus;
- Dev = HrConfigs[i].DevId.Dev;
- Fun = HrConfigs[i].DevId.Fun;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrConfigs[i].Res.Cls);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 & 0xFFFF));
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 & 0xFFFF));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64 >> 16));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64 >> 16));
- PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), HrConfigs[i].Res.IoBase);
- PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, HrConfigs[i].Res.Cmd);
- }
- if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C || Hr_Config->DeviceId == AR_HR_LP) {
- for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
- if(HrConfigs[i].IsDSBridge) {
- UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfigs[i].DevId.Fun);
- }
- }
- }
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
- return Ret;
- } // InitializeHostRouter
- STATIC
- UINT8
- ConfigureSlot (
- IN UINT8 Bus,
- IN UINT8 MAX_DEVICE,
- IN INT8 Depth,
- IN BOOLEAN ArPcie,
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 Device;
- UINT8 SBus;
- UINT8 UsedBusNumbers;
- UINT8 RetBusNum;
- PORT_INFO CurrentSlot;
- RetBusNum = 0;
- for (Device = 0; Device < MAX_DEVICE; Device++) {
- //
- // Continue if device is absent
- //
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, 0x00, 0);
- if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
- continue;
- }
- if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
- SetDevResources (
- Bus,
- Device,
- PCI_MAX_FUNC,
- PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
- PortInfo
- );
- continue;
- }
- //
- // Else Bridge
- //
- CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
- ++RetBusNum; // UP Bridge
- SBus = Bus + RetBusNum; // DS Bridge
- if (SBus + 1 >= PortInfo->BusNumLimit) {
- continue;
- }
- SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), PortInfo);
- //
- // Init UP Bridge to reach DS Bridge
- //
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
- if(ArPcie) {
- UnsetVesc(Bus, Device, 0x00);
- }
- UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
- RetBusNum += UsedBusNumbers;
- SetPhyPortResources (
- Bus,
- Device,
- SBus + UsedBusNumbers,
- Depth,
- &CurrentSlot,
- PortInfo
- );
- }
- //
- // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
- //
- return RetBusNum;
- } // ConfigureSlot
- STATIC
- VOID
- SetCioPortResources (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 SBus,
- IN UINT8 SubBus,
- IN PORT_INFO *portInfoBeforeChange,
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 Cmd;
- Cmd = CMD_BUS_MASTER;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x00, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
- if (PortInfo->IoBase <= PortInfo->IoLimit) {
- PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), PortInfo->IoBase);
- PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), PortInfo->IoLimit);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
- Cmd |= CMD_BM_IO;
- } else {
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
- }
- if (PortInfo->MemBase <= PortInfo->MemLimit) {
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), PortInfo->MemBase);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemLimit);
- Cmd |= CMD_BM_MEM;
- } else {
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
- }
- if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 & 0xFFFF));
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 & 0xFFFF));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
- Cmd |= CMD_BM_MEM;
- } else {
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
- }
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
- } // SetCioPortResources
- STATIC
- VOID
- SetSlotsAsUnused (
- IN UINT8 Bus,
- IN UINT8 MaxSlotNum,
- IN UINT8 CioSlot,
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 Slot;
- for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, 0x00, 0);
- if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
- continue;
- }
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
- PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
- PortInfo->BusNumLimit--;
- }
- } // SetSlotsAsUnused
- STATIC
- UINT16
- FindVendorSpecificHeader(
- IN UINT8 Bus
- )
- {
- PCI_EXP_EXT_HDR *ExtHdr;
- UINT32 ExtHdrValue;
- UINT16 ExtendedRegister;
- ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
- ExtendedRegister = 0x100;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
- while (ExtendedRegister) {
- ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegister);
- if (ExtHdr->CapabilityId == 0xFFFF) {
- return 0x0000; // No Vendor-Specific Extended Capability header
- }
- if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID == ExtHdr->CapabilityId) {
- return ExtendedRegister;
- }
- ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
- }
- return 0x0000; // No Vendor-Specific Extended Capability header
- }
- STATIC
- UINT8
- FindSsid_SsvidHeader (
- IN UINT8 Bus
- )
- {
- UINT8 CapHeaderId;
- UINT8 CapHeaderOffset;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
- CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
- while (CapHeaderOffset != 0) {
- CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset);
- if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
- return CapHeaderOffset;
- }
- CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset + 1);
- }
- DEBUG((DEBUG_INFO, "SID0\n"));
- return 0;
- } // FindSsid_SsvidHeader
- STATIC
- BOOLEAN
- GetCioSlotByDevId (
- IN UINT8 Bus,
- OUT UINT8 *CioSlot,
- OUT UINT8 *MaxSlotNum,
- OUT BOOLEAN *ArPcie
- )
- {
- UINT16 VSECRegister;
- BRDG_CIO_MAP_REG BridgMap;
- UINT32 BitScanRes;
- UINT16 DevId;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0x00, 0);
- DevId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- //
- // Init out params in case device is not recognised
- //
- *CioSlot = 4;
- *MaxSlotNum = 7;
- *ArPcie = FALSE;
- switch (DevId) {
- //
- // For known device IDs
- //
- case 0x1578:
- *ArPcie = TRUE;
- }
- switch (DevId) {
- //
- // For known device IDs
- //
- case 0x1513:
- case 0x151A:
- case 0x151B:
- case 0x1547:
- case 0x1548:
- return TRUE; // Just return
- case 0x1549:
- return FALSE; // Just return
- }
- VSECRegister = FindVendorSpecificHeader(Bus);
- if (!VSECRegister) {
- return TRUE; // Just return
- }
- //
- // Go to Bridge/CIO map register
- //
- VSECRegister += 0x18;
- BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress + VSECRegister);
- //
- // Check for range
- //
- if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
- return TRUE;
- //
- // Not a valid register
- //
- }
- //
- // Set OUT params
- //
- *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
- #ifdef _MSC_VER
- if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS bridge which is CIO port
- return FALSE;
- }
- #else
- #ifdef __GNUC__
- if (BridgMap.Bits.CioPortMap == 0) {
- return FALSE;
- }
- BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
- #else
- #error Unsupported Compiler
- #endif
- #endif
- *CioSlot = (UINT8)BitScanRes;
- return TRUE;
- } // GetCioSlotByDevId
- #define TBT_LEGACY_SUB_SYS_ID 0x11112222
- STATIC
- BOOLEAN
- IsLegacyDevice (
- IN UINT8 Bus
- )
- {
- UINT32 Sid;
- UINT8 SidRegister;
- UINT16 DevId;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
- DevId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- switch (DevId) {
- //
- // For known device IDs
- //
- case 0x1513:
- case 0x151A:
- case 0x151B:
- DEBUG((DEBUG_INFO, "Legacy "));
- DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
- return TRUE;
- //
- // Legacy device by Device Id
- //
- }
- SidRegister = FindSsid_SsvidHeader(Bus);
- if (!SidRegister) {
- return TRUE; // May be absent for legacy devices
- }
- //
- // Go to register
- //
- SidRegister += 0x4;
- Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
- DEBUG((DEBUG_INFO, "SID"));
- DEBUG((DEBUG_INFO, " = %d\n", Sid));
- return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
- } // IsLegacyDevice
- STATIC
- VOID
- UnsetVescEp(
- IN UINT8 Bus,
- IN UINT8 MaxSlotNum
- )
- {
- UINT8 i;
- for (i = 0; i <= MaxSlotNum; ++i)
- {
- UnsetVesc(Bus, i, 0);
- }
- }// Unset_VESC_REG2_EP
- STATIC
- BOOLEAN
- ConfigureEP (
- IN INT8 Depth,
- IN OUT UINT8 *Bus,
- IN OUT PORT_INFO *PortInfo
- )
- {
- UINT8 SBus;
- UINT8 CioSlot;
- UINT8 MaxSlotNum;
- BOOLEAN ArPcie;
- UINT8 MaxPHYSlots;
- UINT8 UsedBusNumbers;
- UINT8 cmd;
- BOOLEAN CioSlotPresent;
- BOOLEAN Continue;
- PORT_INFO PortInfoOrg;
- UINT8 CioBus;
- CioSlot = 4;
- MaxSlotNum = 7;
- CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, 0x00, 0);
- cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
- // AR ONLY
- // Endpoint on CIO slot, but not a bridge device
- if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
- DEBUG((DEBUG_INFO, "UEP\n"));
- // Check whether EP already configured by examining CMD register
- if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
- {
- DEBUG((DEBUG_INFO, "BMF\n"));
- return FALSE;
- }
- // Configure it as regular PCIe device
- ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
- return FALSE;
- }
- //
- // Based on Device ID assign Cio slot and max number of PHY slots to scan
- //
- CioSlotPresent = GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArPcie);
- MaxPHYSlots = MaxSlotNum;
- //
- // Check whether EP already configured by examining CMD register
- //
- if (cmd & CMD_BUS_MASTER) {
- //
- // Yes no need to touch this EP, just move to next one in chain
- //
- CioBus = *Bus + 1;
- if(ArPcie){
- UnsetVescEp(CioBus, MaxSlotNum);
- }
- if (!CioSlotPresent) {
- //
- // Cio slot is not present in EP, just return FALSE
- //
- DEBUG((DEBUG_INFO, "BMF\n"));
- return FALSE;
- }
- //
- // Take all resources from Cio slot and return
- //
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, CioSlot, 0x00, 0);
- PortInfo->BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
- PortInfo->IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
- PortInfo->IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
- PortInfo->MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
- PortInfo->MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
- PortInfo->PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
- PortInfo->PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
- PortInfo->PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
- PortInfo->PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
- PortInfo->PMemLimit64 |= 0xF;
- //
- // Jump to next EP
- //
- *Bus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
- //
- // Should we continue?
- //
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
- Continue = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- return Continue;
- }
- //
- // Set is legacy dvice
- //
- isLegacyDevice = IsLegacyDevice (*Bus);
- SetCioPortResources (
- *Bus,
- 0, // Assign all available resources to US port of EP
- *Bus + 1,
- PortInfo->BusNumLimit,
- 0,
- PortInfo
- );
- SBus = *Bus + 1;// Jump to DS port
- if (CioSlotPresent) {
- MaxPHYSlots = CioSlot;
- }
- UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortInfo);
- if (!CioSlotPresent) {
- return FALSE;
- //
- // Stop resource assignment on this chain
- //
- }
- //
- // Set rest of slots us unused
- //
- SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
- SetCioPortResources (
- SBus,
- CioSlot,
- SBus + UsedBusNumbers + 1,
- PortInfo->BusNumLimit,
- &PortInfoOrg,
- PortInfo
- );
- *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
- if(ArPcie) {
- UnsetVesc(SBus, CioSlot, 0x00);
- }
- if (*Bus > PortInfo->BusNumLimit - 2) {
- //
- // In case of bus numbers are exhausted stop enumeration
- //
- return FALSE;
- }
- //
- // Check whether we should continue on this chain
- //
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
- Continue = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- return Continue;
- } // ConfigureEP
- STATIC
- VOID
- GetPortResources (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 Fun,
- IN OUT PORT_INFO *PortInfo
- )
- {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
- PortInfo->BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
- PortInfo->IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
- PortInfo->IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
- PortInfo->MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
- PortInfo->MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
- PortInfo->PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
- PortInfo->PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
- PortInfo->PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
- PortInfo->PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
- PortInfo->IoLimit |= 0xF;
- PortInfo->MemLimit |= 0xF;
- PortInfo->PMemLimit64 |= 0xF;
- } // GetPortResources
- STATIC
- VOID
- ConfigurePort (
- IN UINT8 Bus,
- IN UINT8 Dev,
- IN UINT8 Fun,
- IN OUT PORT_INFO *PortInfo
- )
- {
- INT8 i;
- UINT8 USBusNum;
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
- USBusNum = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x00, 0x00, 0);
- if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
- //
- // Nothing to do if TBT device is not connected
- //
- return ;
- }
- GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from DS port
- //
- // Assign resources to EPs
- //
- for (i = 0; i < MAX_TBT_DEPTH; ++i) {
- PortInfo->ConfedEP++;
- if (!ConfigureEP (i, &USBusNum, PortInfo)) {
- return ;
- }
- }
- } // ConfigurePort
- VOID
- ThunderboltCallback (
- IN UINT8 Type
- )
- {
- PORT_INFO PortInfoOrg = { 0 };
- HR_CONFIG HrConfig = { 0 };
- UINT8 i;
- UINTN Segment = 0;
- UINTN Bus = 0;
- UINTN Device;
- UINTN Function;
- DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
- DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
- PortInfoInit (&PortInfoOrg);
- if(Type == DTBT_CONTROLLER) {
- if (gCurrentDiscreteTbtRootPort == 0) {
- DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
- return;
- }
- GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
- DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
- if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
- return ;
- }
- //
- // Configure DS ports
- //
- for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
- DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
- ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
- }
- DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
- EndOfThunderboltCallback (Segment, Bus, Device, Function);
- }
- DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
- } // ThunderboltCallback
- VOID
- DisablePCIDevicesAndBridges (
- IN UINT8 MinBus,
- IN UINT8 MaxBus
- )
- {
- UINT8 Bus;
- UINT8 Dev;
- UINT8 Fun;
- UINT8 RegVal;
- //
- // Disable PCI device First, and then Disable PCI Bridge
- //
- for (Bus = MaxBus; Bus > MinBus; --Bus) {
- for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
- for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
- if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
- if (Fun == 0) {
- break;
- }
- continue;
- }
- RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
- if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
- //
- // ******** Disable PCI Device ********
- // BIT0 I/O Space Enabled BIT1 Memory Space Enabled
- // BIT2 Bus Master Enabled BIT4 Memory Write and Invalidation Enable
- //
- PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
- PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
- }
- }
- }
- }
- //
- // now no more PCI dev on another side of PCI Bridge can safty disable PCI Bridge
- //
- for (Bus = MaxBus; Bus > MinBus; --Bus) {
- for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
- for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
- if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
- if (Fun == 0) {
- break;
- }
- continue;
- }
- RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
- if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
- PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
- PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
- PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
- }
- } // for ( Fun .. )
- } // for ( Dev ... )
- } // for ( Bus ... )
- } // DisablePCIDevicesAndBridges
- VOID
- TbtDisablePCIDevicesAndBridges (
- IN UINT8 Type
- )
- {
- UINTN Segment = 0;
- UINTN Bus = 0;
- UINTN Device;
- UINTN Function;
- UINT8 MinBus;
- UINT8 MaxBus;
- UINT16 DeviceId;
- MinBus = 1;
- if(Type == DTBT_CONTROLLER) {
- //
- // for(Dev = 0; Dev < 8; ++Dev)
- // {
- // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
- // gBS->Stall(2000); // 2msec
- // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
- // }
- // gBS->Stall(200 * 1000); // 200 msec
- //
- if (gCurrentDiscreteTbtRootPort == 0) {
- DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
- return;
- }
- GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
- MinBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
- MaxBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
- gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00, 0x00, 0);
- DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
- if (!(IsTbtHostRouter (DeviceId))) {
- return;
- }
- TbtSegment = (UINT8)Segment;
- MinBus++;
- //
- // @todo : Move this out when we dont have Loop for ITBT
- //
- DisablePCIDevicesAndBridges(MinBus, MaxBus);
- }
- } // DisablePCIDevicesAndBridges
|