Beispiel #1
0
static void here(void)
{
	PUSH(pointer2cell(dict) + dicthead);
#ifdef CONFIG_DEBUG_INTERNAL
	printk("here: %x\n", pointer2cell(dict) + dicthead);
#endif
}
Beispiel #2
0
static
int printf_console(const char *fmt, ...)
{
    cell tmp;

    char buf[512];
    va_list args;
    int i;

    va_start(args, fmt);
    i = vsnprintf(buf, sizeof(buf), fmt, args);
    va_end(args);

    /* Push to the Forth interpreter for console output */
    tmp = rstackcnt;

    PUSH(pointer2cell(buf));
    PUSH((int)strlen(buf));
    trampoline[1] = findword("type");

    PUSHR(PC);
    PC = pointer2cell(trampoline);

    while (rstackcnt > tmp) {
        dbg_interp_printk("printf_console: NEXT\n");
        next();
    }

    return i;
}
Beispiel #3
0
ucell lfa2nfa(ucell ilfa)
{
	/* get offset from dictionary start */
	ilfa = ilfa - (ucell)pointer2cell(dict);
	ilfa--;				/* skip status        */
	while (dict[--ilfa] == 0);	/* skip all pad bytes */
	ilfa -= (dict[ilfa] - 128);
	return ilfa + (ucell)pointer2cell(dict);
}
Beispiel #4
0
void
bind_func( const char *name, void (*func)(void) )
{
	PUSH( pointer2cell(func) );
	push_str( name );
	fword("is-cfunc");
}
Beispiel #5
0
void init_trampoline(ucell *tramp)
{
    tramp[0] = DOCOL;
    tramp[1] = 0;
    tramp[2] = target_ucell(pointer2cell(tramp) + 3 * sizeof(ucell));
    tramp[3] = 0;
}
Beispiel #6
0
/* ( -- cstr ) */
static void
grubfs_files_get_fstype( grubfs_info_t *mi )
{
	grubfs_t *gfs = mi->gfs;

	PUSH( pointer2cell(strdup(gfs->fsys->name)) );
}
Beispiel #7
0
static ucell findsemis_wordlist(ucell xt, ucell wordlist)
{
	ucell tmplfa, nextlfa, nextcfa;

	if (!wordlist)
		return 0;

	tmplfa = read_ucell(cell2pointer(wordlist));
	nextcfa = lfa2cfa(tmplfa);

	/* Catch the special case where the lfa of the word we
	 * want is the last word in the dictionary; in that case
	 * the end of the word is given by "here" - 1 */
	if (nextcfa == xt)
		return pointer2cell(dict) + dicthead - sizeof(cell);

	while (tmplfa) {

		/* Peek ahead and see if the next CFA in the list is the
		 * one we are searching for */ 
		nextlfa = read_ucell(cell2pointer(tmplfa)); 
		nextcfa = lfa2cfa(nextlfa);

		/* If so, count back 1 cell from the current NFA */
		if (nextcfa == xt)
			return lfa2nfa(tmplfa) - sizeof(cell);

		tmplfa = nextlfa;
	}

	return 0;
}
Beispiel #8
0
static void spfetch(void)
{
	// FIXME this can only work if the stack pointer
	// is within range.
	ucell tmp = pointer2cell(&(dstack[dstackcnt]));
	PUSH(tmp);
}
Beispiel #9
0
xt_t
bind_noname_func( void (*func)(void) )
{
	PUSH( pointer2cell(func) );
	fword("is-noname-cfunc");
	return POP_xt();
}
Beispiel #10
0
void
update_nvram( void )
{
	PUSH( pointer2cell(nvram.config->data) );
	PUSH( nvram.config_size );
	fword("nvram-store-configs");
	arch_nvram_put( nvram.data );
}
Beispiel #11
0
/* ( -- cstr ) */
static void
grubfs_files_get_path( grubfs_info_t *mi )
{
	grubfile_t *file = mi->gfs->fd;
	const char *path = file->path;

	RET( pointer2cell(strdup(path)) );
}
Beispiel #12
0
ucell fstrlen(ucell fstr)
{
	fstr -= pointer2cell(dict)+1;
	//fstr -= pointer2cell(dict); FIXME
	while (dict[++fstr] < 128)
		;
	return dict[fstr] - 128;
}
Beispiel #13
0
ucell load_dictionary(const char *data, ucell len)
{
	u32 checksum=0;
	const char *checksum_walk;
	ucell *walk, *reloc_table;
	dictionary_header_t *header=(dictionary_header_t *)data;

	/* assertions */
	if (len <= (sizeof(dictionary_header_t)) || strncmp(DICTID, data, 8))
		return 0;
#ifdef CONFIG_DEBUG_DICTIONARY
	dump_header(header);
#endif

	checksum_walk=data;
	while (checksum_walk<data+len) {
		checksum+=read_long(checksum_walk);
		checksum_walk+=sizeof(u32);
	}

	if(checksum) {
		printk("Checksum invalid (%08x)!\n", checksum);
		return 0;
	}

	data += sizeof(dictionary_header_t);

	dicthead = target_long(header->length);

	memcpy(dict, data, dicthead);
	reloc_table=(ucell *)(data+dicthead);

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("\nmoving dictionary (%x bytes) to %x\n",
			(ucell)dicthead, (ucell)dict);
	printk("\ndynamic relocation...");
#endif

	for (walk = (ucell *) dict; walk < (ucell *) (dict + dicthead);
	     walk++) {
		int pos, bit, l;
		l=(walk-(ucell *)dict);
		pos=l/BITS;
		bit=l&~(-BITS);
                if (reloc_table[pos] & target_ucell((ucell)1ULL << bit)) {
			// printk("%lx, pos %x, bit %d\n",*walk, pos, bit);
			write_ucell(walk, read_ucell(walk)+pointer2cell(dict));
		}
	}

#ifdef CONFIG_DEBUG_DICTIONARY
	printk(" done.\n");
#endif

	last = (ucell *)(dict + target_ucell(header->last));

	return -1;
}
Beispiel #14
0
static void execute(void)
{                               /* EXECUTE */
    ucell address = POP();
    dbg_interp_printk("execute: %x\n", address);

    PUSHR(PC);
    trampoline[1] = target_ucell(address);
    PC = pointer2cell(trampoline);
}
Beispiel #15
0
void
bind_xtfunc( const char *name, xt_t xt, ucell arg, void (*func)(void) )
{
	PUSH_xt( xt );
	PUSH( arg );
	PUSH( pointer2cell(func) );
	push_str( name );
	fword("is-xt-cfunc");
}
Beispiel #16
0
int ofmem_posix_memalign( void **memptr, size_t alignment, size_t size )
{
    ofmem_t *ofmem = ofmem_arch_get_private();
    alloc_desc_t *d, **pp;
    void *ret;
    ucell top;
    phys_addr_t pa;

    if( !size )
        return ENOMEM;

    if( !ofmem->next_malloc )
        ofmem->next_malloc = (char*)ofmem_arch_get_malloc_base();

    size = align_size(size + sizeof(alloc_desc_t), alignment);

    /* look in the freelist */
    for( pp=&ofmem->mfree; *pp && (**pp).size < size; pp = &(**pp).next ) {
    }

    /* waste at most 4K by taking an entry from the freelist */
    if( *pp && (**pp).size > size + 0x1000 ) {
        /* Alignment should be on physical not virtual address */
        pa = va2pa((uintptr_t)*pp + sizeof(alloc_desc_t));
        pa = align_ptr(pa, alignment);
        ret = (void *)pa2va(pa);

        memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) );
        *pp = (**pp).next;

        *memptr = ret;
        return 0;
    }

    top = ofmem_arch_get_heap_top();

    /* Alignment should be on physical not virtual address */
    pa = va2pa((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t));
    pa = align_ptr(pa, alignment);
    ret = (void *)pa2va(pa);

    if( pointer2cell(ret) + size > top ) {
        printk("out of malloc memory (%x)!\n", size );
        return ENOMEM;
    }

    d = (alloc_desc_t*)((uintptr_t)ret - sizeof(alloc_desc_t));
    ofmem->next_malloc += size;

    d->next = NULL;
    d->size = size;

    memset( ret, 0, size - sizeof(alloc_desc_t) );

    *memptr = ret;
    return 0;
}
Beispiel #17
0
static void doival(void)
{
    ucell r, *p = (ucell *)(*(ucell *) cell2pointer(PC) + sizeof(ucell));
    ucell ibase = get_myself();

    dbg_interp_printk("ivar, offset: %d size: %d\n", p[0], p[1] );

    r = ibase ? ibase + p[0] : pointer2cell(&p[2]);
    PUSH( *(ucell *)cell2pointer(r) );
}
Beispiel #18
0
static void doidefer(void)
{
    ucell *p = (ucell *)(*(ucell *) cell2pointer(PC) + sizeof(ucell));
    ucell ibase = get_myself();

    dbg_interp_printk("doidefer, offset: %d size: %d\n", p[0], p[1] );

    PUSHR(PC);
    PC = ibase ? ibase + p[0] : pointer2cell(&p[2]);
    PC -= sizeof(ucell);
}
Beispiel #19
0
int enterforth(xt_t xt)
{
    ucell *_cfa = (ucell*)cell2pointer(xt);
    cell tmp;

    if (read_ucell(_cfa) != DOCOL) {
        trampoline[1] = target_ucell(xt);
        _cfa = trampoline;
    }

    if (rstackcnt < 0) {
        rstackcnt = 0;
    }

    tmp = rstackcnt;
    interruptforth = FORTH_INTSTAT_CLR;

    PUSHR(PC);
    PC = pointer2cell(_cfa);

    while (rstackcnt > tmp && !(interruptforth & FORTH_INTSTAT_STOP)) {
        if (debug_xt_list->next == NULL) {
            while (rstackcnt > tmp && !interruptforth) {
                dbg_interp_printk("enterforth: NEXT\n");
                next();
            }
        } else {
            while (rstackcnt > tmp && !interruptforth) {
                dbg_interp_printk("enterforth: NEXT_DBG\n");
                next_dbg();
            }
        }

        /* Always clear the debug mode change flag */
        interruptforth = interruptforth & (~FORTH_INTSTAT_DBG);
    }

#if 0
    /* return true if we took an exception. The caller should normally
     * handle exceptions by returning immediately since the throw
     * is supposed to abort the execution of this C-code too.
     */

    if (rstackcnt != tmp) {
        printk("EXCEPTION DETECTED!\n");
    }
#endif
    return rstackcnt != tmp;
}
Beispiel #20
0
static void semis_dbg(void)
{
    struct debug_xt *debug_xt_item, *debug_xt_up = NULL;

    /* If current semis is in our debug xt list, disable debug mode */
    debug_xt_item = debug_xt_list;
    while (debug_xt_item->next) {
        if (debug_xt_item->xt_semis == PC) {
            if (debug_xt_item->mode != DEBUG_MODE_STEPUP) {
                /* Handle the normal case */
                fstrncpy(xtname, lfa2nfa(debug_xt_item->xt_docol - sizeof(cell)), MAXNFALEN);
                printf_console("\n[ Finished %s ] ", xtname);

                /* Reset to step mode in case we were in trace mode */
                debug_xt_item->mode = DEBUG_MODE_STEP;
            } else {
                /* This word requires execution of the debugger "Up"
                 * semantics. However we can't do this here since we
                 * are iterating through the debug list, and we need
                 * to change it. So we do it afterwards.
                 */
                debug_xt_up = debug_xt_item;
            }
        }

        debug_xt_item = debug_xt_item->next;
    }

    /* Execute debugger "Up" semantics if required */
    if (debug_xt_up) {
        /* Only add the parent word if it is not within the trampoline */
        if (rstack[rstackcnt] != (cell)pointer2cell(&trampoline[1])) {
            del_debug_xt(debug_xt_up->xt_docol);
            add_debug_xt(findxtfromcell(rstack[rstackcnt]));

            fstrncpy(xtname, lfa2nfa(findxtfromcell(rstack[rstackcnt]) - sizeof(cell)), MAXNFALEN);
            printf_console("\n[ Up to %s ] ", xtname);
        } else {
            fstrncpy(xtname, lfa2nfa(findxtfromcell(debug_xt_up->xt_docol) - sizeof(cell)), MAXNFALEN);
            printf_console("\n[ Finished %s (Unable to go up, hit trampoline) ] ", xtname);

            del_debug_xt(debug_xt_up->xt_docol);
        }

        debug_xt_up = NULL;
    }

    PC = POPR();
}
static int build_dictionary(void)
{
	ucell lfa = 0;
	unsigned int i;

	/* we need a temporary place for latest outside the dictionary */
	latest = &lfa;

	/* starting a new dictionary: clear dicthead */
	dicthead = 0;

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("building dictionary, %d primitives.\nbuilt words:",
	       sizeof(wordnames) / sizeof(void *));
#endif

	for (i = 0; i < sizeof(wordnames) / sizeof(void *); i++) {
		if (strlen(wordnames[i]) != 0) {
			fcreate((char *) wordnames[i], i);
#ifdef CONFIG_DEBUG_DICTIONARY
			printk(" %s", wordnames[i]);
#endif
		}
	}
#ifdef CONFIG_DEBUG_DICTIONARY
	printk(".\n");
#endif

	/* get last/latest and state */
	state = buildvariable("state", 0);
	last = buildvariable("forth-last", 0);
	latest = buildvariable("latest", 0);

	*latest = target_ucell(pointer2cell(latest)-2*sizeof(cell));

	base=buildvariable("base", 10);

	buildconstant("/c", sizeof(u8));
	buildconstant("/w", sizeof(u16));
	buildconstant("/l", sizeof(u32));
	buildconstant("/n", sizeof(ucell));
	buildconstant("/x", sizeof(u64));

	reveal();
        if (verbose) {
                printk("Dictionary initialization finished.\n");
        }
	return 0;
}
Beispiel #22
0
/* ( -- cstr ) */
static void
hfsp_files_get_path( hfsp_info_t *mi )
{
	char *buf;
	hfsp_file_t *t = mi->hfspfile;

	if( !t->path )
		RET ( 0 );

	buf = malloc(strlen(t->path) + 1);
	strncpy( buf, t->path, strlen(t->path) );
	buf[strlen(t->path)] = 0;

	PUSH(pointer2cell(buf));
}
Beispiel #23
0
static void herewrite(void)
{
	ucell tmp = POP(); /* converted pointer */
	dicthead = tmp - pointer2cell(dict);
#ifdef CONFIG_DEBUG_INTERNAL
	printk("here!: new value: %x\n", tmp);
#endif

	if (dictlimit && dicthead >= dictlimit) {
	    printk("Dictionary space overflow:"
	            " dicthead=" FMT_ucellx
	            " dictlimit=" FMT_ucellx
	            "\n",
	            dicthead, dictlimit);
	}
}
Beispiel #24
0
/* ( -- cstr|0 ) */
static void
hfsp_files_volume_name( hfsp_info_t *mi )
{
	int fd;
	char *volname = malloc(VOLNAME_SIZE);

	fd = open_ih(my_self());
        if (fd >= 0) {
                get_hfs_vol_name(fd, volname, VOLNAME_SIZE);
                close_io(fd);
        } else {
                volname[0] = '\0';
        }

	PUSH(pointer2cell(volname));
}
Beispiel #25
0
static void
ofmem_set_property( phandle_t ph, const char *name, const char *buf, int len )
{
    /* This is very similar to set_property() in libopenbios/bindings.c but allows
       us to set the property pointer directly, rather than having to copy it
       into the Forth dictonary every time we update the memory properties */
    if( !ph ) {
        printk("ofmem_set_property: NULL phandle\n");
        return;
    }
    PUSH(pointer2cell(buf));
    PUSH(len);
    push_str(name);
    PUSH_ph(ph);
    fword("encode-property");
}
Beispiel #26
0
void
nvconf_init( void )
{
	int once=0;

	/* initialize nvram structure completely */
	nvram.config = NULL;
	nvram.config_size = 0;

	nvram.size = arch_nvram_size();
	nvram.data = malloc( nvram.size );
	arch_nvram_get( nvram.data );

	bind_func( "update-nvram", update_nvram );

	for( ;; ) {
		nvpart_t *p = NULL;
		int err;

		while( (err=next_nvpart(&p)) > 0 ) {
			if( nvpart_checksum(p) != p->checksum ) {
				err = -1;
				break;
			}
			if( p->signature == NV_SIG_SYSTEM ) {
				nvram.config = p;
				nvram.config_size = nvpart_size(p) - 0x10;

				if( !once++ ) {
					PUSH( pointer2cell(p->data) );
					PUSH( nvram.config_size );
					fword("nvram-load-configs");
				}
			}
		}
		if( err || !nvram.config ) {
			printk("nvram error detected, zapping pram\n");
			zap_nvram();
			if( !once++ )
				fword("set-defaults");
			continue;
		}
		break;
	}
}
static void fcreate(const char *word, ucell cfaval)
{
	if (strlen(word) == 0) {
		printk("WARNING: tried to create unnamed word.\n");
		return;
	}

	writestring(word);
	/* get us at least 1 byte for flags */
	writebyte(0);
	paddict(sizeof(cell));
	/* set flags high bit. */
	dict[dicthead - 1] = 128;
	/* lfa and cfa */
	writecell(read_ucell(latest));
	*latest = target_ucell(pointer2cell(dict) + dicthead - sizeof(cell));
	writecell(cfaval);
}
Beispiel #28
0
static
int getchar_console(void)
{
    cell tmp;

    /* Push to the Forth interpreter for console output */
    tmp = rstackcnt;

    trampoline[1] = findword("key");

    PUSHR(PC);
    PC = pointer2cell(trampoline);

    while (rstackcnt > tmp) {
        dbg_interp_printk("getchar_console: NEXT\n");
        next();
    }

    return POP();
}
/*
 * Compare two dictionaries constructed at different addresses. When
 * the cells don't match, a need for relocation is detected and the
 * corresponding bit in reloc_table bitmap is set.
 */
