2 Common Lib function for QNC internal network access.
4 Copyright (c) 2013-2015 Intel Corporation.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 // The package level header files this module uses
21 #include <IntelQNCRegs.h>
22 #include <Library/QNCAccessLib.h>
23 #include <Library/DebugLib.h>
24 #include <IndustryStandard/Pci22.h>
33 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
34 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_READ_DW (Port
, RegAddress
);
35 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
46 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
47 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
48 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_WRITE_DW (Port
, RegAddress
);
58 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
59 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = ALT_MESSAGE_READ_DW (Port
, RegAddress
);
60 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
71 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
72 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
73 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = ALT_MESSAGE_WRITE_DW (Port
, RegAddress
);
83 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
84 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_IO_READ_DW (Port
, RegAddress
);
85 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
96 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
97 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
98 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_IO_WRITE_DW (Port
, RegAddress
);
105 QNC_MEM_IO_WIDTH Width
,
113 This is for the special consideration for QNC MMIO write, as required by FWG, a reading must be performed after MMIO writing
114 to ensure the expected write is processed and data is flushed into chipset
118 Row -- row number to be cleared ( start from 1 )
126 RETURN_STATUS Status
;
129 Status
= RETURN_SUCCESS
;
131 for (Index
=0; Index
< DataNumber
; Index
++) {
133 case QNCMmioWidthUint8
:
134 QNCMmio8 (MmIoAddress
, 0) = ((UINT8
*)pData
)[Index
];
135 if (QNCMmio8 (MmIoAddress
, 0) != ((UINT8
*)pData
)[Index
]) {
136 Status
= RETURN_DEVICE_ERROR
;
141 case QNCMmioWidthUint16
:
142 QNCMmio16 (MmIoAddress
, 0) = ((UINT16
*)pData
)[Index
];
143 if (QNCMmio16 (MmIoAddress
, 0) != ((UINT16
*)pData
)[Index
]) {
144 Status
= RETURN_DEVICE_ERROR
;
149 case QNCMmioWidthUint32
:
150 QNCMmio32 (MmIoAddress
, 0) = ((UINT32
*)pData
)[Index
];
151 if (QNCMmio32 (MmIoAddress
, 0) != ((UINT32
*)pData
)[Index
]) {
152 Status
= RETURN_DEVICE_ERROR
;
157 case QNCMmioWidthUint64
:
158 QNCMmio64 (MmIoAddress
, 0) = ((UINT64
*)pData
)[Index
];
159 if (QNCMmio64 (MmIoAddress
, 0) != ((UINT64
*)pData
)[Index
]) {
160 Status
= RETURN_DEVICE_ERROR
;
179 return QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
);
192 // Check what Soc we are running on (read Host bridge DeviceId)
194 DeviceId
= QNCMmPci16(0, MC_BUS
, MC_DEV
, MC_FUN
, PCI_DEVICE_ID_OFFSET
);
196 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
198 // Disable HSMMC configuration
200 Data32
= QncHsmmcRead ();
201 Data32
&= ~SMM_CTL_EN
;
202 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
, Data32
);
205 // Validate HSMMC configuration is disabled
207 Data32
= QncHsmmcRead ();
208 ASSERT((Data32
& SMM_CTL_EN
) == 0);
211 // Enable HSMMC configuration
213 WriteValue
|= SMM_CTL_EN
;
217 // Write the register value
219 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
, WriteValue
);
221 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
223 // Validate HSMMC configuration is enabled
225 Data32
= QncHsmmcRead ();
226 ASSERT((Data32
& SMM_CTL_EN
) != 0);
233 UINT32 ImrBaseOffset
,
244 // Check what Soc we are running on (read Host bridge DeviceId)
246 DeviceId
= QNCMmPci16(0, MC_BUS
, MC_DEV
, MC_FUN
, PCI_DEVICE_ID_OFFSET
);
249 // Disable IMR protection
251 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
253 // Disable IMR protection
255 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
257 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, Data32
);
260 // Validate IMR protection is disabled
262 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
263 ASSERT((Data32
& IMR_EN
) == 0);
266 // Update the IMR (IMRXL must be last as it may enable IMR violation checking)
268 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, ImrReadMask
);
269 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, ImrWriteMask
);
270 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXH
, ImrHigh
);
271 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, ImrLow
);
274 // Validate IMR protection is enabled/disabled
276 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
277 ASSERT((Data32
& IMR_EN
) == (ImrLow
& IMR_EN
));
280 // Disable IMR protection (allow all access)
282 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, (UINT32
)IMRX_ALL_ACCESS
);
283 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, (UINT32
)IMRX_ALL_ACCESS
);
286 // Update the IMR (IMRXRM/IMRXWM must be last as they restrict IMR access)
288 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, (ImrLow
& ~IMR_EN
));
289 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXH
, ImrHigh
);
290 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, ImrReadMask
);
291 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, ImrWriteMask
);
305 // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
306 // should always consist of a READ from the address followed by 2 identical
307 // WRITEs to that address.
309 RegValue
= QNCAltPortRead (QUARK_ICLK_SB_PORT_ID
, RegAddress
);
310 RegValue
&= AndValue
;
312 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
313 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
325 // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
326 // should always consist of a READ from the address followed by 2 identical
327 // WRITEs to that address.
329 RegValue
= QNCAltPortRead (QUARK_ICLK_SB_PORT_ID
, RegAddress
);
331 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
332 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);