Example #1
0
void *vm_mappages(phys_bytes p, int pages)
{
    vir_bytes loc;
    int r;
    pt_t *pt = &vmprocess->vm_pt;

    /* Where in our virtual address space can we put it? */
    loc = findhole(pages);
    if(loc == NO_MEM) {
        printf("vm_mappages: findhole failed\n");
        return NULL;
    }

    /* Map this page into our address space. */
    if((r=pt_writemap(vmprocess, pt, loc, p, VM_PAGE_SIZE*pages,
                      ARCH_VM_PTE_PRESENT | ARCH_VM_PTE_USER | ARCH_VM_PTE_RW
#if defined(__arm__)
                      | ARM_VM_PTE_WT
#endif
                      , 0)) != OK) {
        printf("vm_mappages writemap failed\n");
        return NULL;
    }

    if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
        panic("VMCTL_FLUSHTLB failed: %d", r);
    }

    assert(loc);

    return (void *) loc;
}
Example #2
0
// write id:value, unless value is empty, in which case we erase the id
void writeMacro(char *id) {
	eraseentry(id);

	// we need to know the macro value length to allocate space for it
	// we don't realistically have enough buffer space handy to parse it into
	// so this is a two-pass operation: first we measure the text, then on
	// the second pass we stuff it into the eeprom
	//
	// measure length of macro value
	// we get here with inchar = first char of macro and fetchptr one past that
	//
	char *fetchmark = --fetchptr;		// back up and mark first char of macro text
	primec();							// re-prime
	expval = 0;							// zero the count
	parsestring(&countByte);			// now expval is the macro value length
	if (!expval) return;				// empty string? we're done
	
	int addr = findhole(strlen(id) + expval + 2);	// longjmps on fail
	if (addr >= 0) {
		saveString(addr, id);

		// reset parse context
		fetchptr = fetchmark;
		primec();

		expval = addr + strlen(id) + 1;		// set up address for saveByte
		parsestring(&saveByte);
		saveByte(0);
	}
}
Example #3
0
File: mmu.c Project: Shamar/harvey
/*
 * Look for free space in the vmap.
 */
static uintptr_t
vmapalloc(usize size)
{
    int i, n, o;
    PTE *pd, *pt;
    int pdsz, ptsz;

    pd = (PTE*)(PDMAP+PDX(PDMAP)*4096);
    pd += PDX(VMAP);
    pdsz = VMAPSZ/PGLSZ(1);

    /*
     * Look directly in the PD entries if the size is
     * larger than the range mapped by a single entry.
     */
    if(size >= PGLSZ(1)) {
        n = HOWMANY(size, PGLSZ(1));
        if((o = findhole(pd, pdsz, n)) != -1)
            return VMAP + o*PGLSZ(1);
        return 0;
    }

    /*
     * Size is smaller than that mapped by a single PD entry.
     * Look for an already mapped PT page that has room.
     */
    n = HOWMANY(size, PGLSZ(0));
    ptsz = PGLSZ(0)/sizeof(PTE);
    for(i = 0; i < pdsz; i++) {
        if(!(pd[i] & PteP) || (pd[i] & PtePS))
            continue;

        pt = (PTE*)(PDMAP+(PDX(VMAP)+i)*4096);
        if((o = findhole(pt, ptsz, n)) != -1)
            return VMAP + i*PGLSZ(1) + o*PGLSZ(0);
    }

    /*
     * Nothing suitable, start using a new PD entry.
     */
    if((o = findhole(pd, pdsz, 1)) != -1)
        return VMAP + o*PGLSZ(1);

    return 0;
}
Example #4
0
// Parse and store a function definition
//
void cmd_function(void) {
char id[IDLEN+1];			// buffer for id

	getsym();				// eat "function", get putative id
	if ((sym != s_undef) && (sym != s_script_eeprom) &&
		(sym != s_script_progmem) && (sym != s_script_file)) unexpected(M_id);
	strncpy(id, idbuf, IDLEN+1);	// save id string through value parse
	eraseentry(id);
	
	getsym();		// eat the id, move on to '{'

	if (sym != s_lcurly) expected(s_lcurly);

	// measure the macro text using skipstatement
	// fetchptr is on the character after '{'
	//
	// BUG: This is broken for file scripts
	char *startmark = (char *) fetchptr;		// mark first char of macro text
	void skipstatement(void);
	skipstatement();				// gobble it up without executing it
	char *endmark = (char *) fetchptr;		// and note the char past '}'

	// endmark is past the closing '}' - back up and find it
	do {
		--endmark;
	} while ((endmark > startmark) && (*endmark != '}'));
	
	int idlen = strlen(id);
	int addr = findhole(idlen + (endmark-startmark) + 2);	// longjmps on fail
	if (addr >= 0) {
		saveString(addr, id);		// write the id and its terminator
		addr += idlen + 1;		// advance to payload offset
		while (startmark < endmark) eewrite(addr++, *startmark++);
		eewrite(addr, 0);
	}

	msgpl(M_saved);
}
Example #5
0
/*===========================================================================*
 *				vm_allocpage		     		     *
 *===========================================================================*/
