837e964854
* add the ag9064 platform Signed-off-by: hans <hans.tseng@deltaww.com>
637 lines
15 KiB
C
637 lines
15 KiB
C
|
|
#include "i2c-mei_rw.h"
|
|
|
|
|
|
/* ========== IoLibGcc.c ========= */
|
|
|
|
/**
|
|
Reads an 8-bit I/O port.
|
|
|
|
Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
|
|
This function must guarantee that all I/O read and write operations are
|
|
serialized.
|
|
|
|
If 8-bit I/O port operations are not supported, then ASSERT().
|
|
|
|
@param Port The I/O port to read.
|
|
|
|
@return The value read.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT8
|
|
IoRead8 (
|
|
IN UINTN Port
|
|
)
|
|
{
|
|
UINT8 Data;
|
|
|
|
__asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
|
|
return Data;
|
|
}
|
|
|
|
/**
|
|
Writes an 8-bit I/O port.
|
|
|
|
Writes the 8-bit I/O port specified by Port with the value specified by Value
|
|
and returns Value. This function must guarantee that all I/O read and write
|
|
operations are serialized.
|
|
|
|
If 8-bit I/O port operations are not supported, then ASSERT().
|
|
|
|
@param Port The I/O port to write.
|
|
@param Value The value to write to the I/O port.
|
|
|
|
@return The value written the I/O port.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT8
|
|
IoWrite8 (
|
|
IN UINTN Port,
|
|
IN UINT8 Value
|
|
)
|
|
{
|
|
__asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
|
|
return Value;;
|
|
}
|
|
|
|
/**
|
|
Reads a 16-bit I/O port.
|
|
|
|
Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
|
|
This function must guarantee that all I/O read and write operations are
|
|
serialized.
|
|
|
|
If 16-bit I/O port operations are not supported, then ASSERT().
|
|
If Port is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
@param Port The I/O port to read.
|
|
|
|
@return The value read.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT16
|
|
IoRead16 (
|
|
IN UINTN Port
|
|
)
|
|
{
|
|
UINT16 Data;
|
|
|
|
if((Port & 1) != 0)
|
|
printk("Failed\n");
|
|
__asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
|
|
return Data;
|
|
}
|
|
|
|
/**
|
|
Writes a 16-bit I/O port.
|
|
|
|
Writes the 16-bit I/O port specified by Port with the value specified by Value
|
|
and returns Value. This function must guarantee that all I/O read and write
|
|
operations are serialized.
|
|
|
|
If 16-bit I/O port operations are not supported, then ASSERT().
|
|
If Port is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
@param Port The I/O port to write.
|
|
@param Value The value to write to the I/O port.
|
|
|
|
@return The value written the I/O port.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT16
|
|
IoWrite16 (
|
|
IN UINTN Port,
|
|
IN UINT16 Value
|
|
)
|
|
{
|
|
if((Port & 1) != 0)
|
|
printk("Failed\n");
|
|
__asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
|
|
return Value;;
|
|
}
|
|
|
|
/**
|
|
Reads a 32-bit I/O port.
|
|
|
|
Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
|
|
This function must guarantee that all I/O read and write operations are
|
|
serialized.
|
|
|
|
If 32-bit I/O port operations are not supported, then ASSERT().
|
|
If Port is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
@param Port The I/O port to read.
|
|
|
|
@return The value read.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT32
|
|
IoRead32 (
|
|
IN UINTN Port
|
|
)
|
|
{
|
|
UINT32 Data;
|
|
|
|
if((Port & 3) != 0)
|
|
printk("Failed\n");
|
|
__asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
|
|
return Data;
|
|
}
|
|
|
|
/**
|
|
Writes a 32-bit I/O port.
|
|
|
|
Writes the 32-bit I/O port specified by Port with the value specified by Value
|
|
and returns Value. This function must guarantee that all I/O read and write
|
|
operations are serialized.
|
|
|
|
If 32-bit I/O port operations are not supported, then ASSERT().
|
|
If Port is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
@param Port The I/O port to write.
|
|
@param Value The value to write to the I/O port.
|
|
|
|
@return The value written the I/O port.
|
|
|
|
**/
|
|
//__inline__
|
|
UINT32
|
|
IoWrite32 (
|
|
IN UINTN Port,
|
|
IN UINT32 Value
|
|
)
|
|
{
|
|
if((Port & 3) != 0)
|
|
printk("Failed\n");
|
|
__asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
|
|
return Value;
|
|
}
|
|
|
|
|
|
|
|
/* ========== GccInline.c ========= */
|
|
|
|
/**
|
|
Enables CPU interrupts.
|
|
|
|
Enables CPU interrupts.
|
|
|
|
**/
|
|
VOID
|
|
EnableInterrupts (
|
|
VOID
|
|
)
|
|
{
|
|
__asm__ __volatile__ ("sti"::: "memory");
|
|
}
|
|
|
|
/**
|
|
Disables CPU interrupts.
|
|
|
|
Disables CPU interrupts.
|
|
|
|
**/
|
|
VOID
|
|
DisableInterrupts (
|
|
VOID
|
|
)
|
|
{
|
|
__asm__ __volatile__ ("cli"::: "memory");
|
|
}
|
|
|
|
/**
|
|
Reads the current value of the EFLAGS register.
|
|
|
|
Reads and returns the current value of the EFLAGS register. This function is
|
|
only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
|
|
64-bit value on X64.
|
|
|
|
@return EFLAGS on IA-32 or RFLAGS on X64.
|
|
|
|
**/
|
|
UINTN
|
|
AsmReadEflags (
|
|
VOID
|
|
)
|
|
{
|
|
UINTN Eflags;
|
|
|
|
__asm__ __volatile__ (
|
|
"pushfq \n\t"
|
|
"pop %0 "
|
|
: "=r" (Eflags) // %0
|
|
);
|
|
|
|
return Eflags;
|
|
}
|
|
|
|
|
|
|
|
/* ========== X86GetInterruptState.c ========= */
|
|
|
|
/**
|
|
Retrieves the current CPU interrupt state.
|
|
|
|
Returns TRUE is interrupts are currently enabled. Otherwise
|
|
returns FALSE.
|
|
|
|
@retval TRUE CPU interrupts are enabled.
|
|
@retval FALSE CPU interrupts are disabled.
|
|
|
|
**/
|
|
BOOLEAN
|
|
GetInterruptState (
|
|
VOID
|
|
)
|
|
{
|
|
IA32_EFLAGS32 EFlags;
|
|
|
|
EFlags.UintN = AsmReadEflags ();
|
|
return (BOOLEAN)(1 == EFlags.Bits.IF);
|
|
}
|
|
|
|
|
|
|
|
/* ========== Cpu.c ========= */
|
|
|
|
/**
|
|
Disables CPU interrupts and returns the interrupt state prior to the disable
|
|
operation.
|
|
|
|
@retval TRUE CPU interrupts were enabled on entry to this call.
|
|
@retval FALSE CPU interrupts were disabled on entry to this call.
|
|
|
|
**/
|
|
BOOLEAN
|
|
SaveAndDisableInterrupts (
|
|
VOID
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
|
|
InterruptState = GetInterruptState ();
|
|
DisableInterrupts ();
|
|
return InterruptState;
|
|
}
|
|
|
|
/**
|
|
Set the current CPU interrupt state.
|
|
|
|
Sets the current CPU interrupt state to the state specified by
|
|
InterruptState. If InterruptState is TRUE, then interrupts are enabled. If
|
|
InterruptState is FALSE, then interrupts are disabled. InterruptState is
|
|
returned.
|
|
|
|
@param InterruptState TRUE if interrupts should be enabled. FALSE if
|
|
interrupts should be disabled.
|
|
|
|
@return InterruptState
|
|
|
|
**/
|
|
BOOLEAN
|
|
SetInterruptState (
|
|
IN BOOLEAN InterruptState
|
|
)
|
|
{
|
|
if (InterruptState) {
|
|
EnableInterrupts ();
|
|
} else {
|
|
DisableInterrupts ();
|
|
}
|
|
return InterruptState;
|
|
}
|
|
|
|
|
|
|
|
/* ========== pciLib.c ========= */
|
|
|
|
//
|
|
// Declare I/O Ports used to perform PCI Confguration Cycles
|
|
//
|
|
#define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
|
|
#define PCI_CONFIGURATION_DATA_PORT 0xCFC
|
|
|
|
/**
|
|
Convert a PCI Library address to PCI CF8 formatted address.
|
|
|
|
Declare macro to convert PCI Library address to PCI CF8 formatted address.
|
|
Bit fields of PCI Library and CF8 formatted address is as follows:
|
|
PCI Library formatted address CF8 Formatted Address
|
|
============================= ======================
|
|
Bits 00..11 Register Bits 00..07 Register
|
|
Bits 12..14 Function Bits 08..10 Function
|
|
Bits 15..19 Device Bits 11..15 Device
|
|
Bits 20..27 Bus Bits 16..23 Bus
|
|
Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
|
|
Bits 31..31 Must be 1
|
|
|
|
@param A The address to convert.
|
|
|
|
@retval The coverted address.
|
|
|
|
**/
|
|
#define PCI_TO_CF8_ADDRESS(A) \
|
|
((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
|
|
|
|
/**
|
|
Reads an 8-bit PCI configuration register.
|
|
|
|
Reads and returns the 8-bit PCI configuration register specified by Address.
|
|
This function must guarantee that all PCI read and write operations are
|
|
serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
|
|
@return The read value from the PCI configuration register.
|
|
|
|
**/
|
|
UINT8
|
|
PciCf8Read8 (
|
|
IN UINTN Address
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT8 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
Writes an 8-bit PCI configuration register.
|
|
|
|
Writes the 8-bit PCI configuration register specified by Address with the
|
|
value specified by Value. Value is returned. This function must guarantee
|
|
that all PCI read and write operations are serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
@param Value The value to write.
|
|
|
|
@return The value written to the PCI configuration register.
|
|
|
|
**/
|
|
UINT8
|
|
PciCf8Write8 (
|
|
IN UINTN Address,
|
|
IN UINT8 Value
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT8 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoWrite8 (
|
|
PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
|
|
Value
|
|
);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
Reads a 16-bit PCI configuration register.
|
|
|
|
Reads and returns the 16-bit PCI configuration register specified by Address.
|
|
This function must guarantee that all PCI read and write operations are
|
|
serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If Address is not aligned on a 16-bit boundary, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
|
|
@return The read value from the PCI configuration register.
|
|
|
|
**/
|
|
UINT16
|
|
PciCf8Read16 (
|
|
IN UINTN Address
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT16 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
Writes a 16-bit PCI configuration register.
|
|
|
|
Writes the 16-bit PCI configuration register specified by Address with the
|
|
value specified by Value. Value is returned. This function must guarantee
|
|
that all PCI read and write operations are serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If Address is not aligned on a 16-bit boundary, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
@param Value The value to write.
|
|
|
|
@return The value written to the PCI configuration register.
|
|
|
|
**/
|
|
UINT16
|
|
PciCf8Write16 (
|
|
IN UINTN Address,
|
|
IN UINT16 Value
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT16 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoWrite16 (
|
|
PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
|
|
Value
|
|
);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
Reads a 32-bit PCI configuration register.
|
|
|
|
Reads and returns the 32-bit PCI configuration register specified by Address.
|
|
This function must guarantee that all PCI read and write operations are
|
|
serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If Address is not aligned on a 32-bit boundary, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
|
|
@return The read value from the PCI configuration register.
|
|
|
|
**/
|
|
UINT32
|
|
PciCf8Read32 (
|
|
IN UINTN Address
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT32 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
Writes a 32-bit PCI configuration register.
|
|
|
|
Writes the 32-bit PCI configuration register specified by Address with the
|
|
value specified by Value. Value is returned. This function must guarantee
|
|
that all PCI read and write operations are serialized.
|
|
|
|
If Address > 0x0FFFFFFF, then ASSERT().
|
|
If Address is not aligned on a 32-bit boundary, then ASSERT().
|
|
If the register specified by Address >= 0x100, then ASSERT().
|
|
|
|
@param Address The address that encodes the PCI Bus, Device, Function and
|
|
Register.
|
|
@param Value The value to write.
|
|
|
|
@return The value written to the PCI configuration register.
|
|
|
|
**/
|
|
UINT32
|
|
PciCf8Write32 (
|
|
IN UINTN Address,
|
|
IN UINT32 Value
|
|
)
|
|
{
|
|
BOOLEAN InterruptState;
|
|
UINT32 AddressPort;
|
|
UINT32 Result;
|
|
|
|
InterruptState = SaveAndDisableInterrupts ();
|
|
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
|
|
Result = IoWrite32 (
|
|
PCI_CONFIGURATION_DATA_PORT,
|
|
Value
|
|
);
|
|
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
|
|
SetInterruptState (InterruptState);
|
|
return Result;
|
|
}
|
|
|
|
|
|
|
|
/* ========== Other ========= */
|
|
|
|
// UINT8 PciRead8(UINT64 addr)
|
|
// {
|
|
// printf("[%s] addr: %8X.\n", __func__, addr);
|
|
// return 0x01;
|
|
// }
|
|
|
|
// UINT8 PciWrite8(UINT64 addr, UINT8 data)
|
|
// {
|
|
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
|
|
// return 0x02;
|
|
// }
|
|
|
|
|
|
// UINT16 PciRead16(UINT64 addr)
|
|
// {
|
|
// printf("[%s] addr: %8X.\n", __func__, addr);
|
|
// return 0x03;
|
|
// }
|
|
|
|
// UINT16 PciWrite16(UINT64 addr, UINT8 data)
|
|
// {
|
|
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
|
|
// return 0x04;
|
|
// }
|
|
|
|
|
|
// UINT32 PciRead32(UINT64 addr)
|
|
// {
|
|
// printf("[%s] addr: %8X.\n", __func__, addr);
|
|
// return 0x05;
|
|
// }
|
|
|
|
// UINT32 PciWrite32(UINT64 addr, UINT8 data)
|
|
// {
|
|
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
|
|
// return 0x06;
|
|
// }
|
|
|
|
UINT8 PciRead8(UINT64 addr)
|
|
{
|
|
return PciCf8Read8 (addr);
|
|
}
|
|
|
|
UINT8 PciWrite8(UINT64 addr, UINT8 data)
|
|
{
|
|
return PciCf8Write8 (addr, data);
|
|
}
|
|
|
|
|
|
UINT16 PciRead16(UINT64 addr)
|
|
{
|
|
return PciCf8Read16 (addr);
|
|
}
|
|
|
|
UINT16 PciWrite16(UINT64 addr, UINT8 data)
|
|
{
|
|
return PciCf8Write16 (addr, data);
|
|
}
|
|
|
|
|
|
UINT32 PciRead32(UINT64 addr)
|
|
{
|
|
return PciCf8Read32 (addr);
|
|
}
|
|
|
|
UINT32 PciWrite32(UINT64 addr, UINT8 data)
|
|
{
|
|
return PciCf8Write32 (addr, data);
|
|
}
|