summaryrefslogtreecommitdiff
path: root/gtt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtt.c')
-rw-r--r--gtt.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/gtt.c b/gtt.c
new file mode 100644
index 0000000..c6ef9f9
--- /dev/null
+++ b/gtt.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include "main.h"
+#include "i915_reg.h"
+
+
+int process_dumpgtt(char *cmdhdr,unsigned int fbaddr,unsigned int size)
+{
+ uint32_t i,start_entry,end_entry,total_entries;
+ uint32_t aligned_size, entries = 0;
+ uint64_t *p, previous_entry=0;
+ //const char *type = "1:valid,2:WR,4:RO,8:cached";
+
+ if (fbaddr >= gtt_mapable_size) {
+ printf("Address 0x%x is out of GTT mappable range 0x%x\n",
+ fbaddr, gtt_mapable_size/4096);
+ return 0;
+ }
+
+ total_entries = gtt_mapable_size/4096;
+ start_entry = fbaddr/4096;
+ aligned_size = (size + 4095) & (~4095);
+ entries = aligned_size / 4096;
+ end_entry = min(start_entry + entries, total_entries);
+
+ fprintf(stdout,"\nGTT entry from entry %d to %d(total %d, size %d/%dK)\n",
+ start_entry,end_entry,end_entry - start_entry + 1,
+ size, size/1024);
+ fprintf(stdout,"\nSkip if the entry map to same address\n");
+
+ p =(uint64_t *)((char *)linear_gtt + 8*start_entry);
+ for (i=start_entry;i<end_entry;i++) {
+ uint64_t tmp = *p++;
+ uint32_t tmp1 = (uint32_t) tmp;
+ if (previous_entry == tmp)
+ continue;
+
+ previous_entry = tmp;
+ if (i%256==0)
+ printf("\n-----------------------------%03dM FB------------------------------\n",i/256);
+ fprintf(stdout,"FB:0x%07x|%03dM+%04dK|GTT offset:0x%05lx(entry 0x%05x):",
+ i*4096,i>>8,(i<<2)&0x3ff,(unsigned char *)p-linear_gtt-8, i);
+ fprintf(stdout," %010x", (uint32_t)tmp);
+ if (verbose)
+ fprintf(stdout," page no.=%06d(%04dM+%04dK),map type=0x%x",
+ (tmp1>>12),(tmp1>>20),(tmp1>>10)&0x3ff,tmp1&0xf);
+ fprintf(stdout,"\n");
+ }
+
+ return 0;
+}
+
+int process_stolen(char *cmdhdr)
+{
+ uint32_t stolen_phy_start = stolen_base;
+ uint32_t stolen_phy_end = stolen_base + stolen_size;
+ uint32_t i, start_i=~0, total_entry = gtt_size / 8;
+ uint64_t *p, previous_entry=0;
+
+ printf("Dump all stolen memory mappings in GTT\n");
+
+ p =(uint64_t *)linear_gtt;
+
+ for (i=0;i<total_entry;i++) {
+ uint64_t tmp = *p++;
+ uint32_t tmp1 = (uint32_t) tmp;
+
+ if (previous_entry == tmp)
+ continue;
+
+ previous_entry = tmp;
+ if (tmp1<stolen_phy_start || tmp1>stolen_phy_end)
+ continue;
+
+ if (i != start_i) {
+ printf("\n-----------------------------%03dM+%04dK FB------------------------------\n",
+ i>>8,(i<<2)&0x3ff);
+ start_i = i;
+ }
+ start_i++;
+
+ fprintf(stdout,"FB:0x%07x|%03dM+%04dK|GTT offset:0x%05lx(entry 0x%05x):",
+ i*4096,i>>8,(i<<2)&0x3ff,(unsigned char *)p-linear_gtt-8,i);
+ fprintf(stdout," %010x", (uint32_t)tmp);
+ if (verbose)
+ fprintf(stdout," page no.=%06d(%04dM+%04dK),map type=0x%x",
+ (tmp1>>12),(tmp1>>20),(tmp1>>10)&0x3ff,tmp1&0xf);
+ fprintf(stdout,"\n");
+ }
+
+ return 0;
+}
+
+static uint32_t old_lsb;
+static uint32_t old_msb;
+static int set_fence(unsigned int offset, unsigned int size)
+{
+ unsigned int force_stride = 5120;
+ unsigned int fence_idx = 0;
+ uint32_t fencereg_offset = 0x100000;
+
+ uint32_t lsb = (offset & 0xfffff000) | 1;
+ uint32_t msb = ((offset + size + 0xfff) & 0xfffff000) | (force_stride/128 -1);
+
+ old_lsb = INREG(linear_mmio, fence_idx*8 + fencereg_offset);
+ old_msb = INREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset);
+
+ printf("Force FENCE0 for linear access with stride %d\n", force_stride);
+ OUTREG(linear_mmio, fence_idx*8 + fencereg_offset, lsb);
+ OUTREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset, msb);
+
+ return 0;
+}
+
+static int unset_fence()
+{
+ uint32_t fencereg_offset = 0x100000;
+ int fence_idx = 0;
+
+ printf("Restore FENCE0\n");
+ OUTREG(linear_mmio, fence_idx*8 + fencereg_offset, old_lsb);
+ OUTREG(linear_mmio, (fence_idx*8 + 4) + fencereg_offset, old_msb);
+
+ return 0;
+}
+
+int process_fillfb(char *cmdhdr,unsigned int offset,
+ unsigned int size,unsigned int value)
+{
+ printf("Fill frame buffer from offset 0x%x (%dM+%dK),with value 0x%x,size %d\n",
+ offset,offset>>20, (offset>>10)&0x3ff,value,size);
+ if ((offset>>20) > FB_MMAP_MB) {
+ printf("!!!!!Sorry, Out of aperture mmap range %dM!!!!!\n", FB_MMAP_MB);
+ return 0;
+ }
+
+ memset((char *)(linear_fb+offset),value,size);
+
+ return 0;
+}
+
+int process_fillfbl(char *cmdhdr,unsigned int offset,
+ unsigned int size,unsigned int value)
+{
+ set_fence(offset, size);
+ process_fillfb(NULL, offset, size, value);
+ unset_fence();
+
+ return 0;
+}
+
+int process_dumpfb(char *cmdhdr,unsigned int offset,
+ unsigned int size)
+{
+ unsigned int i;
+
+ printf("Dump frame buffer from offset 0x%x,size %d\n",offset,size);
+ for (i=0;i<size;i++) {
+ if ((i%8) == 0) {
+ printf("\n0x%08x: ",offset+i);
+ }
+ printf("0x%02x ",*((unsigned char *)(linear_fb+offset+i)));
+ }
+ printf("\n");
+
+ return 0;
+}
+
+int process_dumpfbl(char *cmdhdr,unsigned int offset,
+ unsigned int size)
+{
+ set_fence(offset, size);
+ process_dumpfb(NULL, offset, size);
+ unset_fence();
+
+ return 0;
+}
+
+int process_fence(char *cmdhdr)
+{
+ printf("Dump all fence register information\n");
+ uint32_t i, fence_offset = 0x100000;
+
+ for (i=0;i<16;i++) {
+ uint32_t lsb = INREG(linear_mmio, i*8 + fence_offset);
+ uint32_t msb = INREG(linear_mmio, (i*8 + 4) + fence_offset);
+ uint32_t addr = lsb&(~0xfff);
+
+ fprintf(stdout,"FENCDE%d_LSB:0x%08x (valid:%d, tile:%c, start addr:0x%08x(%dM+%dK))\n",
+ i, lsb, lsb&1, (lsb>>1)&1?'Y':'X',
+ addr, addr>>20, (addr>>10)&0x3ff);
+
+ addr = msb&(~0xfff);
+ fprintf(stdout,"FENCDE%d_MSB:0x%08x (pitch=%d,size=%dK,end addr:0x%08x(%dM+%dK))\n",
+ i, msb, ((msb&0x7ff) + 1) * 128, ((msb&(~0xfff)) - (lsb&(~0xfff))) >> 10 ,
+ addr, addr>>20, (addr>>10)&0x3ff);
+ printf("\n");
+ }
+
+ return 0;
+}
+
+