ulong
devportreadlong(Engine *E, State *S, ulong addr)
{
	if (addr == SUPERH_THREADID)
	{
		return S->NODE_ID;
	}
	else if ((addr >= SUPERH_NUMAREGION_RDCNT_BEGIN) &&
		(addr < SUPERH_NUMAREGION_RDCNT_END))
	{
		/*							*/
		/*	CNT register addresses are longword-aligned,	*/
		/*	so lower 2 bits of address are irrelevant, 	*/
		/*	(should always be zero).			*/
		/*							*/
		int	which = ((addr - SUPERH_NUMAREGION_RDCNT_BEGIN) >> 2) & 0x3FFF;

		if (which >= S->N->count)
		{
			mprint(E, S, nodeinfo,
				"Longword access to address [0x" UHLONGFMT 
				"] (NUMAREGION_RDCNT register)\n",
				addr);
			mprint(E, S, nodeinfo, "which = %d\n", which);

			sfatal(E, S, "Attempt to access NUMAREGION_RDCNT register "
				"outside number of NUMAREGIONs");
		}

		return S->N->regions[which]->nreads;
	}
void Tracer::fatal(const char* method, const char* message, ...) const
{
    // fatal traces cannot be suppressed!

    ///@todo with qt4 the follwing code can be used:
    /*
    va_list ap;
    va_start(ap, message);
    QString str;
    str.vsprintf(message, ap);
    va_end(ap);

    sfatal(method) << str << endl;
    */

    va_list ap;

    int maxLength = 1024;
    int result = maxLength;
    char* str;
    while (result >= maxLength) {
        va_start(ap, message);
        str = (char*)malloc(maxLength);
        result = vsnprintf(str, maxLength-1, message, ap);
        va_end(ap);

        if (result >= maxLength) {
            delete str;
            maxLength = 2 * maxLength;
            result = maxLength;
        }
    }

    sfatal(method) << str << endl;
    delete str;
}
示例#3
0
tuck int
superHtake_nic_intr(Engine *E, State *S)
{
	Interrupt	*interrupt;

	if (!interruptible(S))
	{
		return -1;
	}

	/* 								*/
	/*	(PC is incremented at end of step() in pipeline.c)	*/
	/*	We need to re-exec instruction which is currently in	*/
	/*	ID when we RTE, so save that kids PC! (then do a 	*/
	/*	ifidflush()). If we are faststeping, then S->PC is 	*/
	/*	the next instr that we would place into EX and exec.	*/
	/*								*/
	/*	i.e., at this point, we are yet to execute instruction	*/
	/*	@PC (fastep/step below) so rather than setting SPC 	*/
	/*	to PC+2, we set it to PC, so that RTE executes the	*/
	/*	instr after then one after we caught the interrupt.	*/
	/*								*/
	if (S->step == superHfaststep)
	{
		S->superH->SPC = S->PC;
	}
	else
	{
		drain_pipeline(E, S);

		/*						*/
		/*	Must do this after drain because 	*/	
		/*	executed instruction during drain 	*/
		/*	might set PC (e.g. a BRA)		*/
		/*						*/
		S->superH->SPC = S->PC;
	}

	S->superH->SSR = S->superH->SR;
	S->superH->SR.BL = 1;
	S->superH->SR.MD = 1;
	S->superH->SR.RB = 1;

	S->PC = S->superH->VBR + 0x600;
	S->sleep = 0;

	interrupt = (Interrupt *)pic_intr_dequeue(E, S, S->superH->nicintrQ);
	if (interrupt == NULL)
	{
		sfatal(E, S,
		"We supposedly had an interrupt, but nothing was queued!");
	}

	/*								*/
	/*	The value field, which in the case of NIC, specifies 	*/
	/*	which  interface the interrupt was generated by. The	*/
	/*	apps. interpret exception codes offset from base as	*/
	/*	the interface number (well, you know what i mean...)	*/
	/*								*/
	switch (interrupt->type)
	{
		case NIC_RXOK_INTR:
		{
			S->superH->INTEVT = (NIC_RX_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_TXOK_INTR:
		{
			S->superH->INTEVT = (NIC_TX_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_ADDRERR_INTR:
		{
			S->superH->INTEVT = (NIC_ADDR_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_FRAMEERR_INTR:
		{
			S->superH->INTEVT = (NIC_FRAME_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_COLLSERR_INTR:
		{
			S->superH->INTEVT = (NIC_COLLS_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_CSENSEERR_INTR:
		{
			S->superH->INTEVT = (NIC_CSENSE_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_RXOVRRUNERR_INTR:
		{
			S->superH->INTEVT = (NIC_RXOVRRUN_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_RXUNDRRUNERR_INTR:
		{
			S->superH->INTEVT = (NIC_RXUNDRRUN_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_TXOVRRUNERR_INTR:
		{
			S->superH->INTEVT = (NIC_TXOVRRUN_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_TXUNDRRUNERR_INTR:
		{
			S->superH->INTEVT = (NIC_TXUNDRRUN_EXCP_CODE + interrupt->value);
			break;
		}

		case NIC_CSUMERR_INTR:
		{
			S->superH->INTEVT = (NIC_CSUM_EXCP_CODE + interrupt->value);
			break;
		}

		default:
		{
			mprint(E, S, nodeinfo, "Received interrupt type [%d]\n",
				interrupt->type);

			sfatal(E, S, "Unknown interrupt type!");
		}
	}
	mfree(E, interrupt, "Interrupt *interrupt in machine-hitachi-sh.c");

	return 0;
}
示例#4
0
tuck void
superHtake_exception(Engine *E, State *S)
{
	enum		{ABORTED_AND_RETRIED, ABORTED, COMPLETED, INVALID_HANDLING};
	Interrupt	*intr;
	int		handling = INVALID_HANDLING;


	intr = (Interrupt *)pic_intr_dequeue(E, S, S->superH->excpQ);
	if (intr == NULL)
	{
		sfatal(E, S,
		"We supposedly had an exception, but nothing was queued!");
	}

	S->superH->SSR = S->superH->SR;
	S->superH->SR.BL = 1;
	S->superH->SR.MD = 1;
	S->superH->SR.RB = 1;
	S->sleep = 0;

	switch (intr->type)
	{
		case H_UDI_RESET_EXCP:
		{
			S->PC = RESET_VECTOR_ADDR;
			S->superH->EXPEVT = H_UDI_RESET_EXCP_CODE;
			handling = ABORTED;
			break;
		}
		case POWER_ON_RESET_EXCP:
		{
			S->PC = RESET_VECTOR_ADDR;
			S->superH->EXPEVT = POWER_ON_RESET_EXCP_CODE;
			handling = ABORTED;
			break;
		}
		case MANUAL_RESET_EXCP:
		{
			S->PC = RESET_VECTOR_ADDR;
			S->superH->EXPEVT = MANUAL_RESET_EXCP_CODE;
			handling = ABORTED;
			break;
		}
		case TLB_LOAD_MISS_EXCP:
		{
			S->PC = S->superH->VBR + TLB_MISS_OFFSET;
			S->superH->EXPEVT = TLB_LOAD_MISS_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_STORE_MISS_EXCP:
		{
			S->PC = S->superH->VBR + TLB_MISS_OFFSET;
			S->superH->EXPEVT = TLB_STORE_MISS_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_LOAD_INVALID_EXCP:
		{
			S->PC = S->superH->VBR + TLB_INVALID_OFFSET;
			S->superH->EXPEVT = TLB_LOAD_INVALID_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_STORE_INVALID_EXCP:
		{
			S->PC = S->superH->VBR + TLB_INVALID_OFFSET;
			S->superH->EXPEVT = TLB_STORE_INVALID_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_INIT_PAGEWRITE_EXCP:
		{
			S->PC = S->superH->VBR + TLB_INIT_PAGEWRITE_OFFSET;
			S->superH->EXPEVT = TLB_INIT_PAGEWRITE_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_LOAD_PROTECT_EXCP:
		{
			S->PC = S->superH->VBR + TLB_PROTECT_OFFSET;
			S->superH->EXPEVT = TLB_LOAD_PROTECT_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TLB_STORE_PROTECT_EXCP:
		{
			S->PC = S->superH->VBR + TLB_PROTECT_OFFSET;
			S->superH->EXPEVT = TLB_STORE_PROTECT_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case CPU_LOAD_ADDRERR_EXCP:
		{
			/*	Doesn't make a difference; Self documenting.	*/
			if (intr->misc == MEM_ACCESS_IFETCH)
			{
				S->PC = S->superH->VBR + CPU_INSTR_ADDRERR_OFFSET;
			}
			else
			{
				S->PC = S->superH->VBR + CPU_ADDRERR_OFFSET;
			}

			S->superH->EXPEVT = CPU_LOAD_ADDRERR_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case CPU_STORE_ADDRERR_EXCP:
		{
			S->PC = S->superH->VBR + CPU_ADDRERR_OFFSET;
			S->superH->EXPEVT = CPU_STORE_ADDRERR_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case TRAPA_EXCP_CODE:
		{
			S->PC = S->superH->VBR + TRAPA_OFFSET;
			S->superH->EXPEVT = TRAPA_EXCP_CODE;
			handling = COMPLETED;
			break;
		}
		case ILLEGAL_INSTR_EXCP:
		{
			S->PC = S->superH->VBR + ILLEGAL_INSTR_OFFSET;
			S->superH->EXPEVT = ILLEGAL_INSTR_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case ILLEGAL_SLOT_INSTR_EXCP:
		{
			S->PC = S->superH->VBR + ILLEGAL_SLOT_INSTR_OFFSET;
			S->superH->EXPEVT = ILLEGAL_SLOT_INSTR_EXCP_CODE;
			handling = ABORTED_AND_RETRIED;
			break;
		}
		case USER_BKPOINT_TRAP_EXCP:
		{
			S->PC = S->superH->VBR + USER_BKPOINT_OFFSET;
			S->superH->EXPEVT = USER_BKPOINT_TRAP_EXCP_CODE;
			handling = COMPLETED;
			break;
		}
		case DMA_ADDRERR_EXCP:
		{
			S->PC = S->superH->VBR + DMA_ADDRERR_OFFSET;
			S->superH->EXPEVT = DMA_ADDRERR_EXCP_CODE;
			handling = COMPLETED;
			break;
		}

		default:
		{
			sfatal(E, S, "Unknown/invalid exception code");
		}
	}

	if (handling == ABORTED)
	{
		/*	Current instruction is aborted		*/
		superHpipeflush(S);
	}
	else if (handling == ABORTED_AND_RETRIED)
	{
		superHpipeflush(S);
		S->superH->SPC = intr->value;
	}
	else if (handling == COMPLETED)
	{
		/*	Current instruction is completed	*/
		if (S->step == superHfaststep)
		{
			S->superH->SPC = S->PC;
		}
		else
		{
			drain_pipeline(E, S);
			S->superH->SPC = S->PC;
		}
	}

	mfree(E, intr, "Interrupt *interrupt in machine-hitachi-sh.c");

	return;

}