rPi MMU: Cleanup, add gPeripheralBase

* gPeripheralBase keeps track of the device
  peripherals before and after mmu_init
* Add ability to disable mmu for troubleshooting
* Remove static FB_BASE, we actually don't know
  where the FB is yet. (depends on firmware used)
This commit is contained in:
Alexander von Gluck IV
2012-05-24 06:39:43 -05:00
parent 16307934fa
commit 361ec26f10
4 changed files with 34 additions and 20 deletions
+1 -3
View File
@@ -62,9 +62,7 @@
// SMI Base // SMI Base
#define USB_BASE 0x980000 #define USB_BASE 0x980000
// USB Controller, 15.2, page 202 // USB Controller, 15.2, page 202
#define FB_BASE 0x000000 // FB_BASE will depend on memory split
// Fake frame buffer
#define FB_SIZE SIZE_4K
// 7.5, page 112 // 7.5, page 112
@@ -40,9 +40,14 @@
// You also need to define ENABLE_SERIAL in serial.cpp // You also need to define ENABLE_SERIAL in serial.cpp
// for output to work. // for output to work.
//#define DEBUG_DISABLE_MMU
extern uint8 __stack_start; extern uint8 __stack_start;
extern uint8 __stack_end; extern uint8 __stack_end;
extern addr_t gPeripheralBase;
/* /*
*defines a block in memory *defines a block in memory
@@ -60,6 +65,7 @@ struct memblock {
static struct memblock LOADER_MEMORYMAP[] = { static struct memblock LOADER_MEMORYMAP[] = {
// We map this first so we can always find peripherals
{ {
"devices", "devices",
PERIPHERAL_BASE, PERIPHERAL_BASE,
@@ -114,20 +120,20 @@ static struct memblock LOADER_MEMORYMAP[] = {
//static const uint32 kDefaultPageTableFlags = MMU_FLAG_READWRITE; //static const uint32 kDefaultPageTableFlags = MMU_FLAG_READWRITE;
// not cached not buffered, R/W // not cached not buffered, R/W
static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel
static addr_t sNextPhysicalAddress = 0; //will be set by mmu_init static addr_t sNextPhysicalAddress = 0; // will be set by mmu_init
static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize; static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize;
static addr_t sMaxVirtualAddress = KERNEL_BASE + kMaxKernelSize; static addr_t sMaxVirtualAddress = KERNEL_BASE + kMaxKernelSize;
static addr_t sNextPageTableAddress = 0; static addr_t sNextPageTableAddress = 0;
//the page directory is in front of the pagetable // the page directory is in front of the pagetable
static uint32 kPageTableRegionEnd = 0; static uint32 kPageTableRegionEnd = 0;
// working page directory and page table // working page directory and page table
static uint32 *sPageDirectory = 0 ; static uint32 *sPageDirectory = 0 ;
//page directory has to be on a multiple of 16MB for // page directory has to be on a multiple of 16MB for
//some arm processors // some arm processors
static addr_t static addr_t
@@ -141,11 +147,13 @@ get_next_virtual_address(size_t size)
static addr_t static addr_t
get_next_virtual_address_alligned (size_t size, uint32 mask) get_next_virtual_address_alligned(size_t size, uint32 mask)
{ {
addr_t address = (sNextVirtualAddress) & mask; addr_t address = sNextVirtualAddress & mask;
sNextVirtualAddress = address + size; sNextVirtualAddress = address + size;
TRACE("%s: %p\n", __func__, (void*)address);
return address; return address;
} }
@@ -190,7 +198,7 @@ get_next_physical_page(size_t pagesize)
void void
mmu_set_TTBR(uint32 ttb) mmu_set_TTBR(uint32 ttb)
{ {
TRACE("%s: Set Translation Table Base to 0x%lx\n", __func__); TRACE("%s: Set Translation Table Base to 0x%" B_PRIx32 "\n", __func__, ttb);
ttb &= 0xffffc000; ttb &= 0xffffc000;
asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb)); asm volatile("MRC p15, 0, %[adr], c2, c0, 0"::[adr] "r" (ttb));
} }
@@ -233,7 +241,8 @@ mmu_write_C1(uint32 value)
void void
mmu_write_DACR(uint32 value) mmu_write_DACR(uint32 value)
{ {
TRACE("%s: Set Domain Access Register to 0x%lx\n", __func__); TRACE("%s: Set Domain Access Register to 0x%" B_PRIx32 "\n",
__func__, value);
asm volatile("MCR p15, 0, %[c1in], c3, c0, 0"::[c1in] "r" (value)); asm volatile("MCR p15, 0, %[c1in], c3, c0, 0"::[c1in] "r" (value));
} }
@@ -242,7 +251,7 @@ static uint32 *
get_next_page_table(uint32 type) get_next_page_table(uint32 type)
{ {
TRACE("%s: sNextPageTableAddress %p, kPageTableRegionEnd %p, " TRACE("%s: sNextPageTableAddress %p, kPageTableRegionEnd %p, "
"type 0x%" B_PRIX32 "\n", __func__, sNextPageTableAddress, "type 0x%" B_PRIx32 "\n", __func__, sNextPageTableAddress,
kPageTableRegionEnd, type); kPageTableRegionEnd, type);
size_t size = 0; size_t size = 0;
@@ -289,7 +298,7 @@ init_page_directory()
sPageDirectory[i] = 0; sPageDirectory[i] = 0;
uint32 *pageTable = NULL; uint32 *pageTable = NULL;
for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP);i++) { for (uint32 i = 0; i < ARRAY_SIZE(LOADER_MEMORYMAP); i++) {
pageTable = get_next_page_table(MMU_L1_TYPE_COARSE); pageTable = get_next_page_table(MMU_L1_TYPE_COARSE);
TRACE("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name, TRACE("BLOCK: %s START: %lx END %lx\n", LOADER_MEMORYMAP[i].name,
@@ -328,12 +337,16 @@ init_page_directory()
// TLB Flush // TLB Flush
mmu_flush_TLB(); mmu_flush_TLB();
// Set domain access register // Set domain access register, manager access to all
mmu_write_DACR(0xFFFFFFFF); mmu_write_DACR(0xFFFFFFFF);
#ifndef DEBUG_DISABLE_MMU
TRACE("%s: Enable MMU...\n", __func__); TRACE("%s: Enable MMU...\n", __func__);
mmu_write_C1(mmu_read_C1() | 0x1); mmu_write_C1(mmu_read_C1() | 0x1);
gPeripheralBase = sNextVirtualAddress;
#endif
TRACE("%s: Complete\n", __func__); TRACE("%s: Complete\n", __func__);
} }
@@ -23,6 +23,7 @@ DebugUART *gUART;
static bool sSerialEnabled = false; static bool sSerialEnabled = false;
extern addr_t gPeripheralBase;
static void static void
@@ -88,10 +89,8 @@ serial_cleanup(void)
extern "C" void extern "C" void
serial_init(void) serial_init(void)
{ {
addr_t uart0 = mmu_map_physical_memory(PERIPHERAL_BASE + BOARD_UART_DEBUG, gUART = arch_get_uart_pl011(gPeripheralBase + BOARD_UART_DEBUG,
0x00004000, kDefaultPageFlags); BOARD_UART_CLOCK);
gUART = arch_get_uart_pl011(uart0, BOARD_UART_CLOCK);
gUART->InitEarly(); gUART->InitEarly();
gUART->InitPort(9600); gUART->InitPort(9600);
@@ -37,6 +37,9 @@ extern uint8 __stack_end;
extern int main(stage2_args *args); extern int main(stage2_args *args);
void _start(void); void _start(void);
// Adjusted during mmu_init
addr_t gPeripheralBase = PERIPHERAL_BASE;
static void static void
clear_bss(void) clear_bss(void)
@@ -112,8 +115,9 @@ pi_start(void)
gpio_init(); gpio_init();
// Flick on "OK" led, use pre-mmu firmware base // Flick on "OK" led, use pre-mmu firmware base
gpio_write(PERIPHERAL_BASE + GPIO_BASE, 16, 0); gpio_write(gPeripheralBase + GPIO_BASE, 16, 0);
// To debug mmu, enable serial_init above me!
mmu_init(); mmu_init();
serial_init(); serial_init();