1 /** @file
2   Set up ROM Table for PCI Bus module.
3 
4 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include "PciBus.h"
10 
11 //
12 // PCI ROM image information
13 //
14 typedef struct {
15   EFI_HANDLE  ImageHandle;
16   UINTN       Seg;
17   UINT8       Bus;
18   UINT8       Dev;
19   UINT8       Func;
20   VOID        *RomImage;
21   UINT64      RomSize;
22 } PCI_ROM_IMAGE;
23 
24 UINTN          mNumberOfPciRomImages     = 0;
25 UINTN          mMaxNumberOfPciRomImages  = 0;
26 PCI_ROM_IMAGE  *mRomImageTable           = NULL;
27 
28 /**
29   Add the Rom Image to internal database for later PCI light enumeration.
30 
31   @param ImageHandle    Option Rom image handle.
32   @param Seg            Segment of PCI space.
33   @param Bus            Bus NO of PCI space.
34   @param Dev            Dev NO of PCI space.
35   @param Func           Func NO of PCI space.
36   @param RomImage       Option Rom buffer.
37   @param RomSize        Size of Option Rom buffer.
38 **/
39 VOID
PciRomAddImageMapping(IN EFI_HANDLE ImageHandle,IN UINTN Seg,IN UINT8 Bus,IN UINT8 Dev,IN UINT8 Func,IN VOID * RomImage,IN UINT64 RomSize)40 PciRomAddImageMapping (
41   IN  EFI_HANDLE  ImageHandle,
42   IN  UINTN       Seg,
43   IN  UINT8       Bus,
44   IN  UINT8       Dev,
45   IN  UINT8       Func,
46   IN  VOID        *RomImage,
47   IN  UINT64      RomSize
48   )
49 {
50   UINTN           Index;
51   PCI_ROM_IMAGE   *NewTable;
52 
53   for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
54     if (mRomImageTable[Index].Seg  == Seg &&
55         mRomImageTable[Index].Bus  == Bus &&
56         mRomImageTable[Index].Dev  == Dev &&
57         mRomImageTable[Index].Func == Func) {
58       //
59       // Expect once RomImage and RomSize are recorded, they will be passed in
60       // later when updating ImageHandle
61       //
62       ASSERT ((mRomImageTable[Index].RomImage == NULL) || (RomImage == mRomImageTable[Index].RomImage));
63       ASSERT ((mRomImageTable[Index].RomSize  == 0   ) || (RomSize  == mRomImageTable[Index].RomSize ));
64       break;
65     }
66   }
67 
68   if (Index == mNumberOfPciRomImages) {
69     //
70     // Rom Image Table buffer needs to grow.
71     //
72     if (mNumberOfPciRomImages == mMaxNumberOfPciRomImages) {
73       NewTable = ReallocatePool (
74                    mMaxNumberOfPciRomImages * sizeof (PCI_ROM_IMAGE),
75                    (mMaxNumberOfPciRomImages + 0x20) * sizeof (PCI_ROM_IMAGE),
76                    mRomImageTable
77                    );
78       if (NewTable == NULL) {
79         return ;
80       }
81 
82       mRomImageTable            = NewTable;
83       mMaxNumberOfPciRomImages += 0x20;
84     }
85     //
86     // Record the new PCI device
87     //
88     mRomImageTable[Index].Seg  = Seg;
89     mRomImageTable[Index].Bus  = Bus;
90     mRomImageTable[Index].Dev  = Dev;
91     mRomImageTable[Index].Func = Func;
92     mNumberOfPciRomImages++;
93   }
94 
95   mRomImageTable[Index].ImageHandle = ImageHandle;
96   mRomImageTable[Index].RomImage    = RomImage;
97   mRomImageTable[Index].RomSize     = RomSize;
98 }
99 
100 /**
101   Get Option rom driver's mapping for PCI device.
102 
103   @param PciIoDevice Device instance.
104 
105   @retval TRUE   Found Image mapping.
106   @retval FALSE  Cannot found image mapping.
107 
108 **/
109 BOOLEAN
PciRomGetImageMapping(IN PCI_IO_DEVICE * PciIoDevice)110 PciRomGetImageMapping (
111   IN  PCI_IO_DEVICE                       *PciIoDevice
112   )
113 {
114   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
115   UINTN                           Index;
116 
117   PciRootBridgeIo = PciIoDevice->PciRootBridgeIo;
118 
119   for (Index = 0; Index < mNumberOfPciRomImages; Index++) {
120     if (mRomImageTable[Index].Seg  == PciRootBridgeIo->SegmentNumber &&
121         mRomImageTable[Index].Bus  == PciIoDevice->BusNumber         &&
122         mRomImageTable[Index].Dev  == PciIoDevice->DeviceNumber      &&
123         mRomImageTable[Index].Func == PciIoDevice->FunctionNumber    ) {
124 
125       if (mRomImageTable[Index].ImageHandle != NULL) {
126         AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle, NULL);
127       }
128       PciIoDevice->PciIo.RomImage = mRomImageTable[Index].RomImage;
129       PciIoDevice->PciIo.RomSize  = mRomImageTable[Index].RomSize;
130       return TRUE;
131     }
132   }
133 
134   return FALSE;
135 }
136