VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/DevPcArch.cpp@ 60756

Last change on this file since 60756 was 60404, checked in by vboxsync, 9 years ago

VMM,Devices,Main: Implemented soft/warm reset for shutdown status codes 05h, 09h and 0Ah.

This is a shot at adjusting our VM reset handling to handle the ancient way of
getting a 286 out of protected mode and back to real mode. Our exiting reset
code (XXXR3Reset, PDMDEVREG::pfnReset, and so on) is doing a cold reset of the
system and then some additional device & memory initialization that the firmware
is usually responsible for doing. When the guest triggers a reset via the
keyboard controller, system control port A, CPU triple fault, and possibly ACPI,
only the CPU is supposed to be reset. The BIOS would then decide whether memory
and devices needed resetting as well, or if the resetter justed wanted to get out
protected mode and resume executing some real mode code pointed to by 467h.

  • New states SOFT_RESETTING and SOFT_RESETTING_LS. The latter returns to RUNNING_LS, not SUSPENDED_LS like for hard reset.
  • Added a firmware interface so the VMM/PDM can ask it whether we're supposed to do a hard reset or a soft(/warm) one.
  • Implemented firmware interface for the PC BIOS (but not EFI). It indicates soft(/warm) reset when CMOS[0xf] is 5, 9 or 10.
  • Moved the CMOS[0xf] resetting from the RTC device to the PC BIOS since it's firmware thing, not RTC.
  • Added a flag parameter to PDMDevHlpVMReset for specifying the source of the reset operation. One class of sources (GIM) will always trigger hard resets, whereas the others will check with the firmware first.
  • Added PDMR3GetResetInfo for query the flags passed to PDMDevHlpVMReset and for asking the firmware whether it's a hard or soft reset. The latter, however, is only done if only CPU 0 is active. Systems with more than one CPU in a state other than EMSTATE_WAIT_SIPI status will always be hard reset.
  • Added internal VMR3ResetFF and VMR3ResetTripleFault APIs for handling the VM_FF_RESET and VINF_EM_TRIPLE_FAULT conditions.
  • Added PMDR3ResetSoft and had it call pfnSoftReset (which is now defined).

