2 Common Lib function for QNC internal network access.
4 Copyright (c) 2013-2015 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 // The package level header files this module uses
15 #include <IntelQNCRegs.h>
16 #include <Library/QNCAccessLib.h>
17 #include <Library/DebugLib.h>
18 #include <IndustryStandard/Pci22.h>
27 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
28 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_READ_DW (Port
, RegAddress
);
29 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
40 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
41 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
42 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_WRITE_DW (Port
, RegAddress
);
52 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
53 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = ALT_MESSAGE_READ_DW (Port
, RegAddress
);
54 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
65 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
66 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
67 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = ALT_MESSAGE_WRITE_DW (Port
, RegAddress
);
77 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
78 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_IO_READ_DW (Port
, RegAddress
);
79 return McD0PciCfg32 (QNC_ACCESS_PORT_MDR
);
90 McD0PciCfg32 (QNC_ACCESS_PORT_MDR
) = WriteValue
;
91 McD0PciCfg32 (QNC_ACCESS_PORT_MEA
) = (RegAddress
& 0xFFFFFF00);
92 McD0PciCfg32 (QNC_ACCESS_PORT_MCR
) = MESSAGE_IO_WRITE_DW (Port
, RegAddress
);
99 QNC_MEM_IO_WIDTH Width
,
107 This is for the special consideration for QNC MMIO write, as required by FWG, a reading must be performed after MMIO writing
108 to ensure the expected write is processed and data is flushed into chipset
112 Row -- row number to be cleared ( start from 1 )
120 RETURN_STATUS Status
;
123 Status
= RETURN_SUCCESS
;
125 for (Index
=0; Index
< DataNumber
; Index
++) {
127 case QNCMmioWidthUint8
:
128 QNCMmio8 (MmIoAddress
, 0) = ((UINT8
*)pData
)[Index
];
129 if (QNCMmio8 (MmIoAddress
, 0) != ((UINT8
*)pData
)[Index
]) {
130 Status
= RETURN_DEVICE_ERROR
;
135 case QNCMmioWidthUint16
:
136 QNCMmio16 (MmIoAddress
, 0) = ((UINT16
*)pData
)[Index
];
137 if (QNCMmio16 (MmIoAddress
, 0) != ((UINT16
*)pData
)[Index
]) {
138 Status
= RETURN_DEVICE_ERROR
;
143 case QNCMmioWidthUint32
:
144 QNCMmio32 (MmIoAddress
, 0) = ((UINT32
*)pData
)[Index
];
145 if (QNCMmio32 (MmIoAddress
, 0) != ((UINT32
*)pData
)[Index
]) {
146 Status
= RETURN_DEVICE_ERROR
;
151 case QNCMmioWidthUint64
:
152 QNCMmio64 (MmIoAddress
, 0) = ((UINT64
*)pData
)[Index
];
153 if (QNCMmio64 (MmIoAddress
, 0) != ((UINT64
*)pData
)[Index
]) {
154 Status
= RETURN_DEVICE_ERROR
;
173 return QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
);
186 // Check what Soc we are running on (read Host bridge DeviceId)
188 DeviceId
= QNCMmPci16(0, MC_BUS
, MC_DEV
, MC_FUN
, PCI_DEVICE_ID_OFFSET
);
190 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
192 // Disable HSMMC configuration
194 Data32
= QncHsmmcRead ();
195 Data32
&= ~SMM_CTL_EN
;
196 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
, Data32
);
199 // Validate HSMMC configuration is disabled
201 Data32
= QncHsmmcRead ();
202 ASSERT((Data32
& SMM_CTL_EN
) == 0);
205 // Enable HSMMC configuration
207 WriteValue
|= SMM_CTL_EN
;
211 // Write the register value
213 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID
, QNC_MSG_FSBIC_REG_HSMMC
, WriteValue
);
215 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
217 // Validate HSMMC configuration is enabled
219 Data32
= QncHsmmcRead ();
220 ASSERT((Data32
& SMM_CTL_EN
) != 0);
227 UINT32 ImrBaseOffset
,
238 // Check what Soc we are running on (read Host bridge DeviceId)
240 DeviceId
= QNCMmPci16(0, MC_BUS
, MC_DEV
, MC_FUN
, PCI_DEVICE_ID_OFFSET
);
243 // Disable IMR protection
245 if (DeviceId
== QUARK2_MC_DEVICE_ID
) {
247 // Disable IMR protection
249 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
251 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, Data32
);
254 // Validate IMR protection is disabled
256 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
257 ASSERT((Data32
& IMR_EN
) == 0);
260 // Update the IMR (IMRXL must be last as it may enable IMR violation checking)
262 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, ImrReadMask
);
263 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, ImrWriteMask
);
264 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXH
, ImrHigh
);
265 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, ImrLow
);
268 // Validate IMR protection is enabled/disabled
270 Data32
= QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
);
271 ASSERT((Data32
& IMR_EN
) == (ImrLow
& IMR_EN
));
274 // Disable IMR protection (allow all access)
276 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, (UINT32
)IMRX_ALL_ACCESS
);
277 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, (UINT32
)IMRX_ALL_ACCESS
);
280 // Update the IMR (IMRXRM/IMRXWM must be last as they restrict IMR access)
282 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXL
, (ImrLow
& ~IMR_EN
));
283 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXH
, ImrHigh
);
284 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXRM
, ImrReadMask
);
285 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID
, ImrBaseOffset
+QUARK_NC_MEMORY_MANAGER_IMRXWM
, ImrWriteMask
);
299 // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
300 // should always consist of a READ from the address followed by 2 identical
301 // WRITEs to that address.
303 RegValue
= QNCAltPortRead (QUARK_ICLK_SB_PORT_ID
, RegAddress
);
304 RegValue
&= AndValue
;
306 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
307 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
319 // Whenever an iCLK SB register (Endpoint 32h) is being programmed the access
320 // should always consist of a READ from the address followed by 2 identical
321 // WRITEs to that address.
323 RegValue
= QNCAltPortRead (QUARK_ICLK_SB_PORT_ID
, RegAddress
);
325 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);
326 QNCAltPortWrite (QUARK_ICLK_SB_PORT_ID
, RegAddress
, RegValue
);