В эти дни я просто хочу написать некоторые коды с открытым кодом для работы с MMU, после нескольких дней попыток, я все еще не могу заставить его работать. Поскольку я не могу отлаживать его с помощью последовательной консоли, и у меня нет дорогого отладчика, такого как D-STREAM, что я могу сделать, это вставить коды здесь и обратиться за помощью. Я не хочу быть пиявкой, но я действительно не знаю, какую дополнительную информацию я могу предоставить.Проблемы с MMU на ARM Cortex-A8. CPU - это S5PV210
Мой процессор S5PV210 на основе Cortex-A8 архитектуры Что я хочу сделать, это просто делает плоское отображение памяти, который просто означает «Виртуальный адрес == Физический адрес» Коды после
"ldr pc, =0x30000000\n"
- это только программа для светодиодной вспышки. Если комментарий эту строку в «enable_mmu»
"orr r0, r0, #0x0001\n" /* .... .... .... ...1 Enable MMU */
моя вспышка водить программа будет работать хорошо, если я раскоментировать, вспышка водить перестанет работать. Вот вся программа
#define ttl_base 0x2F000000
#define MMU_DES_FULL_ACESS (3<<10)
#define MMU_DES_DOMAIN (0<<5)
#define MMU_DES_EXECUTE_NEVER (0<<4)
#define MMU_DES_CACHEABLE (1<<3)
#define MMU_DES_BUFFERABLE (1<<2)
#define MMU_DES_SECTION (2)
#define MMU_DES_ATTRIBUTE (MMU_DES_SECTION|MMU_DES_BUFFERABLE|MMU_DES_CACHEABLE|MMU_DES_EXECUTE_NEVER|MMU_DES_DOMAIN|MMU_DES_FULL_ACESS)
void init_mmu()
{
//Create Translation Table for a flat map (Vitual Address == Physical Address)
u32 virtualaddr,phyaddr;
u32 *mmu_tlb_base=(u32 *)ttl_base;
virtualaddr = 0x0;
phyaddr = 0x0;
while(1)
{
*(mmu_tlb_base + (virtualaddr>>20)) = (phyaddr & 0xFFF00000) | (MMU_DES_ATTRIBUTE); //map 0x0x30000000-0x30100000 to 0xB0000000-0xB0100000
virtualaddr+=0x100000;
phyaddr+=0x100000;
if (phyaddr==0x00000000)
{
break;
}
}
}
void enable_mmu()
{
__asm__(
"mrc p15, 0, r0, c1, c0, 0\n"
"bic r0, r0, #0x3000\n"
"mcr p15, 0, r0, c1, c0, 0\n" /* Disable Insturection cache */
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c5, 0\n" /*Instruction cache invalidate all*/
"mcr p15, 0, r0, c7, c5, 6\n" /*branch predictor invalidate all*/
"mcr p15, 0, r0, c8, c7, 0\n" /* Invalidate data and instruction TLB */
/*Invalidate entire Data cache*/
/*Start*/
"MRC p15, 1, r0, c0, c0, 0\n" /* Read Cache Size ID */
"LDR r3, =0x1ff\n"
"AND r0, r3, r0, LSR #13\n" /* r0 = no. of sets - 1 */
"MOV r1, #0\n" /* r1 = way counter way_loop */
"way_loop:\n"
"MOV r3, #0\n" /* r3 = set counter set_loop */
"set_loop:\n"
"MOV r2, r1, LSL #30\n" /* */
"ORR r2, r3, LSL #5\n" /* r2 = set/way cache operation format */
"MCR p15, 0, r2, c7, c6, 2\n" /* Invalidate line described by r2 */
"ADD r3, r3, #1\n" /* Increment set counter */
"CMP r0, r3\n" /* Last set reached yet? */
"BGT set_loop\n" /* if not, iterate set_loop */
"ADD r1, r1, #1\n" /* else, next */
"CMP r1, #4\n" /* Last way reached yet? */
"BNE way_loop\n" /* if not, iterate way_loop */
/*End*/
/*Data and Instruction barrier*/
"dsb\n"
"isb\n"
"mov r0, #0\n"
"mcr p15, 0, r0, c2, c0, 2\n" /*Clear L2 Translation Table Entry*/
"mov r4, #0x2F000000\n"
"mcr p15, 0, r4, c2, c0, 0\n" /*Write L1 Translation Table Entry*/
"mvn r0, #0\n"
"mcr p15, 0, r0, c3, c0, 0\n" /*Write 0xFFFFFFFF to Domain Access Register, which means no permission check*/
"mrc p15, 0, r0, c1, c0, 0\n" /* Read SCTLR */
/* .RVI ..RS B... .CAM */
"bic r0, r0, #0x3000\n" /* ..11 .... .... .... Clear bit V、bit I */
"bic r0, r0, #0x0087\n" /* .... .... 1... .111 Clear bit B/C/A/M */
"orr r0, r0, #0x0002\n" /* .... .... .... ..1. Enable Aligment Check */
"orr r0, r0, #0x0004\n" /* .... .... .... .1.. Enable Data Caches */
"orr r0, r0, #0x1000\n" /* ...1 .... .... .... Enable Instruction Caches */
"orr r0, r0, #0x0800\n" /* .... 1... .... .... Enble brach prediction */
"orr r0, r0, #0x0001\n" /* .... .... .... ...1 Enable MMU */
"mcr p15, 0, r0, c1, c0, 0\n" /* Write back to SCTLR */
"ldr sp, =0x3F000000\n"
"ldr pc, =0x30000000\n"
"loop:\n"
"b loop\n"
);
}
Как вы знаете, компилятор не поместил 'ttb' в r0-r3? Большой встроенный asm с жестко запрограммированными регистрами и без клоблинга, как правило, очень плох. – Notlikethat
@Notlikethat Вы правы. Но даже если я объявляю «void enable_mmu (void) __ атрибут __ ((голый));». И не используйте локальную переменную. проблема стоит на месте. – demonguy
голый влияет только на пролог и эпилог функциональности, который здесь не имеет значения (конечно, это должно быть, но вы не говорите компилятору, что вы уничтожаете регистр, зарегистрированный пользователем). Я просто попытался скомпилировать это, и, конечно же, gcc поместил 'ttb' в r3, так что это было бы хорошо и по-настоящему испорчено. Я бы рекомендовал обновить код до чего-то, что не является тривиально сломанным, - что многие asm, вероятно, принадлежат к отдельному файлу .S, во всяком случае. – Notlikethat