PUBLIC void *vm_allocpage(phys_bytes *phys, int reason)
{
/* Allocate a page for use by VM itself. */
	phys_bytes newpage;
	vir_bytes loc;
	pt_t *pt;
	int r;
	static int level = 0;
	void *ret;

	pt = &vmprocess->vm_pt;
	assert(reason >= 0 && reason < VMP_CATEGORIES);

	level++;

	assert(level >= 1);
	assert(level <= 2);

	if(level > 1 || !(vmprocess->vm_flags & VMF_HASPT) || !meminit_done) {
		int r;
		void *s;
		s=vm_getsparepage(phys);
		level--;
		if(!s) {
			util_stacktrace();
			printf("VM: warning: out of spare pages\n");
		}
		return s;
	}

	/* VM does have a pagetable, so get a page and map it in there.
	 * Where in our virtual address space can we put it?
	 */
	loc = findhole(pt,  arch_vir2map(vmprocess, vmprocess->vm_stacktop),
		vmprocess->vm_arch.vm_data_top);
	if(loc == NO_MEM) {
		level--;
		printf("VM: vm_allocpage: findhole failed\n");
		return NULL;
	}

	/* Allocate page of memory for use by VM. As VM
	 * is trusted, we don't have to pre-clear it.
	 */
	if((newpage = alloc_mem(CLICKSPERPAGE, 0)) == NO_MEM) {
		level--;
		printf("VM: vm_allocpage: alloc_mem failed\n");
		return NULL;
	}

	*phys = CLICK2ABS(newpage);

	/* Map this page into our address space. */
	if((r=pt_writemap(vmprocess, pt, loc, *phys, I386_PAGE_SIZE,
		I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE, 0)) != OK) {
		free_mem(newpage, CLICKSPERPAGE);
		printf("vm_allocpage writemap failed\n");
		level--;
		return NULL;
	}

	if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
		panic("VMCTL_FLUSHTLB failed: %d", r);
	}

	level--;

	/* Return user-space-ready pointer to it. */
	ret = (void *) arch_map2vir(vmprocess, loc);

	return ret;
}
Example #6
0
/*===========================================================================*
 *				vm_allocpage		     		     *
 *===========================================================================*/
void *vm_allocpages(phys_bytes *phys, int reason, int pages)
{
    /* Allocate a page for use by VM itself. */
    phys_bytes newpage;
    vir_bytes loc;
    pt_t *pt;
    int r;
    static int level = 0;
    void *ret;
    u32_t mem_flags = 0;

    pt = &vmprocess->vm_pt;
    assert(reason >= 0 && reason < VMP_CATEGORIES);

    assert(pages > 0);

    level++;

    assert(level >= 1);
    assert(level <= 2);

    if((level > 1) || !pt_init_done) {
        void *s;

        if(pages == 1) s=vm_getsparepage(phys);
        else if(pages == 4) s=vm_getsparepagedir(phys);
        else panic("%d pages", pages);

        level--;
        if(!s) {
            util_stacktrace();
            printf("VM: warning: out of spare pages\n");
        }
        if(!is_staticaddr(s)) vm_self_pages++;
        return s;
    }

#if defined(__arm__)
    if (reason == VMP_PAGEDIR) {
        mem_flags |= PAF_ALIGN16K;
    }
#endif

    /* VM does have a pagetable, so get a page and map it in there.
     * Where in our virtual address space can we put it?
     */
    loc = findhole(pages);
    if(loc == NO_MEM) {
        level--;
        printf("VM: vm_allocpage: findhole failed\n");
        return NULL;
    }

    /* Allocate page of memory for use by VM. As VM
     * is trusted, we don't have to pre-clear it.
     */
    if((newpage = alloc_mem(pages, mem_flags)) == NO_MEM) {
        level--;
        printf("VM: vm_allocpage: alloc_mem failed\n");
        return NULL;
    }

    *phys = CLICK2ABS(newpage);

    /* Map this page into our address space. */
    if((r=pt_writemap(vmprocess, pt, loc, *phys, VM_PAGE_SIZE*pages,
                      ARCH_VM_PTE_PRESENT | ARCH_VM_PTE_USER | ARCH_VM_PTE_RW
#if defined(__arm__)
                      | ARM_VM_PTE_WB | ARM_VM_PTE_SHAREABLE
#endif
                      , 0)) != OK) {
        free_mem(newpage, pages);
        printf("vm_allocpage writemap failed\n");
        level--;
        return NULL;
    }

    if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
        panic("VMCTL_FLUSHTLB failed: %d", r);
    }

    level--;

    /* Return user-space-ready pointer to it. */
    ret = (void *) loc;

    vm_self_pages++;
    return ret;
}