aboutsummaryrefslogtreecommitdiff
path: root/vbox.c
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-03-29 01:15:53 +0200
committerJavier <dev.git@javispedro.com>2022-03-29 01:15:53 +0200
commita816d1a09b1045fb5c155ac73f3231fcf9d93180 (patch)
treec4e31e850b9f2afb36acd6119483cf350c33f596 /vbox.c
parent67ebca92621aef31ff97705013456e95e60f7fbe (diff)
downloadvbados-a816d1a09b1045fb5c155ac73f3231fcf9d93180.tar.gz
vbados-a816d1a09b1045fb5c155ac73f3231fcf9d93180.zip
initial import of DOS mouse driver
Diffstat (limited to 'vbox.c')
-rw-r--r--vbox.c243
1 files changed, 33 insertions, 210 deletions
diff --git a/vbox.c b/vbox.c
index b384b6f..6d33659 100644
--- a/vbox.c
+++ b/vbox.c
@@ -17,57 +17,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <windows.h>
#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
#include <i86.h>
#include "pci.h"
#include "vds.h"
+#include "dlog.h"
#include "vboxdev.h"
#include "vbox.h"
-// PCI device information
-/** VBox's PCI bus, device number, etc. */
-static pcisel vbpci;
-/** IO base of VBox's PCI device. */
-static uint16_t vbiobase;
-/** IRQ number of VBox's PCI device. Unused. */
-static uint8_t vbirq;
-
-/** Handle to fixed buffer used for communication with VBox device.
- * We also use Virtual DMA Service to obtain the physical address of this buffer,
- * so it must remain fixed in memory. */
-static HANDLE hBuf;
-static LPVOID pBuf;
-/** The DMA descriptor used by VDS corresponding to the above buffer. */
-static VDS_DDS bufdds;
-
-/** Actually send a request to the VirtualBox VMM device.
- * @param addr 32-bit physical address containing the VMMDevRequest struct.
- */
-static void vbox_send_request(uint32_t addr);
-#pragma aux vbox_send_request = \
- "movzx eax, ax" /* Need to make a single 32-bit write so combine both regs. */ \
- "movzx ebx, bx" \
- "shl ebx, 16" \
- "or eax, ebx" \
- "mov dx, vbiobase" \
- "out dx, eax" \
- "shr ebx, 16" \
- __parm [bx ax] \
- __modify [dx]
-
-/** Acknowledge an interrupt from the VirtualBox VMM device at iobase.
- * @return bitmask with all pending events (e.g. VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED). */
-static uint32_t vbox_irq_ack();
-#pragma aux vbox_irq_ack = \
- "mov dx, vbiobase" \
- "add dx, 8" \
- "in eax, dx" \
- "mov edx, eax" \
- "shr edx, 16" \
- __value [dx ax]
-
// Classic PCI defines
#define VBOX_PCI_VEND_ID 0x80ee
#define VBOX_PCI_PROD_ID 0xcafe
@@ -80,60 +40,48 @@ enum {
/** Finds the VirtualBox PCI device and reads the current IO base.
* @returns 0 if the device was found. */
-int vbox_init(void)
+static int vbox_find_iobase(uint16_t __far *iobase)
{
int err;
+ pcisel pcidev;
uint16_t command;
uint32_t bar;
if ((err = pci_init_bios())) {
- return -1;
+ return err;
}
- if ((err = pci_find_device(&vbpci, VBOX_PCI_VEND_ID, VBOX_PCI_PROD_ID, 0))) {
- return -1;
+ if ((err = pci_find_device(&pcidev, VBOX_PCI_VEND_ID, VBOX_PCI_PROD_ID, 0))) {
+ return err;
}
- if ((err = pci_read_config_word(vbpci, CFG_COMMAND, &command))
- || !(command & 1)) {
- return -2;
+ if ((err = pci_read_config_word(pcidev, CFG_COMMAND, &command))) {
+ return err;
}
- if ((err = pci_read_config_byte(vbpci, CFG_INTERRUPT, &vbirq))) {
- return -2;
+ if (!(command & 1)) {
+ // The card is not configured
+ return -1;
}
- if ((err = pci_read_config_dword(vbpci, CFG_BAR0, &bar))) {
- return -2;
+ if ((err = pci_read_config_dword(pcidev, CFG_BAR0, &bar))) {
+ return err;
}
if (!(bar & 1)) {
+ // This is not an IO BAR
return -2;
}
- vbiobase = bar & 0xFFFC;
+ *iobase = bar & 0xFFFC;
return 0;
}
-/** Allocates the buffers that will be used to communicate with the VirtualBox device. */
-int vbox_alloc_buffers(void)
+static int vbox_get_phys_addr(uint32_t __far *physaddr, void __far *buf)
{
- const unsigned int bufferSize = 36; // This should be the largest of all VMMDevRequest* structs that we can send
- int err;
-
- // Allocate the buffer (double the size for reasons explained below)
- hBuf = GlobalAlloc(GMEM_FIXED|GMEM_SHARE, bufferSize * 2);
- if (!hBuf) return -1;
-
- // Keep it in memory at a fixed location
- GlobalFix(hBuf);
- GlobalPageLock(hBuf);
-
- // Get the usable pointer / logical address of the buffer
- pBuf = (LPVOID) GlobalLock(hBuf);
- if (!pBuf) return -1;
-
+ int err = 0;
+#if 0
if (vds_available()) {
// Use the Virtual DMA Service to get the physical address of this buffer
bufdds.regionSize = bufferSize;
@@ -163,152 +111,27 @@ int vbox_alloc_buffers(void)
// If VDS is not available, assume we are not paging
// Just use the linear address as physical
- bufdds.physicalAddress = GetSelectorBase(FP_SEG(pBuf)) + FP_OFF(pBuf);
+ bufdds.physicalAddress = FP_SEG(pBuf + FP_OFF(pBuf);
err = 0;
}
+#endif
- return err;
-}
-
-/** Frees the buffers allocated by vbox_alloc_buffers(). */
-int vbox_free_buffers(void)
-{
- if (bufdds.regionSize > 0) {
- vds_unlock_dma_buffer_region(&bufdds, 0);
- }
- bufdds.regionSize = 0;
- bufdds.segOrSelector = 0;
- bufdds.offset = 0;
- bufdds.bufferId = 0;
- bufdds.physicalAddress = 0;
- GlobalFree(hBuf);
- hBuf = NULL;
- pBuf = NULL;
-
- return 0;
-}
-
-/** Lets VirtualBox know that there are VirtualBox Guest Additions on this guest.
- * @param osType os installed on this guest. */
-int vbox_report_guest_info(uint32_t osType)
-{
- VMMDevReportGuestInfo *req = pBuf;
-
- memset(req, 0, sizeof(VMMDevReportGuestInfo));
-
- req->header.size = sizeof(VMMDevReportGuestInfo);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_ReportGuestInfo;
- req->header.rc = -1;
- req->guestInfo.interfaceVersion = VMMDEV_VERSION;
- req->guestInfo.osType = osType;
-
- vbox_send_request(bufdds.physicalAddress);
-
- return req->header.rc;
-}
-
-/** Tells VirtualBox about the events we are interested in receiving.
- These events are notified via the PCI IRQ which we are not using, so this is not used either. */
-int vbox_set_filter_mask(uint32_t add, uint32_t remove)
-{
- VMMDevCtlGuestFilterMask *req = pBuf;
-
- memset(req, 0, sizeof(VMMDevCtlGuestFilterMask));
-
- req->header.size = sizeof(VMMDevCtlGuestFilterMask);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_CtlGuestFilterMask;
- req->header.rc = -1;
- req->u32OrMask = add;
- req->u32NotMask = remove;
-
- vbox_send_request(bufdds.physicalAddress);
-
- return req->header.rc;
-}
-
-/** Tells VirtualBox whether we want absolute mouse information or not. */
-int vbox_set_mouse(bool enable)
-{
- VMMDevReqMouseStatus *req = pBuf;
-
- memset(req, 0, sizeof(VMMDevReqMouseStatus));
-
- req->header.size = sizeof(VMMDevReqMouseStatus);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_SetMouseStatus;
- req->header.rc = -1;
- req->mouseFeatures = enable ? VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE : 0;
-
- vbox_send_request(bufdds.physicalAddress);
-
- return req->header.rc;
-}
-
-/** Gets the current absolute mouse position from VirtualBox.
- * @param abs false if user has disabled mouse integration in VirtualBox,
- * in which case we should fallback to PS/2 relative events. */
-int vbox_get_mouse(bool *abs, uint16_t *xpos, uint16_t *ypos)
-{
- VMMDevReqMouseStatus *req = pBuf;
-
- memset(req, 0, sizeof(VMMDevReqMouseStatus));
-
- req->header.size = sizeof(VMMDevReqMouseStatus);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_GetMouseStatus;
- req->header.rc = -1;
+ *physaddr = ((uint32_t)(FP_SEG(buf)) << 4) + FP_OFF(buf);
- vbox_send_request(bufdds.physicalAddress);
-
- *abs = req->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;
- *xpos = req->pointerXPos;
- *ypos = req->pointerYPos;
-
- return req->header.rc;
-}
-
-#pragma code_seg ( "CALLBACKS" )
-
-/** This is a version of vbox_set_mouse() that does not call any other functions,
- * and may be called inside an interrupt handler. */
-int vbox_set_mouse_locked(bool enable)
-{
- VMMDevReqMouseStatus *req = pBuf;
-
- req->header.size = sizeof(VMMDevReqMouseStatus);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_SetMouseStatus;
- req->header.rc = -1;
- req->mouseFeatures = enable ? VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE : 0;
- req->pointerXPos = 0;
- req->pointerYPos = 0;
-
- vbox_send_request(bufdds.physicalAddress);
-
- return req->header.rc;
+ return err;
}
-/** Likewise for vbox_get_mouse() */
-int vbox_get_mouse_locked(bool *abs, uint16_t *xpos, uint16_t *ypos)
+int vbox_init(LPVBOXCOMM vb)
{
- VMMDevReqMouseStatus *req = pBuf;
-
- req->header.size = sizeof(VMMDevReqMouseStatus);
- req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
- req->header.requestType = VMMDevReq_GetMouseStatus;
- req->header.rc = -1;
- req->mouseFeatures = 0;
- req->pointerXPos = 0;
- req->pointerYPos = 0;
+ int err;
- vbox_send_request(bufdds.physicalAddress);
+ if ((err = vbox_find_iobase(&vb->iobase))) {
+ return err;
+ }
- *abs = req->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;
- *xpos = req->pointerXPos;
- *ypos = req->pointerYPos;
+ if (err = vbox_get_phys_addr(&vb->buf_physaddr, vb->buf)) {
+ return err;
+ }
- return req->header.rc;
+ return 0;
}
-