blob: e339854453ce5ebd5f76d17e2951ada987dc6678 [file] [log] [blame]
wdenk7ebf7442002-11-02 23:17:16 +00001/* Memory.c - Memory mappings and remapping functions */
2
3/* Copyright - Galileo technology. */
4
5/* modified by Josh Huber to clean some things up, and
6 * fit it into the U-Boot framework */
7
8#include <galileo/core.h>
9#include <galileo/memory.h>
10
11/********************************************************************
12* memoryGetBankBaseAddress - Gets the base address of a memory bank
13* - If the memory bank size is 0 then this base address has no meaning!!!
14*
15*
16* INPUTS: MEMORY_BANK bank - The bank we ask for its base Address.
17* OUTPUT: N/A
18* RETURNS: Memory bank base address.
19*********************************************************************/
20static unsigned long memoryGetBankRegOffset(MEMORY_BANK bank)
21{
22 switch (bank)
23 {
24 case BANK0:
25 return SCS_0_LOW_DECODE_ADDRESS;
26 case BANK1:
27 return SCS_1_LOW_DECODE_ADDRESS;
28 case BANK2:
29 return SCS_2_LOW_DECODE_ADDRESS;
30 case BANK3:
31 return SCS_3_LOW_DECODE_ADDRESS;
32 }
33 return SCS_0_LOW_DECODE_ADDRESS; /* default value */
34}
35
36unsigned int memoryGetBankBaseAddress(MEMORY_BANK bank)
37{
38 unsigned int base;
39 unsigned int regOffset=memoryGetBankRegOffset(bank);
40
41 GT_REG_READ(regOffset,&base);
42 base = base << 20;
43 return base;
44}
45
46/********************************************************************
47* memoryGetDeviceBaseAddress - Gets the base address of a device.
48* - If the device size is 0 then this base address has no meaning!!!
49*
50*
51* INPUT: DEVICE device - The device we ask for its base address.
52* OUTPUT: N/A
53* RETURNS: Device base address.
54*********************************************************************/
55static unsigned int memoryGetDeviceRegOffset(DEVICE device)
56{
57 switch (device)
58 {
59 case DEVICE0:
60 return CS_0_LOW_DECODE_ADDRESS;
61 case DEVICE1:
62 return CS_1_LOW_DECODE_ADDRESS;
63 case DEVICE2:
64 return CS_2_LOW_DECODE_ADDRESS;
65 case DEVICE3:
66 return CS_3_LOW_DECODE_ADDRESS;
67 case BOOT_DEVICE:
68 return BOOTCS_LOW_DECODE_ADDRESS;
69 }
70 return CS_0_LOW_DECODE_ADDRESS; /* default value */
71}
72
73unsigned int memoryGetDeviceBaseAddress(DEVICE device)
74{
75 unsigned int regBase;
76 unsigned int regEnd;
77 unsigned int regOffset=memoryGetDeviceRegOffset(device);
78
79 GT_REG_READ(regOffset, &regBase);
80 GT_REG_READ(regOffset+8, &regEnd);
81
82 if(regEnd<=regBase) return 0xffffffff; /* ERROR !!! */
83
84 regBase = regBase << 20;
85 return regBase;
86}
87
88/********************************************************************
89* memoryGetBankSize - Returns the size of a memory bank.
90*
91*
92* INPUT: MEMORY_BANK bank - The bank we ask for its size.
93* OUTPUT: N/A
94* RETURNS: Memory bank size.
95*********************************************************************/
96unsigned int memoryGetBankSize(MEMORY_BANK bank)
97{
98 unsigned int size,base;
99 unsigned int highValue;
100 unsigned int highAddress=memoryGetBankRegOffset(bank)+8;
101
102 base = memoryGetBankBaseAddress(bank);
103 GT_REG_READ(highAddress,&highValue);
104 highValue = (highValue + 1) << 20;
105 if(base > highValue)
wdenk8bde7f72003-06-27 21:31:46 +0000106 size=0;
wdenk7ebf7442002-11-02 23:17:16 +0000107 else
wdenk8bde7f72003-06-27 21:31:46 +0000108 size = highValue - base;
wdenk7ebf7442002-11-02 23:17:16 +0000109 return size;
110}
111
112/********************************************************************
113* memoryGetDeviceSize - Returns the size of a device memory space
114*
115*
116* INPUT: DEVICE device - The device we ask for its base address.
117* OUTPUT: N/A
118* RETURNS: Size of a device memory space.
119*********************************************************************/
120unsigned int memoryGetDeviceSize(DEVICE device)
121{
122 unsigned int size,base;
123 unsigned int highValue;
124 unsigned int highAddress=memoryGetDeviceRegOffset(device)+8;
125
126 base = memoryGetDeviceBaseAddress(device);
127 GT_REG_READ(highAddress,&highValue);
128 if (highValue == 0xfff)
129 {
wdenk8bde7f72003-06-27 21:31:46 +0000130 size = (~base) + 1; /* what the heck is this? */
131 return size;
wdenk7ebf7442002-11-02 23:17:16 +0000132 }
133 else
wdenk8bde7f72003-06-27 21:31:46 +0000134 highValue = (highValue + 1) << 20;
wdenk7ebf7442002-11-02 23:17:16 +0000135
136 if(base > highValue)
wdenk8bde7f72003-06-27 21:31:46 +0000137 size=0;
wdenk7ebf7442002-11-02 23:17:16 +0000138 else
wdenk8bde7f72003-06-27 21:31:46 +0000139 size = highValue - base;
wdenk7ebf7442002-11-02 23:17:16 +0000140 return size;
141}
142
143/********************************************************************
144* memoryGetDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width.
145* The width is determine in registers: 'Device Parameters'
146* registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device.
147* at bits: [21:20].
148*
149* INPUT: DEVICE device - Device number
150* OUTPUT: N/A
151* RETURNS: Device width in Bytes (1,2,4 or 8), 0 if error had occurred.
152*********************************************************************/
153unsigned int memoryGetDeviceWidth(DEVICE device)
154{
155 unsigned int width;
156 unsigned int regValue;
157
158 GT_REG_READ(DEVICE_BANK0PARAMETERS + device*4,&regValue);
159 width = (regValue & 0x00300000) >> 20;
160 switch (width)
161 {
wdenk8bde7f72003-06-27 21:31:46 +0000162 case 0:
163 return 1;
164 case 1:
165 return 2;
166 case 2:
167 return 4;
168 case 3:
169 return 8;
170 default:
171 return 0;
wdenk7ebf7442002-11-02 23:17:16 +0000172 }
173}
174
175bool memoryMapBank(MEMORY_BANK bank, unsigned int bankBase,unsigned int bankLength)
176{
177 unsigned int low=0xfff;
178 unsigned int high=0x0;
179 unsigned int regOffset=memoryGetBankRegOffset(bank);
180
181 if(bankLength!=0) {
182 low = (bankBase >> 20) & 0xffff;
183 high=((bankBase+bankLength)>>20)-1;
184 }
185
186#ifdef DEBUG
187 {
188 unsigned int oldLow, oldHigh;
189 GT_REG_READ(regOffset,&oldLow);
190 GT_REG_READ(regOffset+8,&oldHigh);
191
192 printf("b%d %x-%x->%x-%x\n", bank, oldLow, oldHigh, low, high);
193 }
194#endif
195
196 GT_REG_WRITE(regOffset,low);
197 GT_REG_WRITE(regOffset+8,high);
198
199 return true;
200}
201bool memoryMapDeviceSpace(DEVICE device, unsigned int deviceBase,unsigned int deviceLength)
202{
203 /* TODO: what are appropriate "unmapped" values? */
204 unsigned int low=0xfff;
205 unsigned int high=0x0;
206 unsigned int regOffset=memoryGetDeviceRegOffset(device);
207
208 if(deviceLength != 0) {
209 low=deviceBase>>20;
210 high=((deviceBase+deviceLength)>>20)-1;
211 } else {
212 /* big problems in here... */
213 /* this will HANG */
214 }
215
216 GT_REG_WRITE(regOffset,low);
217 GT_REG_WRITE(regOffset+8,high);
218
219 return true;
220}
221
222
223/********************************************************************
224* memoryMapInternalRegistersSpace - Sets new base address for the internals
225* registers.
226*
227* INPUTS: unsigned int internalRegBase - The new base address.
228* RETURNS: true on success, false on failure
229*********************************************************************/
230bool memoryMapInternalRegistersSpace(unsigned int internalRegBase)
231{
232 unsigned int currentValue;
233 unsigned int internalValue = internalRegBase;
234
235 internalRegBase = (internalRegBase >> 20);
236 GT_REG_READ(INTERNAL_SPACE_DECODE,&currentValue);
237 internalRegBase = (currentValue & 0xffff0000) | internalRegBase;
238 GT_REG_WRITE(INTERNAL_SPACE_DECODE,internalRegBase);
239 INTERNAL_REG_BASE_ADDR = internalValue;
240 return true;
241}
242
243/********************************************************************
244* memoryGetInternalRegistersSpace - Gets internal registers Base Address.
245*
246* INPUTS: unsigned int internalRegBase - The new base address.
247* RETURNS: true on success, false on failure
248*********************************************************************/
249unsigned int memoryGetInternalRegistersSpace(void)
250{
251 return INTERNAL_REG_BASE_ADDR;
252}
253
254/********************************************************************
255* memorySetProtectRegion - This function modifys one of the 8 regions with
256* one of the three protection mode.
257* - Be advised to check the spec before modifying them.
258*
259*
260* Inputs: CPU_PROTECT_REGION - one of the eight regions.
261* CPU_ACCESS - general access.
262* CPU_WRITE - read only access.
263* CPU_CACHE_PROTECT - chache access.
264* we defining CPU because there is another protect from the pci SIDE.
265* Returns: false if one of the parameters is wrong and true else
266*********************************************************************/
267bool memorySetProtectRegion(MEMORY_PROTECT_REGION region,
wdenk8bde7f72003-06-27 21:31:46 +0000268 MEMORY_ACCESS memAccess,
269 MEMORY_ACCESS_WRITE memWrite,
270 MEMORY_CACHE_PROTECT cacheProtection,
271 unsigned int baseAddress,
272 unsigned int regionLength)
wdenk7ebf7442002-11-02 23:17:16 +0000273{
274 unsigned int protectHigh = baseAddress + regionLength;
275
276 if(regionLength == 0) /* closing the region */
277 {
wdenk8bde7f72003-06-27 21:31:46 +0000278 GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,0x0000ffff);
279 GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,0);
280 return true;
wdenk7ebf7442002-11-02 23:17:16 +0000281 }
282 baseAddress = (baseAddress & 0xfff00000) >> 20;
283 baseAddress = baseAddress | memAccess << 16 | memWrite << 17
wdenk8bde7f72003-06-27 21:31:46 +0000284 | cacheProtection << 18;
wdenk7ebf7442002-11-02 23:17:16 +0000285 GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,baseAddress);
286 protectHigh = (protectHigh & 0xfff00000) >> 20;
287 GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,protectHigh - 1);
288 return true;
289}
290
291/********************************************************************
292* memorySetRegionSnoopMode - This function modifys one of the 4 regions which
293* supports Cache Coherency.
294*
295*
296* Inputs: SNOOP_REGION region - One of the four regions.
297* SNOOP_TYPE snoopType - There is four optional Types:
298* 1. No Snoop.
299* 2. Snoop to WT region.
300* 3. Snoop to WB region.
301* 4. Snoop & Invalidate to WB region.
302* unsigned int baseAddress - Base Address of this region.
303* unsigned int topAddress - Top Address of this region.
304* Returns: false if one of the parameters is wrong and true else
305*********************************************************************/
306bool memorySetRegionSnoopMode(MEMORY_SNOOP_REGION region,
wdenk8bde7f72003-06-27 21:31:46 +0000307 MEMORY_SNOOP_TYPE snoopType,
308 unsigned int baseAddress,
309 unsigned int regionLength)
wdenk7ebf7442002-11-02 23:17:16 +0000310{
311 unsigned int snoopXbaseAddress;
312 unsigned int snoopXtopAddress;
313 unsigned int data;
314 unsigned int snoopHigh = baseAddress + regionLength;
315
316 if( (region > MEM_SNOOP_REGION3) || (snoopType > MEM_SNOOP_WB) )
wdenk8bde7f72003-06-27 21:31:46 +0000317 return false;
wdenk7ebf7442002-11-02 23:17:16 +0000318 snoopXbaseAddress = SNOOP_BASE_ADDRESS_0 + 0x10 * region;
319 snoopXtopAddress = SNOOP_TOP_ADDRESS_0 + 0x10 * region;
320 if(regionLength == 0) /* closing the region */
321 {
wdenk8bde7f72003-06-27 21:31:46 +0000322 GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
323 GT_REG_WRITE(snoopXtopAddress,0);
324 return true;
wdenk7ebf7442002-11-02 23:17:16 +0000325 }
326 baseAddress = baseAddress & 0xffff0000;
327 data = (baseAddress >> 16) | snoopType << 16;
328 GT_REG_WRITE(snoopXbaseAddress,data);
329 snoopHigh = (snoopHigh & 0xfff00000) >> 20;
330 GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
331 return true;
332}
333
334/********************************************************************
335* memoryRemapAddress - This fubction used for address remapping.
336*
337*
338* Inputs: regOffset: remap register
339* remapValue :
340* Returns: false if one of the parameters is erroneous,true otherwise.
341*********************************************************************/
342bool memoryRemapAddress(unsigned int remapReg, unsigned int remapValue)
343{
344 unsigned int valueForReg;
345 valueForReg = (remapValue & 0xfff00000) >> 20;
346 GT_REG_WRITE(remapReg, valueForReg);
347 return true;
348}
349
350/********************************************************************
351* memoryGetDeviceParam - This function used for getting device parameters from
352* DEVICE BANK PARAMETERS REGISTER
353*
354*
355* Inputs: - deviceParam: STRUCT with paramiters for DEVICE BANK
356* PARAMETERS REGISTER
357* - deviceNum : number of device
358* Returns: false if one of the parameters is erroneous,true otherwise.
359*********************************************************************/
360bool memoryGetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum)
361{
362 unsigned int valueOfReg;
363 unsigned int calcData;
364
365 GT_REG_READ(DEVICE_BANK0PARAMETERS + 4 * deviceNum, &valueOfReg);
366 calcData = (0x7 & valueOfReg) + ((0x400000 & valueOfReg) >> 19);
367 deviceParam -> turnOff = calcData; /* Turn Off */
368
369 calcData = ((0x78 & valueOfReg) >> 3) + ((0x800000 & valueOfReg) >> 19);
370 deviceParam -> acc2First = calcData; /* Access To First */
371
372 calcData = ((0x780 & valueOfReg) >> 7) + ((0x1000000 & valueOfReg) >> 20);
373 deviceParam -> acc2Next = calcData; /* Access To Next */
374
375 calcData = ((0x3800 & valueOfReg) >> 11) + ((0x2000000 & valueOfReg) >> 22);
376 deviceParam -> ale2Wr = calcData; /* Ale To Write */
377
378 calcData = ((0x1c000 & valueOfReg) >> 14) + ((0x4000000 & valueOfReg) >> 23);
379 deviceParam -> wrLow = calcData; /* Write Active */
380
381 calcData = ((0xe0000 & valueOfReg) >> 17) + ((0x8000000 & valueOfReg) >> 24);
382 deviceParam -> wrHigh = calcData; /* Write High */
383
384 calcData = ((0x300000 & valueOfReg) >> 20);
385 switch (calcData)
386 {
387 case 0:
wdenk8bde7f72003-06-27 21:31:46 +0000388 deviceParam -> deviceWidth = 1; /* one Byte - 8-bit */
389 break;
wdenk7ebf7442002-11-02 23:17:16 +0000390 case 1:
wdenk8bde7f72003-06-27 21:31:46 +0000391 deviceParam -> deviceWidth = 2; /* two Bytes - 16-bit */
392 break;
wdenk7ebf7442002-11-02 23:17:16 +0000393 case 2:
wdenk8bde7f72003-06-27 21:31:46 +0000394 deviceParam -> deviceWidth = 4; /* four Bytes - 32-bit */
395 break;
wdenk7ebf7442002-11-02 23:17:16 +0000396 case 3:
wdenk8bde7f72003-06-27 21:31:46 +0000397 deviceParam -> deviceWidth = 8; /* eight Bytes - 64-bit */
398 break;
wdenk7ebf7442002-11-02 23:17:16 +0000399 default:
wdenk8bde7f72003-06-27 21:31:46 +0000400 deviceParam -> deviceWidth = 1;
401 break;
wdenk7ebf7442002-11-02 23:17:16 +0000402 }
403 return true;
404}
405
406/********************************************************************
407* memorySetDeviceParam - This function used for setting device parameters to
408* DEVICE BANK PARAMETERS REGISTER
409*
410*
411* Inputs: - deviceParam: STRUCT for store paramiters from DEVICE BANK
412* PARAMETERS REGISTER
413* - deviceNum : number of device
414* Returns: false if one of the parameters is erroneous,true otherwise.
415*********************************************************************/
416bool memorySetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum)
417{
418 unsigned int valueForReg;
419
420 if((deviceParam -> turnOff >= 0xf) || (deviceParam -> acc2First >= 0x1f) ||
421 (deviceParam -> acc2Next >= 0x1f) || (deviceParam -> ale2Wr >= 0xf) ||
wdenk8bde7f72003-06-27 21:31:46 +0000422 (deviceParam -> wrLow >= 0xf) || (deviceParam -> wrHigh >= 0xf))
423 return false;
wdenk7ebf7442002-11-02 23:17:16 +0000424 valueForReg = (((deviceParam -> turnOff) & 0x7) |
wdenk8bde7f72003-06-27 21:31:46 +0000425 (((deviceParam -> turnOff) & 0x8) << 19) |
426 (((deviceParam -> acc2First) & 0xf) << 3) |
427 (((deviceParam -> acc2First) & 0x10) << 19) |
428 (((deviceParam -> acc2Next) & 0xf) << 7) |
429 (((deviceParam -> acc2Next) & 0x10) << 20) |
430 (((deviceParam -> ale2Wr) & 0x7) << 11) |
431 (((deviceParam -> ale2Wr) & 0xf) << 22) |
432 (((deviceParam -> wrLow) & 0x7) << 14) |
433 (((deviceParam -> wrLow) & 0xf) << 23) |
434 (((deviceParam -> wrHigh) & 0x7) << 17) |
435 (((deviceParam -> wrHigh) & 0xf) << 24));
wdenk7ebf7442002-11-02 23:17:16 +0000436 /* insert the device width: */
437 switch(deviceParam->deviceWidth)
438 {
439 case 1:
wdenk8bde7f72003-06-27 21:31:46 +0000440 valueForReg = valueForReg | _8BIT;
441 break;
wdenk7ebf7442002-11-02 23:17:16 +0000442 case 2:
wdenk8bde7f72003-06-27 21:31:46 +0000443 valueForReg = valueForReg | _16BIT;
444 break;
wdenk7ebf7442002-11-02 23:17:16 +0000445 case 4:
wdenk8bde7f72003-06-27 21:31:46 +0000446 valueForReg = valueForReg | _32BIT;
447 break;
wdenk7ebf7442002-11-02 23:17:16 +0000448 case 8:
wdenk8bde7f72003-06-27 21:31:46 +0000449 valueForReg = valueForReg | _64BIT;
450 break;
wdenk7ebf7442002-11-02 23:17:16 +0000451 default:
wdenk8bde7f72003-06-27 21:31:46 +0000452 valueForReg = valueForReg | _8BIT;
453 break;
wdenk7ebf7442002-11-02 23:17:16 +0000454 }
455 GT_REG_WRITE(DEVICE_BANK0PARAMETERS + 4 * deviceNum, valueForReg);
456 return true;
457}