示例#1
0
文件: frame.c 项目: stev47/brickemu
void frame_dump_stack(FILE *out, uint16 fp) {
    char buf[10];
    char *funcname;
    int lastpc = pc;
    int i;
    thread_info *thread;
    thread = fp == GET_REG16(7) ? current_thread : hash_get(&threads, fp);
    
    if (!thread)
	return;

    for (i = thread->num_frames; i >= 0; i--) {
	int fpc = thread->frames[i].pc & ~1;
	int fp = thread->frames[i].fp;
	funcname = symbols_get(fpc, 0);
	if (!funcname) {
	    snprintf(buf, 10, "0x%04x", fpc);
	    funcname=buf;
	}
	fprintf(out, "    %04x: %30s [%04x+%04x]\n", 
	       fp, funcname, fpc, lastpc - fpc);
	lastpc = (memory[fp] << 8 | memory[fp+1]);
    }
    return;
}
示例#2
0
文件: nor.c 项目: chronzz/openiBoot
static int nor_read(mtd_t *_dev, void *_dest, uint32_t _off, int _amt)
{
	uint16_t* alignedBuffer = (uint16_t*)_dest;
	int len = _amt;
	for(; len >= 2; len -= 2)
	{
		*alignedBuffer = GET_REG16(NOR + _off);
		_off += 2;
		alignedBuffer++;
	}

	if(len > 0) {
		uint16_t lastWord = GET_REG16(NOR + _off);
		uint8_t* unalignedBuffer = (uint8_t*) alignedBuffer;
		*unalignedBuffer = *((uint8_t*)(&lastWord));
	}

	return _amt;
}
示例#3
0
文件: nor.c 项目: chronzz/openiBoot
static int nor_device_init(nor_device_t *_dev)
{
	nor_prepare(&_dev->mtd);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_UNLOCK);
	SET_REG16(NOR + LOCK, LOCK_UNLOCK);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_IDENTIFY);
	GET_REG16(NOR);
	GET_REG16(NOR);

	_dev->vendor = GET_REG16(NOR + VENDOR);
	_dev->device = GET_REG16(NOR + DEVICE);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_LOCK);
	SET_REG16(NOR, DATA_MODE);
	GET_REG16(NOR);
	GET_REG16(NOR);

	if(_dev->vendor == 0)
	{
		bufferPrintf("NOR not detected.\n");
		return -1;
	}

	nor_finish(&_dev->mtd);

	bufferPrintf("NOR vendor=%x, device=%x\r\n", _dev->vendor, _dev->device);

	return mtd_init(&_dev->mtd);
}
示例#4
0
文件: nor.c 项目: chronzz/openiBoot
static int nor_erase_sector(nor_device_t *_dev, uint32_t _offset)
{
	SET_REG16(NOR + NOR_COMMAND, COMMAND_UNLOCK);
	SET_REG16(NOR + LOCK, LOCK_UNLOCK);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_ERASE);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_UNLOCK);
	SET_REG16(NOR + LOCK, LOCK_UNLOCK);

	SET_REG16(NOR + _offset, ERASE_DATA);

	while(TRUE)
	{
		udelay(50000);
		if(GET_REG16(NOR + _offset) != 0xFFFF)
			bufferPrintf("failed to erase NOR sector: %x %x\r\n", (unsigned int) GET_REG16(NOR + _offset), GET_REG(0x20000000));
		else
			break;
	}

	return 0;
}
示例#5
0
文件: nor.c 项目: chronzz/openiBoot
static int nor_write_short(nor_device_t *_dev, uint32_t offset, uint16_t data)
{
	SET_REG16(NOR + NOR_COMMAND, COMMAND_UNLOCK);
	SET_REG16(NOR + LOCK, LOCK_UNLOCK);

	SET_REG16(NOR + NOR_COMMAND, COMMAND_WRITE);
	SET_REG16(NOR + offset, data);

	while(TRUE)
	{
		udelay(40);
		if(GET_REG16(NOR + offset) != data)
			bufferPrintf("failed to write to NOR\r\n");
		else
			break;
	}

	return 0;
}
示例#6
0
文件: frame.c 项目: stev47/brickemu
void frame_end(uint16 fp, int in_irq) {
    unsigned long local, total;
    frame_info * frame;
    frame_info * pframe;
    profile_info *prof, *pprof;

    if (!current_thread)
	return;

    /* If this is the bottom most frame insert a new frame below */
    if (current_thread->num_frames == 0)
	frame_insert_subframe(fp);

    frame = &current_thread->frames[current_thread->num_frames];
    /* Check if frame pointers match */
    while (frame->fp && frame->fp < fp) {
	/* This means that the function on top of the stack had no return.
	 * We just remove it as if it never had been called and reassign
	 * its cycles to the caller.
	 */
	(frame-1)->irqcycles += frame->irqcycles;
	(frame-1)->threadcycles += frame->threadcycles;

	if (--current_thread->num_frames == 0)
	    frame_insert_subframe(fp);
	frame = &current_thread->frames[current_thread->num_frames];
    }

#ifdef LOG_CALLS
#ifndef LOG_CALLS_IRQ
    int i, rec_in_irq = 0;
    for (i = current_thread->num_frames; i >= 0; i--)
	if (current_thread->frames[i].pc & 1)
	    rec_in_irq = 1;
    if (!rec_in_irq)
#endif
    {
	fprintf(framelog, "%*s<- %04x\n",
		current_thread->num_frames * 3, "", 
		pc < 0x8000 ? GET_REG16(6) : GET_REG16(0));
    }
#endif

    current_thread->num_frames--;
    /* Compute number of cycles spent in child frame and its children */
    total = cycles - frame->startcycle - frame->threadcycles
	- frame->irqcycles;
    local = total - frame->childcycles;

    /* If fp is 0 this means that the return address has been put on stack
     * manually.  We don't add the cycles of the "child" function in that
     * case.
     */
    if (frame->fp != 0) {
	/* get parent frame */
	pframe = frame - 1;
	
	/* Move irq cycles and cycles spent in different threads to parent
	 * frame */
	pframe->irqcycles += frame->irqcycles;
	pframe->threadcycles += frame->threadcycles;
	
	/* Add the total number of cycles to child cycles of parent */
	if ((frame->pc & 1)) {
	    /* The function that finished was an interrupt handler */
	    pframe->irqcycles += total;
	} else {
	    pframe->childcycles += total;
	}


#ifdef HASH_PROFILES
	pprof = hash_get(&profiles, pframe->pc & ~1);
#else
	pprof = profiles[pframe->pc & ~1];
#endif
	/* since fp was okay, we know that this function was called regularly
	 * and we have a profile entry for its caller.
	 */
	frame_add_callee(pprof, frame->pc, total);
    }

#ifdef LOG_CALLS
    /* log data structures if a method finished that manipulates them */
#ifdef LOG_TIMERS
    if (frame->pc == symbols_getaddr("_add_timer")
	|| frame->pc == symbols_getaddr("_remove_timer")
	|| frame->pc == symbols_getaddr("_run_timers")) {
	extern void bibo_dump_timers(FILE* file);
	bibo_dump_timers(framelog);
    }
#endif

#ifdef LOG_MEMORY
    if (frame->pc == symbols_getaddr("_mm_init")) {
	extern void bibo_dump_memory(FILE*);
	bibo_dump_memory(framelog);
    }
    if (frame->pc == symbols_getaddr("_malloc")) {
	extern void bibo_dump_memory(FILE*);
	bibo_dump_memory(framelog);
    }
    if (frame->pc == symbols_getaddr("_free")) {
	extern void bibo_dump_memory(FILE*);
	bibo_dump_memory(framelog);
    }
#endif

#ifdef LOG_THREADS
    if (frame->pc == symbols_getaddr("_execi")
	|| frame->pc == symbols_getaddr("_wait")
	|| frame->pc == symbols_getaddr("_make_running")
	|| frame->pc == symbols_getaddr("_shutdown_tasks")
	|| frame->pc == symbols_getaddr("_wakeup")
	|| frame->pc == symbols_getaddr("_wakeup_single")) {
	extern void bibo_dump_threads(FILE*);
	bibo_dump_threads(framelog);
    }
#endif
#endif

    /* add profile info for child frame */
#ifdef HASH_PROFILES
    prof = hash_get(&profiles, frame->pc & ~1);
#else
    prof = profiles[frame->pc & ~1];
#endif
    if (!prof) {
#ifdef HASH_PROFILES
	prof = hash_create(&profiles, frame->pc & ~1, sizeof(profile_info));
#else
	prof = profiles[frame->pc & ~1] = malloc(sizeof(profile_info));
#endif
	memset(prof, 0, sizeof(profile_info));
	hash_init(&prof->callees, 5);
    }
	
    prof->irq_cycles   += frame->irqcycles;
    prof->local_cycles += local;
    prof->total_cycles += total;
    prof->calls++;
    prof->isIRQ |= (frame->pc & 1);
    if (total > prof->max_total_cycles)
	prof->max_total_cycles = total;
    if (local > prof->max_local_cycles)
	prof->max_local_cycles = local;
}
示例#7
0
文件: frame.c 项目: stev47/brickemu
/**
 * Handle a call instruction and add profile information for the
 * called and calling function.
 */
