VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/DevPcArch.c@ 44600

Last change on this file since 44600 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

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