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