1 /** @file
2 The interface layer for memory controller access.
3 It is supporting both real hardware platform and simulation environment.
4
5 Copyright (c) 2013-2015 Intel Corporation.
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16 #include "mrc.h"
17 #include "memory_options.h"
18 #include "meminit_utils.h"
19 #include "io.h"
20
21 #ifdef SIM
22
23 void SimMmio32Write (
24 uint32_t be,
25 uint32_t address,
26 uint32_t data );
27
28 void SimMmio32Read (
29 uint32_t be,
30 uint32_t address,
31 uint32_t *data );
32
33 void SimDelayClk (
34 uint32_t x2clk );
35
36 // This is a simple delay function.
37 // It takes "nanoseconds" as a parameter.
delay_n(uint32_t nanoseconds)38 void delay_n(uint32_t nanoseconds)
39 {
40 SimDelayClk( 800*nanoseconds/1000);
41 }
42 #endif
43
44 /****
45 *
46 ***/
Rd32(uint32_t unit,uint32_t addr)47 uint32_t Rd32(
48 uint32_t unit,
49 uint32_t addr)
50 {
51 uint32_t data;
52
53 switch (unit)
54 {
55 case MEM:
56 case MMIO:
57 #ifdef SIM
58 SimMmio32Read( 1, addr, &data);
59 #else
60 data = *PTR32(addr);
61 #endif
62 break;
63
64 case MCU:
65 case HOST_BRIDGE:
66 case MEMORY_MANAGER:
67 case HTE:
68 // Handle case addr bigger than 8bit
69 pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
70 addr &= 0x00FF;
71
72 pciwrite32(0, 0, 0, SB_PACKET_REG,
73 SB_COMMAND(SB_REG_READ_OPCODE, unit, addr));
74 data = pciread32(0, 0, 0, SB_DATA_REG);
75 break;
76
77 case DDRPHY:
78 // Handle case addr bigger than 8bit
79 pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
80 addr &= 0x00FF;
81
82 pciwrite32(0, 0, 0, SB_PACKET_REG,
83 SB_COMMAND(SB_DDRIO_REG_READ_OPCODE, unit, addr));
84 data = pciread32(0, 0, 0, SB_DATA_REG);
85 break;
86
87 default:
88 DEAD_LOOP()
89 ;
90 }
91
92 if (unit < MEM)
93 DPF(D_REGRD, "RD32 %03X %08X %08X\n", unit, addr, data);
94
95 return data;
96 }
97
98 /****
99 *
100 ***/
Wr32(uint32_t unit,uint32_t addr,uint32_t data)101 void Wr32(
102 uint32_t unit,
103 uint32_t addr,
104 uint32_t data)
105 {
106 if (unit < MEM)
107 DPF(D_REGWR, "WR32 %03X %08X %08X\n", unit, addr, data);
108
109 switch (unit)
110 {
111 case MEM:
112 case MMIO:
113 #ifdef SIM
114 SimMmio32Write( 1, addr, data);
115 #else
116 *PTR32(addr) = data;
117 #endif
118 break;
119
120 case MCU:
121 case HOST_BRIDGE:
122 case MEMORY_MANAGER:
123 case HTE:
124 // Handle case addr bigger than 8bit
125 pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
126 addr &= 0x00FF;
127
128 pciwrite32(0, 0, 0, SB_DATA_REG, data);
129 pciwrite32(0, 0, 0, SB_PACKET_REG,
130 SB_COMMAND(SB_REG_WRITE_OPCODE, unit, addr));
131 break;
132
133 case DDRPHY:
134 // Handle case addr bigger than 8bit
135 pciwrite32(0, 0, 0, SB_HADR_REG, addr & 0xFFF00);
136 addr &= 0x00FF;
137
138 pciwrite32(0, 0, 0, SB_DATA_REG, data);
139 pciwrite32(0, 0, 0, SB_PACKET_REG,
140 SB_COMMAND(SB_DDRIO_REG_WRITE_OPCODE, unit, addr));
141 break;
142
143 case DCMD:
144 pciwrite32(0, 0, 0, SB_HADR_REG, 0);
145 pciwrite32(0, 0, 0, SB_DATA_REG, data);
146 pciwrite32(0, 0, 0, SB_PACKET_REG,
147 SB_COMMAND(SB_DRAM_CMND_OPCODE, MCU, 0));
148 break;
149
150 default:
151 DEAD_LOOP()
152 ;
153 }
154 }
155
156 /****
157 *
158 ***/
WrMask32(uint32_t unit,uint32_t addr,uint32_t data,uint32_t mask)159 void WrMask32(
160 uint32_t unit,
161 uint32_t addr,
162 uint32_t data,
163 uint32_t mask)
164 {
165 Wr32(unit, addr, ((Rd32(unit, addr) & ~mask) | (data & mask)));
166 }
167
168 /****
169 *
170 ***/
pciwrite32(uint32_t bus,uint32_t dev,uint32_t fn,uint32_t reg,uint32_t data)171 void pciwrite32(
172 uint32_t bus,
173 uint32_t dev,
174 uint32_t fn,
175 uint32_t reg,
176 uint32_t data)
177 {
178 Wr32(MMIO, PCIADDR(bus,dev,fn,reg), data);
179 }
180
181 /****
182 *
183 ***/
pciread32(uint32_t bus,uint32_t dev,uint32_t fn,uint32_t reg)184 uint32_t pciread32(
185 uint32_t bus,
186 uint32_t dev,
187 uint32_t fn,
188 uint32_t reg)
189 {
190 return Rd32(MMIO, PCIADDR(bus,dev,fn,reg));
191 }
192
193