void frame_begin(uint16 fp, int in_irq) {
    frame_info *frame, *pframe;
    profile_info *pprof;

    /* If we there is no current thread, just return.  The current thread
     * will be created by the opcode that initializes the stack pointer. 
     * So there should be always a current thread at the moment we call
     * a function.
     */
    if (!current_thread)
	return;

    if (fp < current_thread->minfp)
	current_thread->minfp = fp;

    /* Add a new frame to the current thread.  Resize the stack structure
     * if necessary.
     */
    frame_grow_num_frames();
    
    /* Initialize the new frame.
     */
    frame = &current_thread->frames[current_thread->num_frames];
    frame->startcycle = cycles;
    frame->childcycles = 0;
    frame->irqcycles = 0;
    frame->threadcycles = 0;
    frame->pc = pc | (in_irq ? 1 : 0);
    frame->fp = fp;

#ifdef LOG_CALLS
#ifndef LOG_CALLS_IRQ
    int i, rec_in_irq = 0;
    /* Check if this frame was directly or indirectly called by interrupt. */
    for (i = current_thread->num_frames; i >= 0; i--) {
	if (current_thread->frames[i].pc & 1) {
	    rec_in_irq = 1;
	    break;
	}
    }
    /* Log the call to framelog, unless called from interrupt. */
    if (!rec_in_irq)
#endif
    {
	char* funcname, buf[10];
	funcname = symbols_get(pc, 0);
	if (!funcname) {
	    snprintf(buf, 10, "0x%04x", pc);
	    funcname=buf;
	}
	fprintf(framelog, "%*s%s(%04x,%04x,%04x,%04x) fp: %04x klock: %d inirq: %d\n",
		current_thread->num_frames * 3, "", funcname,
		pc < 0x8000 ? GET_REG16(6) : GET_REG16(0), 
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+2) : GET_REG16(1),
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+4) : GET_REG16(2),
		pc < 0x8000 ? READ_WORD(GET_REG16(7)+6) : GET_REG16(3),
		GET_REG16(7),
		memory[symbols_getaddr("_kernel_lock")], in_irq);
    }
