/** @file | |
The interface layer for memory controller access. | |
It is supporting both real hardware platform and simulation environment. | |
Copyright (c) 2013-2015 Intel Corporation. | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#include "mrc.h" | |
#include "memory_options.h" | |
#include "meminit_utils.h" | |
#include "io.h" | |
#ifdef SIM | |
void SimMmio32Write ( | |
uint32_t be, | |
uint32_t address, | |
uint32_t data ); | |
void SimMmio32Read ( | |
uint32_t be, | |
uint32_t address, | |
uint32_t *data ); | |
void SimDelayClk ( | |
uint32_t x2clk ); | |
// This is a simple delay function. | |
// It takes "nanoseconds" as a parameter. | |
void delay_n(uint32_t nanoseconds) | |
{ | |
SimDelayClk( 800*nanoseconds/1000); | |
} | |
#endif | |
/**** | |
* | |
***/ | |
uint32_t Rd32( | |
uint32_t unit, | |
uint32_t addr) | |
{ | |
uint32_t data; | |
switch (unit) | |
{ | |
case MEM: | |
case MMIO: | |
#ifdef SIM | |
SimMmio32Read( 1, addr, &data); | |
#else | |
data = *PTR32(addr); | |
#endif | |
break; | |
case MCU: | |
case HOST_BRIDGE: | |
case MEMORY_MANAGER: | |
case HTE: | |
// Handle case addr bigger than 8bit | |
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00); | |
addr &= 0x00FF; | |
pciwrite32(0, 0, 0, SB_PACKET_REG, | |
SB_COMMAND(SB_REG_READ_OPCODE, unit, addr)); | |
data = pciread32(0, 0, 0, SB_DATA_REG); | |
break; | |
case DDRPHY: | |
// Handle case addr bigger than 8bit | |
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00); | |
addr &= 0x00FF; | |
pciwrite32(0, 0, 0, SB_PACKET_REG, | |
SB_COMMAND(SB_DDRIO_REG_READ_OPCODE, unit, addr)); | |
data = pciread32(0, 0, 0, SB_DATA_REG); | |
break; | |
default: | |
DEAD_LOOP() | |
; | |
} | |
if (unit < MEM) | |
DPF(D_REGRD, "RD32 %03X %08X %08X\n", unit, addr, data); | |
return data; | |
} | |
/**** | |
* | |
***/ | |
void Wr32( | |
uint32_t unit, | |
uint32_t addr, | |
uint32_t data) | |
{ | |
if (unit < MEM) | |
DPF(D_REGWR, "WR32 %03X %08X %08X\n", unit, addr, data); | |
switch (unit) | |
{ | |
case MEM: | |
case MMIO: | |
#ifdef SIM | |
SimMmio32Write( 1, addr, data); | |
#else | |
*PTR32(addr) = data; | |
#endif | |
break; | |
case MCU: | |
case HOST_BRIDGE: | |
case MEMORY_MANAGER: | |
case HTE: | |
// Handle case addr bigger than 8bit | |
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00); | |
addr &= 0x00FF; | |
pciwrite32(0, 0, 0, SB_DATA_REG, data); | |
pciwrite32(0, 0, 0, SB_PACKET_REG, | |
SB_COMMAND(SB_REG_WRITE_OPCODE, unit, addr)); | |
break; | |
case DDRPHY: | |
// Handle case addr bigger than 8bit | |
pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00); | |
addr &= 0x00FF; | |
pciwrite32(0, 0, 0, SB_DATA_REG, data); | |
pciwrite32(0, 0, 0, SB_PACKET_REG, | |
SB_COMMAND(SB_DDRIO_REG_WRITE_OPCODE, unit, addr)); | |
break; | |
case DCMD: | |
pciwrite32(0, 0, 0, SB_HADR_REG, 0); | |
pciwrite32(0, 0, 0, SB_DATA_REG, data); | |
pciwrite32(0, 0, 0, SB_PACKET_REG, | |
SB_COMMAND(SB_DRAM_CMND_OPCODE, MCU, 0)); | |
break; | |
default: | |
DEAD_LOOP() | |
; | |
} | |
} | |
/**** | |
* | |
***/ | |
void WrMask32( | |
uint32_t unit, | |
uint32_t addr, | |
uint32_t data, | |
uint32_t mask) | |
{ | |
Wr32(unit, addr, ((Rd32(unit, addr) & ~mask) | (data & mask))); | |
} | |
/**** | |
* | |
***/ | |
void pciwrite32( | |
uint32_t bus, | |
uint32_t dev, | |
uint32_t fn, | |
uint32_t reg, | |
uint32_t data) | |
{ | |
Wr32(MMIO, PCIADDR(bus,dev,fn,reg), data); | |
} | |
/**** | |
* | |
***/ | |
uint32_t pciread32( | |
uint32_t bus, | |
uint32_t dev, | |
uint32_t fn, | |
uint32_t reg) | |
{ | |
return Rd32(MMIO, PCIADDR(bus,dev,fn,reg)); | |
} | |