memory.c 15 KB

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