From owner-svn-src-all@FreeBSD.ORG Mon Jan 26 08:42:48 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6B8FED70; Mon, 26 Jan 2015 08:42:48 +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 56CB2F34; Mon, 26 Jan 2015 08:42:48 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0Q8gmWH014667; Mon, 26 Jan 2015 08:42:48 GMT (envelope-from royger@FreeBSD.org) Received: (from royger@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0Q8gmhL014666; Mon, 26 Jan 2015 08:42:48 GMT (envelope-from royger@FreeBSD.org) Message-Id: <201501260842.t0Q8gmhL014666@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: royger set sender to royger@FreeBSD.org using -f From: Roger Pau Monné Date: Mon, 26 Jan 2015 08:42:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277735 - head/sys/amd64/amd64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jan 2015 08:42:48 -0000 Author: royger Date: Mon Jan 26 08:42:47 2015 New Revision: 277735 URL: https://svnweb.freebsd.org/changeset/base/277735 Log: amd64: allow base memory segment to start at address different than 0 Current code requires that the first physical memory segment starts at 0, but this is not really needed. We only need to make sure the bootstrap code and page tables for APs are allocated below 4GB. This patch removes this requirement and allows booting a Dell R710 from UEFI, where the first physical memory segment starts at 0x10000. Sponsored by: Citrix Systems R&D Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D1417 Modified: head/sys/amd64/amd64/machdep.c Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Mon Jan 26 08:30:24 2015 (r277734) +++ head/sys/amd64/amd64/machdep.c Mon Jan 26 08:42:47 2015 (r277735) @@ -1355,8 +1355,10 @@ add_physmap_entry(uint64_t base, uint64_ /* * Find insertion point while checking for overlap. Start off by * assuming the new entry will be added to the end. + * + * NB: physmap_idx points to the next free slot. */ - insert_idx = physmap_idx + 2; + insert_idx = physmap_idx; for (i = 0; i <= physmap_idx; i += 2) { if (base < physmap[i + 1]) { if (base + length <= physmap[i]) { @@ -1394,7 +1396,7 @@ add_physmap_entry(uint64_t base, uint64_ * Move the last 'N' entries down to make room for the new * entry if needed. */ - for (i = physmap_idx; i > insert_idx; i -= 2) { + for (i = (physmap_idx - 2); i > insert_idx; i -= 2) { physmap[i] = physmap[i - 2]; physmap[i + 1] = physmap[i - 1]; } @@ -1580,23 +1582,27 @@ getmemsize(caddr_t kmdp, u_int64_t first int page_counter; bzero(physmap, sizeof(physmap)); - basemem = 0; physmap_idx = 0; init_ops.parse_memmap(kmdp, physmap, &physmap_idx); + physmap_idx -= 2; /* * Find the 'base memory' segment for SMP */ basemem = 0; for (i = 0; i <= physmap_idx; i += 2) { - if (physmap[i] == 0x00000000) { + if (physmap[i] <= 0xA0000) { basemem = physmap[i + 1] / 1024; break; } } - if (basemem == 0) - panic("BIOS smap did not include a basemem segment!"); + if (basemem == 0 || basemem > 640) { + if (bootverbose) + printf( + "Memory map doesn't contain a basemem segment, faking it"); + basemem = 640; + } /* * Make hole for "AP -> long mode" bootstrap code. The @@ -1604,8 +1610,12 @@ getmemsize(caddr_t kmdp, u_int64_t first * is configured to support APs and APs for the system start * in 32bit mode (e.g. SMP bare metal). */ - if (init_ops.mp_bootaddress) + if (init_ops.mp_bootaddress) { + if (physmap[1] >= 0x100000000) + panic( + "Basemem segment is not suitable for AP bootstrap code!"); physmap[1] = init_ops.mp_bootaddress(physmap[1] / 1024); + } /* * Maxmem isn't the "maximum memory", it's one larger than the @@ -1657,12 +1667,14 @@ getmemsize(caddr_t kmdp, u_int64_t first */ physmem_start = (vm_guest > VM_GUEST_NO ? 1 : 16) << PAGE_SHIFT; TUNABLE_ULONG_FETCH("hw.physmem.start", &physmem_start); - if (physmem_start < PAGE_SIZE) - physmap[0] = PAGE_SIZE; - else if (physmem_start >= physmap[1]) - physmap[0] = round_page(physmap[1] - PAGE_SIZE); - else - physmap[0] = round_page(physmem_start); + if (physmap[0] < physmem_start) { + if (physmem_start < PAGE_SIZE) + physmap[0] = PAGE_SIZE; + else if (physmem_start >= physmap[1]) + physmap[0] = round_page(physmap[1] - PAGE_SIZE); + else + physmap[0] = round_page(physmem_start); + } pa_indx = 0; da_indx = 1; phys_avail[pa_indx++] = physmap[0];