blob: 0c5b99b7e23478f21887029870d3a3e400d1726e [file] [log] [blame]
#include "BootLoader.h"
#include "loadoffsets.h"
/* section attributes */
#define NORMAL_OIWBWT 0x00001C0E
#define NORMAL_OINCNB 0x00001C02
#define SHAREABLE_DEV 0x00000C06
/* small page attributes */
#define SP_NORMAL_OIWBWT 0x0000007E
#define SP_NORMAL_OINCNB 0x00000036
#define DDR_ADDR 0x00000000
#define DDR_SIZE 0x20000000 /* 512MB, big enough for most platforms */
#define SQU_ADDR 0xD1000000
#define SQU_SIZE 0x00100000 /* actually 64KB or 128KB */
#define MCU_ADDR 0xC0000000
#define MCU_SIZE 0x10000000
#define REG_ADDR 0xD1100000
#define REG_SIZE 0x20000000
#define ROM_ADDR 0xFFE00000
#define ROM_SIZE 0x00100000 /* actually 64KB or 128KB */
#define XIP_ADDR 0x80000000
#define XIP_SIZE 0x01000000
#define PAGE_1MB 0x00100000
#define PAGE_4KB 0x00001000
#define SECTION_PA(x) ((x) & 0xFFF00000)
#define SMALLPAGE_PA(x) ((x) & 0xFFFFF000)
/* bit define in ARM control */
#define ENABLEMMU 0x00000001
#define ENABLEALIGNFT 0x00000002
#define ENABLEDCACHE 0x00000004
#define ENABLEICACHE 0x00001000
#define DOMAIN_MANAGER 0x3
#define DOMAIN_RESERVED 0x2
#define DOMAIN_CLIENT 0x1
#define DOMAIN_NO_ACCESS 0x0
typedef struct {
UINT_T VA; //vAddress is the starting address of the region in virtual memory
UINT_T PA; //pAddress is the starting address of the region in virtual memory
UINT_T pageSize; //pageSize is the size of a virtual page
UINT_T numPages; //numPages is the number of pages in the region
UINT_T ATTR; //memory attribute
} Region;
Region L1Regions[] = {
{DDR_ADDR, DDR_ADDR, PAGE_1MB, (DDR_SIZE/PAGE_1MB), NORMAL_OIWBWT},
{SQU_ADDR, SQU_ADDR, PAGE_1MB, (SQU_SIZE/PAGE_1MB), NORMAL_OIWBWT},
{MCU_ADDR, MCU_ADDR, PAGE_1MB, (MCU_SIZE/PAGE_1MB), SHAREABLE_DEV},
{REG_ADDR, REG_ADDR, PAGE_1MB, (REG_SIZE/PAGE_1MB), SHAREABLE_DEV},
{ROM_ADDR, ROM_ADDR, PAGE_1MB, (ROM_SIZE/PAGE_1MB), NORMAL_OIWBWT},
{XIP_ADDR, XIP_ADDR, PAGE_1MB, (XIP_SIZE/PAGE_1MB), NORMAL_OINCNB},
};
extern UINT_T PageTableStart;
void setup_mmu(void)
{
INT_T i, j;
UINT_T PA, Offset;
UINT_T *MMUTable = (UINT_T *)PageTableStart;
/* clear L1 Page Table */
for (i = 0; i < 4096; i++)
MMUTable[i] = 0;
for (i = 0; i < sizeof(L1Regions)/sizeof(Region); i++)
{
for(j = 0; j < L1Regions[i].numPages; j++)
{
Offset = (L1Regions[i].VA >> 20) + j;
MMUTable[Offset] = SECTION_PA(L1Regions[i].PA + (PAGE_1MB * j)) | L1Regions[i].ATTR;
}
}
/* Not used, leave here as reference */
#ifdef L2_TABLE
UINT_T ObmCodeAddr, ObmCodeSize, ObmBuffAddr, ObmBuffSize;
UINT_T *L2MMUTable = (UINT_T *)(PageTableStart+0x4000);
/* Configure L2 table for the 2MB memory where OBM resides in */
for (i = 0; i < 512; i++)
L2MMUTable[i] = 0; /* clear L2 Page Table */
ObmCodeAddr = OBM_DDR_BASE_ADDR;
ObmCodeSize = PageTableStart - OBM_DDR_BASE_ADDR;
ObmBuffAddr = SECTION_PA(ObmCodeAddr);
ObmBuffSize = 0x200000; /* OBM@0xXE8000, resides in two MBs */
Region L2Regions[] = {
{ObmBuffAddr, ObmBuffAddr, PAGE_4KB, (ObmBuffSize/PAGE_4KB), SP_NORMAL_OINCNB},
{ObmCodeAddr, ObmCodeAddr, PAGE_4KB, (ObmCodeSize/PAGE_4KB), SP_NORMAL_OIWBWT},
};
for (i = 0; i < sizeof(L2Regions)/sizeof(Region); i++)
{
for(j = 0; j < L2Regions[i].numPages; j++)
{
Offset = ((L2Regions[i].VA >> 12) & 0xFF) + j;
L2MMUTable[Offset] = SMALLPAGE_PA(L2Regions[i].PA + (PAGE_4KB * j) ) | L2Regions[i].ATTR;
}
}
Offset = SECTION_PA(ObmCodeAddr) >> 20;
MMUTable[Offset] = ((UINT_T)L2MMUTable) | 1;
MMUTable[Offset+1] = ((UINT_T)L2MMUTable + 0x400) | 1;
#endif
SetupTTBR0((UINT_T)MMUTable);
SetDomainAccess(0, DOMAIN_MANAGER);
SetDomainAccess(1, DOMAIN_MANAGER);
l1_icache_invalidate_all();
dcache_invalidate_all();
InvBpuAll();
InvTlbAll();
SetupARMCtrl((ENABLEMMU | ENABLEICACHE ), ENABLEALIGNFT);
}