VirtualBox

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

Last change on this file since 62509 was 62509, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.4 KB
Line 
1/* $Id: DevPcArch.cpp 62509 2016-07-22 19:12:22Z vboxsync $ */
2/** @file
3 * DevPcArch - PC Architecture Device.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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