Beispiel #1
0
void
dae_print(unsigned *eframe)
{
	int x;
	unsigned dmax, dmdx, dmtx;

	if (!ISSET(eframe[EF_DMT0], DMT_VALID))
		return;

	for (x = 0; x < 3; x++) {
		dmtx = eframe[EF_DMT0 + x * 3];
		if (!ISSET(dmtx, DMT_VALID))
			continue;

		dmdx = eframe[EF_DMD0 + x * 3];
		dmax = eframe[EF_DMA0 + x * 3];

		if (ISSET(dmtx, DMT_WRITE))
			printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
			    x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
			    DMT_ENBITS(dmtx),
			    dmtx & DMT_DOUB1 ? "double": "not double",
			    dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
		else
			printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
			    x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
			    DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
			    dmtx & DMT_DOUB1 ? "double": "not double",
			    dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
	}
}
void
dae_print_one(u_int x, u_int dmax, u_int dmdx, u_int dmtx)
{
    if (!ISSET(dmtx, DMT_VALID))
        return;

    if (ISSET(dmtx, DMT_WRITE))
        printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
               x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
               DMT_ENBITS(dmtx),
               dmtx & DMT_DOUB1 ? "double": "not double",
               dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
    else
        printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
               x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
               DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
               dmtx & DMT_DOUB1 ? "double": "not double",
               dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
}
void
dae_print_one(u_int x, u_int dmax, u_int dmdx, u_int dmtx)
{
	u_int enbits;
	const char *width, *usr, *xmem;

	if (!ISSET(dmtx, DMT_VALID))
		return;

	enbits = DMT_ENBITS(dmtx);
	dmax += dmt_en_info[enbits].offset;

	if (dmtx & DMT_DOUB1)
		width = ".d";
	else {
		switch (dmt_en_info[enbits].size) {
		case DMT_BYTE:
			if (dmtx & DMT_SIGNED)
				width = ".b";
			else
				width = ".bu";
			break;
		case DMT_HALF:
			if (dmtx & DMT_SIGNED)
				width = ".h";
			else
				width = ".hu";
			break;
		case DMT_WORD:
			width = "";
			break;
		default:
			width = ".???";
			break;
		}
	}
	if (dmtx & DMT_DAS)
		usr = "";
	else
		usr = "******";
	if (dmtx & DMT_LOCKBAR)
		xmem = "(xmem)";
	else
		xmem = "";

	if (ISSET(dmtx, DMT_WRITE))
		printf("[DMT%d=%x: %sst%s%s %08x to %08x]\n",
		    x, dmtx, xmem, width, usr, dmdx, dmax);
	else
		printf("[DMT%d=%x: %sld%s%s r%d <- %x]\n",
		    x, dmtx, xmem, width, usr, DMT_DREGBITS(dmtx), dmax);
}
void
dae_process(struct trapframe *eframe, u_int x,
            u_int dmax, u_int dmdx, u_int dmtx)
{
    u_int v, reg;

    if (!ISSET(dmtx, DMT_VALID))
        return;

    DAE_DEBUG(
        if (ISSET(dmtx, DMT_WRITE))
        printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
               x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
               DMT_ENBITS(dmtx),
               dmtx & DMT_DOUB1 ? "double": "not double",
               dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
        else
            printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
                   x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
                   DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
                   dmtx & DMT_DOUB1 ? "double": "not double",
                   dmtx & DMT_LOCKBAR ? "xmem": "not xmem")
        );

    dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset;
    reg = DMT_DREGBITS(dmtx);

    if (!ISSET(dmtx, DMT_LOCKBAR)) {
        /* the fault is not during an XMEM */

        if (x == 2 && ISSET(dmtx, DMT_DOUB1)) {
            /* pipeline 2 (earliest stage) for a double */

            if (ISSET(dmtx, DMT_WRITE)) {
                /*
                 * STORE DOUBLE WILL BE REINITIATED BY rte
                 */
            } else {
                /* EMULATE ld.d INSTRUCTION */
                v = do_load_word(dmax, dmtx & DMT_DAS);
                if (reg != 0)
                    eframe->tf_r[reg] = v;
                v = do_load_word(dmax ^ 4, dmtx & DMT_DAS);
                if (reg != 31)
                    eframe->tf_r[reg + 1] = v;
            }
        } else {
            /* not pipeline #2 with a double */
            if (dmtx & DMT_WRITE) {
                switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
                case DMT_BYTE:
                    DAE_DEBUG(
                        printf("[byte %x -> [%x(%c)]\n",
                               dmdx & 0xff, dmax,
                               ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    );
                    do_store_byte(dmax, dmdx,
                                  dmtx & DMT_DAS);
                    break;
                case DMT_HALF:
                    DAE_DEBUG(
                        printf("[half %x -> [%x(%c)]\n",
                               dmdx & 0xffff, dmax,
                               ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    );
                    do_store_half(dmax, dmdx,
                                  dmtx & DMT_DAS);
                    break;
                case DMT_WORD:
                    DAE_DEBUG(
                        printf("[word %x -> [%x(%c)]\n",
                               dmdx, dmax,
                               ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    );
                    do_store_word(dmax, dmdx,
                                  dmtx & DMT_DAS);
                    break;
                }
            } else {
                /* else it's a read */
                switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
                case DMT_BYTE:
                    v = do_load_byte(dmax, dmtx & DMT_DAS);
                    if (!ISSET(dmtx, DMT_SIGNED))
                        v &= 0x000000ff;
                    break;
                case DMT_HALF:
                    v = do_load_half(dmax, dmtx & DMT_DAS);
                    if (!ISSET(dmtx, DMT_SIGNED))
                        v &= 0x0000ffff;
                    break;
                case DMT_WORD:
                    v = do_load_word(dmax, dmtx & DMT_DAS);
                    break;
                }
                DAE_DEBUG(
                    if (reg == 0)
                    printf("[no write to r0 done]\n");
                    else
                        printf("[r%d <- %x]\n", reg, v);
                    );
                if (reg != 0)
                    eframe->tf_r[reg] = v;
            }
        }
    } else {
Beispiel #5
0
void
data_access_emulation(unsigned *eframe)
{
	int x;
	unsigned dmax, dmdx, dmtx;
	unsigned v, reg;

	dmtx = eframe[EF_DMT0];
	if (!ISSET(dmtx, DMT_VALID))
		return;

	for (x = 0; x < 3; x++) {
		dmtx = eframe[EF_DMT0 + x * 3];
		if (!ISSET(dmtx, DMT_VALID) || ISSET(dmtx, DMT_SKIP))
			continue;

		dmdx = eframe[EF_DMD0 + x * 3];
		dmax = eframe[EF_DMA0 + x * 3];

      DAE_DEBUG(
		if (ISSET(dmtx, DMT_WRITE))
			printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
			    x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
			    DMT_ENBITS(dmtx),
			    dmtx & DMT_DOUB1 ? "double": "not double",
			    dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
		else
			printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
			    x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
			    DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
			    dmtx & DMT_DOUB1 ? "double": "not double",
			    dmtx & DMT_LOCKBAR ? "xmem": "not xmem")
	);

		dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset;
		reg = DMT_DREGBITS(dmtx);

		if (!ISSET(dmtx, DMT_LOCKBAR)) {
			/* the fault is not during an XMEM */

			if (x == 2 && ISSET(dmtx, DMT_DOUB1)) {
				/* pipeline 2 (earliest stage) for a double */

				if (ISSET(dmtx, DMT_WRITE)) {
					/*
					 * STORE DOUBLE WILL BE REINITIATED
					 * BY rte
					 */
				} else {
					/* EMULATE ld.d INSTRUCTION */
					v = do_load_word(dmax, dmtx & DMT_DAS);
					if (reg != 0)
						eframe[EF_R0 + reg] = v;
					v = do_load_word(dmax ^ 4,
					    dmtx & DMT_DAS);
					if (reg != 31)
						eframe[EF_R0 + reg + 1] = v;
				}
			} else {
				/* not pipeline #2 with a double */
				if (dmtx & DMT_WRITE) {
					switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
					case DMT_BYTE:
					DAE_DEBUG(
						printf("[byte %x -> [%x(%c)]\n",
						    dmdx & 0xff, dmax,
						    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
					);
						do_store_byte(dmax, dmdx,
						    dmtx & DMT_DAS);
						break;
					case DMT_HALF:
					DAE_DEBUG(
						printf("[half %x -> [%x(%c)]\n",
						    dmdx & 0xffff, dmax,
						    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
					);
						do_store_half(dmax, dmdx,
						    dmtx & DMT_DAS);
						break;
					case DMT_WORD:
					DAE_DEBUG(
						printf("[word %x -> [%x(%c)]\n",
						    dmdx, dmax,
						    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
					);
						do_store_word(dmax, dmdx,
						    dmtx & DMT_DAS);
						break;
					}
				} else {
					/* else it's a read */
					switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
					case DMT_BYTE:
						v = do_load_byte(dmax,
						    dmtx & DMT_DAS);
						if (!ISSET(dmtx, DMT_SIGNED))
							v &= 0x000000ff;
						break;
					case DMT_HALF:
						v = do_load_half(dmax,
						    dmtx & DMT_DAS);
						if (!ISSET(dmtx, DMT_SIGNED))
							v &= 0x0000ffff;
						break;
					case DMT_WORD:
						v = do_load_word(dmax,
						    dmtx & DMT_DAS);
						break;
					}
					DAE_DEBUG(
						if (reg == 0)
							printf("[no write to r0 done]\n");
						else
							printf("[r%d <- %x]\n", reg, v);
					);
					if (reg != 0)
						eframe[EF_R0 + reg] = v;
				}
			}
		} else {
			/* if lockbar is set... it's part of an XMEM */
			/*
			 * According to Motorola's "General Information",
			 * the DMT_DOUB1 bit is never set in this case, as it
			 * should be.
			 * If lockbar is set (as it is if we're here) and if
			 * the write is not set, then it's the same as if DOUB1
			 * was set...
			 */
			if (!ISSET(dmtx, DMT_WRITE)) {