uboot/board/evb64260/memory.c
<<
>>
Prefs
   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*********************************************************************/
  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)
 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*********************************************************************/
 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    {
 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*********************************************************************/
 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    {
 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
 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,
 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*********************************************************************/
 306bool 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*********************************************************************/
 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:
 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*********************************************************************/
 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) ||
 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}
 458