Break out vbox guest driver
- Add general support for changing display resolution. - Support display resolution changes in the vmware svga driver. - Add a small module to add a set_mode command to the debug shell. - Include these modules on CDs. - Include the vidset module in debug/qemu targets.
This commit is contained in:
parent
a9fabe285d
commit
ee81679c40
1
Makefile
1
Makefile
@ -83,6 +83,7 @@ BOOT_MODULES += ext2
|
||||
BOOT_MODULES += debug_shell
|
||||
BOOT_MODULES += ps2mouse ps2kbd
|
||||
BOOT_MODULES += lfbvideo
|
||||
BOOT_MODULES += vidset
|
||||
BOOT_MODULES += packetfs
|
||||
BOOT_MODULES += snd
|
||||
BOOT_MODULES += pcspkr
|
||||
|
@ -7,4 +7,12 @@
|
||||
#define IO_VID_ADDR 0x5004
|
||||
#define IO_VID_SIGNAL 0x5005
|
||||
|
||||
#ifdef _KERNEL_
|
||||
extern void lfb_set_resolution(uint16_t x, uint16_t y);
|
||||
extern uint16_t lfb_resolution_x;
|
||||
extern uint16_t lfb_resolution_y;
|
||||
extern uint16_t lfb_resolution_b;
|
||||
extern uint8_t * lfb_vid_memory;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include <tokenize.h>
|
||||
#include <module.h>
|
||||
#include <video.h>
|
||||
#include <pipe.h>
|
||||
#include <mouse.h>
|
||||
|
||||
#include "../userspace/gui/terminal/terminal-font.h"
|
||||
|
||||
@ -27,16 +25,15 @@
|
||||
/* Generic (pre-set, 32-bit, linear frame buffer) */
|
||||
static void graphics_install_preset(uint16_t, uint16_t);
|
||||
|
||||
static uint16_t lfb_resolution_x = 0;
|
||||
static uint16_t lfb_resolution_y = 0;
|
||||
static uint16_t lfb_resolution_b = 0;
|
||||
uint16_t lfb_resolution_x = 0;
|
||||
uint16_t lfb_resolution_y = 0;
|
||||
uint16_t lfb_resolution_b = 0;
|
||||
|
||||
/* BOCHS / QEMU VBE Driver */
|
||||
static void graphics_install_bochs(uint16_t, uint16_t);
|
||||
static void bochs_set_y_offset(uint16_t y);
|
||||
static uint16_t bochs_current_scroll(void);
|
||||
|
||||
static void vbox_check(void);
|
||||
static pid_t display_change_recipient = 0;
|
||||
|
||||
/*
|
||||
@ -44,7 +41,7 @@ static pid_t display_change_recipient = 0;
|
||||
* This can move, so it's a pointer instead of
|
||||
* #define.
|
||||
*/
|
||||
static uint8_t * lfb_vid_memory = (uint8_t *)0xE0000000;
|
||||
uint8_t * lfb_vid_memory = (uint8_t *)0xE0000000;
|
||||
|
||||
static int ioctl_vid(fs_node_t * node, int request, void * argp) {
|
||||
/* TODO: Make this actually support multiple video devices */
|
||||
@ -199,11 +196,42 @@ static void bochs_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra
|
||||
}
|
||||
}
|
||||
|
||||
static void (*lfb_resolution_impl)(uint16_t,uint16_t) = NULL;
|
||||
|
||||
void lfb_set_resolution(uint16_t x, uint16_t y) {
|
||||
|
||||
if (lfb_resolution_impl) {
|
||||
lfb_resolution_impl(x,y);
|
||||
if (display_change_recipient) {
|
||||
send_signal(display_change_recipient, SIGWINEVENT);
|
||||
debug_print(WARNING, "Telling %d to SIGWINEVENT", display_change_recipient);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void res_change_bochs(uint16_t x, uint16_t y) {
|
||||
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x00);
|
||||
/* Uh oh, here we go. */
|
||||
outports(0x1CE, 0x01);
|
||||
outports(0x1CF, x);
|
||||
/* Set Y resolution to 768 */
|
||||
outports(0x1CE, 0x02);
|
||||
outports(0x1CF, y);
|
||||
/* Turn it back on */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x41);
|
||||
|
||||
lfb_resolution_x = x;
|
||||
lfb_resolution_y = y;
|
||||
}
|
||||
|
||||
|
||||
static void graphics_install_bochs(uint16_t resolution_x, uint16_t resolution_y) {
|
||||
debug_print(NOTICE, "Setting up BOCHS/QEMU graphics controller...");
|
||||
|
||||
vbox_check();
|
||||
|
||||
outports(0x1CE, 0x00);
|
||||
uint16_t i = inports(0x1CF);
|
||||
if (i < 0xB0C0 || i > 0xB0C6) {
|
||||
@ -232,6 +260,8 @@ static void graphics_install_bochs(uint16_t resolution_x, uint16_t resolution_y)
|
||||
|
||||
pci_scan(bochs_scan_pci, -1, &lfb_vid_memory);
|
||||
|
||||
lfb_resolution_impl = &res_change_bochs;
|
||||
|
||||
if (lfb_vid_memory) {
|
||||
/* Enable the higher memory */
|
||||
uintptr_t fb_offset = (uintptr_t)lfb_vid_memory;
|
||||
@ -332,231 +362,6 @@ mem_found:
|
||||
}
|
||||
}
|
||||
|
||||
#define VBOX_VENDOR_ID 0x80EE
|
||||
#define VBOX_DEVICE_ID 0xCAFE
|
||||
|
||||
static void vbox_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra) {
|
||||
if (v == VBOX_VENDOR_ID && d == VBOX_DEVICE_ID) {
|
||||
*((uint32_t *)extra) = device;
|
||||
}
|
||||
}
|
||||
|
||||
#define VMMDEV_VERSION 0x00010003
|
||||
#define VBOX_REQUEST_HEADER_VERSION 0x10001
|
||||
struct vbox_header {
|
||||
uint32_t size;
|
||||
uint32_t version;
|
||||
uint32_t requestType;
|
||||
int32_t rc;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
struct vbox_guest_info {
|
||||
struct vbox_header header;
|
||||
uint32_t version;
|
||||
uint32_t ostype;
|
||||
};
|
||||
|
||||
struct vbox_guest_caps {
|
||||
struct vbox_header header;
|
||||
uint32_t caps;
|
||||
};
|
||||
|
||||
struct vbox_ack_events {
|
||||
struct vbox_header header;
|
||||
uint32_t events;
|
||||
};
|
||||
|
||||
struct vbox_display_change {
|
||||
struct vbox_header header;
|
||||
uint32_t xres;
|
||||
uint32_t yres;
|
||||
uint32_t bpp;
|
||||
uint32_t eventack;
|
||||
};
|
||||
|
||||
struct vbox_mouse {
|
||||
struct vbox_header header;
|
||||
uint32_t features;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
};
|
||||
|
||||
|
||||
#define EARLY_LOG_DEVICE 0x504
|
||||
static uint32_t _vbox_write(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
outportb(EARLY_LOG_DEVICE, buffer[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
static fs_node_t vb = { .write = &_vbox_write };
|
||||
|
||||
static uint32_t vbox_device = 0;
|
||||
static uint32_t vbox_port = 0x0;
|
||||
static int vbox_irq = 0;
|
||||
|
||||
static struct vbox_ack_events * vbox_irq_ack;
|
||||
static uint32_t vbox_phys_ack;
|
||||
static struct vbox_display_change * vbox_disp;
|
||||
static uint32_t vbox_phys_disp;
|
||||
static struct vbox_mouse * vbox_m;
|
||||
static uint32_t vbox_phys_mouse;
|
||||
static uint32_t * vbox_vmmdev = 0;
|
||||
|
||||
static fs_node_t * mouse_pipe;
|
||||
|
||||
#define PACKETS_IN_PIPE 1024
|
||||
#define DISCARD_POINT 32
|
||||
|
||||
static int vbox_irq_handler(struct regs *r) {
|
||||
// debug_print(WARNING, "(vbox-toaru) irq received; pending events are 0x%x", vbox_vmmdev[4]);
|
||||
outportl(vbox_port, vbox_phys_disp);
|
||||
outportl(vbox_port, vbox_phys_mouse);
|
||||
outportl(vbox_port, vbox_phys_ack);
|
||||
irq_ack(vbox_irq);
|
||||
// debug_print(WARNING, "Display stuff: %d %d %d\n", vbox_disp->xres, vbox_disp->yres, vbox_disp->bpp);
|
||||
|
||||
if (lfb_vid_memory && lfb_resolution_x && lfb_resolution_y && vbox_m->x && vbox_m->y) {
|
||||
// debug_print(WARNING, "Mouse stuff: 0x%x 0x%x 0x%x\n", vbox_m->features, vbox_m->x, vbox_m->y);
|
||||
|
||||
unsigned int x = ((unsigned int)vbox_m->x * lfb_resolution_x) / 0xFFFF;
|
||||
unsigned int y = ((unsigned int)vbox_m->y * lfb_resolution_y) / 0xFFFF;
|
||||
|
||||
mouse_device_packet_t packet;
|
||||
packet.magic = MOUSE_MAGIC;
|
||||
packet.x_difference = x;
|
||||
packet.y_difference = y;
|
||||
packet.buttons = 0;
|
||||
|
||||
mouse_device_packet_t bitbucket;
|
||||
while (pipe_size(mouse_pipe) > (int)(DISCARD_POINT * sizeof(packet))) {
|
||||
read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket);
|
||||
}
|
||||
write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet);
|
||||
}
|
||||
|
||||
|
||||
if (lfb_resolution_x && vbox_disp->xres && (vbox_disp->xres != lfb_resolution_x || vbox_disp->yres != lfb_resolution_y)) {
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x00);
|
||||
/* Uh oh, here we go. */
|
||||
outports(0x1CE, 0x01);
|
||||
outports(0x1CF, vbox_disp->xres);
|
||||
/* Set Y resolution to 768 */
|
||||
outports(0x1CE, 0x02);
|
||||
outports(0x1CF, vbox_disp->yres);
|
||||
/* Turn it back on */
|
||||
outports(0x1CE, 0x04);
|
||||
outports(0x1CF, 0x41);
|
||||
lfb_resolution_x = vbox_disp->xres;
|
||||
lfb_resolution_y = vbox_disp->yres;
|
||||
|
||||
if (display_change_recipient) {
|
||||
send_signal(display_change_recipient, SIGWINEVENT);
|
||||
debug_print(WARNING, "Telling %d to SIGWINEVENT", display_change_recipient);
|
||||
}
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vbox_check(void) {
|
||||
pci_scan(vbox_scan_pci, -1, &vbox_device);
|
||||
|
||||
if (vbox_device) {
|
||||
fprintf(&vb, "VirtualBox host detected, switching log to VirtualBox.\n");
|
||||
debug_file = &vb;
|
||||
|
||||
uintptr_t t = pci_read_field(vbox_device, PCI_BAR0, 4);
|
||||
if (t > 0) {
|
||||
vbox_port = (t & 0xFFFFFFF0);
|
||||
}
|
||||
|
||||
mouse_pipe = make_pipe(sizeof(mouse_device_packet_t) * PACKETS_IN_PIPE);
|
||||
mouse_pipe->flags = FS_CHARDEVICE;
|
||||
|
||||
vfs_mount("/dev/absmouse", mouse_pipe);
|
||||
|
||||
vbox_irq = pci_read_field(vbox_device, PCI_INTERRUPT_LINE, 1);
|
||||
debug_print(WARNING, "(vbox) device IRQ is set to %d\n", vbox_irq);
|
||||
irq_install_handler(vbox_irq, vbox_irq_handler);
|
||||
|
||||
uint32_t vbox_phys = 0;
|
||||
struct vbox_guest_info * packet = (void*)kvmalloc_p(0x1000, &vbox_phys);
|
||||
packet->header.size = sizeof(struct vbox_guest_info);
|
||||
packet->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
packet->header.requestType = 50;
|
||||
packet->header.rc = 0;
|
||||
packet->header.reserved1 = 0;
|
||||
packet->header.reserved2 = 0;
|
||||
packet->version = VMMDEV_VERSION;
|
||||
packet->ostype = 0;
|
||||
|
||||
outportl(vbox_port, vbox_phys);
|
||||
|
||||
struct vbox_guest_caps * caps = (void*)kvmalloc_p(0x1000, &vbox_phys);
|
||||
caps->header.size = sizeof(struct vbox_guest_caps);
|
||||
caps->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
caps->header.requestType = 55;
|
||||
caps->header.rc = 0;
|
||||
caps->header.reserved1 = 0;
|
||||
caps->header.reserved2 = 0;
|
||||
caps->caps = 1 << 2;
|
||||
outportl(vbox_port, vbox_phys);
|
||||
|
||||
vbox_irq_ack = (void*)kvmalloc_p(0x1000, &vbox_phys_ack);
|
||||
vbox_irq_ack->header.size = sizeof(struct vbox_ack_events);
|
||||
vbox_irq_ack->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_irq_ack->header.requestType = 41;
|
||||
vbox_irq_ack->header.rc = 0;
|
||||
vbox_irq_ack->header.reserved1 = 0;
|
||||
vbox_irq_ack->header.reserved2 = 0;
|
||||
vbox_irq_ack->events = 0;
|
||||
|
||||
vbox_disp = (void*)kvmalloc_p(0x1000, &vbox_phys_disp);
|
||||
vbox_disp->header.size = sizeof(struct vbox_display_change);
|
||||
vbox_disp->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_disp->header.requestType = 51;
|
||||
vbox_disp->header.rc = 0;
|
||||
vbox_disp->header.reserved1 = 0;
|
||||
vbox_disp->header.reserved2 = 0;
|
||||
vbox_disp->xres = 0;
|
||||
vbox_disp->yres = 0;
|
||||
vbox_disp->bpp = 0;
|
||||
vbox_disp->eventack = 1;
|
||||
|
||||
vbox_m = (void*)kvmalloc_p(0x1000, &vbox_phys_mouse);
|
||||
vbox_m->header.size = sizeof(struct vbox_mouse);
|
||||
vbox_m->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_m->header.requestType = 2;
|
||||
vbox_m->header.rc = 0;
|
||||
vbox_m->header.reserved1 = 0;
|
||||
vbox_m->header.reserved2 = 0;
|
||||
vbox_m->features = (1 << 0) | (1 << 4);
|
||||
vbox_m->x = 0;
|
||||
vbox_m->y = 0;
|
||||
outportl(vbox_port, vbox_phys_mouse);
|
||||
|
||||
vbox_m->header.requestType = 1;
|
||||
|
||||
/* device memory region mapping? */
|
||||
{
|
||||
uintptr_t t = pci_read_field(vbox_device, PCI_BAR1, 4);
|
||||
if (t > 0) {
|
||||
vbox_vmmdev = (void *)(t & 0xFFFFFFF0);
|
||||
}
|
||||
uintptr_t fb_offset = (uintptr_t)vbox_vmmdev;
|
||||
for (uintptr_t i = fb_offset; i <= fb_offset + 0x2000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
vbox_vmmdev[3] = 0xFFFFFFFF; /* Enable all for now */
|
||||
}
|
||||
}
|
||||
|
||||
#define SVGA_IO_BASE (vmware_io)
|
||||
#define SVGA_IO_MUL 1
|
||||
#define SVGA_INDEX_PORT 0
|
||||
@ -590,6 +395,18 @@ static uint32_t vmware_read(int reg) {
|
||||
return inportl(SVGA_IO_MUL * SVGA_VALUE_PORT + SVGA_IO_BASE);
|
||||
}
|
||||
|
||||
static void vmware_set_mode(uint16_t w, uint16_t h) {
|
||||
vmware_write(SVGA_REG_ENABLE, 0);
|
||||
vmware_write(SVGA_REG_ID, 0);
|
||||
vmware_write(SVGA_REG_WIDTH, w);
|
||||
vmware_write(SVGA_REG_HEIGHT, h);
|
||||
vmware_write(SVGA_REG_BITS_PER_PIXEL, 32);
|
||||
vmware_write(SVGA_REG_ENABLE, 1);
|
||||
|
||||
lfb_resolution_x = w;
|
||||
lfb_resolution_y = h;
|
||||
}
|
||||
|
||||
static void graphics_install_vmware(uint16_t w, uint16_t h) {
|
||||
debug_print(WARNING, "Please note that the `vmware` display driver is experimental.");
|
||||
pci_scan(vmware_scan_pci, -1, &vmware_io);
|
||||
@ -607,6 +424,8 @@ static void graphics_install_vmware(uint16_t w, uint16_t h) {
|
||||
vmware_write(SVGA_REG_BITS_PER_PIXEL, 32);
|
||||
vmware_write(SVGA_REG_ENABLE, 1);
|
||||
|
||||
lfb_resolution_impl = &vmware_set_mode;
|
||||
|
||||
uint32_t fb_addr = vmware_read(SVGA_REG_FB_START);
|
||||
debug_print(WARNING, "vmware fb address: 0x%x", fb_addr);
|
||||
|
||||
|
231
modules/vboxguest.c
Normal file
231
modules/vboxguest.c
Normal file
@ -0,0 +1,231 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2016 Kevin Lange
|
||||
*
|
||||
* VirtualBox Guest Additions driver
|
||||
*/
|
||||
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
#include <printf.h>
|
||||
#include <types.h>
|
||||
#include <logging.h>
|
||||
#include <pci.h>
|
||||
#include <module.h>
|
||||
#include <video.h>
|
||||
#include <pipe.h>
|
||||
#include <mouse.h>
|
||||
|
||||
#define VBOX_VENDOR_ID 0x80EE
|
||||
#define VBOX_DEVICE_ID 0xCAFE
|
||||
|
||||
static void vbox_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra) {
|
||||
if (v == VBOX_VENDOR_ID && d == VBOX_DEVICE_ID) {
|
||||
*((uint32_t *)extra) = device;
|
||||
}
|
||||
}
|
||||
|
||||
#define VMMDEV_VERSION 0x00010003
|
||||
#define VBOX_REQUEST_HEADER_VERSION 0x10001
|
||||
struct vbox_header {
|
||||
uint32_t size;
|
||||
uint32_t version;
|
||||
uint32_t requestType;
|
||||
int32_t rc;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
struct vbox_guest_info {
|
||||
struct vbox_header header;
|
||||
uint32_t version;
|
||||
uint32_t ostype;
|
||||
};
|
||||
|
||||
struct vbox_guest_caps {
|
||||
struct vbox_header header;
|
||||
uint32_t caps;
|
||||
};
|
||||
|
||||
struct vbox_ack_events {
|
||||
struct vbox_header header;
|
||||
uint32_t events;
|
||||
};
|
||||
|
||||
struct vbox_display_change {
|
||||
struct vbox_header header;
|
||||
uint32_t xres;
|
||||
uint32_t yres;
|
||||
uint32_t bpp;
|
||||
uint32_t eventack;
|
||||
};
|
||||
|
||||
struct vbox_mouse {
|
||||
struct vbox_header header;
|
||||
uint32_t features;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
};
|
||||
|
||||
|
||||
#define EARLY_LOG_DEVICE 0x504
|
||||
static uint32_t _vbox_write(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
outportb(EARLY_LOG_DEVICE, buffer[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
static fs_node_t vb = { .write = &_vbox_write };
|
||||
|
||||
static uint32_t vbox_device = 0;
|
||||
static uint32_t vbox_port = 0x0;
|
||||
static int vbox_irq = 0;
|
||||
|
||||
static struct vbox_ack_events * vbox_irq_ack;
|
||||
static uint32_t vbox_phys_ack;
|
||||
static struct vbox_display_change * vbox_disp;
|
||||
static uint32_t vbox_phys_disp;
|
||||
static struct vbox_mouse * vbox_m;
|
||||
static uint32_t vbox_phys_mouse;
|
||||
static uint32_t * vbox_vmmdev = 0;
|
||||
|
||||
static fs_node_t * mouse_pipe;
|
||||
|
||||
#define PACKETS_IN_PIPE 1024
|
||||
#define DISCARD_POINT 32
|
||||
|
||||
static int vbox_irq_handler(struct regs *r) {
|
||||
outportl(vbox_port, vbox_phys_disp);
|
||||
outportl(vbox_port, vbox_phys_mouse);
|
||||
outportl(vbox_port, vbox_phys_ack);
|
||||
irq_ack(vbox_irq);
|
||||
|
||||
if (lfb_vid_memory && lfb_resolution_x && lfb_resolution_y && vbox_m->x && vbox_m->y) {
|
||||
unsigned int x = ((unsigned int)vbox_m->x * lfb_resolution_x) / 0xFFFF;
|
||||
unsigned int y = ((unsigned int)vbox_m->y * lfb_resolution_y) / 0xFFFF;
|
||||
|
||||
mouse_device_packet_t packet;
|
||||
packet.magic = MOUSE_MAGIC;
|
||||
packet.x_difference = x;
|
||||
packet.y_difference = y;
|
||||
packet.buttons = 0;
|
||||
|
||||
mouse_device_packet_t bitbucket;
|
||||
while (pipe_size(mouse_pipe) > (int)(DISCARD_POINT * sizeof(packet))) {
|
||||
read_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&bitbucket);
|
||||
}
|
||||
write_fs(mouse_pipe, 0, sizeof(packet), (uint8_t *)&packet);
|
||||
}
|
||||
|
||||
|
||||
if (lfb_resolution_x && vbox_disp->xres && (vbox_disp->xres != lfb_resolution_x || vbox_disp->yres != lfb_resolution_y)) {
|
||||
|
||||
lfb_set_resolution(vbox_disp->xres, vbox_disp->yres);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vbox_check(void) {
|
||||
pci_scan(vbox_scan_pci, -1, &vbox_device);
|
||||
|
||||
if (vbox_device) {
|
||||
fprintf(&vb, "VirtualBox host detected, switching log to VirtualBox.\n");
|
||||
debug_file = &vb;
|
||||
|
||||
uintptr_t t = pci_read_field(vbox_device, PCI_BAR0, 4);
|
||||
if (t > 0) {
|
||||
vbox_port = (t & 0xFFFFFFF0);
|
||||
}
|
||||
|
||||
mouse_pipe = make_pipe(sizeof(mouse_device_packet_t) * PACKETS_IN_PIPE);
|
||||
mouse_pipe->flags = FS_CHARDEVICE;
|
||||
|
||||
vfs_mount("/dev/absmouse", mouse_pipe);
|
||||
|
||||
vbox_irq = pci_read_field(vbox_device, PCI_INTERRUPT_LINE, 1);
|
||||
debug_print(WARNING, "(vbox) device IRQ is set to %d\n", vbox_irq);
|
||||
irq_install_handler(vbox_irq, vbox_irq_handler);
|
||||
|
||||
uint32_t vbox_phys = 0;
|
||||
struct vbox_guest_info * packet = (void*)kvmalloc_p(0x1000, &vbox_phys);
|
||||
packet->header.size = sizeof(struct vbox_guest_info);
|
||||
packet->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
packet->header.requestType = 50;
|
||||
packet->header.rc = 0;
|
||||
packet->header.reserved1 = 0;
|
||||
packet->header.reserved2 = 0;
|
||||
packet->version = VMMDEV_VERSION;
|
||||
packet->ostype = 0;
|
||||
|
||||
outportl(vbox_port, vbox_phys);
|
||||
|
||||
struct vbox_guest_caps * caps = (void*)kvmalloc_p(0x1000, &vbox_phys);
|
||||
caps->header.size = sizeof(struct vbox_guest_caps);
|
||||
caps->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
caps->header.requestType = 55;
|
||||
caps->header.rc = 0;
|
||||
caps->header.reserved1 = 0;
|
||||
caps->header.reserved2 = 0;
|
||||
caps->caps = 1 << 2;
|
||||
outportl(vbox_port, vbox_phys);
|
||||
|
||||
vbox_irq_ack = (void*)kvmalloc_p(0x1000, &vbox_phys_ack);
|
||||
vbox_irq_ack->header.size = sizeof(struct vbox_ack_events);
|
||||
vbox_irq_ack->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_irq_ack->header.requestType = 41;
|
||||
vbox_irq_ack->header.rc = 0;
|
||||
vbox_irq_ack->header.reserved1 = 0;
|
||||
vbox_irq_ack->header.reserved2 = 0;
|
||||
vbox_irq_ack->events = 0;
|
||||
|
||||
vbox_disp = (void*)kvmalloc_p(0x1000, &vbox_phys_disp);
|
||||
vbox_disp->header.size = sizeof(struct vbox_display_change);
|
||||
vbox_disp->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_disp->header.requestType = 51;
|
||||
vbox_disp->header.rc = 0;
|
||||
vbox_disp->header.reserved1 = 0;
|
||||
vbox_disp->header.reserved2 = 0;
|
||||
vbox_disp->xres = 0;
|
||||
vbox_disp->yres = 0;
|
||||
vbox_disp->bpp = 0;
|
||||
vbox_disp->eventack = 1;
|
||||
|
||||
vbox_m = (void*)kvmalloc_p(0x1000, &vbox_phys_mouse);
|
||||
vbox_m->header.size = sizeof(struct vbox_mouse);
|
||||
vbox_m->header.version = VBOX_REQUEST_HEADER_VERSION;
|
||||
vbox_m->header.requestType = 2;
|
||||
vbox_m->header.rc = 0;
|
||||
vbox_m->header.reserved1 = 0;
|
||||
vbox_m->header.reserved2 = 0;
|
||||
vbox_m->features = (1 << 0) | (1 << 4);
|
||||
vbox_m->x = 0;
|
||||
vbox_m->y = 0;
|
||||
outportl(vbox_port, vbox_phys_mouse);
|
||||
|
||||
vbox_m->header.requestType = 1;
|
||||
|
||||
/* device memory region mapping? */
|
||||
{
|
||||
uintptr_t t = pci_read_field(vbox_device, PCI_BAR1, 4);
|
||||
if (t > 0) {
|
||||
vbox_vmmdev = (void *)(t & 0xFFFFFFF0);
|
||||
}
|
||||
uintptr_t fb_offset = (uintptr_t)vbox_vmmdev;
|
||||
for (uintptr_t i = fb_offset; i <= fb_offset + 0x2000; i += 0x1000) {
|
||||
dma_frame(get_page(i, 1, kernel_directory), 0, 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
vbox_vmmdev[3] = 0xFFFFFFFF; /* Enable all for now */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fini(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DEF(vboxguest, vbox_check, fini);
|
||||
MODULE_DEPENDS(lfbvideo);
|
43
modules/vidset.c
Normal file
43
modules/vidset.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2016 Kevin Lange
|
||||
*
|
||||
* Module to provide a debug shell command to set display mode.
|
||||
*/
|
||||
#include <system.h>
|
||||
#include <hashmap.h>
|
||||
#include <module.h>
|
||||
#include <logging.h>
|
||||
#include <printf.h>
|
||||
|
||||
#include <mod/shell.h>
|
||||
#include <video.h>
|
||||
|
||||
DEFINE_SHELL_FUNCTION(set_mode, "Set display mode") {
|
||||
if (argc < 3) {
|
||||
fprintf(tty, "set_mode <x> <y>\n");
|
||||
return 1;
|
||||
}
|
||||
int x = atoi(argv[1]);
|
||||
int y = atoi(argv[2]);
|
||||
fprintf(tty, "Setting mode to %dx%d.\n", x, y);
|
||||
lfb_set_resolution(x,y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hello(void) {
|
||||
BIND_SHELL_FUNCTION(set_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodbye(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DEF(test, hello, goodbye);
|
||||
MODULE_DEPENDS(debugshell);
|
||||
MODULE_DEPENDS(lfbvideo);
|
||||
|
||||
|
@ -43,6 +43,8 @@ function load_modules {
|
||||
module /mod/ps2kbd.ko
|
||||
module /mod/ps2mouse.ko
|
||||
module /mod/lfbvideo.ko
|
||||
module /mod/vboxguest.ko
|
||||
module /mod/vidset.ko
|
||||
module /mod/packetfs.ko
|
||||
module /mod/snd.ko
|
||||
module /mod/ac97.ko
|
||||
|
Loading…
Reference in New Issue
Block a user