lfbvideo: allow display initialize to be triggered by ioctl
This commit is contained in:
parent
e3fd396897
commit
4d854b156c
@ -22,7 +22,7 @@
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s width height\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s [--initialize DRIVER] WIDTH HEIGHT\n", argv[0]);
|
||||
}
|
||||
|
||||
/* Open framebuffer */
|
||||
@ -33,15 +33,34 @@ int main(int argc, char * argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
int init = 0;
|
||||
char * driver = NULL;
|
||||
|
||||
if (argc > 4 && !strcmp(argv[1],"--initialize")) {
|
||||
init = 1;
|
||||
driver = argv[2];
|
||||
i += 2;
|
||||
}
|
||||
|
||||
/* Prepare ioctl from arguments */
|
||||
struct vid_size s;
|
||||
s.width = atoi(argv[1]);
|
||||
s.height = atoi(argv[2]);
|
||||
s.width = atoi(argv[i]);
|
||||
s.height = atoi(argv[i+1]);
|
||||
|
||||
/* Send ioctl */
|
||||
if (ioctl(fd, IO_VID_SET, &s) < 0) {
|
||||
perror("ioctl");
|
||||
return 1;
|
||||
if (init) {
|
||||
char tmp[100];
|
||||
sprintf(tmp, "%s,%lu,%lu", driver, s.width, s.height);
|
||||
if (ioctl(fd, IO_VID_REINIT, tmp) < 0) {
|
||||
perror("ioctl");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (ioctl(fd, IO_VID_SET, &s) < 0) {
|
||||
perror("ioctl");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -7,7 +7,8 @@
|
||||
#define IO_VID_SIGNAL 0x5005
|
||||
#define IO_VID_SET 0x5006
|
||||
#define IO_VID_STRIDE 0x5007
|
||||
#define IO_VID_DRIVER 0x6008
|
||||
#define IO_VID_DRIVER 0x5008
|
||||
#define IO_VID_REINIT 0x5009
|
||||
|
||||
struct vid_size {
|
||||
uint32_t width;
|
||||
|
@ -37,6 +37,9 @@ uint32_t lfb_resolution_s = 0;
|
||||
uint8_t * lfb_vid_memory = (uint8_t *)0xE0000000;
|
||||
const char * lfb_driver_name = NULL;
|
||||
|
||||
static fs_node_t * lfb_device = NULL;
|
||||
static int lfb_init(char * c);
|
||||
|
||||
/* Where to send display size change signals */
|
||||
static pid_t display_change_recipient = 0;
|
||||
|
||||
@ -99,6 +102,12 @@ static int ioctl_vid(fs_node_t * node, int request, void * argp) {
|
||||
validate(argp);
|
||||
memcpy(argp, lfb_driver_name, strlen(lfb_driver_name));
|
||||
return 0;
|
||||
case IO_VID_REINIT:
|
||||
if (current_process->user != 0) {
|
||||
return -EPERM;
|
||||
}
|
||||
validate(argp);
|
||||
return lfb_init(argp);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -109,7 +118,7 @@ static fs_node_t * lfb_video_device_create(void /* TODO */) {
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
sprintf(fnode->name, "fb0"); /* TODO */
|
||||
fnode->length = lfb_resolution_s * lfb_resolution_y; /* Size is framebuffer size in bytes */
|
||||
fnode->length = 0;
|
||||
fnode->flags = FS_BLOCKDEVICE; /* Framebuffers are block devices */
|
||||
fnode->mask = 0660; /* Only accessible to root user/group */
|
||||
fnode->ioctl = ioctl_vid; /* control function defined above */
|
||||
@ -254,8 +263,7 @@ static struct procfs_entry framebuffer_entry = {
|
||||
/* Install framebuffer device */
|
||||
static void finalize_graphics(const char * driver) {
|
||||
lfb_driver_name = driver;
|
||||
fs_node_t * fb_device = lfb_video_device_create();
|
||||
vfs_mount("/dev/fb0", fb_device);
|
||||
lfb_device->length = lfb_resolution_s * lfb_resolution_y; /* Size is framebuffer size in bytes */
|
||||
debug_video_crash = lfb_video_panic;
|
||||
|
||||
int (*procfs_install)(struct procfs_entry *) = (int (*)(struct procfs_entry *))(uintptr_t)hashmap_get(modules_get_symbols(),"procfs_install");
|
||||
@ -527,54 +535,63 @@ static void auto_scan_pci(uint32_t device, uint16_t v, uint16_t d, void * extra)
|
||||
}
|
||||
}
|
||||
|
||||
static int lfb_init(char * c) {
|
||||
char * arg = strdup(c);
|
||||
char * argv[10];
|
||||
int argc = tokenize(arg, ",", argv);
|
||||
|
||||
uint16_t x, y;
|
||||
if (argc < 3) {
|
||||
x = PREFERRED_W;
|
||||
y = PREFERRED_H;
|
||||
} else {
|
||||
x = atoi(argv[1]);
|
||||
y = atoi(argv[2]);
|
||||
}
|
||||
|
||||
int ret_val = 0;
|
||||
if (!strcmp(argv[0], "auto")) {
|
||||
/* Attempt autodetection */
|
||||
debug_print(NOTICE, "Automatically detecting display driver...");
|
||||
struct disp_mode mode = {x,y,0};
|
||||
pci_scan(auto_scan_pci, -1, &mode);
|
||||
if (!mode.set) {
|
||||
graphics_install_preset(x,y);
|
||||
}
|
||||
} else if (!strcmp(argv[0], "qemu")) {
|
||||
/* Bochs / Qemu Video Device */
|
||||
graphics_install_bochs(x,y);
|
||||
} else if (!strcmp(argv[0],"vmware")) {
|
||||
/* VMware SVGA */
|
||||
graphics_install_vmware(x,y);
|
||||
} else if (!strcmp(argv[0],"preset")) {
|
||||
/* Set by bootloader (UEFI) */
|
||||
graphics_install_preset(x,y);
|
||||
} else if (!strcmp(argv[0],"kludge")) {
|
||||
/* Old hack to find vid memory from the VGA window */
|
||||
graphics_install_kludge(x,y);
|
||||
} else {
|
||||
debug_print(WARNING, "Unrecognized video adapter: %s", argv[0]);
|
||||
ret_val = 1;
|
||||
}
|
||||
|
||||
free(arg);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int init(void) {
|
||||
|
||||
if (mboot_ptr->vbe_mode_info) {
|
||||
lfb_vid_memory = (uint8_t *)((vbe_info_t *)(mboot_ptr->vbe_mode_info))->physbase;
|
||||
}
|
||||
|
||||
lfb_device = lfb_video_device_create();
|
||||
vfs_mount("/dev/fb0", lfb_device);
|
||||
|
||||
char * c;
|
||||
if ((c = args_value("vid"))) {
|
||||
debug_print(NOTICE, "Video mode requested: %s", c);
|
||||
|
||||
char * arg = strdup(c);
|
||||
char * argv[10];
|
||||
int argc = tokenize(arg, ",", argv);
|
||||
|
||||
uint16_t x, y;
|
||||
if (argc < 3) {
|
||||
x = PREFERRED_W;
|
||||
y = PREFERRED_H;
|
||||
} else {
|
||||
x = atoi(argv[1]);
|
||||
y = atoi(argv[2]);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "auto")) {
|
||||
/* Attempt autodetection */
|
||||
debug_print(NOTICE, "Automatically detecting display driver...");
|
||||
struct disp_mode mode = {x,y,0};
|
||||
pci_scan(auto_scan_pci, -1, &mode);
|
||||
if (!mode.set) {
|
||||
graphics_install_preset(x,y);
|
||||
}
|
||||
} else if (!strcmp(argv[0], "qemu")) {
|
||||
/* Bochs / Qemu Video Device */
|
||||
graphics_install_bochs(x,y);
|
||||
} else if (!strcmp(argv[0],"vmware")) {
|
||||
/* VMware SVGA */
|
||||
graphics_install_vmware(x,y);
|
||||
} else if (!strcmp(argv[0],"preset")) {
|
||||
/* Set by bootloader (UEFI) */
|
||||
graphics_install_preset(x,y);
|
||||
} else if (!strcmp(argv[0],"kludge")) {
|
||||
/* Old hack to find vid memory from the VGA window */
|
||||
graphics_install_kludge(x,y);
|
||||
} else {
|
||||
debug_print(WARNING, "Unrecognized video adapter: %s", argv[0]);
|
||||
}
|
||||
|
||||
free(arg);
|
||||
lfb_init(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user