Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ep9307. Виртуальные адреса. Переадресация RAM ROM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Микула
Доброго времени суток.
Есть программа, которая выполняет настройку виртуальных адресов с помощью MMU.
Нужно переадресовать весь RAM и ROM, но в данный момент по этим адресам выполняется текущая программа..
Как мне после включения MMU вызвать другую программу по определенному адресу (установить PC)?

Подробнее:
RAM располагается на физических адресах 0x30..0 а ROM на адресах 0x0..0.
Появилась необходимость переадресовать RAM по нулевым адресам (0x0..0).
Собственно, для этого нужно переадресовать весь RAM и ROM, но в данный момент по этим адресам выполняется текущая программа..
После включения MMU программа сразу улетит в тар_тара-ры?
Как мне после включения MMU вызвать другую программу по определенному адресу (установить PC)?
Использую IAR4.
Микула
При выполнении инструкции asm("mov pc, #0x0; "); вываливается в abort data.
После настойки ММУ настраиваю только домен (все разрешено) и табличку с ссылкой на неё.
Все кеши отрублены.
По нулевым адресам ( RAM после настройки ММУ) лежит программа которая должна запуститься..
Если выставляю в отладчике принудительно PC 0 то программа нужная работает как часы.


Привожу код настройки ММУ и перехода. Извиняюсь за коменты на русском:

CODE
#include "MMU.h"
#include <intrinsics.h>
#define MB_SIZE 0x100000
#define KB_SIZE 0x400

#define START_RAM_ADR 0x30000000 //àäðåñ RAM ôèçè÷åñêèé
#define START_ROM_ADR 0x0 //àäðåñ ROM ôèçè÷åñêèé

#define TBL_SIZE 16*KB_SIZE //16êá
#define TBL_ADR START_RAM_ADR+MB_SIZE-TBL_SIZE //àäðåñ áàçîâîé òàáëèöû â êîíöå RAM
#define TBL_PAGE_SIZE 4*KB_SIZE
#define TBL_PAGE_ADR TBL_ADR - TBL_PAGE_SIZE

//---PAGE TYPE
#define TYPE_DESCR_COARCE_PAGE 1
#define TYPE_DESCR_SECTOR 2
#define TYPE_DESCR_FINE_PAGE 3
//-------------

#define GET_DOMAIN(NUM) NUM<<5

#define GET_SECT_TABLE_DESC(ADRESS) ( (ADRESS>>20) & 0xFFF)<<20
#define GET_1KB_PAGE_DESC(ADRESS) ( (ADRESS>>10) & 0x3FFFFF)<<10

#define GET_FPAGE_TABLE_ADR(ADRESS) ( (ADRESS>>12) & 0xFFFFF) <<12

#define TYPE_1KB_PAGE 3
#define TYPE_4KB_PAGE 2
#define TYPE_64KB_PAGE 1

#define AP_R_W 3


#define CACH_MODE_WB 3<<2
#define CACH_MODE_WT 2<<2
#define CACH_MODE_NCB 1<<2
#define CACH_MODE_NCNB 0<<2

//---MMU Control
#define ENABLE_MMU 1

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

void _write_TTB(unsigned int ttb)
{
__MCR(15, 0, ttb, 2, 0, 0);
}
//----------------------------------------------------------------------------

void _write_domain(unsigned int domain)
{
__MCR(15, 0, domain, 3, 0, 0);
}
//----------------------------------------------------------------------------

unsigned int _read_MMU_control()
{
register unsigned int ctl;
ctl = __MRC(15, 0, 1, 0, 0);
return ctl;
}
//----------------------------------------------------------------------------

