VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp@ 51926

最後變更 在這個檔案從51926是 51797,由 vboxsync 提交於 11 年 前

VMM/GIM/Minimal: OS X bits.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 6.1 KB
 
1/* $Id: GIMMinimal.cpp 51797 2014-07-02 06:09:31Z vboxsync $ */
2/** @file
3 * GIM - Guest Interface Manager, Minimal implementation.
4 */
5
6/*
7 * Copyright (C) 2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#define LOG_GROUP LOG_GROUP_GIM
22#include "GIMInternal.h"
23
24#include <iprt/assert.h>
25#include <iprt/err.h>
26#include <iprt/asm-amd64-x86.h>
27
28#include <VBox/vmm/cpum.h>
29#include <VBox/vmm/vm.h>
30
31/*******************************************************************************
32* Defined Constants And Macros *
33*******************************************************************************/
34
35VMMR3_INT_DECL(int) GIMR3MinimalInit(PVM pVM, GIMOSID enmGuest)
36{
37 AssertReturn(pVM, VERR_INVALID_PARAMETER);
38 AssertReturn(pVM->gim.s.enmProviderId == GIMPROVIDERID_MINIMAL, VERR_INTERNAL_ERROR_5);
39
40 /*
41 * Enable the Hypervisor Present.
42 */
43 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
44
45 if (GIMR3IsOSXGuest(enmGuest))
46 {
47 /*
48 * Enable MWAIT Extensions for OS X Guests.
49 */
50 CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_MWAIT_EXTS);
51
52 /*
53 * Fake the CPU family/model so the guest works. This is partly because older
54 * Mac releases really doesn't work on newer CPUs, and partly because OS X
55 * expects more from systems with newer CPUs (MSRs, power features etc.)
56 */
57 if (CPUMGetGuestCpuVendor(pVM) == CPUMCPUVENDOR_INTEL)
58 {
59 uint32_t uMaxIntelFamilyModelStep = UINT32_MAX;
60 switch (enmGuest)
61 {
62 case GIMOSID_OSX:
63 case GIMOSID_OSX_64:
64 uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482. */
65 break;
66 case GIMOSID_OSX_106:
67 case GIMOSID_OSX_106_64:
68 uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */
69 break;
70 case GIMOSID_OSX_107:
71 case GIMOSID_OSX_107_64:
72 /** @todo Figure out what is required here. */
73 uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */
74 break;
75 case GIMOSID_OSX_108:
76 case GIMOSID_OSX_108_64:
77 /** @todo Figure out what is required here. */
78 uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */
79 break;
80 case GIMOSID_OSX_109:
81 case GIMOSID_OSX_109_64:
82 /** @todo Figure out what is required here. */
83 uMaxIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(1, 23, 6, 7); /* Penryn / X5482 */
84 break;
85
86 default: /* shut up gcc */
87 break;
88 }
89
90 if (uMaxIntelFamilyModelStep != UINT32_MAX)
91 {
92 CPUMCPUIDLEAF Leaf;
93 int rc = CPUMR3CpuIdGetLeaf(pVM, &Leaf, 1, 0);
94 if (RT_SUCCESS(rc))
95 {
96 uint32_t uCurIntelFamilyModelStep = RT_MAKE_U32_FROM_U8(ASMGetCpuStepping(Leaf.uEax),
97 ASMGetCpuModelIntel(Leaf.uEax),
98 ASMGetCpuFamily(Leaf.uEax),
99 0);
100 if (uMaxIntelFamilyModelStep < uCurIntelFamilyModelStep)
101 {
102 uint32_t uNew = Leaf.uEax & UINT32_C(0xf0003000);
103 uNew |= RT_BYTE1(uMaxIntelFamilyModelStep) & 0xf; /* stepping */
104 uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) & 0xf) << 4; /* 4 low model bits */
105 uNew |= (RT_BYTE2(uMaxIntelFamilyModelStep) >> 4) << 16; /* 4 high model bits */
106 uNew |= (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf) << 8; /* 4 low family bits */
107 /* 8 high family bits, Intel's suggested calculation. */
108 if (RT_BYTE3(uMaxIntelFamilyModelStep) > 0xf)
109 {
110 uNew |= ( (RT_BYTE3(uMaxIntelFamilyModelStep)
111 - (RT_BYTE3(uMaxIntelFamilyModelStep) & 0xf)) & 0xff ) << 20;
112 }
113
114 LogRel(("GIM: Minimal: CPUID(0).EAX %#x -> %#x (uMaxIntelFamilyModelStep=%#x, uCurIntelFamilyModelStep=%#x\n",
115 Leaf.uEax, uNew, uMaxIntelFamilyModelStep, uCurIntelFamilyModelStep));
116 Leaf.uEax = uNew;
117 }
118
119 rc = CPUMR3CpuIdInsert(pVM, &Leaf);
120 if (RT_FAILURE(rc))
121 {
122 LogRel(("GIM: Minimal: Failed to insert CPUID leaf for OS X guest. rc=%Rrc\n", rc));
123 return rc;
124 }
125 }
126 else
127 {
128 LogRel(("GIM: Minimal: Failed to retreive std. CPUID leaf. rc=%Rrc\n", rc));
129 return rc;
130 }
131 }
132 }
133 }
134
135 /** @todo Register CPUID leaves, MSR ranges with CPUM. */
136 /** -XXX_ CPUMGetGuestCpuId CPUMGetGuestCpuVendor CPUMR3CpuIdInsert */
137 return VINF_SUCCESS;
138}
139
140
141VMMR3_INT_DECL(void) GIMR3MinimalRelocate(PVM pVM, RTGCINTPTR offDelta)
142{
143 NOREF(pVM); NOREF(offDelta);
144}
145
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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