Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / evb64260 / memory.c
1 /* 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 *********************************************************************/
20 static 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
36 unsigned 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 *********************************************************************/
55 static 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
73 unsigned 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 *********************************************************************/
96 unsigned 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)
106         size=0;
107     else
108         size = highValue - base;
109     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 *********************************************************************/
120 unsigned 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     {
130         size = (~base) + 1;     /* what the heck is this? */
131         return size;
132     }
133     else
134         highValue = (highValue + 1) << 20;
135
136     if(base > highValue)
137         size=0;
138     else
139         size = highValue - base;
140     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 *********************************************************************/
153 unsigned 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     {
162         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;
172     }
173 }
174
175 bool 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 }
201 bool 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 *********************************************************************/
230 bool 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 *********************************************************************/
249 unsigned 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 *********************************************************************/
267 bool memorySetProtectRegion(MEMORY_PROTECT_REGION region,
268                             MEMORY_ACCESS memAccess,
269                             MEMORY_ACCESS_WRITE memWrite,
270                             MEMORY_CACHE_PROTECT cacheProtection,
271                             unsigned int baseAddress,
272                             unsigned int regionLength)
273 {
274     unsigned int protectHigh = baseAddress + regionLength;
275
276     if(regionLength == 0) /* closing the region */
277     {
278         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;
281     }
282     baseAddress =  (baseAddress & 0xfff00000) >> 20;
283     baseAddress = baseAddress | memAccess << 16 |  memWrite << 17
284                      | cacheProtection << 18;
285     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 *********************************************************************/
306 bool memorySetRegionSnoopMode(MEMORY_SNOOP_REGION region,
307                               MEMORY_SNOOP_TYPE snoopType,
308                               unsigned int baseAddress,
309                               unsigned int regionLength)
310 {
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) )
317         return false;
318     snoopXbaseAddress = SNOOP_BASE_ADDRESS_0 + 0x10 * region;
319     snoopXtopAddress = SNOOP_TOP_ADDRESS_0 + 0x10 * region;
320     if(regionLength == 0) /* closing the region */
321     {
322         GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
323         GT_REG_WRITE(snoopXtopAddress,0);
324         return true;
325     }
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 *********************************************************************/
342 bool 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 *********************************************************************/
360 bool 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:
388         deviceParam -> deviceWidth = 1;         /* one Byte - 8-bit */
389         break;
390     case 1:
391         deviceParam -> deviceWidth = 2;         /* two Bytes - 16-bit */
392         break;
393     case 2:
394         deviceParam -> deviceWidth = 4;         /* four Bytes - 32-bit */
395         break;
396     case 3:
397         deviceParam -> deviceWidth = 8;         /* eight Bytes - 64-bit */
398         break;
399     default:
400         deviceParam -> deviceWidth = 1;
401         break;
402     }
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 *********************************************************************/
416 bool 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) ||
422         (deviceParam -> wrLow >= 0xf) || (deviceParam -> wrHigh >= 0xf))
423         return false;
424     valueForReg = (((deviceParam -> turnOff) & 0x7) |
425                    (((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));
436     /* insert the device width: */
437     switch(deviceParam->deviceWidth)
438     {
439     case 1:
440         valueForReg = valueForReg | _8BIT;
441         break;
442     case 2:
443         valueForReg = valueForReg | _16BIT;
444         break;
445     case 4:
446         valueForReg = valueForReg | _32BIT;
447         break;
448     case 8:
449         valueForReg = valueForReg | _64BIT;
450         break;
451     default:
452         valueForReg = valueForReg | _8BIT;
453         break;
454     }
455     GT_REG_WRITE(DEVICE_BANK0PARAMETERS + 4 * deviceNum, valueForReg);
456     return true;
457 }