示例#1
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;
}
示例#2
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;
}