void _write_MMU_control(unsigned int ctl)
{
__MCR(15, 0, ctl, 1, 0, 0);
}
//----------------------------------------------------------------------------
int MMU_init()
{
unsigned int ctl = _read_MMU_control();
if(ctl & ENABLE_MMU)
asm("mov pc, #0x0;");

unsigned int *TLB =(unsigned int *) (TBL_ADR);
unsigned int *TLB_PAGE =(unsigned int *) (TBL_PAGE_ADR);

_write_domain(0xFFFFFFFF); // Ïðàâà äîñòóïà íå ïðîâåðÿþòñÿ äëÿ âñåõ äîìåíîâ
_write_TTB(TBL_ADR);//çàïèñûâàåì àäðåñ áàçîâîé òàáëèöû


for(int i=0;i<0x100;i++)
{
TLB[0x0+i] = 0;//Îïåðàòèâíàÿ áàìÿòü áóäåò ïåðåîáîçíà÷åíà íèæå äëÿ 1 ìåãàáàéòà
TLB[0x100+i] = 0;
TLB[0x200+i] = 0;
TLB[0x300+i] = 0;
TLB[0x400+i] = 0;
TLB[0x500+i] = 0;

//òóò FPGA
TLB[0x600+i] = 1<<4 | TYPE_DESCR_SECTOR | GET_DOMAIN(0) | GET_SECT_TABLE_DESC(0x60000000 +i*MB_SIZE);// | CACH_MODE_WB;
TLB[0x700+i] = 0;

//òóò ðåãèñòðû (íå êýøèðóåì)
TLB[0x800+i] = 1<<4 | TYPE_DESCR_SECTOR | GET_DOMAIN(0) | GET_SECT_TABLE_DESC(0x80000000 + i*MB_SIZE);

TLB[0x900+i] = 0;

//òóò áóäåò RAM 16ìá
TLB[0xA00+i] = 0;

TLB[0xB00+i] = 0;
TLB[0xC00+i] = 0;
TLB[0xE00+i] = 0;
TLB[0xD00+i] = 0;
TLB[0xF00+i] = 0;
}

//Íàñòðàèâàåì îïåðòèâêó 1ÌÁ-------------
//Äëÿ îïðåòàâíîé ïàìÿòè äåëàåì áîëåå òî÷íóþ íàñòðîéêó
TLB[0] = 1<<4 | TYPE_DESCR_FINE_PAGE | GET_DOMAIN(0) |
GET_FPAGE_TABLE_ADR(TBL_PAGE_ADR);

//òåïåðü íàñòðàèâàåì áîëåå òî÷íóþ òàáëèöó ïî 1êá äëÿ îïåðàòèâêè
for(int i=0;i<1004;i++)
TLB_PAGE[i]=TYPE_1KB_PAGE | GET_1KB_PAGE_DESC(0x30000000+i*KB_SIZE) | AP_R_W<<4;// | CACH_MODE_WB;

for(int i=1004;i<1024;i++)
TLB_PAGE[i]= 0;//äåëàåì îáðàùåíèå ïî àäðåñàì ãäå ëåæàò òàáëèöû íåäîñòóïíûìè
//--------------------------------------


//Íàñòðàèâàåì ROM 16ìá------------------
TLB[0xA00] = 1<<4 | TYPE_DESCR_FINE_PAGE | GET_DOMAIN(0) |
GET_FPAGE_TABLE_ADR(TBL_PAGE_ADR);
for(int i=0;i<16;i++)
{
TLB[0xA00+i]= 1<<4 | TYPE_DESCR_SECTOR | GET_DOMAIN(0) |
GET_SECT_TABLE_DESC(0x0+i*MB_SIZE)|;//CACH_MODE_WB;//FLASH c 0x0 âåøàåì íà 0xA0000000
}
//--------------------------------------


ctl = _read_MMU_control();
//
////Âêëþ÷àåì Icash
//ctl |= (1 << 12);
// //Âêëþ÷àåì Dcash
//ctl |= (1 << 2);

//ïåðåäâèãàåì PC íà íà÷àëî îïåðàòèâêè (òàì äîëæíà ðàñïîëàãàòñÿ ïðîãðàììà)
//âêëþ÷àåì MMU*/
ctl |= ENABLE_MMU;
_write_MMU_control(ctl);
//asm("mov lr, pc; ");
asm("mov pc, #0x0; ");
//---
}
Микула
Вываливалось в data abort на PC потому, что я забыл записать "1111" в контрольный регистр ММУ.
После включения ММУ в дебагере вижу что команды асемблеровские не исполняются и через пару действий улетают в data abort.
Сюда по всему после включения ММУ он выполняет что-то уже по перемапированным адресам...
Хотелось бы найти другой способ кроме копирования программы по новым адресам перед включениям ММУ.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.