[ create a new paste ] login | about

Link: http://codepad.org/7qp704g0    [ raw code | fork ]

Plain Text, pasted on Jun 24:
/*
 * Copyright (C) 2013 Martin Peres <martin.peres@free.fr>
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/* Usage: gcc -g sw_mth_test.c `pkg-config --libs --cflags libdrm_nouveau`&& ./a.out */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <assert.h>

#include "nouveau_local.h"
#include <sched.h>

#define SUBC_SW(m) 7, (m)
#define NV01_SUBCHAN_OBJECT                                        0x00000000

#define NV50_MAX_COUNTERS 12
#define RING_SIZE 9
#define TIMEOUT 1e6

int main()
{
	struct nouveau_device *dev;
	struct nouveau_client *client;
	struct nouveau_object *channel;
	struct nouveau_pushbuf *push;
	struct nouveau_object *query;
	struct nouveau_object *nvsw;
	struct nouveau_bo *notify;
	struct nv04_fifo *fifo;
	struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
	uint32_t *nvsw_map;
	int ret, fd, i, e, offset;
	uint64_t cnt;

	fd = open("/dev/dri/renderD129", O_RDWR);
	assert(fd > 0);

	assert(!nouveau_device_wrap(fd, 0, &dev));
	assert(!nouveau_client_new(dev, &client));
	assert(!nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
				&nv04_data, sizeof(nv04_data), &channel));
	assert(!nouveau_pushbuf_new(client, channel, 1, 4000, 1, &push));
	assert(!nouveau_object_new(channel, 0xD8000100, NOUVEAU_NOTIFIER_CLASS,
				&(struct nv04_notify){ .length = 1300 },
				sizeof(struct nv04_notify), &query));
	assert(!nouveau_object_new(channel, 0xbeef506e, 0x506e, NULL, 0, &nvsw));

	fifo = channel->data;

	assert(!nouveau_bo_wrap(dev, fifo->notify, &notify));
	assert(!nouveau_bo_map(notify, 0, client));

	nvsw_map = notify->map + ((struct nv04_notify*)query->data)->offset;
	nvsw_map[0] = 0x42;

	BEGIN_NV04(push, SUBC_SW(NV01_SUBCHAN_OBJECT), 1);
	PUSH_DATA (push, nvsw->handle);
	BEGIN_NV04(push, SUBC_SW(0x0600), 1);
	PUSH_DATA (push, query->handle);
	BEGIN_NV04(push, SUBC_SW(0x0604), 1);
	PUSH_DATA (push, RING_SIZE);
	BEGIN_NV04(push, SUBC_SW(0x0608), 1);
	PUSH_DATA (push, 0xa);

        BEGIN_NV04(push, SUBC_SW(0x060c), 1);
        PUSH_DATA (push, 0);
        //BEGIN_NV04(push, SUBC_SW(0x0610), 1);
        //PUSH_DATA (push, 0);
	PUSH_KICK (push);

#if 1
	for (i = 0; i < 1000 * RING_SIZE; i++) {
                /*
                BEGIN_NV04(push, SUBC_SW(0x060c), 1);
		PUSH_DATA (push, 0);
		PUSH_KICK (push);
                */

                BEGIN_NV04(push, SUBC_SW(0x0608), 1);
		PUSH_DATA (push, i);
		PUSH_KICK (push);

		cnt = 0;
		offset = (1 + (i % RING_SIZE) * NV50_MAX_COUNTERS * 3);
		printf("seq %u: ", i);
		while (nvsw_map[0] != i && cnt < TIMEOUT) {
			cnt++;
			sched_yield();
		}

		uint32_t read_seq = nvsw_map[offset];
		if (cnt < TIMEOUT && read_seq == i)
			printf("OK\n");
		else if (cnt < TIMEOUT) {
			printf("NOK (nvsw_map[offset = %u] == %u)\n", offset * 4, read_seq);
			return 1;
		} else {
			printf("TIMEOUT");
			return 1;
		}
	}
#endif

#if 0
	/* stress test */
	for (e = 0; e < 1000; e++) {
		uint32_t size = 1;
		assert(PUSH_SPACE(push, size * 2));
		assert(PUSH_AVAIL(push) >= size * 2);
		for (i = 0; i < size; i++) {
			BEGIN_NV04(push, SUBC_SW(0x0608), 1);
			PUSH_DATA (push, e * 100 + i);
		}
		PUSH_KICK (push);
	}
#endif

	return 0;
}



Create a new paste based on this one


Comments: