summaryrefslogtreecommitdiff
path: root/ramin.cpp
blob: 79d836c4437bdd99bc05a3391db1f2c199039305 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "nvlib.h"
#include <algorithm>
#include <tuple>
using namespace std;

int main(int argc, char** argv)
{
	unique_ptr<nv_device> dev(nv_device::open_default());
	
	vector<tuple<unsigned, unsigned, string> > objects;

	for(unsigned j = 0; j < dev->ramhts; ++j) {
		shared_ptr<nv_ramht> ramht = dev->ramht(j);
		if(!ramht)
			continue;

		int ramht_offset = ramht->offset_in(*dev->ramin);
		if(ramht_offset >= 0) {
			ostringstream ss;
			ss << "RAMHT";
			if(ramht != dev->dev_ramht)
				ss << '(' << j << ')';
			objects.push_back(make_tuple((unsigned)ramht_offset, (unsigned)(ramht_offset + ramht->size), ss.str()));
		}

		for(unsigned i = 0; i < ramht->entries; ++i) {
			nv_ramht_entry entry = ramht->get_at(i);
			if(!entry.valid)
				continue;
			ostringstream ss;
			//ss << "RAMHT[" << dec << i << "] " << make_pair(&*dev, entry);
			ss << (unsigned)entry.channel << ":" << hex08 << entry.handle;
			nv_object obj(dev->ramin, entry.instance);
			objects.push_back(make_tuple(entry.instance, entry.instance + obj.size, ss.str()));
		}
	}

	for(unsigned i = 0; i < dev->channels; ++i) {
		shared_ptr<nv_hwchannel> hwchan = dev->hwchannel(i);
		if(!hwchan)
			continue;
		if(hwchan->grctx) {
			unsigned offset = hwchan->grctx->offset_in(*dev->ramin);
			ostringstream ss;
			ss << "GRCTX(" << i << ")";
			objects.push_back(make_tuple(offset, offset + hwchan->grctx->size, ss.str()));
		}

		ostringstream ss;
		ss << "FIFOCTX(" << i << ")";
		unsigned offset = hwchan->fifoctx->offset_in(*dev->ramin);
		objects.push_back(make_tuple(offset, offset + hwchan->fifoctx->size, ss.str()));
	}

	// TODO: nv50 runout table?
	if(dev->ramro) {
		int ramro_offset = dev->ramro->offset_in(*dev->ramin);
		if(ramro_offset >= 0)
			objects.push_back(make_tuple((unsigned)ramro_offset, (unsigned)(ramro_offset + dev->ramro->size), string("RAMRO")));
	}

	for(unsigned i = 0; i < objects.size(); ++i) {
		get<1>(objects[i]) = -get<1>(objects[i]);
	}
	sort(objects.begin(), objects.end());
	for(unsigned i = 0; i < objects.size(); ++i) {
		get<1>(objects[i]) = -get<1>(objects[i]);
	}

	string object_name;
	unsigned object_start = 0;
	unsigned object_end = 0;
	unsigned object_w;
	unsigned ramin_w = 0;
	int next_object_idx = 0;
	string object_prefix;

	while((1u << (4 * ramin_w)) < dev->ramin->size)
		++ramin_w;

	for(unsigned i = 0; i < dev->ramin->size; i += 16) {
		while(next_object_idx < (int)objects.size() && i > get<0>(objects[next_object_idx]))
			++next_object_idx;

		while(next_object_idx < (int)objects.size() && i == get<0>(objects[next_object_idx])) {
			object_start = get<0>(objects[next_object_idx]);
			object_end = get<1>(objects[next_object_idx]);
			object_w = 0;
			while((1u << (4 * object_w)) < (object_end - object_start))
				++object_w;
			object_name = get<2>(objects[next_object_idx]);
			++next_object_idx;

			goto update_prefix;
		}

		if(i >= object_end) {
			object_start = 0;
			object_end = dev->ramin->size;
			object_name = "RAMIN";
			object_w = ramin_w;
update_prefix:
			object_prefix = "\t";
			while((((11 + object_name.size() + 3 + object_w) >> 3) + object_prefix.size()) < 4)
				object_prefix += '\t';
		}

		unsigned v[4];
		for(unsigned j = 0; j < 4; ++j)
			v[j] = dev->ramin->rd32(i + j * 4);

		if(!v[0] && !v[1] && !v[2] && !v[3])
			continue;

		cout << hex08 << i << " = " << object_name << '[' << hex << setfill('0') << setw(object_w) << i - object_start << "]:" << object_prefix;

		for(unsigned j = 0; j < 4; ++j)
			cout << (j ? " " : "") << hex08 << v[j];
		cout << endl;
	}

	return 0;
}