diff options
| author | Javier <dev.git@javispedro.com> | 2022-03-29 01:15:53 +0200 | 
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2022-03-29 01:15:53 +0200 | 
| commit | a816d1a09b1045fb5c155ac73f3231fcf9d93180 (patch) | |
| tree | c4e31e850b9f2afb36acd6119483cf350c33f596 /vbox.c | |
| parent | 67ebca92621aef31ff97705013456e95e60f7fbe (diff) | |
| download | vbados-a816d1a09b1045fb5c155ac73f3231fcf9d93180.tar.gz vbados-a816d1a09b1045fb5c155ac73f3231fcf9d93180.zip | |
initial import of DOS mouse driver
Diffstat (limited to 'vbox.c')
| -rw-r--r-- | vbox.c | 243 | 
1 files changed, 33 insertions, 210 deletions
| @@ -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;  } - | 