static void relocation_table(unsigned char * dict_one, unsigned char *dict_two, int length)
{
	ucell *d1=(ucell *)dict_one, *d2=(ucell *)dict_two;
	ucell *reloc_table;
	int pos, bit;
	int l=(length+(sizeof(cell)-1))/sizeof(ucell), i;

	/* prepare relocation table */
	relocation_length=(length+BITS-1)/BITS;
	reloc_table = malloc(relocation_length*sizeof(cell));
	memset(reloc_table,0,relocation_length*sizeof(cell));

	for (i=0; i<l; i++) {

		pos=i/BITS;
		bit=i&~(-BITS);

		if(d1[i]==d2[i]) {
                        reloc_table[pos] &= target_ucell(~((ucell)1ULL << bit));

			// This check might bring false positives in data.
			//if(d1[i] >= pointer2cell(dict_one) &&
			//		d1[i] <= pointer2cell(dict_one+length))
			//	printk("\nWARNING: inconsistent relocation (%x:%x)!\n", d1[i], d2[i]);
		} else {
			/* This is a pointer, it needs relocation, d2==dict */
                        reloc_table[pos] |= target_ucell((ucell)1ULL << bit);
			d2[i] = target_ucell(target_ucell(d2[i]) - pointer2cell(d2));
		}
	}

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("dict1 %lx dict2 %lx dict %lx\n",dict_one, dict_two, dict);
	for (i=0; i< relocation_length ; i++)
		printk("reloc %d %lx\n",i+1, reloc_table[i]);
#endif
	relocation_address=reloc_table;
}
Beispiel #30
0
void
evangelionbios_init( void )
{
	// Bind the saved program state context into Forth
	PUSH(pointer2cell((void *)&__context));
	feval("['] __context cell+ !");
	
#if defined(CONFIG_DRIVER_FW_CFG)
	// Bind the Forth fw_cfg file interface
	bind_func("fw-cfg-read-file", forth_fw_cfg_read_file);
#endif
	
	// Bind the C implementation of (init-program) into Forth
	bind_func("(init-program)", init_program);
	
	// Bind the C implementation of (go) into Forth
	bind_func("(go)", go);
	
	// Bind the LE access words
	bind_func("le-w!", lewstore);
	bind_func("le-l!", lelstore);
	bind_func("le-w@", lewfetch);
	bind_func("le-l@", lelfetch);
}