From owner-svn-src-projects@FreeBSD.ORG Mon May 5 17:00:17 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 E55127CA; Mon, 5 May 2014 17:00:17 +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)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C65113F3; Mon, 5 May 2014 17:00:17 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s45H0HG3093182; Mon, 5 May 2014 17:00:17 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s45H0H4c093181; Mon, 5 May 2014 17:00:17 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201405051700.s45H0H4c093181@svn.freebsd.org> From: Andrew Turner Date: Mon, 5 May 2014 17:00:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r265369 - 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.18 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: Mon, 05 May 2014 17:00:18 -0000 Author: andrew Date: Mon May 5 17:00:17 2014 New Revision: 265369 URL: http://svnweb.freebsd.org/changeset/base/265369 Log: Update pmap_bootstrap: * Stop passing empty ranges to phys_avail * When splitting phys_avail use the correct end address * Add the memory after the kernel and early allocations to phys_avail * Use the correct address in pmap_early_page_idx * Add the offset within the l2 map to pmap_early_vtophys * Add a direct mapped range and use it with pmap_map Modified: projects/arm64/sys/arm64/arm64/pmap.c Modified: projects/arm64/sys/arm64/arm64/pmap.c ============================================================================== --- projects/arm64/sys/arm64/arm64/pmap.c Mon May 5 16:52:38 2014 (r265368) +++ projects/arm64/sys/arm64/arm64/pmap.c Mon May 5 17:00:17 2014 (r265369) @@ -67,14 +67,14 @@ pmap_early_page_idx(vm_offset_t l1pt, vm pd_entry_t *pde; pde = (pd_entry_t *)l1pt; - *l1_slot = (KERNBASE >> L1_SHIFT) & Ln_ADDR_MASK; + *l1_slot = (va >> L1_SHIFT) & Ln_ADDR_MASK; /* Check locore has used a table L1 map */ KASSERT((pde[*l1_slot] & ATTR_DESCR_MASK) == L1_TABLE, ("Invalid bootstrap L1 table")); /* Find the address of the L2 table */ ptep = (pt_entry_t *)((pde[*l1_slot] & ~ATTR_MASK) + kern_delta); - *l2_slot = (KERNBASE >> L2_SHIFT) & Ln_ADDR_MASK; + *l2_slot = (va >> L2_SHIFT) & Ln_ADDR_MASK; return (ptep); } @@ -87,13 +87,33 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_ ptep = pmap_early_page_idx(l1pt, va, kern_delta, &l1_slot, &l2_slot); - return (ptep[l2_slot] & ~ATTR_MASK); + return ((ptep[l2_slot] & ~ATTR_MASK) + (va & L2_OFFSET)); +} + +static void +pmap_bootstrap_dmap(vm_offset_t l1pt) +{ + vm_offset_t va; + vm_paddr_t pa; + pd_entry_t *pde; + u_int l1_slot; + + va = DMAP_MIN_ADDRESS; + pde = (pd_entry_t *)l1pt; + l1_slot = (DMAP_MIN_ADDRESS >> L1_SHIFT) & Ln_ADDR_MASK; + + for (pa = 0; va < DMAP_MAX_ADDRESS; + pa += L1_SIZE, va += L1_SIZE, l1_slot++) { + KASSERT(l1_slot < Ln_ENTRIES, ("Invalid L1 index")); + + pde[l1_slot] = (pa & ~L1_OFFSET) | ATTR_AF | L1_BLOCK; + } } void pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) { - u_int l1_slot, l2_slot, avail_slot, map_slot; + u_int l1_slot, l2_slot, avail_slot, map_slot, used_map_slot; uint64_t kern_delta; pt_entry_t *ptep; vm_offset_t va, freemempos; @@ -111,24 +131,29 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd /* * Start to initialise phys_avail by copying from physmap - * up to the physicaladdress KERNBASE points at. + * up to the physical address KERNBASE points at. */ - for (avail_slot = 0; avail_slot < physmap_idx; avail_slot += 2) { - if (physmap[avail_slot] <= pa && - physmap[avail_slot] + physmap[avail_slot + 1] > pa) + map_slot = avail_slot = 0; + for (; map_slot < (physmap_idx * 2); map_slot += 2) { + if (physmap[map_slot] == physmap[map_slot + 1]) + continue; + + if (physmap[map_slot] <= pa && + physmap[map_slot + 1] > pa) break; - phys_avail[avail_slot] = physmap[avail_slot]; - phys_avail[avail_slot + 1] = physmap[avail_slot + 1]; + phys_avail[avail_slot] = physmap[map_slot]; + phys_avail[avail_slot + 1] = physmap[map_slot + 1]; + avail_slot += 2; } /* Add the memory before the kernel */ - if (physmap[avail_slot] != pa) { - phys_avail[avail_slot] = physmap[avail_slot]; - phys_avail[avail_slot + 1] = pa - physmap[avail_slot]; + if (physmap[avail_slot] < pa) { + phys_avail[avail_slot] = physmap[map_slot]; + phys_avail[avail_slot + 1] = pa; avail_slot += 2; } - map_slot = avail_slot; + used_map_slot = map_slot; /* * Read the page table to find out what is already mapped. @@ -149,7 +174,7 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd /* Check locore used L2 blocks */ KASSERT((ptep[l2_slot] & ATTR_DESCR_MASK) == L2_BLOCK, ("Invalid bootstrap L2 table")); - KASSERT((ptep[l2_slot] & ~ATTR_DESCR_MASK) == pa, + KASSERT((ptep[l2_slot] & ~ATTR_MASK) == pa, ("Incorrect PA in L2 table")); va += L2_SIZE; @@ -206,6 +231,47 @@ pmap_bootstrap(vm_offset_t l1pt, vm_padd /* Allocate dynamic per-cpu area. */ alloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); dpcpu_init((void *)dpcpu, 0); + + virtual_avail = roundup2(freemempos, L2_SIZE); + + pa = pmap_early_vtophys(l1pt, virtual_avail, kern_delta); + + /* Finish initialising physmap */ + map_slot = used_map_slot; + for (; avail_slot < (PHYS_AVAIL_SIZE - 2) && + map_slot < (physmap_idx * 2); map_slot += 2) { + if (physmap[map_slot] == physmap[map_slot + 1]) + continue; + + /* Have we used the current range? */ + if (physmap[map_slot + 1] <= pa) + continue; + + /* Do we need to split the entry? */ + if (physmap[map_slot] < pa) { + phys_avail[avail_slot] = pa; + phys_avail[avail_slot + 1] = physmap[map_slot + 1]; + } else { + phys_avail[avail_slot] = physmap[map_slot]; + phys_avail[avail_slot + 1] = physmap[map_slot + 1]; + } + + avail_slot += 2; + } + phys_avail[avail_slot] = 0; + phys_avail[avail_slot + 1] = 0; + + /* Create a direct map region */ + pmap_bootstrap_dmap(l1pt); + + /* Flush the cache and tlb to ensure the new entries are valid */ + /* TODO: Flush the cache, we are relying on it being off */ + /* TODO: Move this to a function */ + __asm __volatile( + "dsb sy \n" + "tlbi vmalle1is \n" + "dsb sy \n" + "isb \n"); } /* @@ -314,7 +380,7 @@ vm_offset_t pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) { - panic("pmap_map"); + return (start | DMAP_MIN_ADDRESS); } /*