diff options
author | Jerome Glisse <jglisse@redhat.com> | 2011-10-27 13:23:21 -0400 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2011-10-27 13:23:21 -0400 |
commit | d667313dbea67c4b2067e4220bd7fa1f81f6e1bb (patch) | |
tree | 359cd425e4c7ecefee2deafe064d4bf51ce21d8f | |
parent | df6292fb9cbb927505d864367734649016cf39f4 (diff) |
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 9 | ||||
-rw-r--r-- | src/revenge_detect.c | 65 | ||||
-rw-r--r-- | src/revenge_detect.h | 16 | ||||
-rw-r--r-- | src/revenge_dump.c | 11 | ||||
-rw-r--r-- | src/revenge_dump_r600.c | 129 | ||||
-rw-r--r-- | src/revenge_main.c | 44 | ||||
-rw-r--r-- | src/revenge_main.h | 4 | ||||
-rw-r--r-- | src/revenge_memory.h | 1 | ||||
-rw-r--r-- | src/revenge_memory_r600.c | 136 |
10 files changed, 395 insertions, 22 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index aef80f0..5ffb090 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,12 +62,14 @@ revenge_SOURCES = \ revenge_detect.c \ revenge_detect.h \ revenge_dump.c \ + revenge_dump_r600.c \ revenge_dump.h \ revenge_dump_misc.c \ revenge_dump_misc.h \ revenge_main.c \ revenge_main.h \ revenge_memory.c \ + revenge_memory_r600.c \ revenge_memory.h \ revenge_register.c \ revenge_register.h \ diff --git a/src/Makefile.in b/src/Makefile.in index b0a1f9f..ff345fb 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -60,8 +60,9 @@ am_revenge_OBJECTS = gl_alpha_test.$(OBJEXT) gl_blend.$(OBJEXT) \ gl_texture_mag_filter.$(OBJEXT) \ gl_texture_min_filter.$(OBJEXT) gl_texture_wrap_s.$(OBJEXT) \ gl_texture_wrap_t.$(OBJEXT) revenge_detect.$(OBJEXT) \ - revenge_dump.$(OBJEXT) revenge_dump_misc.$(OBJEXT) \ - revenge_main.$(OBJEXT) revenge_memory.$(OBJEXT) \ + revenge_dump.$(OBJEXT) revenge_dump_r600.$(OBJEXT) \ + revenge_dump_misc.$(OBJEXT) revenge_main.$(OBJEXT) \ + revenge_memory.$(OBJEXT) revenge_memory_r600.$(OBJEXT) \ revenge_register.$(OBJEXT) revenge_test.$(OBJEXT) revenge_OBJECTS = $(am_revenge_OBJECTS) revenge_LDADD = $(LDADD) @@ -247,12 +248,14 @@ revenge_SOURCES = \ revenge_detect.c \ revenge_detect.h \ revenge_dump.c \ + revenge_dump_r600.c \ revenge_dump.h \ revenge_dump_misc.c \ revenge_dump_misc.h \ revenge_main.c \ revenge_main.h \ revenge_memory.c \ + revenge_memory_r600.c \ revenge_memory.h \ revenge_register.c \ revenge_register.h \ @@ -371,8 +374,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_detect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_dump_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_dump_r600.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_memory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_memory_r600.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_register.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revenge_test.Po@am__quote@ diff --git a/src/revenge_detect.c b/src/revenge_detect.c index 02bec9b..046dfd7 100644 --- a/src/revenge_detect.c +++ b/src/revenge_detect.c @@ -32,13 +32,14 @@ unsigned int agp_addr = 0; unsigned int agp_len = 0; -unsigned int fb_addr = 0; -unsigned int fb_len = 0; +unsigned long fb_addr = 0; +unsigned long fb_len = 0; +unsigned long fb_addr_gpu = 0; -unsigned int pcigart_addr = 0; -unsigned int pcigart_end = 0; -unsigned int pcigart_len = 0; -unsigned int pcigart_start = 0; +unsigned long pcigart_addr = 0; +unsigned long pcigart_end = 0; +unsigned long pcigart_len = 0; +unsigned long pcigart_start = 0; char reg_device_name[BUFSIZ]; unsigned int reg_addr = 0; @@ -131,11 +132,29 @@ detect_fb_aperture (void) if (option_debug) { - printf ("%s: fb_addr = 0x%08x fb_len = 0x%08x\n", __func__, fb_addr, + printf ("%s: fb_addr = 0x%016lx fb_len = 0x%016lx\n", __func__, fb_addr, fb_len); } } +#define R600_MC_VM_FB_LOCATION 0x2180 +void detect_r600_fb_aperture (void) +{ + fb_addr_gpu = (register_read(R600_MC_VM_FB_LOCATION) & 0xffff) << 24; + if (option_debug) { + printf("%s: fb_addr = 0x%016lx fb_len = 0x%016lx\n", __func__, fb_addr, fb_len); + } +} + +#define EG_MC_VM_FB_LOCATION 0x2024 +void detect_evergreen_fb_aperture (void) +{ + fb_addr_gpu = (register_read(EG_MC_VM_FB_LOCATION) & 0xffff) << 24; + if (option_debug) { + printf("%s: fb_addr = 0x%016lx fb_len = 0x%016lx\n", __func__, fb_addr, fb_len); + } +} + void detect_pciegart_aperture (void) { @@ -147,7 +166,7 @@ detect_pciegart_aperture (void) if (option_debug) { printf - ("%s: pcigart_addr = 0x%08x pcigart_len = 0x%08x pcigart_start = 0x%08x pcigart_end = 0x%08x\n", + ("%s: pcigart_addr = 0x%016lx pcigart_len = 0x%016lx pcigart_start = 0x%016lx pcigart_end = 0x%016lx\n", __func__, pcigart_addr, pcigart_len, pcigart_start, pcigart_end); } } @@ -165,11 +184,30 @@ detect_rs690gart_aperture (void) if (option_debug) { printf - ("%s: pcigart_addr = 0x%08x pcigart_len = 0x%08x pcigart_start = 0x%08x pcigart_end = 0x%08x\n", + ("%s: pcigart_addr = 0x%016lx pcigart_len = 0x%016lx pcigart_start = 0x%016lx pcigart_end = 0x%016lx\n", __func__, pcigart_addr, pcigart_len, pcigart_start, pcigart_end); } } +#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 +#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 +#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15B4 + +void +detect_r600_aperture (void) +{ + pcigart_addr = register_read(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR) << 12; + pcigart_start = register_read(VM_CONTEXT0_PAGE_TABLE_START_ADDR) << 12; + pcigart_end = register_read(VM_CONTEXT0_PAGE_TABLE_END_ADDR) << 12; + pcigart_len = pcigart_end - pcigart_start; + pcigart_addr -= fb_addr_gpu; + + if (option_debug) { + printf("%s: pcigart_addr = 0x%016lx pcigart_len = 0x%016lx pcigart_start = 0x%016lx pcigart_end = 0x%016lx\n", + __func__, pcigart_addr, pcigart_len, pcigart_start, pcigart_end); + } +} + void detect_igpgart_aperture (void) { @@ -185,7 +223,7 @@ detect_igpgart_aperture (void) if (option_debug) { printf - ("%s: pcigart_addr = 0x%08x pcigart_len = 0x%08x pcigart_start = 0x%08x pcigart_end = 0x%08x\n", + ("%s: pcigart_addr = 0x%08lx pcigart_len = 0x%08lx pcigart_start = 0x%08lx pcigart_end = 0x%08lx\n", __func__, pcigart_addr, pcigart_len, pcigart_start, pcigart_end); } } @@ -247,6 +285,11 @@ detect_reg_aperture (void) get_conf_long (pci_config, PCI_BASE_ADDRESS_0 + (4 * i)); +fprintf(stderr, "[%d] 0x%lX %d\n", i, pdev->base_addr[i], pdev->size[i]); + if (pdev->size[i] > (4 * 1024 * 1024)) { + fb_addr = pdev->base_addr[i] & PCI_ADDR_MEM_MASK; + fb_len = pdev->size[i]; + } if (!(flag & PCI_BASE_ADDRESS_SPACE_IO)) { addr = pdev->base_addr[i] & PCI_ADDR_MEM_MASK; @@ -254,7 +297,7 @@ detect_reg_aperture (void) device_id = pdev->device_id; if (!(flag & PCI_BASE_ADDRESS_MEM_PREFETCH) - && len == 64 * 1024) + && len >= 64 * 1024 && i == 2) { reg_addr = (unsigned int) addr; reg_len = (unsigned int) len; diff --git a/src/revenge_detect.h b/src/revenge_detect.h index 31d71f9..831b957 100644 --- a/src/revenge_detect.h +++ b/src/revenge_detect.h @@ -25,12 +25,13 @@ extern unsigned int agp_addr; extern unsigned int agp_len; -extern unsigned int fb_addr; -extern unsigned int fb_len; -extern unsigned int pcigart_addr; -extern unsigned int pcigart_end; -extern unsigned int pcigart_len; -extern unsigned int pcigart_start; +extern unsigned long fb_addr; +extern unsigned long fb_len; +extern unsigned long fb_addr_gpu; +extern unsigned long pcigart_addr; +extern unsigned long pcigart_end; +extern unsigned long pcigart_len; +extern unsigned long pcigart_start; extern char reg_device_name[BUFSIZ]; extern unsigned int reg_addr; extern unsigned int reg_device_id; @@ -38,8 +39,11 @@ extern unsigned int reg_len; extern int gl_max_texture_units; void detect_agp_aperture (void); void detect_fb_aperture (void); +void detect_r600_fb_aperture (void); +void detect_evergreen_fb_aperture (void); void detect_pciegart_aperture (void); void detect_rs690gart_aperture (void); +void detect_r600_aperture (void); void detect_igpgart_aperture (void); void detect_reg_aperture (void); void detect_max_texture_units (void); diff --git a/src/revenge_dump.c b/src/revenge_dump.c index 853c14e..841e898 100644 --- a/src/revenge_dump.c +++ b/src/revenge_dump.c @@ -228,9 +228,16 @@ dump_ib (void) } } +void dump_r600_rb_pre(void); +void dump_r600_rb_post(void); + void dump_rb_pre (void) { + if (option_interface >= INTERFACE_R600) { + dump_r600_rb_pre(); + return; + } ib_num = 0; rb_addr = register_read (RADEON_CP_RB_BASE); rb_head = register_read (RADEON_CP_RB_RPTR); @@ -249,6 +256,10 @@ dump_rb_post (void) char buf[BUFSIZ]; unsigned int *rb_mem_map; + if (option_interface >= INTERFACE_R600) { + dump_r600_rb_post(); + return; + } rb_tail = register_read (RADEON_CP_RB_RPTR); if (option_debug) diff --git a/src/revenge_dump_r600.c b/src/revenge_dump_r600.c new file mode 100644 index 0000000..3061716 --- /dev/null +++ b/src/revenge_dump_r600.c @@ -0,0 +1,129 @@ +/* + * $Id$ + * Copyright (C) 2007 Oliver McFadden <omcfadde@gmail.com> + * Copyright (C) 2011 Red Hat + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <revenge_detect.h> +#include <revenge_main.h> +#include <revenge_memory.h> +#include <revenge_register.h> + +#define CP_RB_BASE 0xC100 +#define CP_RB_RPTR 0x8700 +#define CP_RB_WPTR 0xC114 +#define CP_RB_CNTL 0xC104 + +//static unsigned int ib_addr = 0, ib_size = 0; +static unsigned ib_num = 0; +static unsigned int rb_addr = 0, rb_head = 0, rb_size = 0, rb_tail = 0, rb_mask = 0; + +static void dump_ib(void); + +static void dump_packets(unsigned int head, + unsigned int tail, + unsigned int *mem_map, + char *name) +{ + FILE *file; + unsigned packet_type, packet_cnt; + unsigned i; + + if (!(file = fopen(name, "w"))) { + fprintf(stderr, "%s: %s:%d: %s\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno)); + exit(EXIT_FAILURE); + } + + while (head != tail) { + assert(mem_map[head]); + packet_type = (mem_map[head] >> 30) & 0x3; + packet_cnt = (mem_map[head] >> 16) & 0x3fff; + switch (packet_type) { + case 0: + fprintf(file, "PKT0 cnt %d\n", packet_cnt); + break; + case 2: + fprintf(file, "PKT2 cnt %d\n", packet_cnt); + packet_cnt = 0; + break; + case 3: + fprintf(file, "PKT3 cnt %d\n", packet_cnt); + break; + case 1: + default: + fprintf(stderr, "invalid packet type\n"); + exit(EXIT_FAILURE); + } + for (i = 0; i <= packet_cnt; i++) { + fprintf(file, "%08x\n", mem_map[(head + i) & rb_mask]); + } + head += packet_cnt + 1; + head &= rb_mask; + } + fclose(file); +} + +static void dump_ib(void) +{ +} + +void dump_r600_rb_pre(void) +{ + unsigned rb_bufsz; + + ib_num = 0; + rb_addr = register_read(CP_RB_BASE); + rb_head = register_read(CP_RB_RPTR); + rb_bufsz = register_read(CP_RB_CNTL) & 0x3f; + if (rb_bufsz < 2) { + rb_bufsz = 2; + } + if (rb_bufsz > 20) { + rb_bufsz = 20; + } + rb_size = (1 << rb_bufsz); + rb_mask = rb_size - 1; + + if (option_debug) { + printf("%s: rb_addr = 0x%08x rb_head = 0x%08x rb_size = 0x%08x\n", + __func__, rb_addr, rb_head, rb_size); + } +} + +void dump_r600_rb_post(void) +{ + char buf[BUFSIZ]; + unsigned int *rb_mem_map; + + rb_tail = register_read(CP_RB_RPTR); + + if (option_debug) { + printf("%s: rb_tail = 0x%08x (%d)\n", __func__, rb_tail, + rb_tail - rb_head); + } + + snprintf(buf, BUFSIZ, "rb.txt"); + rb_mem_map = memory_r600_read(rb_addr, rb_size << 2); + dump_packets(rb_head, rb_tail, rb_mem_map, buf); + free (rb_mem_map); +} diff --git a/src/revenge_main.c b/src/revenge_main.c index 06e8279..cde18f5 100644 --- a/src/revenge_main.c +++ b/src/revenge_main.c @@ -104,6 +104,8 @@ static struct option long_options[] = { {"pci", no_argument, &option_interface, INTERFACE_PCI}, {"pci-e", no_argument, &option_interface, INTERFACE_PCI_E}, {"rs690", no_argument, &option_interface, INTERFACE_RS690}, + {"r600", no_argument, &option_interface, INTERFACE_R600}, + {"evergreen", no_argument, &option_interface, INTERFACE_EVERGREEN}, {"verbose", no_argument, &option_verbose, 1}, {0, 0, 0, 0}, }; @@ -113,6 +115,7 @@ unsigned int *agp_mem_map = NULL; unsigned int *fb_mem_map = NULL; unsigned int *pcigart_mem_map = NULL; unsigned int *reg_mem_map = NULL; +uint64_t *pcigart_r600_mem_map = NULL; int main (int argc, char **argv) @@ -177,17 +180,38 @@ main (int argc, char **argv) __FILE__, __LINE__, strerror (errno)); exit (EXIT_FAILURE); } +fprintf(stderr, "%s %d\n", __func__, __LINE__); - detect_fb_aperture (); + switch (option_interface) { + case INTERFACE_AGP: + case INTERFACE_IGP: + case INTERFACE_PCI: + case INTERFACE_PCI_E: + case INTERFACE_RS690: + detect_fb_aperture (); + break; + case INTERFACE_R600: + detect_r600_fb_aperture (); + break; + case INTERFACE_EVERGREEN: + detect_evergreen_fb_aperture (); + break; + default: +fprintf(stderr, "%s %d\n", __func__, __LINE__); + assert (0); + break; + } +fprintf(stderr, "%s %d\n", __func__, __LINE__); if ((fb_mem_map = mmap (NULL, fb_len, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, fb_addr)) == MAP_FAILED) { - fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name, - __FILE__, __LINE__, strerror (errno)); + fprintf (stderr, "%s: %s:%d: %s 0x%lX 0x%lX\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno), fb_addr, fb_len); exit (EXIT_FAILURE); } +fprintf(stderr, "%s %d\n", __func__, __LINE__); switch (option_interface) { case INTERFACE_AGP: @@ -224,6 +248,11 @@ main (int argc, char **argv) exit (EXIT_FAILURE); } break; + case INTERFACE_EVERGREEN: + case INTERFACE_R600: + detect_r600_aperture(); + pcigart_r600_mem_map = (void *)(((char*)fb_mem_map) + pcigart_addr); + break; case INTERFACE_RS690: detect_rs690gart_aperture (); if ((pcigart_mem_map = @@ -239,10 +268,12 @@ main (int argc, char **argv) assert (0); break; } +fprintf(stderr, "%s %d\n", __func__, __LINE__); snprintf (buf, BUFSIZ, "%1$s-%2$s-%3$04x-%4$04x", PACKAGE_NAME, PACKAGE_VERSION, reg_device_id, revenge_rand); +fprintf(stderr, "%s %d\n", __func__, __LINE__); if (mkdir (buf, 0777) < 0) { if (errno != EEXIST) @@ -260,9 +291,13 @@ main (int argc, char **argv) exit (EXIT_FAILURE); } +fprintf(stderr, "%s %d\n", __func__, __LINE__); opengl_open (); +fprintf(stderr, "%s %d\n", __func__, __LINE__); test (); +fprintf(stderr, "%s %d\n", __func__, __LINE__); opengl_close (); +fprintf(stderr, "%s %d\n", __func__, __LINE__); if (munmap (reg_mem_map, reg_len) < 0) { @@ -303,6 +338,7 @@ main (int argc, char **argv) assert (0); break; } +fprintf(stderr, "%s %d\n", __func__, __LINE__); if (close (mem_fd) < 0) { @@ -310,6 +346,7 @@ main (int argc, char **argv) __FILE__, __LINE__, strerror (errno)); exit (EXIT_FAILURE); } +fprintf(stderr, "%s %d\n", __func__, __LINE__); if (chdir ("..") < 0) { @@ -317,6 +354,7 @@ main (int argc, char **argv) __FILE__, __LINE__, strerror (errno)); exit (EXIT_FAILURE); } +fprintf(stderr, "%s %d\n", __func__, __LINE__); snprintf (buf, BUFSIZ, "tar -cjf %1$s-%2$s-%3$04x-%4$04x.tar.bz2 %1$s-%2$s-%3$04x-%4$04x/", diff --git a/src/revenge_main.h b/src/revenge_main.h index f6b92a7..de3af6a 100644 --- a/src/revenge_main.h +++ b/src/revenge_main.h @@ -23,6 +23,7 @@ #include <stdio.h> #include <stdlib.h> +#include <stdint.h> /* {{{ */ @@ -145,6 +146,8 @@ enum interface_t INTERFACE_PCI, INTERFACE_PCI_E, INTERFACE_RS690, + INTERFACE_R600, + INTERFACE_EVERGREEN, }; extern int option_debug; @@ -156,6 +159,7 @@ extern int mem_fd; extern unsigned int *agp_mem_map; extern unsigned int *fb_mem_map; extern unsigned int *pcigart_mem_map; +extern uint64_t *pcigart_r600_mem_map; extern unsigned int *reg_mem_map; int main (int argc, char **argv); diff --git a/src/revenge_memory.h b/src/revenge_memory.h index c14dd54..79a4e48 100644 --- a/src/revenge_memory.h +++ b/src/revenge_memory.h @@ -24,5 +24,6 @@ #include <stdlib.h> void *memory_read (unsigned int addr, unsigned int size); +void *memory_r600_read(unsigned int addr, unsigned int size); #endif diff --git a/src/revenge_memory_r600.c b/src/revenge_memory_r600.c new file mode 100644 index 0000000..1196a1b --- /dev/null +++ b/src/revenge_memory_r600.c @@ -0,0 +1,136 @@ +/* + * $Id$ + * Copyright (C) 2007 Oliver McFadden <omcfadde@gmail.com> + * Copyright (C) 2011 Red Hat + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#include <revenge_detect.h> +#include <revenge_main.h> + +#define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1)) +#define round_down(x, y) ((x) & ~((y) - 1)) + +static unsigned long memory_virt_to_phys(unsigned long virt_addr) +{ + unsigned page_num; + unsigned long phys_addr; + + page_num = (virt_addr - pcigart_start) / ATI_PCIGART_PAGE_SIZE; + + switch (option_interface) { + case INTERFACE_EVERGREEN: + case INTERFACE_R600: + phys_addr = pcigart_r600_mem_map[page_num] & 0xFFFFFFFFFFFFF000ULL; + break; + case INTERFACE_PCI_E: + case INTERFACE_PCI: + case INTERFACE_IGP: + case INTERFACE_RS690: + default: + assert (0); + break; + } + + if (option_debug && option_verbose) { + printf("%s: virt_addr = 0x%016lx page_num = 0x%08x phys_addr = 0x%016lx\n", + __func__, virt_addr, page_num, phys_addr); + } + + return phys_addr; +} + +static void *memory_read_pcigart(unsigned int addr, unsigned int size) +{ + unsigned int addr_mod; + unsigned int buf_size; + unsigned int start_page_addr, end_page_addr; + void *dest; + void *mem_map, *mem_map_ptr; + void *page_mem_map; + + addr_mod = addr % ATI_PCIGART_PAGE_SIZE; + buf_size = round_up (addr_mod + size, ATI_PCIGART_PAGE_SIZE); + + start_page_addr = round_down (addr, ATI_PCIGART_PAGE_SIZE); + end_page_addr = start_page_addr + buf_size; + + if (!(mem_map = malloc(buf_size))) { + fprintf(stderr, "%s: %s:%d: %s\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno)); + exit(EXIT_FAILURE); + } + + if (option_debug && option_verbose) { + printf("%s: addr = 0x%08x size = 0x%08x start_page_addr = 0x%08x end_page_addr = 0x%08x\n", + __func__, addr, size, start_page_addr, end_page_addr); + } + + for (mem_map_ptr = mem_map; start_page_addr < end_page_addr; + start_page_addr += ATI_PCIGART_PAGE_SIZE, mem_map_ptr += ATI_PCIGART_PAGE_SIZE) { + if ((page_mem_map = mmap(NULL, ATI_PCIGART_PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, mem_fd, memory_virt_to_phys(start_page_addr))) == MAP_FAILED) { + fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno)); + exit (EXIT_FAILURE); + } + memcpy(mem_map_ptr, page_mem_map, ATI_PCIGART_PAGE_SIZE); + if (munmap (page_mem_map, ATI_PCIGART_PAGE_SIZE) < 0) { + fprintf(stderr, "%s: %s:%d: %s\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno)); + exit(EXIT_FAILURE); + } + } + + if (!(dest = malloc(size))) { + fprintf(stderr, "%s: %s:%d: %s\n", program_invocation_short_name, + __FILE__, __LINE__, strerror (errno)); + exit(EXIT_FAILURE); + } + memcpy (dest, mem_map + addr_mod, size); + free (mem_map); + + return dest; +} + +void *memory_r600_read(unsigned int addr, unsigned int size) +{ + void *mem_map; + + switch (option_interface) { + case INTERFACE_EVERGREEN: + case INTERFACE_R600: + mem_map = memory_read_pcigart(addr, size); + break; + case INTERFACE_PCI_E: + case INTERFACE_PCI: + case INTERFACE_AGP: + case INTERFACE_IGP: + case INTERFACE_RS690: + default: + assert (0); + break; + } + + return mem_map; +} |