summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/linux/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/linux/pm.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/linux/pm.c1809
1 files changed, 0 insertions, 1809 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/linux/pm.c b/board/MAI/bios_emulator/scitech/src/pm/linux/pm.c
deleted file mode 100644
index c12a83500a..0000000000
--- a/board/MAI/bios_emulator/scitech/src/pm/linux/pm.c
+++ /dev/null
@@ -1,1809 +0,0 @@
-;/****************************************************************************
-*
-* SciTech OS Portability Manager Library
-*
-* ========================================================================
-*
-* The contents of this file are subject to the SciTech MGL Public
-* License Version 1.0 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.scitechsoft.com/mgl-license.txt
-*
-* Software distributed under the License is distributed on an
-* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
-*
-* The Initial Developer of the Original Code is SciTech Software, Inc.
-* All Rights Reserved.
-*
-* ========================================================================
-*
-* Portions copyright (C) Josh Vanderhoof
-*
-* Language: ANSI C
-* Environment: Linux
-*
-* Description: Implementation for the OS Portability Manager Library, which
-* contains functions to implement OS specific services in a
-* generic, cross platform API. Porting the OS Portability
-* Manager library is the first step to porting any SciTech
-* products to a new platform.
-*
-****************************************************************************/
-
-#include "pmapi.h"
-#include "drvlib/os/os.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/kd.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/vt.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <syscall.h>
-#include <signal.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <asm/types.h>
-#ifdef ENABLE_MTRR
-#include <asm/mtrr.h>
-#endif
-#include <asm/vm86.h>
-#ifdef __GLIBC__
-#include <sys/perm.h>
-#endif
-
-/*--------------------------- Global variables ----------------------------*/
-
-#define REAL_MEM_BASE ((void *)0x10000)
-#define REAL_MEM_SIZE 0x10000
-#define REAL_MEM_BLOCKS 0x100
-#define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK)
-#define DEFAULT_STACK_SIZE 0x1000
-#define RETURN_TO_32_INT 255
-
-/* Quick and dirty fix for vm86() syscall from lrmi 0.6 */
-static int
-vm86(struct vm86_struct *vm)
- {
- int r;
-#ifdef __PIC__
- asm volatile (
- "pushl %%ebx\n\t"
- "movl %2, %%ebx\n\t"
- "int $0x80\n\t"
- "popl %%ebx"
- : "=a" (r)
- : "0" (113), "r" (vm));
-#else
- asm volatile (
- "int $0x80"
- : "=a" (r)
- : "0" (113), "b" (vm));
-#endif
- return r;
- }
-
-
-static struct {
- int ready;
- unsigned short ret_seg, ret_off;
- unsigned short stack_seg, stack_off;
- struct vm86_struct vm;
- } context = {0};
-
-struct mem_block {
- unsigned int size : 20;
- unsigned int free : 1;
- };
-
-static struct {
- int ready;
- int count;
- struct mem_block blocks[REAL_MEM_BLOCKS];
- } mem_info = {0};
-
-int _PM_console_fd = -1;
-int _PM_leds = 0,_PM_modifiers = 0;
-static ibool inited = false;
-static int tty_vc = 0;
-static int console_count = 0;
-static int startup_vc;
-static int fd_mem = 0;
-static ibool in_raw_mode = false;
-#ifdef ENABLE_MTRR
-static int mtrr_fd;
-#endif
-static uint VESABuf_len = 1024; /* Length of the VESABuf buffer */
-static void *VESABuf_ptr = NULL; /* Near pointer to VESABuf */
-static uint VESABuf_rseg; /* Real mode segment of VESABuf */
-static uint VESABuf_roff; /* Real mode offset of VESABuf */
-#ifdef TRACE_IO
-static ulong traceAddr;
-#endif
-
-static void (PMAPIP fatalErrorCleanup)(void) = NULL;
-
-/*----------------------------- Implementation ----------------------------*/
-
-#ifdef TRACE_IO
-extern void printk(char *msg,...);
-#endif
-
-static inline void port_out(int value, int port)
-{
-#ifdef TRACE_IO
- printk("%04X:%04X: outb.%04X <- %02X\n", traceAddr >> 16, traceAddr & 0xFFFF, (ushort)port, (uchar)value);
-#endif
- asm volatile ("outb %0,%1"
- ::"a" ((unsigned char) value), "d"((unsigned short) port));
-}
-
-static inline void port_outw(int value, int port)
-{
-#ifdef TRACE_IO
- printk("%04X:%04X: outw.%04X <- %04X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ushort)value);
-#endif
- asm volatile ("outw %0,%1"
- ::"a" ((unsigned short) value), "d"((unsigned short) port));
-}
-
-static inline void port_outl(int value, int port)
-{
-#ifdef TRACE_IO
- printk("%04X:%04X: outl.%04X <- %08X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ulong)value);
-#endif
- asm volatile ("outl %0,%1"
- ::"a" ((unsigned long) value), "d"((unsigned short) port));
-}
-
-static inline unsigned int port_in(int port)
-{
- unsigned char value;
- asm volatile ("inb %1,%0"
- :"=a" ((unsigned char)value)
- :"d"((unsigned short) port));
-#ifdef TRACE_IO
- printk("%04X:%04X: inb.%04X -> %02X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (uchar)value);
-#endif
- return value;
-}
-
-static inline unsigned int port_inw(int port)
-{
- unsigned short value;
- asm volatile ("inw %1,%0"
- :"=a" ((unsigned short)value)
- :"d"((unsigned short) port));
-#ifdef TRACE_IO
- printk("%04X:%04X: inw.%04X -> %04X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ushort)value);
-#endif
- return value;
-}
-
-static inline unsigned int port_inl(int port)
-{
- unsigned long value;
- asm volatile ("inl %1,%0"
- :"=a" ((unsigned long)value)
- :"d"((unsigned short) port));
-#ifdef TRACE_IO
- printk("%04X:%04X: inl.%04X -> %08X\n", traceAddr >> 16,traceAddr & 0xFFFF, (ushort)port, (ulong)value);
-#endif
- return value;
-}
-
-static int real_mem_init(void)
-{
- void *m;
- int fd_zero;
-
- if (mem_info.ready)
- return 1;
-
- if ((fd_zero = open("/dev/zero", O_RDONLY)) == -1)
- PM_fatalError("You must have root privledges to run this program!");
- if ((m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, fd_zero, 0)) == (void *)-1) {
- close(fd_zero);
- PM_fatalError("You must have root privledges to run this program!");
- }
- mem_info.ready = 1;
- mem_info.count = 1;
- mem_info.blocks[0].size = REAL_MEM_SIZE;
- mem_info.blocks[0].free = 1;
- return 1;
-}
-
-static void insert_block(int i)
-{
- memmove(
- mem_info.blocks + i + 1,
- mem_info.blocks + i,
- (mem_info.count - i) * sizeof(struct mem_block));
- mem_info.count++;
-}
-
-static void delete_block(int i)
-{
- mem_info.count--;
-
- memmove(
- mem_info.blocks + i,
- mem_info.blocks + i + 1,
- (mem_info.count - i) * sizeof(struct mem_block));
-}
-
-static inline void set_bit(unsigned int bit, void *array)
-{
- unsigned char *a = array;
- a[bit / 8] |= (1 << (bit % 8));
-}
-
-static inline unsigned int get_int_seg(int i)
-{
- return *(unsigned short *)(i * 4 + 2);
-}
-
-static inline unsigned int get_int_off(int i)
-{
- return *(unsigned short *)(i * 4);
-}
-
-static inline void pushw(unsigned short i)
-{
- struct vm86_regs *r = &context.vm.regs;
- r->esp -= 2;
- *(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i;
-}
-
-ibool PMAPI PM_haveBIOSAccess(void)
-{ return true; }
-
-void PMAPI PM_init(void)
-{
- void *m;
- uint r_seg,r_off;
-
- if (inited)
- return;
-
- /* Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502)
- * and the physical framebuffer and ROM images from (0xa0000 - 0x100000)
- */
- real_mem_init();
- if (!fd_mem && (fd_mem = open("/dev/mem", O_RDWR)) == -1) {
- PM_fatalError("You must have root privileges to run this program!");
- }
- if ((m = mmap((void *)0, 0x502,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, fd_mem, 0)) == (void *)-1) {
- PM_fatalError("You must have root privileges to run this program!");
- }
- if ((m = mmap((void *)0xA0000, 0xC0000 - 0xA0000,
- PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_SHARED, fd_mem, 0xA0000)) == (void *)-1) {
- PM_fatalError("You must have root privileges to run this program!");
- }
- if ((m = mmap((void *)0xC0000, 0xD0000 - 0xC0000,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, fd_mem, 0xC0000)) == (void *)-1) {
- PM_fatalError("You must have root privileges to run this program!");
- }
- if ((m = mmap((void *)0xD0000, 0x100000 - 0xD0000,
- PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_SHARED, fd_mem, 0xD0000)) == (void *)-1) {
- PM_fatalError("You must have root privileges to run this program!");
- }
- inited = 1;
-
- /* Allocate a stack */
- m = PM_allocRealSeg(DEFAULT_STACK_SIZE,&r_seg,&r_off);
- context.stack_seg = r_seg;
- context.stack_off = r_off+DEFAULT_STACK_SIZE;
-
- /* Allocate the return to 32 bit routine */
- m = PM_allocRealSeg(2,&r_seg,&r_off);
- context.ret_seg = r_seg;
- context.ret_off = r_off;
- ((uchar*)m)[0] = 0xCD; /* int opcode */
- ((uchar*)m)[1] = RETURN_TO_32_INT;
- memset(&context.vm, 0, sizeof(context.vm));
-
- /* Enable kernel emulation of all ints except RETURN_TO_32_INT */
- memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored));
- set_bit(RETURN_TO_32_INT, &context.vm.int_revectored);
- context.ready = 1;
-#ifdef ENABLE_MTRR
- mtrr_fd = open("/dev/cpu/mtrr", O_RDWR, 0);
- if (mtrr_fd < 0)
- mtrr_fd = open("/proc/mtrr", O_RDWR, 0);
-#endif
- /* Enable I/O permissions to directly access I/O ports. We break the
- * allocation into two parts, one for the ports from 0-0x3FF and
- * another for the remaining ports up to 0xFFFF. Standard Linux kernels
- * only allow the first 0x400 ports to be enabled, so to enable all
- * 65536 ports you need a patched kernel that will enable the full
- * 8Kb I/O permissions bitmap.
- */
-#ifndef TRACE_IO
- ioperm(0x0,0x400,1);
- ioperm(0x400,0x10000-0x400,1);
-#endif
- iopl(3);
-}
-
-long PMAPI PM_getOSType(void)
-{ return _OS_LINUX; }
-
-int PMAPI PM_getModeType(void)
-{ return PM_386; }
-
-void PMAPI PM_backslash(char *s)
-{
- uint pos = strlen(s);
- if (s[pos-1] != '/') {
- s[pos] = '/';
- s[pos+1] = '\0';
- }
-}
-
-void PMAPI PM_setFatalErrorCleanup(
- void (PMAPIP cleanup)(void))
-{
- fatalErrorCleanup = cleanup;
-}
-
-void PMAPI PM_fatalError(const char *msg)
-{
- if (fatalErrorCleanup)
- fatalErrorCleanup();
- fprintf(stderr,"%s\n", msg);
- fflush(stderr);
- exit(1);
-}
-
-static void ExitVBEBuf(void)
-{
- if (VESABuf_ptr)
- PM_freeRealSeg(VESABuf_ptr);
- VESABuf_ptr = 0;
-}
-
-void * PMAPI PM_getVESABuf(uint *len,uint *rseg,uint *roff)
-{
- if (!VESABuf_ptr) {
- /* Allocate a global buffer for communicating with the VESA VBE */
- if ((VESABuf_ptr = PM_allocRealSeg(VESABuf_len, &VESABuf_rseg, &VESABuf_roff)) == NULL)
- return NULL;
- atexit(ExitVBEBuf);
- }
- *len = VESABuf_len;
- *rseg = VESABuf_rseg;
- *roff = VESABuf_roff;
- return VESABuf_ptr;
-}
-
-/* New raw console based getch and kbhit functions */
-
-#define KB_CAPS LED_CAP /* 4 */
-#define KB_NUMLOCK LED_NUM /* 2 */
-#define KB_SCROLL LED_SCR /* 1 */
-#define KB_SHIFT 8
-#define KB_CONTROL 16
-#define KB_ALT 32
-
-/* Structure used to save the keyboard mode to disk. We save it to disk
- * so that we can properly restore the mode later if the program crashed.
- */
-
-typedef struct {
- struct termios termios;
- int kb_mode;
- int leds;
- int flags;
- int startup_vc;
- } keyboard_mode;
-
-/* Name of the file used to save keyboard mode information */
-
-#define KBMODE_DAT "kbmode.dat"
-
-/****************************************************************************
-REMARKS:
-Open the keyboard mode file on disk.
-****************************************************************************/
-static FILE *open_kb_mode(
- char *mode,
- char *path)
-{
- if (!PM_findBPD("graphics.bpd",path))
- return NULL;
- PM_backslash(path);
- strcat(path,KBMODE_DAT);
- return fopen(path,mode);
-}
-
-/****************************************************************************
-REMARKS:
-Restore the keyboard to normal mode
-****************************************************************************/
-void _PM_restore_kb_mode(void)
-{
- FILE *kbmode;
- keyboard_mode mode;
- char path[PM_MAX_PATH];
-
- if (_PM_console_fd != -1 && (kbmode = open_kb_mode("rb",path)) != NULL) {
- if (fread(&mode,1,sizeof(mode),kbmode) == sizeof(mode)) {
- if (mode.startup_vc > 0)
- ioctl(_PM_console_fd, VT_ACTIVATE, mode.startup_vc);
- ioctl(_PM_console_fd, KDSKBMODE, mode.kb_mode);
- ioctl(_PM_console_fd, KDSETLED, mode.leds);
- tcsetattr(_PM_console_fd, TCSAFLUSH, &mode.termios);
- fcntl(_PM_console_fd,F_SETFL,mode.flags);
- }
- fclose(kbmode);
- unlink(path);
- in_raw_mode = false;
- }
-}
-
-/****************************************************************************
-REMARKS:
-Safely abort the event module upon catching a fatal error.
-****************************************************************************/
-void _PM_abort(
- int signo)
-{
- char buf[80];
-
- sprintf(buf,"Terminating on signal %d",signo);
- _PM_restore_kb_mode();
- PM_fatalError(buf);
-}
-
-/****************************************************************************
-REMARKS:
-Put the keyboard into raw mode
-****************************************************************************/
-void _PM_keyboard_rawmode(void)
-{
- struct termios conf;
- FILE *kbmode;
- keyboard_mode mode;
- char path[PM_MAX_PATH];
- int i;
- static int sig_list[] = {
- SIGHUP,
- SIGINT,
- SIGQUIT,
- SIGILL,
- SIGTRAP,
- SIGABRT,
- SIGIOT,
- SIGBUS,
- SIGFPE,
- SIGKILL,
- SIGSEGV,
- SIGTERM,
- };
-
- if ((kbmode = open_kb_mode("rb",path)) == NULL) {
- if ((kbmode = open_kb_mode("wb",path)) == NULL)
- PM_fatalError("Unable to open kbmode.dat file for writing!");
- if (ioctl(_PM_console_fd, KDGKBMODE, &mode.kb_mode))
- perror("KDGKBMODE");
- ioctl(_PM_console_fd, KDGETLED, &mode.leds);
- _PM_leds = mode.leds & 0xF;
- _PM_modifiers = 0;
- tcgetattr(_PM_console_fd, &mode.termios);
- conf = mode.termios;
- conf.c_lflag &= ~(ICANON | ECHO | ISIG);
- conf.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);
- conf.c_iflag |= (IGNBRK | IGNPAR);
- conf.c_cc[VMIN] = 1;
- conf.c_cc[VTIME] = 0;
- conf.c_cc[VSUSP] = 0;
- tcsetattr(_PM_console_fd, TCSAFLUSH, &conf);
- mode.flags = fcntl(_PM_console_fd,F_GETFL);
- if (ioctl(_PM_console_fd, KDSKBMODE, K_MEDIUMRAW))
- perror("KDSKBMODE");
- atexit(_PM_restore_kb_mode);
- for (i = 0; i < sizeof(sig_list)/sizeof(sig_list[0]); i++)
- signal(sig_list[i], _PM_abort);
- mode.startup_vc = startup_vc;
- if (fwrite(&mode,1,sizeof(mode),kbmode) != sizeof(mode))
- PM_fatalError("Error writing kbmode.dat!");
- fclose(kbmode);
- in_raw_mode = true;
- }
-}
-
-int PMAPI PM_kbhit(void)
-{
- fd_set s;
- struct timeval tv = { 0, 0 };
-
- if (console_count == 0)
- PM_fatalError("You *must* open a console before using PM_kbhit!");
- if (!in_raw_mode)
- _PM_keyboard_rawmode();
- FD_ZERO(&s);
- FD_SET(_PM_console_fd, &s);
- return select(_PM_console_fd+1, &s, NULL, NULL, &tv) > 0;
-}
-
-int PMAPI PM_getch(void)
-{
- static uchar c;
- int release;
- static struct kbentry ke;
-
- if (console_count == 0)
- PM_fatalError("You *must* open a console before using PM_getch!");
- if (!in_raw_mode)
- _PM_keyboard_rawmode();
- while (read(_PM_console_fd, &c, 1) > 0) {
- release = c & 0x80;
- c &= 0x7F;
- if (release) {
- switch(c){
- case 42: case 54: /* Shift */
- _PM_modifiers &= ~KB_SHIFT;
- break;
- case 29: case 97: /* Control */
- _PM_modifiers &= ~KB_CONTROL;
- break;
- case 56: case 100: /* Alt / AltGr */
- _PM_modifiers &= ~KB_ALT;
- break;
- }
- continue;
- }
- switch (c) {
- case 42: case 54: /* Shift */
- _PM_modifiers |= KB_SHIFT;
- break;
- case 29: case 97: /* Control */
- _PM_modifiers |= KB_CONTROL;
- break;
- case 56: case 100: /* Alt / AltGr */
- _PM_modifiers |= KB_ALT;
- break;
- case 58: /* Caps Lock */
- _PM_modifiers ^= KB_CAPS;
- ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);
- break;
- case 69: /* Num Lock */
- _PM_modifiers ^= KB_NUMLOCK;
- ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);
- break;
- case 70: /* Scroll Lock */
- _PM_modifiers ^= KB_SCROLL;
- ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);
- break;
- case 28:
- return 0x1C;
- default:
- ke.kb_index = c;
- ke.kb_table = 0;
- if ((_PM_modifiers & KB_SHIFT) || (_PM_modifiers & KB_CAPS))
- ke.kb_table |= K_SHIFTTAB;
- if (_PM_modifiers & KB_ALT)
- ke.kb_table |= K_ALTTAB;
- ioctl(_PM_console_fd, KDGKBENT, (ulong)&ke);
- c = ke.kb_value & 0xFF;
- return c;
- }
- }
- return 0;
-}
-
-/****************************************************************************
-REMARKS:
-Sleep until the virtual terminal is active
-****************************************************************************/
-static void wait_vt_active(
- int _PM_console_fd)
-{
- while (ioctl(_PM_console_fd, VT_WAITACTIVE, tty_vc) < 0) {
- if ((errno != EAGAIN) && (errno != EINTR)) {
- perror("ioctl(VT_WAITACTIVE)");
- exit(1);
- }
- usleep(150000);
- }
-}
-
-/****************************************************************************
-REMARKS:
-Checks the owner of the specified virtual console.
-****************************************************************************/
-static int check_owner(
- int vc)
-{
- struct stat sbuf;
- char fname[30];
-
- sprintf(fname, "/dev/tty%d", vc);
- if ((stat(fname, &sbuf) >= 0) && (getuid() == sbuf.st_uid))
- return 1;
- printf("You must be the owner of the current console to use this program.\n");
- return 0;
-}
-
-/****************************************************************************
-REMARKS:
-Checks if the console is currently in graphics mode, and if so we forcibly
-restore it back to text mode again. This handles the case when a Nucleus or
-MGL program crashes and leaves the console in graphics mode. Running the
-textmode utility (or any other Nucleus/MGL program) via a telnet session
-into the machine will restore it back to normal.
-****************************************************************************/
-static void restore_text_console(
- int console_id)
-{
- if (ioctl(console_id, KDSETMODE, KD_TEXT) < 0)
- LOGWARN("ioctl(KDSETMODE) failed");
- _PM_restore_kb_mode();
-}
-
-/****************************************************************************
-REMARKS:
-Opens up the console device for output by finding an appropriate virutal
-console that we can run on.
-****************************************************************************/
-PM_HWND PMAPI PM_openConsole(
- PM_HWND hwndUser,
- int device,
- int xRes,
- int yRes,
- int bpp,
- ibool fullScreen)
-{
- struct vt_mode vtm;
- struct vt_stat vts;
- struct stat sbuf;
- char fname[30];
-
- /* Check if we have already opened the console */
- if (console_count++)
- return _PM_console_fd;
-
- /* Now, it would be great if we could use /dev/tty and see what it is
- * connected to. Alas, we cannot find out reliably what VC /dev/tty is
- * bound to. Thus we parse stdin through stderr for a reliable VC.
- */
- startup_vc = 0;
- for (_PM_console_fd = 0; _PM_console_fd < 3; _PM_console_fd++) {
- if (fstat(_PM_console_fd, &sbuf) < 0)
- continue;
- if (ioctl(_PM_console_fd, VT_GETMODE, &vtm) < 0)
- continue;
- if ((sbuf.st_rdev & 0xFF00) != 0x400)
- continue;
- if (!(sbuf.st_rdev & 0xFF))
- continue;
- tty_vc = sbuf.st_rdev & 0xFF;
- restore_text_console(_PM_console_fd);
- return _PM_console_fd;
- }
- if ((_PM_console_fd = open("/dev/console", O_RDWR)) < 0) {
- printf("open_dev_console: can't open /dev/console \n");
- exit(1);
- }
- if (ioctl(_PM_console_fd, VT_OPENQRY, &tty_vc) < 0)
- goto Error;
- if (tty_vc <= 0)
- goto Error;
- sprintf(fname, "/dev/tty%d", tty_vc);
- close(_PM_console_fd);
-
- /* Change our control terminal */
- setsid();
-
- /* We must use RDWR to allow for output... */
- if (((_PM_console_fd = open(fname, O_RDWR)) >= 0) &&
- (ioctl(_PM_console_fd, VT_GETSTATE, &vts) >= 0)) {
- if (!check_owner(vts.v_active))
- goto Error;
- restore_text_console(_PM_console_fd);
-
- /* Success, redirect all stdios */
- fflush(stdin);
- fflush(stdout);
- fflush(stderr);
- close(0);
- close(1);
- close(2);
- dup(_PM_console_fd);
- dup(_PM_console_fd);
- dup(_PM_console_fd);
-
- /* clear screen and switch to it */
- fwrite("\e[H\e[J", 6, 1, stderr);
- fflush(stderr);
- if (tty_vc != vts.v_active) {
- startup_vc = vts.v_active;
- ioctl(_PM_console_fd, VT_ACTIVATE, tty_vc);
- wait_vt_active(_PM_console_fd);
- }
- }
- return _PM_console_fd;
-
-Error:
- if (_PM_console_fd > 2)
- close(_PM_console_fd);
- console_count = 0;
- PM_fatalError(
- "Not running in a graphics capable console,\n"
- "and unable to find one.\n");
- return -1;
-}
-
-#define FONT_C 0x10000 /* 64KB for font data */
-
-/****************************************************************************
-REMARKS:
-Returns the size of the console state buffer.
-****************************************************************************/
-int PMAPI PM_getConsoleStateSize(void)
-{
- if (!inited)
- PM_init();
- return PM_getVGAStateSize() + FONT_C*2;
-}
-
-/****************************************************************************
-REMARKS:
-Save the state of the Linux console.
-****************************************************************************/
-void PMAPI PM_saveConsoleState(void *stateBuf,int console_id)
-{
- uchar *regs = stateBuf;
-
- /* Save the current console font */
- if (ioctl(console_id,GIO_FONT,&regs[PM_getVGAStateSize()]) < 0)
- perror("ioctl(GIO_FONT)");
-
- /* Inform the Linux console that we are going into graphics mode */
- if (ioctl(console_id, KDSETMODE, KD_GRAPHICS) < 0)
- perror("ioctl(KDSETMODE)");
-
- /* Save state of VGA registers */
- PM_saveVGAState(stateBuf);
-}
-
-void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags))
-{
- /* TODO: Implement support for allowing console switching! */
-}
-
-/****************************************************************************
-REMARKS:
-Restore the state of the Linux console.
-****************************************************************************/
-void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND console_id)
-{
- const uchar *regs = stateBuf;
-
- /* Restore the state of the VGA compatible registers */
- PM_restoreVGAState(stateBuf);
-
- /* Inform the Linux console that we are back from graphics modes */
- if (ioctl(console_id, KDSETMODE, KD_TEXT) < 0)
- LOGWARN("ioctl(KDSETMODE) failed");
-
- /* Restore the old console font */
- if (ioctl(console_id,PIO_FONT,&regs[PM_getVGAStateSize()]) < 0)
- LOGWARN("ioctl(KDSETMODE) failed");
-
- /* Coming back from graphics mode on Linux also restored the previous
- * text mode console contents, so we need to clear the screen to get
- * around this since the cursor does not get homed by our code.
- */
- fflush(stdout);
- fflush(stderr);
- printf("\033[H\033[J");
- fflush(stdout);
-}
-
-/****************************************************************************
-REMARKS:
-Close the Linux console and put it back to normal.
-****************************************************************************/
-void PMAPI PM_closeConsole(PM_HWND _PM_console_fd)
-{
- /* Restore console to normal operation */
- if (--console_count == 0) {
- /* Re-activate the original virtual console */
- if (startup_vc > 0)
- ioctl(_PM_console_fd, VT_ACTIVATE, startup_vc);
-
- /* Close the console file descriptor */
- if (_PM_console_fd > 2)
- close(_PM_console_fd);
- _PM_console_fd = -1;
- }
-}
-
-void PM_setOSCursorLocation(int x,int y)
-{
- /* Nothing to do in here */
-}
-
-/****************************************************************************
-REMARKS:
-Set the screen width and height for the Linux console.
-****************************************************************************/
-void PM_setOSScreenWidth(int width,int height)
-{
- struct winsize ws;
- struct vt_sizes vs;
-
- /* Resize the software terminal */
- ws.ws_col = width;
- ws.ws_row = height;
- ioctl(_PM_console_fd, TIOCSWINSZ, &ws);
-
- /* And the hardware */
- vs.v_rows = height;
- vs.v_cols = width;
- vs.v_scrollsize = 0;
- ioctl(_PM_console_fd, VT_RESIZE, &vs);
-}
-
-ibool PMAPI PM_setRealTimeClockHandler(PM_intHandler ih, int frequency)
-{
- /* TODO: Implement this for Linux */
- return false;
-}
-
-void PMAPI PM_setRealTimeClockFrequency(int frequency)
-{
- /* TODO: Implement this for Linux */
-}
-
-void PMAPI PM_restoreRealTimeClockHandler(void)
-{
- /* TODO: Implement this for Linux */
-}
-
-char * PMAPI PM_getCurrentPath(
- char *path,
- int maxLen)
-{
- return getcwd(path,maxLen);
-}
-
-char PMAPI PM_getBootDrive(void)
-{ return '/'; }
-
-const char * PMAPI PM_getVBEAFPath(void)
-{ return PM_getNucleusConfigPath(); }
-
-const char * PMAPI PM_getNucleusPath(void)
-{
- char *env = getenv("NUCLEUS_PATH");
- return env ? env : "/usr/lib/nucleus";
-}
-
-const char * PMAPI PM_getNucleusConfigPath(void)
-{
- static char path[256];
- strcpy(path,PM_getNucleusPath());
- PM_backslash(path);
- strcat(path,"config");
- return path;
-}
-
-const char * PMAPI PM_getUniqueID(void)
-{
- static char buf[128];
- gethostname(buf, 128);
- return buf;
-}
-
-const char * PMAPI PM_getMachineName(void)
-{
- static char buf[128];
- gethostname(buf, 128);
- return buf;
-}
-
-void * PMAPI PM_getBIOSPointer(void)
-{
- static uchar *zeroPtr = NULL;
- if (!zeroPtr)
- zeroPtr = PM_mapPhysicalAddr(0,0xFFFFF,true);
- return (void*)(zeroPtr + 0x400);
-}
-
-void * PMAPI PM_getA0000Pointer(void)
-{
- /* PM_init maps in the 0xA0000 framebuffer region 1:1 with our
- * address mapping, so we can return the address here.
- */
- if (!inited)
- PM_init();
- return (void*)(0xA0000);
-}
-
-void * PMAPI PM_mapPhysicalAddr(ulong base,ulong limit,ibool isCached)
-{
- uchar *p;
- ulong baseAddr,baseOfs;
-
- if (!inited)
- PM_init();
- if (base >= 0xA0000 && base < 0x100000)
- return (void*)base;
- if (!fd_mem && (fd_mem = open("/dev/mem", O_RDWR)) == -1)
- return NULL;
-
- /* Round the physical address to a 4Kb boundary and the limit to a
- * 4Kb-1 boundary before passing the values to mmap. If we round the
- * physical address, then we also add an extra offset into the address
- * that we return.
- */
- baseOfs = base & 4095;
- baseAddr = base & ~4095;
- limit = ((limit+baseOfs+1+4095) & ~4095)-1;
- if ((p = mmap(0, limit+1,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- fd_mem, baseAddr)) == (void *)-1)
- return NULL;
- return (void*)(p+baseOfs);
-}
-
-void PMAPI PM_freePhysicalAddr(void *ptr,ulong limit)
-{
- if ((ulong)ptr >= 0x100000)
- munmap(ptr,limit+1);
-}
-
-ulong PMAPI PM_getPhysicalAddr(void *p)
-{
- /* TODO: This function should find the physical address of a linear */
- /* address. */
- return 0xFFFFFFFFUL;
-}
-
-ibool PMAPI PM_getPhysicalAddrRange(void *p,ulong length,ulong *physAddress)
-{
- /* TODO: This function should find a range of physical addresses */
- /* for a linear address. */
- return false;
-}
-
-void PMAPI PM_sleep(ulong milliseconds)
-{
- /* TODO: Put the process to sleep for milliseconds */
-}
-
-int PMAPI PM_getCOMPort(int port)
-{
- /* TODO: Re-code this to determine real values using the Plug and Play */
- /* manager for the OS. */
- switch (port) {
- case 0: return 0x3F8;
- case 1: return 0x2F8;
- }
- return 0;
-}
-
-int PMAPI PM_getLPTPort(int port)
-{
- /* TODO: Re-code this to determine real values using the Plug and Play */
- /* manager for the OS. */
- switch (port) {
- case 0: return 0x3BC;
- case 1: return 0x378;
- case 2: return 0x278;
- }
- return 0;
-}
-
-void * PMAPI PM_mallocShared(long size)
-{
- return PM_malloc(size);
-}
-
-void PMAPI PM_freeShared(void *ptr)
-{
- PM_free(ptr);
-}
-
-void * PMAPI PM_mapToProcess(void *base,ulong limit)
-{ return (void*)base; }
-
-void * PMAPI PM_mapRealPointer(uint r_seg,uint r_off)
-{
- /* PM_init maps in the 0xA0000-0x100000 region 1:1 with our
- * address mapping, as well as all memory blocks in a 1:1 address
- * mapping so we can simply return the physical address in here.
- */
- if (!inited)
- PM_init();
- return (void*)MK_PHYS(r_seg,r_off);
-}
-
-void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off)
-{
- int i;
- char *r = (char *)REAL_MEM_BASE;
-
- if (!inited)
- PM_init();
- if (!mem_info.ready)
- return NULL;
- if (mem_info.count == REAL_MEM_BLOCKS)
- return NULL;
- size = (size + 15) & ~15;
- for (i = 0; i < mem_info.count; i++) {
- if (mem_info.blocks[i].free && size < mem_info.blocks[i].size) {
- insert_block(i);
- mem_info.blocks[i].size = size;
- mem_info.blocks[i].free = 0;
- mem_info.blocks[i + 1].size -= size;
- *r_seg = (uint)(r) >> 4;
- *r_off = (uint)(r) & 0xF;
- return (void *)r;
- }
- r += mem_info.blocks[i].size;
- }
- return NULL;
-}
-
-void PMAPI PM_freeRealSeg(void *mem)
-{
- int i;
- char *r = (char *)REAL_MEM_BASE;
-
- if (!mem_info.ready)
- return;
- i = 0;
- while (mem != (void *)r) {
- r += mem_info.blocks[i].size;
- i++;
- if (i == mem_info.count)
- return;
- }
- mem_info.blocks[i].free = 1;
- if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free) {
- mem_info.blocks[i].size += mem_info.blocks[i + 1].size;
- delete_block(i + 1);
- }
- if (i - 1 >= 0 && mem_info.blocks[i - 1].free) {
- mem_info.blocks[i - 1].size += mem_info.blocks[i].size;
- delete_block(i);
- }
-}
-
-#define DIRECTION_FLAG (1 << 10)
-
-static void em_ins(int size)
-{
- unsigned int edx, edi;
-
- edx = context.vm.regs.edx & 0xffff;
- edi = context.vm.regs.edi & 0xffff;
- edi += (unsigned int)context.vm.regs.ds << 4;
- if (context.vm.regs.eflags & DIRECTION_FLAG) {
- if (size == 4)
- asm volatile ("std; insl; cld"
- : "=D" (edi) : "d" (edx), "0" (edi));
- else if (size == 2)
- asm volatile ("std; insw; cld"
- : "=D" (edi) : "d" (edx), "0" (edi));
- else
- asm volatile ("std; insb; cld"
- : "=D" (edi) : "d" (edx), "0" (edi));
- }
- else {
- if (size == 4)
- asm volatile ("cld; insl"
- : "=D" (edi) : "d" (edx), "0" (edi));
- else if (size == 2)
- asm volatile ("cld; insw"
- : "=D" (edi) : "d" (edx), "0" (edi));
- else
- asm volatile ("cld; insb"
- : "=D" (edi) : "d" (edx), "0" (edi));
- }
- edi -= (unsigned int)context.vm.regs.ds << 4;
- context.vm.regs.edi &= 0xffff0000;
- context.vm.regs.edi |= edi & 0xffff;
-}
-
-static void em_rep_ins(int size)
-{
- unsigned int ecx, edx, edi;
-
- ecx = context.vm.regs.ecx & 0xffff;
- edx = context.vm.regs.edx & 0xffff;
- edi = context.vm.regs.edi & 0xffff;
- edi += (unsigned int)context.vm.regs.ds << 4;
- if (context.vm.regs.eflags & DIRECTION_FLAG) {
- if (size == 4)
- asm volatile ("std; rep; insl; cld"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- else if (size == 2)
- asm volatile ("std; rep; insw; cld"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- else
- asm volatile ("std; rep; insb; cld"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- }
- else {
- if (size == 4)
- asm volatile ("cld; rep; insl"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- else if (size == 2)
- asm volatile ("cld; rep; insw"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- else
- asm volatile ("cld; rep; insb"
- : "=D" (edi), "=c" (ecx)
- : "d" (edx), "0" (edi), "1" (ecx));
- }
-
- edi -= (unsigned int)context.vm.regs.ds << 4;
- context.vm.regs.edi &= 0xffff0000;
- context.vm.regs.edi |= edi & 0xffff;
- context.vm.regs.ecx &= 0xffff0000;
- context.vm.regs.ecx |= ecx & 0xffff;
-}
-
-static void em_outs(int size)
-{
- unsigned int edx, esi;
-
- edx = context.vm.regs.edx & 0xffff;
- esi = context.vm.regs.esi & 0xffff;
- esi += (unsigned int)context.vm.regs.ds << 4;
- if (context.vm.regs.eflags & DIRECTION_FLAG) {
- if (size == 4)
- asm volatile ("std; outsl; cld"
- : "=S" (esi) : "d" (edx), "0" (esi));
- else if (size == 2)
- asm volatile ("std; outsw; cld"
- : "=S" (esi) : "d" (edx), "0" (esi));
- else
- asm volatile ("std; outsb; cld"
- : "=S" (esi) : "d" (edx), "0" (esi));
- }
- else {
- if (size == 4)
- asm volatile ("cld; outsl"
- : "=S" (esi) : "d" (edx), "0" (esi));
- else if (size == 2)
- asm volatile ("cld; outsw"
- : "=S" (esi) : "d" (edx), "0" (esi));
- else
- asm volatile ("cld; outsb"
- : "=S" (esi) : "d" (edx), "0" (esi));
- }
-
- esi -= (unsigned int)context.vm.regs.ds << 4;
- context.vm.regs.esi &= 0xffff0000;
- context.vm.regs.esi |= esi & 0xffff;
-}
-
-static void em_rep_outs(int size)
-{
- unsigned int ecx, edx, esi;
-
- ecx = context.vm.regs.ecx & 0xffff;
- edx = context.vm.regs.edx & 0xffff;
- esi = context.vm.regs.esi & 0xffff;
- esi += (unsigned int)context.vm.regs.ds << 4;
- if (context.vm.regs.eflags & DIRECTION_FLAG) {
- if (size == 4)
- asm volatile ("std; rep; outsl; cld"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- else if (size == 2)
- asm volatile ("std; rep; outsw; cld"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- else
- asm volatile ("std; rep; outsb; cld"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- }
- else {
- if (size == 4)
- asm volatile ("cld; rep; outsl"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- else if (size == 2)
- asm volatile ("cld; rep; outsw"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- else
- asm volatile ("cld; rep; outsb"
- : "=S" (esi), "=c" (ecx)
- : "d" (edx), "0" (esi), "1" (ecx));
- }
-
- esi -= (unsigned int)context.vm.regs.ds << 4;
- context.vm.regs.esi &= 0xffff0000;
- context.vm.regs.esi |= esi & 0xffff;
- context.vm.regs.ecx &= 0xffff0000;
- context.vm.regs.ecx |= ecx & 0xffff;
-}
-
-static int emulate(void)
-{
- unsigned char *insn;
- struct {
- unsigned int size : 1;
- unsigned int rep : 1;
- } prefix = { 0, 0 };
- int i = 0;
-
- insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4);
- insn += context.vm.regs.eip;
-
- while (1) {
-#ifdef TRACE_IO
- traceAddr = ((ulong)context.vm.regs.cs << 16) + context.vm.regs.eip + i;
-#endif
- if (insn[i] == 0x66) {
- prefix.size = 1 - prefix.size;
- i++;
- }
- else if (insn[i] == 0xf3) {
- prefix.rep = 1;
- i++;
- }
- else if (insn[i] == 0xf0 || insn[i] == 0xf2
- || insn[i] == 0x26 || insn[i] == 0x2e
- || insn[i] == 0x36 || insn[i] == 0x3e
- || insn[i] == 0x64 || insn[i] == 0x65
- || insn[i] == 0x67) {
- /* these prefixes are just ignored */
- i++;
- }
- else if (insn[i] == 0x6c) {
- if (prefix.rep)
- em_rep_ins(1);
- else
- em_ins(1);
- i++;
- break;
- }
- else if (insn[i] == 0x6d) {
- if (prefix.rep) {
- if (prefix.size)
- em_rep_ins(4);
- else
- em_rep_ins(2);
- }
- else {
- if (prefix.size)
- em_ins(4);
- else
- em_ins(2);
- }
- i++;
- break;
- }
- else if (insn[i] == 0x6e) {
- if (prefix.rep)
- em_rep_outs(1);
- else
- em_outs(1);
- i++;
- break;
- }
- else if (insn[i] == 0x6f) {
- if (prefix.rep) {
- if (prefix.size)
- em_rep_outs(4);
- else
- em_rep_outs(2);
- }
- else {
- if (prefix.size)
- em_outs(4);
- else
- em_outs(2);
- }
- i++;
- break;
- }
- else if (insn[i] == 0xec) {
- *((uchar*)&context.vm.regs.eax) = port_in(context.vm.regs.edx);
- i++;
- break;
- }
- else if (insn[i] == 0xed) {
- if (prefix.size)
- *((ulong*)&context.vm.regs.eax) = port_inl(context.vm.regs.edx);
- else
- *((ushort*)&context.vm.regs.eax) = port_inw(context.vm.regs.edx);
- i++;
- break;
- }
- else if (insn[i] == 0xee) {
- port_out(context.vm.regs.eax,context.vm.regs.edx);
- i++;
- break;
- }
- else if (insn[i] == 0xef) {
- if (prefix.size)
- port_outl(context.vm.regs.eax,context.vm.regs.edx);
- else
- port_outw(context.vm.regs.eax,context.vm.regs.edx);
- i++;
- break;
- }
- else
- return 0;
- }
-
- context.vm.regs.eip += i;
- return 1;
-}
-
-static void debug_info(int vret)
-{
- int i;
- unsigned char *p;
-
- fputs("vm86() failed\n", stderr);
- fprintf(stderr, "return = 0x%x\n", vret);
- fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax);
- fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx);
- fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx);
- fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx);
- fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi);
- fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi);
- fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp);
- fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip);
- fprintf(stderr, "cs = 0x%04x\n", context.vm.regs.cs);
- fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp);
- fprintf(stderr, "ss = 0x%04x\n", context.vm.regs.ss);
- fprintf(stderr, "ds = 0x%04x\n", context.vm.regs.ds);
- fprintf(stderr, "es = 0x%04x\n", context.vm.regs.es);
- fprintf(stderr, "fs = 0x%04x\n", context.vm.regs.fs);
- fprintf(stderr, "gs = 0x%04x\n", context.vm.regs.gs);
- fprintf(stderr, "eflags = 0x%08lx\n", context.vm.regs.eflags);
- fputs("cs:ip = [ ", stderr);
- p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff));
- for (i = 0; i < 16; ++i)
- fprintf(stderr, "%02x ", (unsigned int)p[i]);
- fputs("]\n", stderr);
- fflush(stderr);
-}
-
-static int run_vm86(void)
-{
- unsigned int vret;
-
- for (;;) {
- vret = vm86(&context.vm);
- if (VM86_TYPE(vret) == VM86_INTx) {
- unsigned int v = VM86_ARG(vret);
- if (v == RETURN_TO_32_INT)
- return 1;
- pushw(context.vm.regs.eflags);
- pushw(context.vm.regs.cs);
- pushw(context.vm.regs.eip);
- context.vm.regs.cs = get_int_seg(v);
- context.vm.regs.eip = get_int_off(v);
- context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK);
- continue;
- }
- if (VM86_TYPE(vret) != VM86_UNKNOWN)
- break;
- if (!emulate())
- break;
- }
- debug_info(vret);
- return 0;
-}
-
-#define IND(ereg) context.vm.regs.ereg = regs->ereg
-#define OUTD(ereg) regs->ereg = context.vm.regs.ereg
-
-void PMAPI DPMI_int86(int intno, DPMI_regs *regs)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- IND(eax); IND(ebx); IND(ecx); IND(edx); IND(esi); IND(edi);
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(intno);
- context.vm.regs.eip = get_int_off(intno);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
- OUTD(eax); OUTD(ebx); OUTD(ecx); OUTD(edx); OUTD(esi); OUTD(edi);
- regs->flags = context.vm.regs.eflags;
-}
-
-#define IN(ereg) context.vm.regs.ereg = in->e.ereg
-#define OUT(ereg) out->e.ereg = context.vm.regs.ereg
-
-int PMAPI PM_int86(int intno, RMREGS *in, RMREGS *out)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(intno);
- context.vm.regs.eip = get_int_off(intno);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
- OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
- out->x.cflag = context.vm.regs.eflags & 1;
- return out->x.ax;
-}
-
-int PMAPI PM_int86x(int intno, RMREGS *in, RMREGS *out,
- RMSREGS *sregs)
-{
- if (!inited)
- PM_init();
- if (intno == 0x21) {
- time_t today = time(NULL);
- struct tm *t;
- t = localtime(&today);
- out->x.cx = t->tm_year + 1900;
- out->h.dh = t->tm_mon + 1;
- out->h.dl = t->tm_mday;
- }
- else {
- unsigned int seg, off;
- seg = get_int_seg(intno);
- off = get_int_off(intno);
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = seg;
- context.vm.regs.eip = off;
- context.vm.regs.es = sregs->es;
- context.vm.regs.ds = sregs->ds;
- context.vm.regs.fs = sregs->fs;
- context.vm.regs.gs = sregs->gs;
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
- OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
- sregs->es = context.vm.regs.es;
- sregs->ds = context.vm.regs.ds;
- sregs->fs = context.vm.regs.fs;
- sregs->gs = context.vm.regs.gs;
- out->x.cflag = context.vm.regs.eflags & 1;
- }
- return out->e.eax;
-}
-
-#define OUTR(ereg) in->e.ereg = context.vm.regs.ereg
-
-void PMAPI PM_callRealMode(uint seg,uint off, RMREGS *in,
- RMSREGS *sregs)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = seg;
- context.vm.regs.eip = off;
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- context.vm.regs.es = sregs->es;
- context.vm.regs.ds = sregs->ds;
- context.vm.regs.fs = sregs->fs;
- context.vm.regs.gs = sregs->gs;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
- OUTR(eax); OUTR(ebx); OUTR(ecx); OUTR(edx); OUTR(esi); OUTR(edi);
- sregs->es = context.vm.regs.es;
- sregs->ds = context.vm.regs.ds;
- sregs->fs = context.vm.regs.fs;
- sregs->gs = context.vm.regs.gs;
- in->x.cflag = context.vm.regs.eflags & 1;
-}
-
-void PMAPI PM_availableMemory(ulong *physical,ulong *total)
-{
- FILE *mem = fopen("/proc/meminfo","r");
- char buf[1024];
-
- fgets(buf,1024,mem);
- fgets(buf,1024,mem);
- sscanf(buf,"Mem: %*d %*d %ld", physical);
- fgets(buf,1024,mem);
- sscanf(buf,"Swap: %*d %*d %ld", total);
- fclose(mem);
- *total += *physical;
-}
-
-void * PMAPI PM_allocLockedMem(uint size,ulong *physAddr,ibool contiguous,ibool below16M)
-{
- /* TODO: Implement this for Linux */
- return NULL;
-}
-
-void PMAPI PM_freeLockedMem(void *p,uint size,ibool contiguous)
-{
- /* TODO: Implement this for Linux */
-}
-
-void * PMAPI PM_allocPage(
- ibool locked)
-{
- /* TODO: Implement this for Linux */
- return NULL;
-}
-
-void PMAPI PM_freePage(
- void *p)
-{
- /* TODO: Implement this for Linux */
-}
-
-void PMAPI PM_setBankA(int bank)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- context.vm.regs.eax = 0x4F05;
- context.vm.regs.ebx = 0x0000;
- context.vm.regs.edx = bank;
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(0x10);
- context.vm.regs.eip = get_int_off(0x10);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
-}
-
-void PMAPI PM_setBankAB(int bank)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- context.vm.regs.eax = 0x4F05;
- context.vm.regs.ebx = 0x0000;
- context.vm.regs.edx = bank;
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(0x10);
- context.vm.regs.eip = get_int_off(0x10);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
- context.vm.regs.eax = 0x4F05;
- context.vm.regs.ebx = 0x0001;
- context.vm.regs.edx = bank;
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(0x10);
- context.vm.regs.eip = get_int_off(0x10);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
-}
-
-void PMAPI PM_setCRTStart(int x,int y,int waitVRT)
-{
- if (!inited)
- PM_init();
- memset(&context.vm.regs, 0, sizeof(context.vm.regs));
- context.vm.regs.eax = 0x4F07;
- context.vm.regs.ebx = waitVRT;
- context.vm.regs.ecx = x;
- context.vm.regs.edx = y;
- context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
- context.vm.regs.cs = get_int_seg(0x10);
- context.vm.regs.eip = get_int_off(0x10);
- context.vm.regs.ss = context.stack_seg;
- context.vm.regs.esp = context.stack_off;
- pushw(DEFAULT_VM86_FLAGS);
- pushw(context.ret_seg);
- pushw(context.ret_off);
- run_vm86();
-}
-
-int PMAPI PM_enableWriteCombine(ulong base,ulong length,uint type)
-{
-#ifdef ENABLE_MTRR
- struct mtrr_sentry sentry;
-
- if (mtrr_fd < 0)
- return PM_MTRR_ERR_NO_OS_SUPPORT;
- sentry.base = base;
- sentry.size = length;
- sentry.type = type;
- if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &sentry) == -1) {
- /* TODO: Need to decode MTRR error codes!! */
- return PM_MTRR_NOT_SUPPORTED;
- }
- return PM_MTRR_ERR_OK;
-#else
- return PM_MTRR_ERR_NO_OS_SUPPORT;
-#endif
-}
-
-/****************************************************************************
-PARAMETERS:
-callback - Function to callback with write combine information
-
-REMARKS:
-Function to enumerate all write combine regions currently enabled for the
-processor.
-****************************************************************************/
-int PMAPI PM_enumWriteCombine(
- PM_enumWriteCombine_t callback)
-{
-#ifdef ENABLE_MTRR
- struct mtrr_gentry gentry;
-
- if (mtrr_fd < 0)
- return PM_MTRR_ERR_NO_OS_SUPPORT;
-
- for (gentry.regnum = 0; ioctl (mtrr_fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
- ++gentry.regnum) {
- if (gentry.size > 0) {
- /* WARNING: This code assumes that the types in pmapi.h match the ones */
- /* in the Linux kernel (mtrr.h) */
- callback(gentry.base, gentry.size, gentry.type);
- }
- }
-
- return PM_MTRR_ERR_OK;
-#else
- return PM_MTRR_ERR_NO_OS_SUPPORT;
-#endif
-}
-
-ibool PMAPI PM_doBIOSPOST(
- ushort axVal,
- ulong BIOSPhysAddr,
- void *copyOfBIOS,
- ulong BIOSLen)
-{
- char *bios_ptr = (char*)0xC0000;
- char *old_bios;
- ulong Current10, Current6D, *rvec = 0;
- RMREGS regs;
- RMSREGS sregs;
-
- /* The BIOS is mapped to 0xC0000 with a private memory mapping enabled
- * which means we have a copy on write scheme. Hence we simply copy
- * the secondary BIOS image over the top of the old one.
- */
- if (!inited)
- PM_init();
- if ((old_bios = PM_malloc(BIOSLen)) == NULL)
- return false;
- if (BIOSPhysAddr != 0xC0000) {
- memcpy(old_bios,bios_ptr,BIOSLen);
- memcpy(bios_ptr,copyOfBIOS,BIOSLen);
- }
-
- /* The interrupt vectors should already be mmap()'ed from 0-0x400 in PM_init */
- Current10 = rvec[0x10];
- Current6D = rvec[0x6D];
-
- /* POST the secondary BIOS */
- rvec[0x10] = rvec[0x42]; /* Restore int 10h to STD-BIOS */
- regs.x.ax = axVal;
- PM_callRealMode(0xC000,0x0003,&regs,&sregs);
-
- /* Restore interrupt vectors */
- rvec[0x10] = Current10;
- rvec[0x6D] = Current6D;
-
- /* Restore original BIOS image */
- if (BIOSPhysAddr != 0xC0000)
- memcpy(bios_ptr,old_bios,BIOSLen);
- PM_free(old_bios);
- return true;
-}
-
-int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh)
-{
- p = p; len = len;
- return 1;
-}
-
-int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
-{
- p = p; len = len;
- return 1;
-}
-
-int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
-{
- p = p; len = len;
- return 1;
-}
-
-int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
-{
- p = p; len = len;
- return 1;
-}
-
-PM_MODULE PMAPI PM_loadLibrary(
- const char *szDLLName)
-{
- /* TODO: Implement this to load shared libraries! */
- (void)szDLLName;
- return NULL;
-}
-
-void * PMAPI PM_getProcAddress(
- PM_MODULE hModule,
- const char *szProcName)
-{
- /* TODO: Implement this! */
- (void)hModule;
- (void)szProcName;
- return NULL;
-}
-
-void PMAPI PM_freeLibrary(
- PM_MODULE hModule)
-{
- /* TODO: Implement this! */
- (void)hModule;
-}
-
-int PMAPI PM_setIOPL(
- int level)
-{
- /* TODO: Move the IOPL switching into this function!! */
- return level;
-}
-
-void PMAPI PM_flushTLB(void)
-{
- /* Do nothing on Linux. */
-}
OpenPOWER on IntegriCloud