From 8f7ea34751886ca754e6246a9d400de18c6a972f Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 25 May 2012 16:56:26 -0700 Subject: tools/dpf: Tool to read and write l3 remap registers. Signed-off-by: Ben Widawsky --- tools/intel_l3_parity.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 tools/intel_l3_parity.c (limited to 'tools/intel_l3_parity.c') diff --git a/tools/intel_l3_parity.c b/tools/intel_l3_parity.c new file mode 100644 index 00000000..260c3d0c --- /dev/null +++ b/tools/intel_l3_parity.c @@ -0,0 +1,159 @@ +/* + * Copyright © 2012 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. + * + * Authors: + * Ben Widawsky + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include "intel_chipset.h" +#include "intel_gpu_tools.h" +#include "drmtest.h" + +#define NUM_BANKS 4 +#define NUM_SUBBANKS 8 +#define NUM_REGS (NUM_BANKS * NUM_SUBBANKS) + +struct __attribute__ ((__packed__)) l3_log_register { + uint32_t row0_enable : 1; + uint32_t rsvd2 : 4; + uint32_t row0 : 11; + uint32_t row1_enable : 1; + uint32_t rsvd1 : 4; + uint32_t row1 : 11; +} l3log[NUM_BANKS][NUM_SUBBANKS]; + +static void dumpit(void) +{ + int i, j; + + for (i = 0; i < NUM_BANKS; i++) { + for (j = 0; j < NUM_SUBBANKS; j++) { + struct l3_log_register *reg = &l3log[i][j]; + + if (reg->row0_enable) + printf("Row %d, Bank %d, Subbank %d is disabled\n", + reg->row0, i, j); + if (reg->row1_enable) + printf("Row %d, Bank %d, Subbank %d is disabled\n", + reg->row1, i, j); + } + } +} + +static int disable_rbs(int row, int bank, int sbank) +{ + struct l3_log_register *reg = &l3log[bank][sbank]; + + // can't map more than 2 rows + if (reg->row0_enable && reg->row1_enable) + return -1; + + // can't remap the same row twice + if ((reg->row0_enable && reg->row0 == row) || + (reg->row1_enable && reg->row1 == row)) { + return -1; + } + + if (reg->row0_enable) { + reg->row1 = row; + reg->row1_enable = 1; + } else { + reg->row0 = row; + reg->row0_enable = 1; + } + + return 0; +} + +static int do_parse(int argc, char *argv[]) +{ + int row, bank, sbank, i, ret; + + for (i = 1; i < argc; i++) { + ret = sscanf(argv[i], "%d,%d,%d", &row, &bank, &sbank); + if (ret != 3) + return i; + assert(disable_rbs(row, bank, sbank) == 0); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + const int device = drm_get_card(0); + char *path; + unsigned int devid; + int drm_fd, fd, ret; + + drm_fd = drm_open_any(); + devid = intel_get_drm_devid(drm_fd); + + ret = asprintf(&path, "/sys/class/drm/card%d/l3_parity", device); + assert(ret != -1); + + fd = open(path, O_RDWR); + if (fd == -1 && IS_IVYBRIDGE(devid)) { + perror("Opening sysfs"); + exit(EXIT_FAILURE); + } else if (fd == -1) + exit(EXIT_SUCCESS); + + ret = read(fd, l3log, NUM_REGS * sizeof(uint32_t)); + if (ret == -1) { + perror("Reading sysfs"); + exit(EXIT_FAILURE); + } + + assert(lseek(fd, 0, SEEK_SET) == 0); + + if (argc == 1) { + dumpit(); + exit(EXIT_SUCCESS); + } else if (!strncmp("-c", argv[1], 2)) { + memset(l3log, 0, sizeof(l3log)); + } else { + ret = do_parse(argc, argv); + if (ret != 0) { + fprintf(stderr, "Malformed command line at %s\n", argv[ret]); + exit(EXIT_FAILURE); + } + } + + ret = write(fd, l3log, NUM_REGS * sizeof(uint32_t)); + if (ret == -1) { + perror("Writing sysfs"); + exit(EXIT_FAILURE); + } + + close(fd); + + exit(EXIT_SUCCESS); +} -- cgit v1.2.3