diff options
Diffstat (limited to 'gtt.c')
-rw-r--r-- | gtt.c | 230 |
1 files changed, 230 insertions, 0 deletions
@@ -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; +} + + |