16c32d3c9SAlexander von Gluck IV/* 26c32d3c9SAlexander von Gluck IV * Copyright 2011, François Revol <revol@free.fr>. 36c32d3c9SAlexander von Gluck IV * All rights reserved. Distributed under the terms of the MIT License. 46c32d3c9SAlexander von Gluck IV */ 56c32d3c9SAlexander von Gluck IV 66c32d3c9SAlexander von Gluck IV#include <asm_defs.h> 76c32d3c9SAlexander von Gluck IV 86c32d3c9SAlexander von Gluck IV 9a3ef09d4SDavid Karoly .arch_extension virt 106c32d3c9SAlexander von Gluck IV .text 116c32d3c9SAlexander von Gluck IV 124d81ddabSDavid Karoly/* status_t arch_enter_kernel(uint32_t ttbr, struct kernel_args *kernelArgs, 136c32d3c9SAlexander von Gluck IV addr_t kernelEntry, addr_t kernelStackTop); 146c32d3c9SAlexander von Gluck IV 154d81ddabSDavid Karoly r0 - ttbr 164d81ddabSDavid Karoly r1 - kernelArgs 174d81ddabSDavid Karoly r2 - kernelEntry 184d81ddabSDavid Karoly r3 - kernelStackTop 196c32d3c9SAlexander von Gluck IV*/ 206c32d3c9SAlexander von Gluck IVFUNCTION(arch_enter_kernel): 216c32d3c9SAlexander von Gluck IV 22a3ef09d4SDavid Karoly // check whether we are running in HYP mode 23a3ef09d4SDavid Karoly mrs r9, cpsr 24a3ef09d4SDavid Karoly and r9, r9, #0x1f 25a3ef09d4SDavid Karoly 26a3ef09d4SDavid Karoly // proceed to _pl1_entry if we're not in HYP mode 27a3ef09d4SDavid Karoly cmp r9, #0x1a 28a3ef09d4SDavid Karoly bne _pl1_entry 29a3ef09d4SDavid Karoly 30a3ef09d4SDavid Karoly // set SVC mode in SPSR 31a3ef09d4SDavid Karoly mrs r9, cpsr 32a3ef09d4SDavid Karoly bic r9, r9, #0x1f 33a3ef09d4SDavid Karoly orr r9, r9, #0x13 34a3ef09d4SDavid Karoly msr spsr_cxsf, r9 35a3ef09d4SDavid Karoly 36a3ef09d4SDavid Karoly // load PL1 entry point address 37a3ef09d4SDavid Karoly adr lr, _pl1_entry 38a3ef09d4SDavid Karoly msr elr_hyp, lr 39a3ef09d4SDavid Karoly 40a3ef09d4SDavid Karoly // drop to PL1 SVC mode 41a3ef09d4SDavid Karoly eret 42a3ef09d4SDavid Karoly 43a3ef09d4SDavid Karoly_pl1_entry: 444d81ddabSDavid Karoly 454d81ddabSDavid Karoly mov r5,r0 464d81ddabSDavid Karoly mov r4,r2 476c32d3c9SAlexander von Gluck IV 486c32d3c9SAlexander von Gluck IV // set up kernel _start args 494d81ddabSDavid Karoly mov r0,r1 // kernelArgs 506c32d3c9SAlexander von Gluck IV mov r1,#0 // currentCPU=0 516c32d3c9SAlexander von Gluck IV 52123aa132SDavid Karoly // enable full access for coprocessors P10, P11 53123aa132SDavid Karoly // by setting the required flags in Access Control Register 54123aa132SDavid Karoly MRC p15, #0, r9, c1, c0, #2 55123aa132SDavid Karoly orr r9, r9, #0x00f00000 56123aa132SDavid Karoly MCR p15, #0, r9, c1, c0, #2 57123aa132SDavid Karoly 58123aa132SDavid Karoly // flush prefetch buffer 59123aa132SDavid Karoly mov r9, #0 60123aa132SDavid Karoly MCR p15, #0, r9, c7, c5, #4 61123aa132SDavid Karoly 62123aa132SDavid Karoly // enable FPU 63123aa132SDavid Karoly mov r9, #0x40000000 64123aa132SDavid Karoly FMXR FPEXC, r9 65123aa132SDavid Karoly 664d81ddabSDavid Karoly // flush TLB 674d81ddabSDavid Karoly MCR p15, 0, r1, c8, c7, 0 684d81ddabSDavid Karoly 694d81ddabSDavid Karoly // set TTBR0 705e6e52cfSDavid Karoly // cacheability attributes for the page tables are: 715e6e52cfSDavid Karoly // Normal Memory, Inner/Outer Write-Back no Write-Allocate Cacheable 725e6e52cfSDavid Karoly 735e6e52cfSDavid Karoly // Note that this relies on ARMv7 multiprocessing extensions 745e6e52cfSDavid Karoly // on uniprocessors we need only the flag 0x01 i.e. Inner Cacheable 755e6e52cfSDavid Karoly 765e6e52cfSDavid Karoly orr r5, r5, #0x59 775e6e52cfSDavid Karoly mcr p15, 0, r5, c2, c0, 0 784d81ddabSDavid Karoly 796f62f456SDavid Karoly // initialize TTBCR to zero (no LPAE, use only TTBR0) 806f62f456SDavid Karoly MCR p15, 0, r1, c2, c0, 2 816f62f456SDavid Karoly 824d81ddabSDavid Karoly // flush TLB (again) 834d81ddabSDavid Karoly MCR p15, 0, r1, c8, c7, 0 844d81ddabSDavid Karoly 854d81ddabSDavid Karoly // write DACR 86adc32659SDavid Karoly mov r9, #0x00000001 87adc32659SDavid Karoly mcr p15, 0, r9, c3, c0, 0 884d81ddabSDavid Karoly 89*b6e15e8bSDavid Karoly // configure PRRR and NMRR for TEX remap 90*b6e15e8bSDavid Karoly 91*b6e15e8bSDavid Karoly // set PRRR as follows: 92*b6e15e8bSDavid Karoly // - memory type 0 is Strongly Ordered 93*b6e15e8bSDavid Karoly // - memory type 1 is Shareable Device 94*b6e15e8bSDavid Karoly // - all others are normal memory 95*b6e15e8bSDavid Karoly // - NS/DS bits are configured as 'pass-through' 96*b6e15e8bSDavid Karoly // - all Shareable Normal memory regions are Outer Shareable 97*b6e15e8bSDavid Karoly mov r9, #0x0000aaa4 98*b6e15e8bSDavid Karoly orr r9, #0x000a0000 99*b6e15e8bSDavid Karoly mcr p15, 0, r9, c10, c2, 0 100*b6e15e8bSDavid Karoly 101*b6e15e8bSDavid Karoly // set NMRR as follows: 102*b6e15e8bSDavid Karoly // - memory type 2 is Inner/Outer Write-Through 103*b6e15e8bSDavid Karoly // - memory type 3 is Inner/Outer Write-Back, no Write-Allocate 104*b6e15e8bSDavid Karoly // - don't care about the rest 105*b6e15e8bSDavid Karoly mov r9, #0x000000e0 106*b6e15e8bSDavid Karoly orr r9, #0x00e00000 107*b6e15e8bSDavid Karoly mcr p15, 0, r9, c10, c2, 1 108*b6e15e8bSDavid Karoly 109*b6e15e8bSDavid Karoly // ensure the PRRR and NMRR registers are updated before enabling MMU 110*b6e15e8bSDavid Karoly dsb 111*b6e15e8bSDavid Karoly isb 112*b6e15e8bSDavid Karoly 1135e6e52cfSDavid Karoly // enable MMU and caches 1145e6e52cfSDavid Karoly mrc p15, 0, r9, c1, c0, 0 115290e43c0SDavid Karoly orr r9, r9, #0x20000000 // access flag enabled 116*b6e15e8bSDavid Karoly orr r9, r9, #0x10000000 // TEX remap enabled 1175e6e52cfSDavid Karoly orr r9, r9, #0x00001000 // i-cache enabled 1185e6e52cfSDavid Karoly orr r9, r9, #0x00000004 // d-cache enabled 1195e6e52cfSDavid Karoly orr r9, r9, #0x00000001 // MMU enabled 1205e6e52cfSDavid Karoly mcr p15, 0, r9, c1, c0, 0 1214d81ddabSDavid Karoly 1224d81ddabSDavid Karoly // set the kernel stack 1234d81ddabSDavid Karoly mov sp,r3 1244d81ddabSDavid Karoly 1256c32d3c9SAlexander von Gluck IV // call the kernel 1266c32d3c9SAlexander von Gluck IV mov pc,r4 1276c32d3c9SAlexander von Gluck IV 1286c32d3c9SAlexander von Gluck IV // return 1296c32d3c9SAlexander von Gluck IV mov r0,#-1 // B_ERROR 1306c32d3c9SAlexander von Gluck IV mov pc,lr 1316c32d3c9SAlexander von Gluck IV 1326c32d3c9SAlexander von Gluck IVFUNCTION_END(arch_enter_kernel) 1336c32d3c9SAlexander von Gluck IV 134