Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions mmu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,3 @@ notmain.hex : memmap novectors.o periph.o notmain.o
$(ARMGNU)-objdump -D notmain.elf > notmain.list
$(ARMGNU)-objcopy notmain.elf -O ihex notmain.hex







863 changes: 0 additions & 863 deletions mmu/README

This file was deleted.

886 changes: 886 additions & 0 deletions mmu/README.md

Large diffs are not rendered by default.

Binary file removed mmu/coarse_translation.ps
Binary file not shown.
109 changes: 64 additions & 45 deletions mmu/notmain.c
Original file line number Diff line number Diff line change
@@ -1,59 +1,78 @@

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
#include <stdint.h>

extern void PUT32 ( unsigned int, unsigned int );
extern void PUT16 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );

extern void start_mmu ( unsigned int, unsigned int );
extern void mmu_init ( uint32_t );
extern void mmu_domain ( uint32_t );
extern void stop_mmu ( void );
extern void invalidate_tlbs ( void );
extern void invalidate_caches ( void );
extern void invalidate_tlb ( void );

extern void uart_init ( void );
extern void uart_send ( unsigned int );

extern void hexstrings ( unsigned int );
extern void hexstring ( unsigned int );

unsigned int system_timer_low ( void );

#define MMUTABLEBASE 0x00004000

//-------------------------------------------------------------------
unsigned int mmu_section ( unsigned int vadd, unsigned int padd, unsigned int flags )
#define CACHEABLE 0x08
#define BUFFERABLE 0x04

/**
* \brief creates an translation table entry (for sections of size 1 MiB)
* \param[in] virtual the virtual address (only top 12 bits used)
* \param[in] physical the physical address (only top 12 bits used)
* \param[in] flags the flags for the section
**/
uint32_t mmu_section ( uint32_t virtual, uint32_t physical, uint32_t flags )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;

ra=vadd>>20;
rb=MMUTABLEBASE|(ra<<2);
rc=(padd&0xFFF00000)|0xC00|flags|2;
//hexstrings(rb); hexstring(rc);
PUT32(rb,rc);
uint32_t offset = virtual >> 20;
// plus and or are the same thing here, as MMUTABLEBASE is 14 bit aligned
uint32_t* entry = (uint32_t*) (MMUTABLEBASE | (offset<<2));

// mask lower 20 bits of physical address then ORR flags and 0x02 for 1 MiB
uint32_t physval = (physical & 0xfff00000) | (flags & 0x7ffa) | 0x02;

*entry = physval;
return(0);
}
//-------------------------------------------------------------------
unsigned int mmu_small ( unsigned int vadd, unsigned int padd, unsigned int flags, unsigned int mmubase )


/**
* \brief creates an translation table entry (for sections of size 1 MiB)
* \param[in] virtual the virtual address (only top 12 bits used)
* \param[in] physical the physical address (only top 12 bits used)
* \param[in] flags the flags for the section
**/
uint32_t mmu_page ( uint32_t virtual, uint32_t physical, uint32_t flags, uint32_t secondbase )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;

ra=vadd>>20;
rb=MMUTABLEBASE|(ra<<2);
rc=(mmubase&0xFFFFFC00)/*|(domain<<5)*/|1;
//hexstrings(rb); hexstring(rc);
PUT32(rb,rc); //first level descriptor
ra=(vadd>>12)&0xFF;
rb=(mmubase&0xFFFFFC00)|(ra<<2);
rc=(padd&0xFFFFF000)|(0xFF0)|flags|2;
//hexstrings(rb); hexstring(rc);
PUT32(rb,rc); //second level descriptor
uint32_t offset = virtual >> 20;
// plus and or are the same thing here, as MMUTABLEBASE is 14 bit aligned
uint32_t* entry = (uint32_t*) (MMUTABLEBASE | (offset<<2));
// mask lower 20 bits of physical address then ORR flags and 0x01 for coarse translation
uint32_t entryval = (secondbase & 0xfffffc00) | (flags & 0xf0) | 0x01;

// set first level descriptor
*entry = entryval;

// mask everything except bits 19:12
offset = (virtual >> 12) & 0xff;
// form the second level
uint32_t* secondLevelEntry = (uint32_t*) ((secondbase & 0xfffffc00) | (offset << 2));

// form the value of the second level descriptor
// bytes 31:12 are the page base address, flags contain B,C, AP_x = 0b11
// for all and the 0x02 at the end to identify the entry as small page
uint32_t physval = (physical & 0xfffff000) | 0xff0 | (flags & 0xc) | 0x02;

// set the second level descriptor
*secondLevelEntry = physval;
return(0);
}


