Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 5 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 04, 2014
@mslusarz mslusarz demmt: move pushbuf decode state from decode fragment to buffer
Writes for single command batch can be interrupted by other writes
or ioctls, so this is needed to not lose state.
4d73920
@mslusarz mslusarz demmt: add support for old-style commands for >= nvc0 buffers
They are not used by the blob, but this code is needed to signal
there's something fishy going on.
917e8b0
@mslusarz mslusarz demmt: do not print "subchannel already taken" messages when buffer i…
…s known-invalid
edc77d8
@mslusarz mslusarz demmt: hacky IB trick detection
Blob writes M2MF header, switches to another buffer for M2MF.DATA and then
switches back for next commands, so we incorrectly use those commands
as M2MF.DATA. Without proper IB detection there's not much we can do other
than hacks like this one.

IB support will come later.
fb901f3
@mslusarz mslusarz demmt: more ioctl message spam 1cf0ff5
View
68 rnn/demmt.c
@@ -49,6 +49,7 @@ struct buffer
uint64_t start;
uint64_t data1;
uint64_t data2;
+ struct pushbuf_decode_state state;
};
#define MAX_ID 1024
@@ -67,6 +68,7 @@ int chipset;
int guess_invalid_pushbuf = 1;
int invalid_pushbufs_visible = 1;
int decode_invalid_buffers = 1;
+int m2mf_hack_enabled = 0;
static void dump(int id)
{
@@ -89,7 +91,7 @@ static void dump_and_abort(int id)
static void dump_writes(int id)
{
struct region *cur = wreg_head[id];
- struct pushbuf_decode_state state;
+ struct pushbuf_decode_state *state = &buffers[id]->state;
char pushbuf_desc[1024];
mmt_log("currently buffered writes for id: %d:\n", id);
while (cur)
@@ -135,35 +137,41 @@ static void dump_writes(int id)
break;
}
}
+ if (addr_start == state->next_command_offset)
+ state->next_command_offset = addr;
+
mmt_log("all zeroes between 0x%04x and 0x%04x\n", addr_start, addr);
fprintf(stdout, "w %d:0x%04x-0x%04x, 0x00000000\n", id, addr_start, addr);
}
- pushbuf_decode_start(&state);
+ if (addr != state->next_command_offset)
+ {
+ mmt_log("restarting pushbuf decode on buffer %d: %x != %x\n", id, addr, state->next_command_offset);
+ pushbuf_decode_start(state);
+ }
+
+ // this is temporary, will be removed when proper IB support lands
+ if (state->pushbuf_invalid == 1)
+ {
+ mmt_log("restarting pushbuf decode on buffer %d\n", id);
+ pushbuf_decode_start(state);
+ }
while (addr < cur->end)
{
if (left >= 4)
{
- if (state.pushbuf_invalid == 0 || decode_invalid_buffers)
- {
- pushbuf_decode(&state, *(uint32_t *)(data + addr), pushbuf_desc);
- if (guess_invalid_pushbuf && !state.pushbuf_invalid && state.size > left / 4)
- {
- mmt_log("command size (%d) is bigger than number of left possible commands (%d), marking this buffer invalid\n", state.size, left / 4);
- state.pushbuf_invalid = 1;
- }
-
- if (state.pushbuf_invalid == 1 && !decode_invalid_buffers)
- pushbuf_desc[0] = 0;
- }
+ if (state->pushbuf_invalid == 0 || decode_invalid_buffers)
+ pushbuf_decode(state, *(uint32_t *)(data + addr), pushbuf_desc);
else
pushbuf_desc[0] = 0;
- if (state.pushbuf_invalid == 1 && invalid_pushbufs_visible == 0)
+ if (state->pushbuf_invalid == 1 && invalid_pushbufs_visible == 0)
break;
- fprintf(stdout, "w %d:0x%04x, 0x%08x %s%s\n", id, addr, *(uint32_t *)(data + addr), state.pushbuf_invalid ? "INVALID " : "", pushbuf_desc);
+ fprintf(stdout, "w %d:0x%04x, 0x%08x %s%s\n", id, addr, *(uint32_t *)(data + addr), state->pushbuf_invalid ? "INVALID " : "", pushbuf_desc);
+ state->next_command_offset = addr + 4;
+
addr += 4;
left -= 4;
}
@@ -181,7 +189,7 @@ static void dump_writes(int id)
}
}
- pushbuf_decode_end(&state);
+ pushbuf_decode_end(state);
cur = cur->next;
}
@@ -562,13 +570,11 @@ static void demmt_mmap(struct mmt_mmap *mm, void *state)
{
mmt_log("mmap: address: %p, length: 0x%08lx, id: %d, offset: 0x%08lx\n",
(void *)mm->start, mm->len, mm->id, mm->offset);
- buffers[mm->id] = malloc(sizeof(struct buffer));
+ buffers[mm->id] = calloc(1, sizeof(struct buffer));
buffers[mm->id]->data = calloc(mm->len, 1);
buffers[mm->id]->start = mm->start;
buffers[mm->id]->length = mm->len;
buffers[mm->id]->offset = mm->offset;
- buffers[mm->id]->data1 = 0;
- buffers[mm->id]->data2 = 0;
}
static void demmt_munmap(struct mmt_unmap *mm, void *state)
@@ -595,13 +601,14 @@ static void demmt_mremap(struct mmt_mremap *mm, void *state)
struct buffer *oldbuf = buffers[mm->id];
- buffers[mm->id] = malloc(sizeof(struct buffer));
+ buffers[mm->id] = calloc(1, sizeof(struct buffer));
buffers[mm->id]->data = calloc(mm->len, 1);
buffers[mm->id]->start = mm->start;
buffers[mm->id]->length = mm->len;
buffers[mm->id]->offset = mm->offset;
buffers[mm->id]->data1 = mm->data1;
buffers[mm->id]->data2 = mm->data2;
+ memcpy(&buffers[mm->id]->state, &oldbuf->state, sizeof(struct pushbuf_decode_state));
memcpy(buffers[mm->id]->data, oldbuf->data, min(mm->len, oldbuf->length));
free(oldbuf->data);
@@ -614,11 +621,13 @@ static void demmt_open(struct mmt_open *o, void *state)
static void demmt_nv_create_object(struct mmt_nvidia_create_object *create, void *state)
{
+ mmt_log("create object: obj1: 0x%08x, obj2: 0x%08x, class: 0x%08x\n", create->obj1, create->obj2, create->class);
pushbuf_add_object(create->obj2, create->class);
}
static void demmt_nv_destroy_object(struct mmt_nvidia_destroy_object *destroy, void *state)
{
+ mmt_log("destroy object: obj1: 0x%08x, obj2: 0x%08x\n", destroy->obj1, destroy->obj2);
}
static void demmt_nv_ioctl_pre(struct mmt_nvidia_ioctl_pre *ctl, void *state)
@@ -653,6 +662,7 @@ static void demmt_nv_memory_dump_cont(struct mmt_buf *b, void *state)
static void demmt_nv_call_method(struct mmt_nvidia_call_method *m, void *state)
{
+ mmt_log("call method: data1: 0x%08x, data2: 0x%08x\n", m->data1, m->data2);
}
static void demmt_nv_create_mapped(struct mmt_nvidia_create_mapped_object *p, void *state)
@@ -677,6 +687,8 @@ static void demmt_nv_create_mapped(struct mmt_nvidia_create_mapped_object *p, vo
static void demmt_nv_create_dma_object(struct mmt_nvidia_create_dma_object *create, void *state)
{
+ mmt_log("create dma object, name: 0x%08x, type: 0x%08x, parent: 0x%08x\n",
+ create->name, create->type, create->parent);
}
static void demmt_nv_alloc_map(struct mmt_nvidia_alloc_map *alloc, void *state)
@@ -698,17 +710,21 @@ static void demmt_nv_alloc_map(struct mmt_nvidia_alloc_map *alloc, void *state)
static void demmt_nv_gpu_map(struct mmt_nvidia_gpu_map *map, void *state)
{
+ mmt_log("gpu map: data1: 0x%08x, data2: 0x%08x, data3: 0x%08x, addr: 0x%08x, len: 0x%08x\n",
+ map->data1, map->data2, map->data3, map->addr, map->len);
}
static void demmt_nv_gpu_unmap(struct mmt_nvidia_gpu_unmap *unmap, void *state)
{
+ mmt_log("gpu unmap: data1: 0x%08x, data2: 0x%08x, data3: 0x%08x, addr: 0x%08x\n",
+ unmap->data1, unmap->data2, unmap->data3, unmap->addr);
}
static void demmt_nv_mmap(struct mmt_nvidia_mmap *mm, void *state)
{
mmt_log("mmap: address: %p, length: 0x%08lx, id: %d, offset: 0x%08lx, data1: 0x%08lx, data2: 0x%08lx\n",
(void *)mm->start, mm->len, mm->id, mm->offset, mm->data1, mm->data2);
- buffers[mm->id] = malloc(sizeof(struct buffer));
+ buffers[mm->id] = calloc(1, sizeof(struct buffer));
buffers[mm->id]->data = calloc(mm->len, 1);
buffers[mm->id]->start = mm->start;
buffers[mm->id]->length = mm->len;
@@ -737,18 +753,22 @@ static void demmt_nv_unmap(struct mmt_nvidia_unmap *mm, void *state)
static void demmt_nv_bind(struct mmt_nvidia_bind *bnd, void *state)
{
+ mmt_log("bind: data1: 0x%08x, data2: 0x%08x\n", bnd->data1, bnd->data2);
}
static void demmt_nv_create_driver_object(struct mmt_nvidia_create_driver_object *create, void *state)
{
+ mmt_log("create driver object: obj1: 0x%08x, obj2: 0x%08x, addr: 0x%08lx\n", create->obj1, create->obj2, create->addr);
}
static void demmt_nv_create_device_object(struct mmt_nvidia_create_device_object *create, void *state)
{
+ mmt_log("create device object: obj1: 0x%08x\n", create->obj1);
}
static void demmt_nv_create_context_object(struct mmt_nvidia_create_context_object *create, void *state)
{
+ mmt_log("create context object: obj1: 0x%08x\n", create->obj1);
}
static void demmt_nv_call_method_data(struct mmt_nvidia_call_method_data *call, void *state)
@@ -757,6 +777,7 @@ static void demmt_nv_call_method_data(struct mmt_nvidia_call_method_data *call,
static void demmt_nv_ioctl_4d(struct mmt_nvidia_ioctl_4d *ctl, void *state)
{
+ mmt_log("ioctl4d: %s\n", ctl->str.data);
}
static void demmt_nv_mmiotrace_mark(struct mmt_nvidia_mmiotrace_mark *mark, void *state)
@@ -798,6 +819,7 @@ static void usage()
" -i\t\tdo not guess invalid pushbufs\n"
" -d\t\thide invalid pushbufs\n"
" -e\t\tdo not decode invalid pushbufs\n"
+ " -b\t\tenable hacky IB trick detection, will be removed when proper IB support lands\n"
"\n");
exit(1);
}
@@ -827,6 +849,8 @@ int main(int argc, char *argv[])
invalid_pushbufs_visible = 0;
else if (!strcmp(argv[i], "-e"))
decode_invalid_buffers = 0;
+ else if (!strcmp(argv[i], "-b"))
+ m2mf_hack_enabled = 1;
else
usage();
}
View
1  rnn/demmt.h
@@ -11,5 +11,6 @@ extern struct rnndomain *domain;
extern struct rnndb *rnndb;
extern int chipset;
extern int guess_invalid_pushbuf;
+extern int m2mf_hack_enabled;
#endif
View
60 rnn/demmt_pushbuf.c
@@ -187,15 +187,52 @@ void pushbuf_decode(struct pushbuf_decode_state *state, uint32_t data, char *out
state->incr = 0;
else if (mode == 5)
state->incr = 1;
- else
+ else if (mode == 1)
state->incr = state->size;
-
- if (mode == 4)
+ else if (mode == 4)
{
decode_method(state, state->size, output);
state->size = 0;
return;
}
+ else if (mode == 0)
+ {
+ state->incr = 1;
+ state->size = (data & 0x1ffc0000) >> 18;
+ int type = (data & 0x30000) >> 16;
+ if (type != 0)
+ {
+ state->incr = 0;//?
+ state->size = 0;
+ sprintf(output, "SLI %d", type);
+ //TODO: decode fully
+ return;
+ }
+
+ if (!state->pushbuf_invalid)
+ mmt_log("unusual, old-style inc mthd%s\n", "");
+ }
+ else if (mode == 2)
+ {
+ state->incr = 0;
+ state->size = (data & 0x1ffc0000) >> 18;
+ int type = (data & 0x30000) >> 16;
+ if (type != 0)
+ {
+ state->size = 0;
+ sprintf(output, "invalid old-style non-inc mthd, type: %d", type);
+ return;
+ }
+
+ if (!state->pushbuf_invalid)
+ mmt_log("unusual, old-style non-inc mthd%s\n", "");
+ }
+ else
+ {
+ state->size = 0;
+ sprintf(output, "unknown mode %d", mode);
+ return;
+ }
}
else
{
@@ -218,6 +255,16 @@ void pushbuf_decode(struct pushbuf_decode_state *state, uint32_t data, char *out
mmt_log("subchannel %d does not have bound object and first command does not bind it, marking this buffer invalid\n", state->subchan);
state->pushbuf_invalid = 1;
}
+
+ // XXX HACK
+ if (m2mf_hack_enabled &&
+ subchans[state->subchan] && subchans[state->subchan]->handle == 0x9039 &&
+ state->addr == 0x0304 && state->incr == 0)
+ {
+ mmt_log("IB trick detected, assuming next word after this one is NOT M2MF.DATA%s\n", "");
+ state->size = 0;
+ }
+ // XXX END HACK
}
else
{
@@ -234,8 +281,11 @@ void pushbuf_decode(struct pushbuf_decode_state *state, uint32_t data, char *out
{
if (guess_invalid_pushbuf && data != subchans[state->subchan]->handle)
{
- mmt_log("subchannel %d is already taken, marking this buffer invalid\n", state->subchan);
- state->pushbuf_invalid = 1;
+ if (state->pushbuf_invalid == 0)
+ {
+ mmt_log("subchannel %d is already taken, marking this buffer invalid\n", state->subchan);
+ state->pushbuf_invalid = 1;
+ }
}
}
}
View
1  rnn/demmt_pushbuf.h
@@ -11,6 +11,7 @@ struct pushbuf_decode_state
int size;
int skip;
int pushbuf_invalid;
+ int next_command_offset;
};
void pushbuf_decode_start(struct pushbuf_decode_state *state);

No commit comments for this range

Something went wrong with that request. Please try again.