Example #1
0
void find_ptimer_b12(int cnum)
{
	uint8_t signals_ref_timer[0x100 * 8];
	uint8_t signals_tmp[0x100 * 8];
	struct signals_comparaison diffs;
	int i;
	uint32_t r_9210, r_9400;

	printf("<PTIMER_B12>\n");

	r_9210 = nva_rd32(cnum, 0x9210);
	r_9400 = nva_rd32(cnum, 0x9400);

	/* stop the time */
	nva_wr32(cnum, 0x9210, 0);
	nva_wr32(cnum, 0x9400, 0);

	poll_signals(cnum, signals_ref_timer);
	nva_wr32(cnum, 0x9400, 0x20000);
	poll_signals(cnum, signals_tmp);

	/* restore ptimer */
	nva_wr32(cnum, 0x9400, r_9400);
	nva_wr32(cnum, 0x9210, r_9210);

	diffs = signals_compare(signals_ref_timer, signals_tmp);

	if (diffs.diff_count >= 1) {
		for (i = 0; i < diffs.diff_count; i++) {
			uint8_t set, signal;

			set = diffs.differences[i].set;
			signal = diffs.differences[i].signal;

			if (diffs.differences[i].set == 0) {
				if (diffs.differences[i].change == ZERO_TO_ONE)
					printf("PTIMER_B12: Set %u, signal 0x%.2x\n", set, signal);
			} else {
				printf("Unexpected difference: ");
				print_difference(diffs.differences[i]);
			}
		}
	} else
		printf("Not found.\n");

	signals_comparaison_free(diffs);

	printf("</PTIMER_B12>\n\n");
}
Example #2
0
void find_ctxCtlFlags(int cnum)
{
	uint8_t signals_ref_ctx[0x100 * 8];
	uint8_t signals_tmp[0x100 * 8];
	struct signals_comparaison diffs;
	int bit, i;
	uint32_t r_400824 = nva_rd32(cnum, 0x400824);

	printf("<CTXCTL FLAGS>\n");

	nva_mask(cnum, 0x400824, 0xf0000000, 0);
	poll_signals(cnum, signals_ref_ctx);

	for (bit = 28; bit < 32; bit++) {
		nva_mask(cnum, 0x400824, 0xf0000000, 1 << bit);

		poll_signals(cnum, signals_tmp);
		diffs = signals_compare(signals_ref_ctx, signals_tmp);

		if (diffs.diff_count >= 1) {
			for (i = 0; i < diffs.diff_count; i++) {
				uint8_t set, signal;

				set = diffs.differences[i].set;
				signal = diffs.differences[i].signal;

				if (diffs.differences[i].set == 1) {
					if (diffs.differences[i].change == ZERO_TO_ONE)
						printf("CTXCTL flag 0x%.2x: Set %u, signal 0x%.2x\n", bit, set, signal);
				} else {
					printf("Unexpected difference: ");
					print_difference(diffs.differences[i]);
				}
			}
		} else
			printf("Not found. Please re-run when the GPU is idle.\n");

		signals_comparaison_free(diffs);
	}

	nva_wr32(cnum, 0x400824, r_400824);

	printf("</CTXCTL FLAGS>\n\n");
}
Example #3
0
int main(int argc, char **argv)
{
	int c, cnum = 0;

	if (nva_init()) {
		fprintf (stderr, "PCI init failure!\n");
		return 1;
	}

	/* Arguments parsing */
	while ((c = getopt (argc, argv, "c:")) != -1)
		switch (c) {
			case 'c':
				sscanf(optarg, "%d", &cnum);
				break;
		}

	if (cnum >= nva_cardsnum) {
		if (nva_cardsnum)
			fprintf (stderr, "No such card.\n");
		else
			fprintf (stderr, "No cards found.\n");
		return 1;
	}

	if (nva_cards[cnum].chipset < 0x10 ||
	    nva_cards[cnum].chipset >= 0xc0)
	{
		fprintf(stderr, "The chipset nv%x isn't currently supported\n",
			nva_cards[cnum].chipset);
		return 1;
	}

	/* Init */
	nva_wr32(cnum, 0x200, 0xffffffff);

	printf("Chipset nv%x:\n\n", nva_cards[cnum].chipset);

	poll_signals(cnum, signals_ref);
	find_counter_noise(cnum);
	find_ptimer_b12(cnum);
	find_host_mem_read_write(cnum);
	find_mmio_read_write(cnum, 0x200, "MMIO");
	find_mmio_read_write(cnum, 0x2210, "MMIO_PFIFO");
	find_mmio_read_write(cnum, 0x610384, "MMIO_PDISPLAY");
	find_mmio_read_write(cnum, 0x6666, "MMIO_INVALID");
	find_pgraphIdle_and_interrupt(cnum);
	find_ctxCtlFlags(cnum);

	return 0;
}
Example #4
0
void poll_loop(void)
{
    SIG_ENTITY *sig;
    fd_set perm,set;
    int fds,ret;

    FD_ZERO(&perm);
    FD_SET(kernel,&perm);
    fds = kernel+1;
    for (sig = entities; sig; sig = sig->next) {
	FD_SET(sig->signaling,&perm);
	if (fds <= sig->signaling) fds = sig->signaling+1;
    }
    gettimeofday(&now,NULL);
    while (!stop) {
	set = perm;
	poll_signals();
	/*
	 * Here we have a small race condition: if a signal is delivered after
	 * poll_signals tests for it but before select sleeps, we miss that
	 * signal. If it is sent again, we're of course likely to get it. This
	 * isn't worth fixing, because those signals are only used for
	 * debugging anyway.
	 */
	ret = select(fds,&set,NULL,NULL,next_timer());
	if (ret < 0) {
	    if (errno != EINTR) perror("select");
	}
	else {
	    diag(COMPONENT,DIAG_DEBUG,"----------");
	    gettimeofday(&now,NULL);
	    if (FD_ISSET(kernel,&set)) recv_kernel();
	    for (sig = entities; sig; sig = sig->next)
		if (FD_ISSET(sig->signaling,&set)) recv_signaling(sig);
	    expire_timers();
	      /* expire timers after handling messges to make sure we don't
		 time out unnecessarily because of scheduling delays */
	}
    }
}
Example #5
0
void find_pgraphIdle_and_interrupt(int cnum)
{
	unsigned char signals_idle[0x100 * 8];
	struct signals_comparaison diffs;
	int i;

	uint32_t r_400500, r_400808, r_40013c;

	printf("<PGRAPH_IDLE/INTERRUPT> /!\\ no drivers should be loaded!\n");

	/* safety check:  */
	if (nva_rd32(cnum, 0x140) == 1) {
		printf("You shouldn't run this tool while a driver is running\n");
		goto error;
	}

	/* reboot PGRAPH */
	nva_mask(cnum, 0x200, 0x00201000, 0x00000000);
	nva_mask(cnum, 0x200, 0x00201000, 0x00201000);

	r_400500 =  nva_rd32(cnum, 0x400500);
	r_400808 = nva_rd32(cnum, 0x400808);
	r_40013c = nva_rd32(cnum, 0x40013c);

	/* generate an illegal method IRQ
	 * that will pull the PGRAP_IDLE signal down and the PGRAPH_INTERRUPT up
	 *
	 * neither nouveau or nvidia should be loaded as they would ack the interrupt
	 * straight away.
	 */
	nva_wr32(cnum, 0x400500, 0x10001);
	nva_wr32(cnum, 0x400808, 0xa00000fc);
	nva_wr32(cnum, 0x40013c, 0xffffffff);

	poll_signals(cnum, signals_idle);
	diffs = signals_compare(signals_ref, signals_idle);

	if (diffs.diff_count >= 1) {
		for (i = 0; i < diffs.diff_count; i++) {
			uint8_t set, signal;

			set = diffs.differences[i].set;
			signal = diffs.differences[i].signal;

			if (diffs.differences[i].set == 1) {
				if (diffs.differences[i].change == ONE_TO_ZERO)
					printf("PGRAPH_IDLE: Set %u, signal 0x%.2x\n", set, signal);
				else if (diffs.differences[i].change == ZERO_TO_ONE)
					printf("PGRAPH_INTERRUPT: Set %u, signal 0x%.2x\n", set, signal);
			} else {
				printf("Unexpected difference: ");
				print_difference(diffs.differences[i]);
			}
		}

		signals_comparaison_free(diffs);
	} else
		printf("Not found. Please re-run when the GPU is idle.\n");

	/* restore our mess */
	nva_wr32(cnum, 0x400500, r_400500);
	nva_wr32(cnum, 0x400808, r_400808);
	nva_wr32(cnum, 0x40013c, r_40013c);

	/* ACK all PGRAPH's interrupts */
	nva_wr32(cnum, 0x400100, 0xffffffff);

error:
	printf("</PGRAPH_IDLE/INTERRUPT>\n\n");
}