Warning! Major PDM_DEVHLPR3_VERSION change, minor PDM_DEVREG_VERSION change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.4 KB
Line 
1/* $Id: DevPcArch.cpp 60404 2016-04-09 23:45:55Z vboxsync $ */
2/** @file
3 * DevPcArch - PC Architecture Device.
4 */
5
6/*
7 * Copyright (C) 2006-2015 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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_PC_ARCH
23#include <VBox/vmm/pdmdev.h>
24#include <VBox/vmm/mm.h>
25#include <VBox/log.h>
26#include <VBox/err.h>
27#include <iprt/assert.h>
28#include <iprt/string.h>
29
30#include "VBoxDD.h"
31
32
33/*********************************************************************************************************************************
34* Structures and Typedefs *
35*********************************************************************************************************************************/
36
37/**
38 * PC Bios instance data structure.
39 */
40typedef struct DEVPCARCH
41{
42 /** Pointer back to the device instance. */
43 PPDMDEVINS pDevIns;
44} DEVPCARCH, *PDEVPCARCH;
45
46
47
48/**
49 * @callback_method_impl{FNIOMIOPORTIN, Math coprocessor.}
50 */
51static DECLCALLBACK(int) pcarchIOPortFPURead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
52{
53 int rc;
54 NOREF(pvUser); NOREF(pDevIns); NOREF(pu32);
55 rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d\n", Port, cb);
56 if (rc == VINF_SUCCESS)
57 rc = VERR_IOM_IOPORT_UNUSED;
58 return rc;
59}
60
61/**
62 * @callback_method_impl{FNIOMIOPORTOUT, Math coprocessor.}
63 * @todo Add IGNNE support.
64 */
65static DECLCALLBACK(int) pcarchIOPortFPUWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
66{
67 int rc = VINF_SUCCESS;
68 NOREF(pvUser);
69 if (cb == 1)
70 {
71 switch (Port)
72 {
73 /*
74 * Clear busy latch.
75 */
76 case 0xf0:
77 Log2(("PCARCH: FPU Clear busy latch u32=%#x\n", u32));
78/* This is triggered when booting Knoppix (3.7) */
79#if 0
80 if (!u32)
81 rc = PDMDeviceDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d u32=%#x\n", Port, cb, u32);
82#endif
83 /* pDevIns->pHlp->pfnPICSetIrq(pDevIns, 13, 0); */
84 break;
85
86 /* Reset. */
87 case 0xf1:
88 Log2(("PCARCH: FPU Reset cb=%d u32=%#x\n", cb, u32));
89 /** @todo figure out what the difference between FPU ports 0xf0 and 0xf1 are... */
90 /* pDevIns->pHlp->pfnPICSetIrq(pDevIns, 13, 0); */
91 break;
92
93 /* opcode transfers */
94 case 0xf8:
95 case 0xfa:
96 case 0xfc:
97 default:
98 rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d u32=%#x\n", Port, cb, u32);
99 break;
100 }
101 /* this works better, but probably not entirely correct. */
102 PDMDevHlpISASetIrq(pDevIns, 13, 0);
103 }
104 else
105 rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d u32=%#x\n", Port, cb, u32);
106 return rc;
107}
108
109
110/**
111 * @callback_method_impl{FNIOMIOPORTIN, PS/2 system control port A.}
112 *
113 * @todo Check if the A20 enable/disable method implemented here in any way
114 * should cooperate with the one implemented in the PS/2 keyboard device.
115 * This probably belongs together in the PS/2 keyboard device (since that
116 * is where the "port B" mentioned by Ralph Brown is implemented).
117 *
118 * @remark Ralph Brown and friends have this to say about this port:
119 *
120 * @verbatim
1210092 RW PS/2 system control port A (port B is at PORT 0061h) (see #P0415)
122
123Bitfields for PS/2 system control port A:
124Bit(s) Description (Table P0415)
125 7-6 any bit set to 1 turns activity light on
126 5 unused
127 4 watchdog timout occurred
128 3 =0 RTC/CMOS security lock (on password area) unlocked
129 =1 CMOS locked (done by POST)
130 2 unused
131 1 A20 is active
132 0 =0 system reset or write
133 =1 pulse alternate reset pin (high-speed alternate CPU reset)
134Notes: once set, bit 3 may only be cleared by a power-on reset
135 on at least the C&T 82C235, bit 0 remains set through a CPU reset to
136 allow the BIOS to determine the reset method
137 on the PS/2 30-286 & "Tortuga" the INT 15h/87h memory copy does
138 not use this port for A20 control, but instead uses the keyboard
139 controller (8042). Reportedly this may cause the system to crash
140 when access to the 8042 is disabled in password server mode
141 (see #P0398).
142SeeAlso: #P0416,#P0417,MSR 00001000h
143 * @endverbatim
144 */
145static DECLCALLBACK(int)
146pcarchIOPortPS2SysControlPortARead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
147{
148 if (cb == 1)
149 {
150 *pu32 = PDMDevHlpA20IsEnabled(pDevIns) << 1;
151 return VINF_SUCCESS;
152 }
153 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d\n", Port, cb);
154}
155
156
157/**
158 * @callback_method_impl{FNIOMIOPORTOUT, PS/2 system control port A.}
159 * @see Remark and todo of pcarchIOPortPS2SysControlPortARead().
160 */
161static DECLCALLBACK(int)
162pcarchIOPortPS2SysControlPortAWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
163{
164 NOREF(pvUser);
165 if (cb == 1)
166 {
167 /*
168 * Fast reset?
169 */
170 if (u32 & 1)
171 {
172 LogRel(("Reset initiated by system port A\n"));
173 return PDMDevHlpVMReset(pDevIns, PDMVMRESET_F_PORT_A);
174 }
175
176 /*
177 * A20 is the only thing we care about of the other stuff.
178 */
179 PDMDevHlpA20Set(pDevIns, !!(u32 & 2));
180 return VINF_SUCCESS;
181 }
182 return PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "Port=%#x cb=%d u32=%#x\n", Port, cb, u32);
183}
184
185
186/**
187 * @interface_method_impl{PDMDEVREG,pfnConstruct}
188 */
189static DECLCALLBACK(int) pcarchConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
190{
191 PDEVPCARCH pThis = PDMINS_2_DATA(pDevIns, PDEVPCARCH);
192 int rc;
193 Assert(iInstance == 0);
194
195 /*
196 * Validate configuration.
197 */
198 if (!CFGMR3AreValuesValid(pCfg, "\0"))
199 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
200
201 /*
202 * Init the data.
203 */
204 pThis->pDevIns = pDevIns;
205
206 /*
207 * Register I/O Ports
208 */
209 rc = PDMDevHlpIOPortRegister(pDevIns, 0xF0, 0x10, NULL,
210 pcarchIOPortFPUWrite, pcarchIOPortFPURead,
211 NULL, NULL, "Math Co-Processor (DOS/OS2 mode)");
212 if (RT_FAILURE(rc))
213 return rc;
214 rc = PDMDevHlpIOPortRegister(pDevIns, 0x92, 1, NULL,
215 pcarchIOPortPS2SysControlPortAWrite, pcarchIOPortPS2SysControlPortARead,
216 NULL, NULL, "PS/2 system control port A (A20 and more)");
217 if (RT_FAILURE(rc))
218 return rc;
219
220 return VINF_SUCCESS;
221}
222
223
224/**
225 * The device registration structure.
226 */
227const PDMDEVREG g_DevicePcArch =
228{
229 /* u32Version */
230 PDM_DEVREG_VERSION,
231 /* szName */
232 "pcarch",
233 /* szRCMod */
234 "",
235 /* szR0Mod */
236 "",
237 /* pszDescription */
238 "PC Architecture Device",
239 /* fFlags */
240 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
241 /* fClass */
242 PDM_DEVREG_CLASS_ARCH,
243 /* cMaxInstances */
244 1,
245 /* cbInstance */
246 sizeof(DEVPCARCH),
247 /* pfnConstruct */
248 pcarchConstruct,
249 /* pfnDestruct */
250 NULL,
251 /* pfnRelocate */
252 NULL,
253 /* pfnMemSetup */
254 NULL,
255 /* pfnPowerOn */
256 NULL,
257 /* pfnReset */
258 NULL,
259 /* pfnSuspend */
260 NULL,
261 /* pfnResume */
262 NULL,
263 /* pfnAttach */
264 NULL,
265 /* pfnDetach */
266 NULL,
267 /* pfnQueryInterface. */
268 NULL,
269 /* pfnInitComplete. */
270 NULL,
271 /* pfnPowerOff */
272 NULL,
273 /* pfnSoftReset */
274 NULL,
275 /* u32VersionEnd */
276 PDM_DEVREG_VERSION
277};
278
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