#endif

    /* get parent frame and add a new callee to its profile information. */
    pframe = frame - 1;
#ifdef HASH_PROFILES
    pprof = hash_get(&profiles, pframe->pc & ~1);
#else
    pprof = profiles[pframe->pc & ~1];
#endif
    if (!pprof) {
#ifdef HASH_PROFILES
       pprof = hash_create(&profiles, pframe->pc & ~1, sizeof(profile_info));
#else
       pprof = profiles[pframe->pc & ~1] = malloc(sizeof(profile_info));
#endif
       memset(pprof, 0, sizeof(profile_info));
       hash_init(&pprof->callees, 5);
    }
}
示例#8
0
文件: printf.c 项目: stev47/brickemu
void debug_printf(void) {
    char buffer[4096];
    size_t maxlen = sizeof(buffer);

    int fp = GET_REG16(7)+2;
    const char *format = (char*) &memory[GET_WORD(fp)];
    fp += 2;

    char ch;
    long value;
    char *strvalue;
    int min;
    int max;
    int state;
    int flags;
    int cflags;
    size_t currlen;
    
    state = DP_S_DEFAULT;
    currlen = flags = cflags = min = 0;
    max = -1;
    ch = *format++;
    
    while (state != DP_S_DONE) {
	if (ch == '\0') 
	    state = DP_S_DONE;
	
	switch(state) {
	case DP_S_DEFAULT:
	    if (ch == '%') 
		state = DP_S_FLAGS;
	    else 
		dopr_outch (buffer, &currlen, maxlen, ch);
	    ch = *format++;
	    break;
	case DP_S_FLAGS:
	    switch (ch) {
	    case '-':
		flags |= DP_F_MINUS;
		ch = *format++;
		break;
	    case '+':
		flags |= DP_F_PLUS;
		ch = *format++;
		break;
	    case ' ':
		flags |= DP_F_SPACE;
		ch = *format++;
		break;
	    case '#':
		flags |= DP_F_NUM;
		ch = *format++;
		break;
	    case '0':
		flags |= DP_F_ZERO;
		ch = *format++;
		break;
	    default:
		state = DP_S_MIN;
		break;
	    }
	    break;
	case DP_S_MIN:
	    if (isdigit((unsigned char)ch)) {
		min = 10*min + char_to_int (ch);
		ch = *format++;
	    } else if (ch == '*') {
		min = (short) GET_WORD(fp);
		fp += 2;
		ch = *format++;
		state = DP_S_DOT;
	    } else {
		state = DP_S_DOT;
	    }
	    break;
	case DP_S_DOT:
	    if (ch == '.') {
		state = DP_S_MAX;
		ch = *format++;
	    } else { 
		state = DP_S_MOD;
	    }
	    break;
	case DP_S_MAX:
	    if (isdigit((unsigned char)ch)) {
		if (max < 0)
		    max = 0;
		max = 10*max + char_to_int (ch);
		ch = *format++;
	    } else if (ch == '*') {
		min = (short) GET_WORD(fp);
		fp += 2;
		ch = *format++;
		state = DP_S_MOD;
	    } else {
		state = DP_S_MOD;
	    }
	    break;
	case DP_S_MOD:
	    switch (ch) {
	    case 'h':
		cflags = DP_C_SHORT;
		ch = *format++;
		break;
	    case 'l':
		cflags = DP_C_LONG;
		ch = *format++;
		break;
	    default:
		break;
	    }
	    state = DP_S_CONV;
	    break;
	case DP_S_CONV:
	    switch (ch) {
	    case 'd':
	    case 'i':
		if (cflags == DP_C_LONG) {
		    value = ((int) (short) GET_WORD(fp)) << 16
			| GET_WORD(fp+2);
		    fp += 4;
		} else {
		    value = (short) GET_WORD(fp);
		    fp += 2;
		}
		fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
		break;
	    case 'o':
		flags |= DP_F_UNSIGNED;
		if (cflags == DP_C_LONG) {
		    value = ((unsigned int) GET_WORD(fp)) << 16
			| GET_WORD(fp+2);
		    fp += 4;
		} else {
		    value = GET_WORD(fp);
		    fp += 2;
		}
		fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
		break;
	    case 'u':
		flags |= DP_F_UNSIGNED;
		if (cflags == DP_C_LONG) {
		    value = ((unsigned int) GET_WORD(fp)) << 16
			| GET_WORD(fp+2);
		    fp += 4;
		} else {
		    value = GET_WORD(fp);
		    fp += 2;
		}
		fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
		break;
	    case 'X':
		flags |= DP_F_UP;
	    case 'x':
		flags |= DP_F_UNSIGNED;
		if (cflags == DP_C_LONG) {
		    value = ((unsigned int) GET_WORD(fp)) << 16
			| GET_WORD(fp+2);
		    fp += 4;
		} else {
		    value = GET_WORD(fp);
		    fp += 2;
		}
		fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
		break;
	    case 'c':
		dopr_outch (buffer, &currlen, maxlen, 
			    (int)(short)GET_WORD(fp));
		fp += 2;
		break;
	    case 's':
		{
		    int addr = GET_WORD(fp);
		    strvalue = (char*) &memory[addr];
		    if (!addr) 
			strvalue = "(NULL)";
		    if (max == -1) {
			max = strlen(strvalue);
		    }
		    if (min > 0 && max >= 0 && min > max) max = min;
		    fmtstr (buffer, &currlen, maxlen, strvalue, flags, 
			    min, max);
		}
		break;
	    case 'p':
		value = GET_WORD(fp);
		fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
		break;
	    case '%':
		dopr_outch (buffer, &currlen, maxlen, ch);
		break;
	    default:
		/* Unknown, skip */
		break;
	    }
	    ch = *format++;
	    state = DP_S_DEFAULT;
	    flags = cflags = min = 0;
	    max = -1;
	    break;
	case DP_S_DONE:
	    break;
	default:
	    /* hmm? */
	    break; /* some picky compilers need this */
	}
    }
    if (maxlen != 0) {
	if (currlen < maxlen - 1) 
	    buffer[currlen] = '\0';
	else if (maxlen > 0) 
	    buffer[maxlen - 1] = '\0';
    }
    
    printf("Program said: `%s'\n", buffer);
}