From owner-svn-src-projects@FreeBSD.ORG Thu Feb 20 23:18:31 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 12B8AD7D; Thu, 20 Feb 2014 23:18:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E48F01C60; Thu, 20 Feb 2014 23:18:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s1KNIU0V007956; Thu, 20 Feb 2014 23:18:30 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s1KNIUWx007955; Thu, 20 Feb 2014 23:18:30 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201402202318.s1KNIUWx007955@svn.freebsd.org> From: Andrew Turner Date: Thu, 20 Feb 2014 23:18:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r262272 - projects/arm64/sys/arm64/arm64 X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Feb 2014 23:18:31 -0000 Author: andrew Date: Thu Feb 20 23:18:30 2014 New Revision: 262272 URL: http://svnweb.freebsd.org/changeset/base/262272 Log: Build the PA == VA map and turn the MMU on Modified: projects/arm64/sys/arm64/arm64/locore.S Modified: projects/arm64/sys/arm64/arm64/locore.S ============================================================================== --- projects/arm64/sys/arm64/arm64/locore.S Thu Feb 20 23:17:46 2014 (r262271) +++ projects/arm64/sys/arm64/arm64/locore.S Thu Feb 20 23:18:30 2014 (r262272) @@ -29,6 +29,10 @@ #include "assym.s" #include #include +#include +#include + +#define VIRT_BITS 38 .globl kernbase .set kernbase, KERNBASE @@ -49,6 +53,21 @@ _start: /* Drop to EL1 */ bl drop_to_el1 + /* Get the virt -> phys offset */ + bl get_virt_delta + + /* + * At this point: + * x29 = PA - VA + * x28 = Our physical load address + */ + + /* Create the page tables */ + bl create_pagetables + + /* Enable the mmu */ + bl start_mmu + /* Load the address of the fvp UART */ mov x0, 0x1c090000 /* Load 'A' */ @@ -103,8 +122,10 @@ drop_to_el1: msr elr_el2, x30 eret + + .align 3 .Lsctlr_res1: - .word SCTLR_RES1 + .quad SCTLR_RES1 #define VECT_EMPTY \ .align 7; \ @@ -135,6 +156,184 @@ hyp_vectors: hyp_trap_invalid: b hyp_trap_invalid +/* + * Get the delta between the physical address we were loaded to and the + * virtual address we expect to run from. This is used when building the + * initial page table. + */ +get_virt_delta: + /* Load the physical address of virt_map */ + adr x29, virt_map + /* Load the virtual address of virt_map stored in virt_map */ + ldr x28, [x29] + /* Find PA - VA as PA' = VA' - VA + PA = VA' + (PA - VA) = VA' + x29 */ + sub x29, x29, x28 + /* Find the load address for the kernel */ + mov x28, #(KERNBASE) + add x28, x28, x29 + ret + + .align 3 +virt_map: + .quad virt_map + +/* + * This builds the page tables containing the identity map, and the kernel + * virtual map. + * + * It relys on: + * We were loaded to an address that is on a 2MiB boundary + * All the memory must not cross a 1GiB boundaty + * x28 contains the physical address we were loaded from + * + * TODO: This is out of date. + * There are at least 5 pages before that address for the page tables + * The pages used are: + * - The identity (PA = VA) table (TTBR0) + * - The Kernel L1 table (TTBR1)(not yet) + * - The PA != VA L2 table to jump into (not yet) + * - The FDT L2 table (not yet) + */ +create_pagetables: + /* Save the Link register */ + mov x5, x30 + + mov x15, #(PAGE_SIZE * 3) + + /* Clean the page table */ + adr x6, pagetable + mov x26, x6 + add x27, x6, x15 +1: + stp xzr, xzr, [x6], #16 + stp xzr, xzr, [x6], #16 + stp xzr, xzr, [x6], #16 + stp xzr, xzr, [x6], #16 + cmp x6, x27 + b.lo 1b + + /* + * Build the TTBR0 maps. + */ + add x27, x26, #1, lsl #PAGE_SHIFT + + /* Create the VA = PA map */ + mov x6, x27 /* The initial page table */ + mov x7, #1 + mov x9, x27 + mov x8, x9 /* VA start (== PA start) */ + bl build_section_pagetable + + /* Create a table for the UART (TODO: Remove) */ + mov x7, #0 + mov x8, #0x10000000 /* VA start (== PA start) */ + mov x9, #0x10000000 /* PA start */ + bl build_section_pagetable + + /* Restore the Link register */ + mov x30, x5 + ret + +/* + * Builds a 1 GiB page table entry + * x6 = L1 table + * x7 = Type (0 = Device, 1 = Normal) + * x8 = VA start + * x9 = PA start (trashed) + * x11, x12 and x13 are trashed + */ +build_section_pagetable: + /* + * Build the L1 table entry. + */ + /* Find the table index */ + lsr x11, x8, #L1_SHIFT + and x11, x11, #Ln_ADDR_MASK + + /* Build the L1 block entry */ + lsl x12, x7, #2 + orr x12, x12, #L1_BLOCK + orr x12, x12, #(ATTR_AF) + + /* Only use the output address bits */ + lsr x9, x9, #L1_SHIFT + orr x12, x12, x9, lsl #L1_SHIFT + + /* Store the entry */ + str x12, [x6, x11, lsl #3] + + ret + +/* + * Builds an L1 -> L2 table descriptor + * + * This is a link for a 1GiB block of memory with up to 2MiB regions mapped + * within it by build_block_pagetable. + * + * x6 = L1 table + * x8 = Virtual Address + * x9 = L2 PA + * x11, x12 and x13 are trashed + */ +link_l1_pagetable: + /* + * Link an L1 -> L2 table entry. + */ + ret + +start_mmu: + dsb sy + + /* Load ttbr0 and ttbr1 */ + msr ttbr0_el1, x27 + msr ttbr1_el1, x26 + isb + + /* Clear the Monitor Debug System control register */ + msr mdscr_el1, xzr + + /* Invalidate the TLB */ + tlbi vmalle1is + + ldr x2, mair + msr mair_el1, x2 + + /* Setup TCR */ + ldr x2, tcr + msr tcr_el1, x2 + + /* Setup SCTLR */ + ldr x2, sctlr_set + ldr x3, sctlr_clear + mrs x1, sctlr_el1 + bic x1, x1, x3 /* Clear the required bits */ + orr x1, x1, x2 /* Set the required bits */ + msr sctlr_el1, x1 + isb + + ret + + .align 3 +mair: + .quad MAIR(0x00, 0) | MAIR(0x44, 1) | MAIR(0xff, 2) +tcr: + .quad (TCR_TxSZ(63 - VIRT_BITS) | TCR_ASID_16 | TCR_IPS_40BIT | \ + TCR_TG1_4K) +sctlr_set: + /* Bits to set */ + .quad (SCTLR_UCI | SCTLR_nTWE | SCTLR_nTWI | SCTLR_UCT | SCTLR_DZE | \ + SCTLR_I | SCTLR_SED | SCTLR_M) +sctlr_clear: + /* Bits to clear */ + .quad (SCTLR_EE | SCTLR_EOE | SCTLR_WXN | SCTLR_UMA | SCTLR_ITD | \ + SCTLR_THEE | SCTLR_CP15BEN | SCTLR_SA0 | SCTLR_SA | SCTLR_C | \ + SCTLR_A) + .globl abort abort: b abort + + //.section .init_pagetable + .align 12 /* 4KiB aligned */ +pagetable: + .space (PAGE_SIZE * 3) /* 3 tables */