//------------------------------------------------------------------------
int notmain ( void )
{
Expand Down Expand Up @@ -95,7 +114,7 @@ int notmain ( void )
mmu_section(0x20000000,0x20000000,0x0000); //NOT CACHED!
mmu_section(0x20200000,0x20200000,0x0000); //NOT CACHED!

start_mmu(MMUTABLEBASE,0x00000001|0x1000|0x0004); //[23]=0 subpages enabled = legacy ARMv4,v5 and v6
mmu_init( MMUTABLEBASE );

hexstring(GET32(0x00045678));
hexstring(GET32(0x00145678));
Expand All @@ -106,24 +125,24 @@ int notmain ( void )
mmu_section(0x00100000,0x00300000,0x0000);
mmu_section(0x00200000,0x00000000,0x0000);
mmu_section(0x00300000,0x00100000,0x0000);
invalidate_tlbs();
invalidate_tlb();

hexstring(GET32(0x00045678));
hexstring(GET32(0x00145678));
hexstring(GET32(0x00245678));
hexstring(GET32(0x00345678));
uart_send(0x0D); uart_send(0x0A);

mmu_small(0x0AA45000,0x00145000,0,0x00000400);
mmu_small(0x0BB45000,0x00245000,0,0x00000800);
mmu_small(0x0CC45000,0x00345000,0,0x00000C00);
mmu_small(0x0DD45000,0x00345000,0,0x00001000);
mmu_small(0x0DD46000,0x00146000,0,0x00001000);
mmu_page(0x0AA45000,0x00145000,0,0x00000400);
mmu_page(0x0BB45000,0x00245000,0,0x00000800);
mmu_page(0x0CC45000,0x00345000,0,0x00000C00);
mmu_page(0x0DD45000,0x00345000,0,0x00001000);
mmu_page(0x0DD46000,0x00146000,0,0x00001000);
//put these back
mmu_section(0x00100000,0x00100000,0x0000);
mmu_section(0x00200000,0x00200000,0x0000);
mmu_section(0x00300000,0x00300000,0x0000);
invalidate_tlbs();
invalidate_tlb();

hexstring(GET32(0x0AA45678));
hexstring(GET32(0x0BB45678));
Expand All @@ -137,9 +156,9 @@ int notmain ( void )
uart_send(0x0D); uart_send(0x0A);

//access violation.

mmu_domain ( 0xffffff03 );
mmu_section(0x00100000,0x00100000,0x0020);
invalidate_tlbs();
invalidate_tlb();

hexstring(GET32(0x00045678));
hexstring(GET32(0x00145678));
Expand Down
60 changes: 40 additions & 20 deletions mmu/novectors.s
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,32 @@ handler:
b hang

data_abort:
// save the link-register
mov r6,lr
// get the last executed instruction
ldr r8,[r6,#-8]

// reading the status register
mrc p15,0,r4,c5,c0,0 ;@ data/combined
mrc p15,0,r5,c5,c0,1 ;@ instruction
mov sp,#0x00004000
bl hexstring

// print data fault status register
mov r0,r4
bl hexstring

// print instruction fault status register
mov r0,r5
bl hexstring

// print the link register
mov r0,r6
bl hexstring

// print the bit-representation of the last executed instruction
mov r0,r8
bl hexstring
mov r0,r7
bl hexstring

b hang

.globl PUT32
Expand All @@ -106,25 +116,35 @@ GET32:
dummy:
bx lr

.globl start_mmu
start_mmu:
mov r2,#0
mcr p15,0,r2,c7,c7,0 ;@ invalidate caches
mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb
mcr p15,0,r2,c7,c10,4 ;@ DSB ??

mvn r2,#0
bic r2,#0xC
mcr p15,0,r2,c3,c0,0 ;@ domain

.global mmu_domain
mmu_domain:
mcr p15, 0, r0, c3, c0, 0
mov pc, lr

.global mmu_init
mmu_init:
mov r1,#0
// invalidate caches
mcr p15,0,r1,c7,c7,0
// invalidate TLB entries
mcr p15,0,r1,c8,c7,0
// data synchronisation barrier
mcr p15,0,r1,c7,c10,4

// set all domains to 0b11
ldr r1, =0xffffffff
mcr p15,0,r1,c3,c0,0

// set the translation table base address (remember to align 16 KiB!)
mcr p15,0,r0,c2,c0,0 ;@ tlb base
mcr p15,0,r0,c2,c0,1 ;@ tlb base


// set the bits mentioned above
ldr r1, =0x00401805
mrc p15,0,r2,c1,c0,0
orr r2,r2,r1
mcr p15,0,r2,c1,c0,0

bx lr
mov pc, lr

.globl stop_mmu
stop_mmu:
Expand All @@ -135,8 +155,8 @@ stop_mmu:
mcr p15,0,r2,c1,c0,0
bx lr

.globl invalidate_tlbs
invalidate_tlbs:
.globl invalidate_tlb
invalidate_tlb:
mov r2,#0
mcr p15,0,r2,c8,c7,0 ;@ invalidate tlb
mcr p15,0,r2,c7,c10,4 ;@ DSB ??
Expand Down
9 changes: 1 addition & 8 deletions mmu/periph.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ extern void PUT32 ( unsigned int, unsigned int );
extern void PUT16 ( unsigned int, unsigned int );
extern void PUT8 ( unsigned int, unsigned int );
extern unsigned int GET32 ( unsigned int );
extern void BRANCHTO ( unsigned int );
extern void dummy ( unsigned int );

#define SYSTIMERCLO (0x20003004)
Expand Down Expand Up @@ -120,13 +119,7 @@ void uart_init ( void )
PUT32(GPPUDCLK0,0);
PUT32(AUX_MU_CNTL_REG,3);
}
//-------------------------------------------------------------------------
unsigned int system_timer_low ( void )
{
return(GET32(SYSTIMERCLO));
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------



//-------------------------------------------------------------------------
Expand Down
Binary file removed mmu/section_translation.ps
Binary file not shown.