⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -