summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c')
-rwxr-xr-xcpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c b/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
new file mode 100755
index 0000000..d1d29ed
--- /dev/null
+++ b/cpu/amd/geode_lx/gplvsa_ii/sysmgr/pci_rd.c
@@ -0,0 +1,177 @@
+/*
+* Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of the
+* License, or (at your option) any later version.
+*
+* This code is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+
+* You should have received a copy of the GNU Lesser General
+* Public License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+* Boston, MA 02111-1307 USA
+*/
+
+//*****************************************************************************
+//* Implements reads of virtualized PCI configuration headers
+//*****************************************************************************
+
+
+#include "VSA2.H"
+#include "PCI.H"
+#include "VPCI.H"
+#include "PROTOS.H"
+#include "SYSMGR.H"
+#include "CHIPSET.H"
+
+
+// External function declarations:
+ULONG pascal Get_Device_Status(PCI_HEADER_ENTRY *);
+ULONG pascal Handle_PCI_PM_Rd(PCI_HEADER_ENTRY *);
+ULONG pascal Handle_EHCI_Rd(PCI_HEADER_ENTRY *);
+ULONG pascal Read_MSR_LO(ULONG);
+UCHAR pascal Get_Latency(PCI_HEADER_ENTRY *);
+PCI_HEADER_ENTRY * pascal Get_Structure(USHORT);
+extern Hardware HardwareInfo;
+
+
+
+// External variable declarations:
+extern DESCRIPTOR MSRs[];
+extern UCHAR Shift, AlignedReg, Function;
+extern PCI_HEADER_ENTRY * CommandPtr;
+extern ULONG ATA_Error;
+
+
+
+//***********************************************************************
+// Reads an embedded PCI register
+//***********************************************************************
+ULONG pascal Read_EPCI(UCHAR AlignedReg)
+{ ULONG MsrAddr;
+
+ MsrAddr = MSRs[CommandPtr->Link].MsrAddr;
+ if (MsrAddr) {
+ (UCHAR)MsrAddr = AlignedReg/4;
+ return Read_MSR_LO(MsrAddr);
+ } else {
+ return 0;
+ }
+}
+
+
+//***********************************************************************
+//
+// This routine implements reads to virtualized configuration space.
+//
+// NOTES:
+// 1) Misaligned accesses are handled. If an access crosses a DWORD
+// boundary, only the bytes within the addressed DWORD are read.
+// The remaining bytes return FFs.
+// 2) The variable Pci points to a PCI_HEADER_ENTRY entry that defines
+// the state and characteristics of the register being read.
+//***********************************************************************
+ULONG pascal Virtual_PCI_Read_Handler(USHORT PCI_Address)
+{ ULONG Data;
+ register PCI_HEADER_ENTRY * Pci;
+
+
+ // Get ptr to virtualized table entry
+ Pci = Get_Structure(PCI_Address);
+
+
+ switch ((USHORT)Pci) {
+
+ case UNIMPLEMENTED_FUNCTION:
+ Data = 0xFFFFFFFF;
+ break;
+
+ case UNIMPLEMENTED_REGISTER:
+ Data = 0x00000000;
+ break;
+
+ default:
+ // Handle special cases
+ if (Pci->Flag & EPCI_R && AlignedReg < 0x40) {
+
+ // Embedded PCI device: read its h/w PCI configuration space
+ Data = Read_EPCI(AlignedReg);
+
+ if (AlignedReg == COMMAND) {
+ // Mark device '66 MHz capable'
+ Data |= PCI_66MHZ_CAPABLE;
+ }
+ break;
+ }
+
+ Data = Pci->Value;
+
+ switch (AlignedReg) {
+
+ case COMMAND:
+ // Get device's Status
+ Data |= Get_Device_Status(Pci);
+ break;
+
+ case BAR0:
+ case BAR1:
+ case BAR2:
+ case BAR3:
+ case BAR4:
+ case BAR5:
+ // If I/O BAR, set bit 0
+ if (Pci->Flag & IO_BAR) {
+ Data |= 1;
+ }
+ break;
+
+ case CACHE_LINE:
+ Pci->LatencyTimer = Get_Latency(Pci);
+ Data = Pci->Value;
+ break;
+
+#if SUPPORT_CAPABILITIES
+ case (PCI_PM_REG+4): // 0x44
+ if (Pci->Flag & PCI_PM) {
+ Data = Handle_PCI_PM_Rd(Pci);
+ break;
+ }
+
+ case USBLEGCTLSTS:
+ if (Pci->Flag & PCI_EHCI) {
+ Data = Handle_EHCI_Rd(Pci);
+ break;
+ }
+#endif
+
+ // Thor ATA vendor-specific registers:
+ case IDE_CFG: // 0x40
+ case IDE_DTC: // 0x48
+ case IDE_CAST: // 0x4C
+ case IDE_ETC: // 0x50
+ if (Pci->LBar) {
+ ULONG MsrAddr = ATA_Error;
+
+ (USHORT)MsrAddr = (USHORT)Pci->LBar;
+ Data = Read_MSR_LO(MsrAddr);
+ }
+ break;
+
+ }
+ }
+
+
+ // Handle non-dword aligned accesses
+ Data >>= Shift;
+ Data |= 0xFFFFFFFFL << (32-Shift);
+
+ return Data;
+}
+
+
+