aboutsummaryrefslogtreecommitdiff
path: root/console-client/vga-support.c
diff options
context:
space:
mode:
Diffstat (limited to 'console-client/vga-support.c')
-rw-r--r--console-client/vga-support.c101
1 files changed, 56 insertions, 45 deletions
diff --git a/console-client/vga-support.c b/console-client/vga-support.c
index 717663ce..c7e9e914 100644
--- a/console-client/vga-support.c
+++ b/console-client/vga-support.c
@@ -76,59 +76,70 @@ error_t
vga_init (void)
{
error_t err;
-#if OSKIT_MACH
int fd;
-#else
- device_t device_master = MACH_PORT_NULL;
- memory_object_t kd_mem = MACH_PORT_NULL;
- static device_t kd_device = MACH_PORT_NULL;
- vm_address_t mapped;
-#endif
-#if OSKIT_MACH
+ /* Acquire I/O port access. */
if (ioperm (VGA_MIN_REG, VGA_MAX_REG - VGA_MIN_REG + 1, 1) < 0)
{
- free (vga_state);
- return errno;
+ /* GNU Mach v1 is broken in that it doesn't implement an I/O
+ perm interface and just allows all tasks to access any I/O
+ port. */
+ if (errno != EMIG_BAD_ID && errno != ENOSYS)
+ {
+ free (vga_state);
+ return errno;
+ }
}
fd = open ("/dev/mem", O_RDWR);
- if (fd < 0)
+ if (fd >= 0)
+ {
+ vga_videomem = mmap (0, VGA_VIDEO_MEM_LENGTH, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, VGA_VIDEO_MEM_BASE_ADDR);
+ err = errno;
+ close (fd);
+ if (vga_videomem == (void *) -1)
+ return err;
+ }
+ else if (errno == ENXIO)
+ {
+ /* GNU Mach v1 does not provide /dev/mem, but allows direct
+ memory access to the video memory through the special "kd"
+ kernel device. */
+ device_t device_master = MACH_PORT_NULL;
+ memory_object_t kd_mem = MACH_PORT_NULL;
+ static device_t kd_device = MACH_PORT_NULL;
+ vm_address_t mapped;
+
+ err = get_privileged_ports (0, &device_master);
+ if (err)
+ return err;
+
+ err = device_open (device_master, D_WRITE, "kd", &kd_device);
+ if (err)
+ return err;
+
+ err = device_map (kd_device, VM_PROT_READ | VM_PROT_WRITE,
+ VIDMMAP_BEGIN - VIDMMAP_KDOFS, VIDMMAP_SIZE,
+ &kd_mem, 0);
+ if (err)
+ return err;
+
+ err = vm_map (mach_task_self (), &mapped, VIDMMAP_SIZE,
+ 0, 1, kd_mem, VIDMMAP_BEGIN - VIDMMAP_KDOFS, 0,
+ VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE,
+ VM_INHERIT_NONE);
+ if (err)
+ return err;
+
+ vga_videomem = (char *) mapped;
+ assert (vga_videomem != NULL);
+
+ mach_port_deallocate (mach_task_self (), device_master);
+ mach_port_deallocate (mach_task_self (), kd_mem);
+ }
+ else
return errno;
- vga_videomem = mmap (0, VGA_VIDEO_MEM_LENGTH, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, VGA_VIDEO_MEM_BASE_ADDR);
- err = errno;
- close (fd);
- if (vga_videomem == (void *) -1)
- return err;
-#else
- err = get_privileged_ports (0, &device_master);
- if (err)
- return err;
-
- err = device_open (device_master, D_WRITE, "kd", &kd_device);
- if (err)
- return err;
-
- err = device_map (kd_device, VM_PROT_READ | VM_PROT_WRITE,
- VIDMMAP_BEGIN - VIDMMAP_KDOFS, VIDMMAP_SIZE,
- &kd_mem, 0);
- if (err)
- return err;
-
- err = vm_map (mach_task_self (), &mapped, VIDMMAP_SIZE,
- 0, 1, kd_mem, VIDMMAP_BEGIN - VIDMMAP_KDOFS, 0,
- VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE,
- VM_INHERIT_NONE);
- if (err)
- return err;
-
- vga_videomem = (char *) mapped;
- assert (vga_videomem != NULL);
-
- mach_port_deallocate (mach_task_self (), device_master);
- mach_port_deallocate (mach_task_self (), kd_mem);
-#endif
/* Save the current state. */
vga_state = malloc (sizeof (*vga_state));