VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingQueryAddressInfo.c@ 77922

Last change on this file since 77922 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/* $Id: bs3-cmn-PagingQueryAddressInfo.c 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * BS3Kit - Bs3PagingQueryAddressInfo
4 */
5
6/*
7 * Copyright (C) 2007-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <bs3kit.h>
32#include <iprt/asm-amd64-x86.h>
33#include <VBox/err.h>
34
35
36#undef Bs3PagingQueryAddressInfo
37BS3_CMN_DEF(int, Bs3PagingQueryAddressInfo,(uint64_t uFlat, PBS3PAGINGINFO4ADDR pPgInfo))
38{
39 RTCCUINTXREG const cr3 = ASMGetCR3();
40 RTCCUINTXREG const cr4 = g_uBs3CpuDetected & BS3CPU_F_CPUID ? ASMGetCR4() : 0;
41 bool const fLegacyPTs = !(cr4 & X86_CR4_PAE);
42 int rc = VERR_OUT_OF_RANGE;
43
44
45 pPgInfo->fFlags = 0;
46 pPgInfo->u.apbEntries[0] = NULL;
47 pPgInfo->u.apbEntries[1] = NULL;
48 pPgInfo->u.apbEntries[2] = NULL;
49 pPgInfo->u.apbEntries[3] = NULL;
50
51 if (!fLegacyPTs)
52 {
53#if TMPL_BITS == 16
54 uint32_t const uMaxAddr = BS3_MODE_IS_RM_OR_V86(g_bBs3CurrentMode) ? _1M - 1 : BS3_SEL_TILED_AREA_SIZE - 1;
55#else
56 uintptr_t const uMaxAddr = ~(uintptr_t)0;
57#endif
58 uint64_t const fEfer = g_uBs3CpuDetected & BS3CPU_F_LONG_MODE ? ASMRdMsr(MSR_K6_EFER) : 0;
59
60 pPgInfo->cEntries = fEfer & MSR_K6_EFER_LMA ? 4 : 3;
61 pPgInfo->cbEntry = sizeof(X86PTEPAE);
62 if ((cr3 & X86_CR3_AMD64_PAGE_MASK) <= uMaxAddr)
63 {
64 if ( (fEfer & MSR_K6_EFER_LMA)
65 && X86_IS_CANONICAL(uFlat))
66 {
67 /* 48-bit long mode paging. */
68 pPgInfo->u.Pae.pPml4e = (X86PML4E BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_AMD64_PAGE_MASK);
69 pPgInfo->u.Pae.pPml4e += (uFlat >> X86_PML4_SHIFT) & X86_PML4_MASK;
70 if (!pPgInfo->u.Pae.pPml4e->n.u1Present)
71 rc = VERR_PAGE_NOT_PRESENT;
72 else if ((pPgInfo->u.Pae.pPml4e->u & X86_PML4E_PG_MASK) <= uMaxAddr)
73 {
74 pPgInfo->u.Pae.pPdpe = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPml4e->u & X86_PML4E_PG_MASK);
75 pPgInfo->u.Pae.pPdpe += (uFlat >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
76 if (!pPgInfo->u.Pae.pPdpe->n.u1Present)
77 rc = VERR_PAGE_NOT_PRESENT;
78 else if (pPgInfo->u.Pae.pPdpe->b.u1Size)
79 rc = VINF_SUCCESS;
80 else
81 rc = VINF_TRY_AGAIN;
82 }
83 }
84 else if ( !(fEfer & MSR_K6_EFER_LMA)
85 && uFlat <= _4G)
86 {
87 /* 32-bit PAE paging. */
88 pPgInfo->u.Pae.pPdpe = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_PAE_PAGE_MASK);
89 pPgInfo->u.Pae.pPdpe += ((uint32_t)uFlat >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE;
90 if (!pPgInfo->u.Pae.pPdpe->n.u1Present)
91 rc = VERR_PAGE_NOT_PRESENT;
92 else
93 rc = VINF_TRY_AGAIN;
94 }
95
96 /* Common code for the PD and PT levels. */
97 if ( rc == VINF_TRY_AGAIN
98 && (pPgInfo->u.Pae.pPdpe->u & X86_PDPE_PG_MASK) <= uMaxAddr)
99 {
100 rc = VERR_OUT_OF_RANGE;
101 pPgInfo->u.Pae.pPde = (X86PDEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPdpe->u & X86_PDPE_PG_MASK);
102 pPgInfo->u.Pae.pPde += (uFlat >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK;
103 if (!pPgInfo->u.Pae.pPde->n.u1Present)
104 rc = VERR_PAGE_NOT_PRESENT;
105 else if (pPgInfo->u.Pae.pPde->b.u1Size)
106 rc = VINF_SUCCESS;
107 else if ((pPgInfo->u.Pae.pPde->u & X86_PDE_PAE_PG_MASK) <= uMaxAddr)
108 {
109 pPgInfo->u.Pae.pPte = (X86PTEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPde->u & X86_PDE_PAE_PG_MASK);
110 rc = VINF_SUCCESS;
111 }
112 }
113 else if (rc == VINF_TRY_AGAIN)
114 rc = VERR_OUT_OF_RANGE;
115 }
116 }
117 else
118 {
119#if TMPL_BITS == 16
120 uint32_t const uMaxAddr = BS3_MODE_IS_RM_OR_V86(g_bBs3CurrentMode) ? _1M - 1 : BS3_SEL_TILED_AREA_SIZE - 1;
121#else
122 uint32_t const uMaxAddr = UINT32_MAX;
123#endif
124
125 pPgInfo->cEntries = 2;
126 pPgInfo->cbEntry = sizeof(X86PTE);
127 if ( uFlat < _4G
128 && cr3 <= uMaxAddr)
129 {
130 pPgInfo->u.Legacy.pPde = (X86PDE BS3_FAR *)Bs3XptrFlatToCurrent(cr3 & X86_CR3_PAGE_MASK);
131 pPgInfo->u.Legacy.pPde += ((uint32_t)uFlat >> X86_PD_SHIFT) & X86_PD_MASK;
132 if (!pPgInfo->u.Legacy.pPde->b.u1Present)
133 rc = VERR_PAGE_NOT_PRESENT;
134 else if (pPgInfo->u.Legacy.pPde->b.u1Size)
135 rc = VINF_SUCCESS;
136 else if (pPgInfo->u.Legacy.pPde->u <= uMaxAddr)
137 {
138 pPgInfo->u.Legacy.pPte = (X86PTE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Legacy.pPde->u & X86_PDE_PG_MASK);
139 pPgInfo->u.Legacy.pPte += ((uint32_t)uFlat >> X86_PT_SHIFT) & X86_PT_MASK;
140 if (pPgInfo->u.Legacy.pPte->n.u1Present)
141 rc = VINF_SUCCESS;
142 else
143 rc = VERR_PAGE_NOT_PRESENT;
144 }
145 }
146 }
147 return rc;
148}
149
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette