pm.c
来自「适合KS8695X」· C语言 代码 · 共 1,810 行 · 第 1/4 页
C
1,810 行
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,®s,&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. */
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?