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 + -
显示快捷键?