Ejemplo n.º 1
0
// CU と RU が受付可能になるまで待機
void pro100_wait_cu_ru_accepable(PRO100_CTX *ctx)
{
	bool flag = false;
	// 引数チェック
	if (ctx == NULL)
	{
		return;
	}

	//printf("{B");
	while (true)
	{
		UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, 1);

		if (t == 0)
		{
			break;
		}

		if (flag == false)
		{
			flag = true;

//			printf(" ** CU=%u, RU=%u **  \n",
//				PRO100_GET_CU_COMMAND(t), PRO100_GET_RU_COMMAND(t));
		}
	}
//	printf("} ");
}
Ejemplo n.º 2
0
// 書き込み操作のフラッシュ
void pro100_flush(PRO100_CTX *ctx)
{
	// 引数チェック
	if (ctx == NULL)
	{
		return;
	}

	pro100_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_0, 1);
}
Ejemplo n.º 3
0
// CU にオペレーションを実行させる
void pro100_exec_cu_op(PRO100_CTX *ctx, PRO100_OP_BLOCK_MAX *op, UINT size)
{
	volatile PRO100_OP_BLOCK *b;
	PRO100_OP_BLOCK *b2;
	phys_t ptr;
	bool src_el, src_s, src_i;
	UINT src_link_addr;
	bool timeouted;
	UINT64 start_tick;
	// 引数チェック
	if (ctx == NULL || op == NULL)
	{
		return;
	}

	// メモリ確保
	b = pro100_alloc_page(&ptr);

	// 一時領域にコピー
	SeCopy((void *)b, op, size);

	// バックアップ
	src_el = b->el;
	src_s = b->s;
	src_i = b->i;
	src_link_addr = b->link_address;

	// フラグセット
	b->el = true;
	b->s = false;
	//b->ok = b->c = false;
	b->link_address = ptr;
	//b->i = false;

	pro100_init_cu_base_addr(ctx);

	pro100_wait_cu_ru_accepable(ctx);

	if (false)
	{
		char tmp[4096];

		SeBinToStrEx(tmp, sizeof(tmp), (void *)b, size);
		printf("%s\n", tmp);
	}

	pro100_write(ctx, PRO100_CSR_OFFSET_SCB_GENERAL_POINTER, (UINT)ptr, 4);
	pro100_write(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, 
		PRO100_MAKE_CU_RU_COMMAND(PRO100_CU_CMD_START, PRO100_RU_CMD_NOOP), 1);
	pro100_flush(ctx);

	// NIC がコマンドを完了するまで待機
	//printf("[");
	start_tick = SeTick64();
	timeouted = true;
	while ((start_tick + 1000ULL) >= SeTick64())
	{
		if (b->c)
		{
			timeouted = false;
			break;
		}
	}
	//printf("%u] ", b->c);
	//b->c = true;

	if (false)
	{
		UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_0, 1);
		PRO100_SCB_STATUS_WORD_BIT *b = (PRO100_SCB_STATUS_WORD_BIT *)(void *)&t;

		printf("STATUS  CU=%u, RU=%u\n", b->cu_status, b->ru_status);
	}

	// 結果を書き戻す
	SeCopy(op, (void *)b, size);
	b2 = (PRO100_OP_BLOCK *)op;

	// バックアップを復元
	b2->el = src_el;
	b2->s = src_s;
	b2->i = src_i;
	b2->link_address = src_link_addr;

	// メモリ解放
	pro100_free_page((void *)b, ptr);

	if (timeouted && src_i)
	{
		//pro100_generate_int(ctx);
	}
}
Ejemplo n.º 4
0
// CSR レジスタ用 MMIO ハンドラ
int pro100_mm_handler(void *data, phys_t gphys, bool wr, void *buf, uint len, u32 flags)
{
	int ret = 0;
	PRO100_CTX *ctx = (PRO100_CTX *)data;

	SeLock(ctx->lock);

	// 範囲チェック
	if (((UINT64)gphys >= (UINT64)ctx->csr_mm_addr) &&
		((UINT64)gphys < ((UINT64)ctx->csr_mm_addr) + (UINT64)PRO100_CSR_SIZE))
	{
		UINT offset = (UINT)((UINT64)gphys - (UINT64)ctx->csr_mm_addr);

		if (len == 1 || len == 2 || len == 4)
		{
			if (wr == 0)
			{
				UINT ret_data = 0;
				if (pro100_hook_read(ctx, offset, len, &ret_data) == false)
				{
					ret_data = pro100_read(ctx, offset, len);
				}

				if (len == 1)
				{
					*((UCHAR *)buf) = (UCHAR)ret_data;
				}
				else if (len == 2)
				{
					*((USHORT *)buf) = (USHORT)ret_data;
				}
				else if (len == 4)
				{
					*((UINT *)buf) = (UINT)ret_data;
				}
			}
			else
			{
				UINT data = 0;
				if (len == 1)
				{
					data = (UINT)(*((UCHAR *)buf));
				}
				else if (len == 2)
				{
					data = (UINT)(*((USHORT *)buf));
				}
				else if (len == 4)
				{
					data = (UINT)(*((UINT *)buf));
				}

				if (pro100_hook_write(ctx, offset, data, len) == false)
				{
					pro100_write(ctx, offset, data, len);
				}
			}

			ret = 1;
		}
	}

	SeUnlock(ctx->lock);

	return ret;
}
Ejemplo n.º 5
0
// 読み取りフック
bool pro100_hook_read(PRO100_CTX *ctx, UINT offset, UINT size, UINT *data)
{
	// 引数チェック
	if (ctx == NULL)
	{
		return false;
	}

	switch (offset)
	{
	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0:	// コマンド実行状態
		if (size == 1)
		{
			UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, 1);

			t = PRO100_MAKE_CU_RU_COMMAND(0, 0);

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_0:	// RU と CU のステータス
		if (size == 1)
		{
			UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_0, 1);
			PRO100_SCB_STATUS_WORD_BIT *sb = (PRO100_SCB_STATUS_WORD_BIT *)(void *)&t;

			sb->ru_status = 2;

			*data = t;
			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_1:	// STAT/ACK
		pro100_poll_ru(ctx);

		if (size == 1)
		{
			UINT t;
			PRO100_STAT_ACK *sa;

			//printf("<INT>");

			pro100_proc_guest_op(ctx);

			t = pro100_read(ctx, offset, size);

			pro100_write(ctx, offset, t, 1);

			sa = (PRO100_STAT_ACK *)(void *)&t;

			sa->cna = sa->cx_tno = sa->fr = sa->rnr = sa->mdi = sa->swi = sa->fcp = 1;
			sa->rnr = 0;

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1:	// 割り込み制御ビット
		if (size == 1)
		{
			UINT t = ctx->int_mask_guest_set;
			PRO100_INT_BIT *bi = (PRO100_INT_BIT *)(void *)&t;
			bi->si = false;

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_GENERAL_POINTER:	// 汎用ポインタ
		if (size == 4)
		{
			*data = ctx->guest_last_general_pointer;
			return true;
		}
		break;
	}

	return false;
}
Ejemplo n.º 6
0
// 読み取りフック
bool pro100_hook_read(PRO100_CTX *ctx, UINT offset, UINT size, UINT *data)
{
	// 引数チェック
	if (ctx == NULL)
	{
		return false;
	}

	switch (offset)
	{
	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0:	// コマンド実行状態
		if (size != 1)
		{
			debugprint("pro100_hook_read: PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0: BAD SIZE: %u\n", size);
		}
		if (size == 1)
		{
			UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_COMMAND_WORD_0, 1);

			t = PRO100_MAKE_CU_RU_COMMAND(0, 0);

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_0:	// RU と CU のステータス
		if (size != 1)
		{
			if (size != 2)
			{
				debugprint("pro100_hook_read: PRO100_CSR_OFFSET_SCB_STATUS_WORD_0: BAD SIZE: %u\n", size);
			}
			else
			{
				UINT data1 = 0, data2 = 0;
				UCHAR data3[4];
				pro100_hook_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_0, 1, &data1);
				pro100_hook_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_1, 1, &data2);
				data3[0] = (UCHAR)data1;
				data3[1] = (UCHAR)data2;
				data3[2] = data3[3] = 0;

				*data = *((UINT *)data3);

				//debugprint("*data = 0x%x\n", *data);

				return true;
			}
		}
		if (size == 1)
		{
			UINT t = pro100_read(ctx, PRO100_CSR_OFFSET_SCB_STATUS_WORD_0, 1);
			PRO100_SCB_STATUS_WORD_BIT *sb = (PRO100_SCB_STATUS_WORD_BIT *)(void *)&t;

			sb->ru_status = 2;

			*data = t;
			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_STATUS_WORD_1:	// STAT/ACK
		pro100_poll_ru(ctx);

		if (size != 1)
		{
			debugprint("pro100_hook_read: PRO100_CSR_OFFSET_SCB_STATUS_WORD_1: BAD SIZE: %u\n", size);
		}
		if (size == 1)
		{
			UINT t;
			PRO100_STAT_ACK *sa;

			//debugprint("<INT>");

			pro100_proc_guest_op(ctx);

			t = pro100_read(ctx, offset, size);

			pro100_write(ctx, offset, t, 1);

			sa = (PRO100_STAT_ACK *)(void *)&t;

			sa->cna = sa->cx_tno = sa->fr = sa->rnr = sa->mdi = sa->swi = sa->fcp = 1;
			sa->rnr = 0;

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1:	// 割り込み制御ビット
		if (size != 1)
		{
			debugprint("pro100_hook_read: PRO100_CSR_OFFSET_SCB_COMMAND_WORD_1: BAD SIZE: %u\n", size);
		}
		if (size == 1)
		{
			UINT t = ctx->int_mask_guest_set;
			PRO100_INT_BIT *bi = (PRO100_INT_BIT *)(void *)&t;
			bi->si = false;

			*data = t;

			return true;
		}
		break;

	case PRO100_CSR_OFFSET_SCB_GENERAL_POINTER:	// 汎用ポインタ
		if (size != 4)
		{
			debugprint("pro100_hook_read: PRO100_CSR_OFFSET_SCB_GENERAL_POINTER: BAD SIZE: %u\n", size);
		}
		if (size == 4)
		{
			*data = ctx->guest_last_general_pointer;
			return true;
		}
		break;

	default:
		if (offset < 0x10)
		{
			printf("*** READ ACCESS TO   0x%x  size=%u\n", offset, size);
		}
		break;
	}

	return false;
}