Thanks. really odd, but if it was wrong you would probably already face other errors even more odd ;) So, all reviewed and merged up. On Fri, Oct 18, 2013 at 6:08 AM, Jani Nikula <jani.nikula@xxxxxxxxx> wrote: > On Thu, 17 Oct 2013, Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> wrote: >> On Tue, Oct 8, 2013 at 3:18 PM, Jani Nikula <jani.nikula@xxxxxxxxx> wrote: >>> Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> >>> --- >>> tools/Makefile.am | 1 + >>> tools/intel_opregion_decode.c | 438 +++++++++++++++++++++++++++++++++++++++++ >>> 2 files changed, 439 insertions(+) >>> create mode 100644 tools/intel_opregion_decode.c >>> >>> diff --git a/tools/Makefile.am b/tools/Makefile.am >>> index 19810cf..59fea97 100644 >>> --- a/tools/Makefile.am >>> +++ b/tools/Makefile.am >>> @@ -13,6 +13,7 @@ bin_PROGRAMS = \ >>> intel_gpu_top \ >>> intel_gpu_time \ >>> intel_gtt \ >>> + intel_opregion_decode \ >>> intel_perf_counters \ >>> intel_stepping \ >>> intel_reg_checker \ >>> diff --git a/tools/intel_opregion_decode.c b/tools/intel_opregion_decode.c >>> new file mode 100644 >>> index 0000000..e5f79df >>> --- /dev/null >>> +++ b/tools/intel_opregion_decode.c >>> @@ -0,0 +1,438 @@ >>> +/* >>> + * Copyright © 2013 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: >>> + * Jani Nikula <jani.nikula@xxxxxxxxx> >>> + * >>> + */ >>> + >>> +#include <errno.h> >>> +#include <fcntl.h> >>> +#include <getopt.h> >>> +#include <stdint.h> >>> +#include <stdio.h> >>> +#include <stdlib.h> >>> +#include <string.h> >>> +#include <unistd.h> >>> +#include <sys/mman.h> >>> +#include <sys/stat.h> >>> +#include <sys/types.h> >>> + >>> +#include "intel_gpu_tools.h" >>> + >>> +#define OPREGION_HEADER_OFFSET 0 >>> +#define OPREGION_ACPI_OFFSET 0x100 >>> +#define OPREGION_SWSCI_OFFSET 0x200 >>> +#define OPREGION_ASLE_OFFSET 0x300 >>> +#define OPREGION_VBT_OFFSET 0x400 >>> +#define OPREGION_ASLE_EXT_OFFSET 0x1C00 >>> + >>> +#define MBOX_ACPI (1 << 0) >>> +#define MBOX_SWSCI (1 << 1) >>> +#define MBOX_ASLE (1 << 2) >>> +#define MBOX_VBT (1 << 3) >>> +#define MBOX_ASLE_EXT (1 << 4) >>> + >>> +struct opregion_header { >>> + char sign[16]; >>> + uint32_t size; >>> + uint32_t over; >>> + char sver[32]; >>> + char vver[16]; >>> + char gver[16]; >>> + uint32_t mbox; >>> + uint32_t dmod; >>> + uint32_t pcon; >>> + char dver[32]; >>> + uint8_t rsv1[124]; >>> +} __attribute__((packed)); >>> + >>> +/* OpRegion mailbox #1: public ACPI methods */ >>> +struct opregion_acpi { >>> + uint32_t drdy; /* driver readiness */ >>> + uint32_t csts; /* notification status */ >>> + uint32_t cevt; /* current event */ >>> + uint8_t rsvd1[20]; >>> + uint32_t didl[8]; /* supported display devices ID list */ >>> + uint32_t cpdl[8]; /* currently presented display list */ >>> + uint32_t cadl[8]; /* currently active display list */ >>> + uint32_t nadl[8]; /* next active devices list */ >>> + uint32_t aslp; /* ASL sleep time-out */ >>> + uint32_t tidx; /* toggle table index */ >>> + uint32_t chpd; /* current hotplug enable indicator */ >>> + uint32_t clid; /* current lid state*/ >>> + uint32_t cdck; /* current docking state */ >>> + uint32_t sxsw; /* Sx state resume */ >>> + uint32_t evts; /* ASL supported events */ >>> + uint32_t cnot; /* current OS notification */ >>> + uint32_t nrdy; /* driver status */ >>> + uint32_t did2[7]; >>> + uint32_t cpd2[7]; >>> + uint8_t rsvd2[4]; >>> +} __attribute__((packed)); >>> + >>> +/* OpRegion mailbox #2: SWSCI */ >>> +struct opregion_swsci { >>> + uint32_t scic; /* SWSCI command|status|data */ >>> + uint32_t parm; /* command parameters */ >>> + uint32_t dslp; /* driver sleep time-out */ >>> + uint8_t rsvd[244]; >> >> spec that I have here (HSW one) says 240 reserved. >> >> with that fixed or explained I'll add my rv-b tag and merge all 6 >> patches (including bios reader ones that I already reviewed) upstream. > > Mine says 240 reserved too. But the beginning of chapter 3 says the size > of the whole mailbox is 256 bytes. Which equals 3 * 4 + 244. *shrug*. > > Jani. > > > >> >>> +} __attribute__((packed)); >>> + >>> +/* OpRegion mailbox #3: ASLE */ >>> +struct opregion_asle { >>> + uint32_t ardy; /* driver readiness */ >>> + uint32_t aslc; /* ASLE interrupt command */ >>> + uint32_t tche; /* technology enabled indicator */ >>> + uint32_t alsi; /* current ALS illuminance reading */ >>> + uint32_t bclp; /* backlight brightness to set */ >>> + uint32_t pfit; /* panel fitting state */ >>> + uint32_t cblv; /* current brightness level */ >>> + uint16_t bclm[20]; /* backlight level duty cycle mapping table */ >>> + uint32_t cpfm; /* current panel fitting mode */ >>> + uint32_t epfm; /* enabled panel fitting modes */ >>> + uint8_t plut_header; /* panel LUT and identifier */ >>> + uint8_t plut_identifier[10]; /* panel LUT and identifier */ >>> + uint8_t plut[63]; /* panel LUT and identifier */ >>> + uint32_t pfmb; /* PWM freq and min brightness */ >>> + uint32_t ccdv; >>> + uint32_t pcft; >>> + uint32_t srot; >>> + uint32_t iuer; >>> + uint8_t fdss[8]; >>> + uint32_t fdsp; >>> + uint32_t stat; >>> + uint8_t rsvd[86]; >>> +} __attribute__((packed)); >>> + >>> +/* OpRegion mailbox #4: VBT */ >>> +struct opregion_vbt { >>> + char product_string[20]; >>> + /* rest ignored */ >>> +} __attribute__((packed)); >>> + >>> +/* OpRegion mailbox #5: ASLE extension */ >>> +struct opregion_asle_ext { >>> + uint32_t phed; >>> + uint8_t bddc[256]; >>> +} __attribute__((packed)); >>> + >>> +static uint32_t decode_header(const void *buffer) >>> +{ >>> + const struct opregion_header *header = buffer; >>> + char *s; >>> + >>> + if (strncmp("IntelGraphicsMem", header->sign, sizeof(header->sign))) { >>> + fprintf(stderr, "invalid opregion signature\n"); >>> + return 0; >>> + } >>> + >>> + printf("OpRegion Header:\n"); >>> + >>> + s = strndup(header->sign, sizeof(header->sign)); >>> + printf("\tsign:\t%s\n", s); >>> + free(s); >>> + >>> + printf("\tsize:\t0x%08x\n", header->size); >>> + printf("\tover:\t0x%08x\n", header->over); >>> + >>> + s = strndup(header->sver, sizeof(header->sver)); >>> + printf("\tsver:\t%s\n", s); >>> + free(s); >>> + >>> + s = strndup(header->vver, sizeof(header->vver)); >>> + printf("\tvver:\t%s\n", s); >>> + free(s); >>> + >>> + s = strndup(header->gver, sizeof(header->gver)); >>> + printf("\tgver:\t%s\n", s); >>> + free(s); >>> + >>> + printf("\tmbox:\t0x%08x\n", header->mbox); >>> + >>> + printf("\tdmod:\t0x%08x\n", header->dmod); >>> + printf("\tpcon:\t0x%08x\n", header->pcon); >>> + >>> + s = strndup(header->dver, sizeof(header->dver)); >>> + printf("\tdver:\t%s\n", s); >>> + free(s); >>> + >>> + printf("\n"); >>> + >>> + return header->mbox; >>> +} >>> + >>> +static void decode_acpi(const void *buffer) >>> +{ >>> + const struct opregion_acpi *acpi = buffer; >>> + int i; >>> + >>> + printf("OpRegion Mailbox 1: Public ACPI Methods:\n"); >>> + >>> + printf("\tdrdy:\t0x%08x\n", acpi->drdy); >>> + printf("\tcsts:\t0x%08x\n", acpi->csts); >>> + printf("\tcevt:\t0x%08x\n", acpi->cevt); >>> + >>> + printf("\tdidl:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->didl); i++) >>> + printf("\t\tdidl[%d]:\t0x%08x\n", i, acpi->didl[i]); >>> + >>> + printf("\tcpdl:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->cpdl); i++) >>> + printf("\t\tcpdl[%d]:\t0x%08x\n", i, acpi->cpdl[i]); >>> + >>> + printf("\tcadl:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->cadl); i++) >>> + printf("\t\tcadl[%d]:\t0x%08x\n", i, acpi->cadl[i]); >>> + >>> + printf("\tnadl:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->nadl); i++) >>> + printf("\t\tnadl[%d]:\t0x%08x\n", i, acpi->nadl[i]); >>> + >>> + printf("\taslp:\t0x%08x\n", acpi->aslp); >>> + printf("\ttidx:\t0x%08x\n", acpi->tidx); >>> + printf("\tchpd:\t0x%08x\n", acpi->chpd); >>> + printf("\tclid:\t0x%08x\n", acpi->clid); >>> + printf("\tcdck:\t0x%08x\n", acpi->cdck); >>> + printf("\tsxsw:\t0x%08x\n", acpi->sxsw); >>> + printf("\tevts:\t0x%08x\n", acpi->evts); >>> + printf("\tcnot:\t0x%08x\n", acpi->cnot); >>> + printf("\tnrdy:\t0x%08x\n", acpi->nrdy); >>> + >>> + printf("\tdid2:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->did2); i++) >>> + printf("\t\tdid2[%d]:\t0x%08x\n", i, acpi->did2[i]); >>> + >>> + printf("\tcpd2:\n"); >>> + for (i = 0; i < ARRAY_SIZE(acpi->cpd2); i++) >>> + printf("\t\tcpd2[%d]:\t0x%08x\n", i, acpi->cpd2[i]); >>> + >>> + printf("\n"); >>> +} >>> + >>> +static void decode_swsci(const void *buffer) >>> +{ >>> + const struct opregion_swsci *swsci = buffer; >>> + >>> + printf("OpRegion Mailbox 2: Software SCI Interface (SWSCI):\n"); >>> + >>> + printf("\tscic:\t0x%08x\n", swsci->scic); >>> + printf("\tparm:\t0x%08x\n", swsci->parm); >>> + printf("\tdslp:\t0x%08x\n", swsci->dslp); >>> + >>> + printf("\n"); >>> +} >>> + >>> +static void decode_asle(const void *buffer) >>> +{ >>> + const struct opregion_asle *asle = buffer; >>> + int i; >>> + >>> + printf("OpRegion Mailbox 3: BIOS to Driver Notification (ASLE):\n"); >>> + >>> + printf("\tardy:\t0x%08x\n", asle->ardy); >>> + printf("\taslc:\t0x%08x\n", asle->aslc); >>> + printf("\ttche:\t0x%08x\n", asle->tche); >>> + printf("\talsi:\t0x%08x\n", asle->alsi); >>> + printf("\tbclp:\t0x%08x\n", asle->bclp); >>> + printf("\tpfit:\t0x%08x\n", asle->pfit); >>> + printf("\tcblv:\t0x%08x\n", asle->cblv); >>> + >>> + printf("\tbclm:\n"); >>> + for (i = 0; i < ARRAY_SIZE(asle->bclm); i++) >>> + printf("\t\tbclm[%d]:\t0x%04x\n", i, asle->bclm[i]); >>> + >>> + printf("\tcpfm:\t0x%08x\n", asle->cpfm); >>> + printf("\tepfm:\t0x%08x\n", asle->epfm); >>> + >>> + printf("\tplut header:\t0x%02x\n", asle->plut_header); >>> + >>> + printf("\tplut identifier:"); >>> + for (i = 0; i < ARRAY_SIZE(asle->plut_identifier); i++) >>> + printf(" %02x", asle->plut_identifier[i]); >>> + printf("\n"); >>> + >>> + printf("\tplut:\n"); >>> + for (i = 0; i < ARRAY_SIZE(asle->plut); i++) { >>> + const int COLUMNS = 7; >>> + >>> + if (i % COLUMNS == 0) >>> + printf("\t\tplut[%d]:\t", i / COLUMNS); >>> + >>> + printf("%02x ", asle->plut[i]); >>> + >>> + if (i % COLUMNS == COLUMNS - 1) >>> + printf("\n"); >>> + } >>> + >>> + printf("\tpfmb:\t0x%08x\n", asle->pfmb); >>> + printf("\tccdv:\t0x%08x\n", asle->ccdv); >>> + printf("\tpcft:\t0x%08x\n", asle->pcft); >>> + printf("\tsrot:\t0x%08x\n", asle->srot); >>> + printf("\tiuer:\t0x%08x\n", asle->iuer); >>> + >>> + printf("\tfdss:\t"); >>> + for (i = 0; i < ARRAY_SIZE(asle->fdss); i++) >>> + printf("%02x ", asle->fdss[i]); >>> + printf("\n"); >>> + >>> + printf("\tfdsp:\t0x%08x\n", asle->fdsp); >>> + printf("\tstat:\t0x%08x\n", asle->stat); >>> + >>> + printf("\n"); >>> +} >>> + >>> +static void decode_vbt(const void *buffer) >>> +{ >>> + const struct opregion_vbt *vbt = buffer; >>> + char *s; >>> + >>> + printf("OpRegion Mailbox 4: Video BIOS Table (VBT):\n"); >>> + >>> + s = strndup(vbt->product_string, sizeof(vbt->product_string)); >>> + printf("\tproduct string:\t%s\n", s); >>> + free(s); >>> + >>> + printf("\t(use intel_bios_reader to decode the VBT)\n"); >>> + >>> + printf("\n"); >>> +} >>> + >>> +static void decode_asle_ext(const void *buffer) >>> +{ >>> + const struct opregion_asle_ext *asle_ext = buffer; >>> + int i; >>> + >>> + printf("OpRegion Mailbox 5: BIOS to Driver Notification Extension:\n"); >>> + >>> + printf("\tphed:\t0x%08x\n", asle_ext->phed); >>> + >>> + printf("\tbddc:\n"); >>> + for (i = 0; i < ARRAY_SIZE(asle_ext->bddc); i++) { >>> + const int COLUMNS = 16; >>> + >>> + if (i % COLUMNS == 0) >>> + printf("\t\tbddc[0x%02x]:\t", i); >>> + >>> + printf("%02x ", asle_ext->bddc[i]); >>> + >>> + if (i % COLUMNS == COLUMNS - 1) >>> + printf("\n"); >>> + } >>> + >>> + printf("\n"); >>> +} >>> + >>> +static void decode_opregion(const uint8_t *opregion, int size) >>> +{ >>> + uint32_t mbox; >>> + >>> + /* XXX: allow decoding up to size */ >>> + if (OPREGION_ASLE_EXT_OFFSET + sizeof(struct opregion_asle_ext) > size) { >>> + fprintf(stderr, "buffer too small\n"); >>> + return; >>> + } >>> + >>> + mbox = decode_header(opregion + OPREGION_HEADER_OFFSET); >>> + if (mbox & MBOX_ACPI) >>> + decode_acpi(opregion + OPREGION_ACPI_OFFSET); >>> + if (mbox & MBOX_SWSCI) >>> + decode_swsci(opregion + OPREGION_SWSCI_OFFSET); >>> + if (mbox & MBOX_ASLE) >>> + decode_asle(opregion + OPREGION_ASLE_OFFSET); >>> + if (mbox & MBOX_VBT) >>> + decode_vbt(opregion + OPREGION_VBT_OFFSET); >>> + if (mbox & MBOX_ASLE_EXT) >>> + decode_asle_ext(opregion + OPREGION_ASLE_EXT_OFFSET); >>> +} >>> + >>> +int main(int argc, char *argv[]) >>> +{ >>> + const char *filename = "/sys/kernel/debug/dri/0/i915_opregion"; >>> + int fd; >>> + struct stat finfo; >>> + uint8_t *opregion; >>> + int c, option_index = 0; >>> + >>> + static struct option long_options[] = { >>> + { "file", required_argument, 0, 'f' }, >>> + { "help", no_argument, 0, 'h' }, >>> + { 0 }, >>> + }; >>> + >>> + while ((c = getopt_long(argc, argv, "hf:", >>> + long_options, &option_index)) != -1) { >>> + switch (c) { >>> + case 'h': >>> + printf("usage: intel_opregion_decode [-f|--file=<input>]\n"); >>> + return 0; >>> + case 'f': >>> + filename = optarg; >>> + break; >>> + default: >>> + fprintf(stderr, "unkown command options\n"); >>> + return 1; >>> + } >>> + } >>> + >>> + fd = open(filename, O_RDONLY); >>> + if (fd == -1) { >>> + printf("Couldn't open \"%s\": %s\n", filename, strerror(errno)); >>> + return 1; >>> + } >>> + >>> + if (stat(filename, &finfo)) { >>> + printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); >>> + return 1; >>> + } >>> + >>> + if (finfo.st_size == 0) { >>> + int len = 0, ret; >>> + finfo.st_size = 8192; >>> + opregion = malloc(finfo.st_size); >>> + while ((ret = read(fd, opregion + len, finfo.st_size - len))) { >>> + if (ret < 0) { >>> + printf("failed to read \"%s\": %s\n", filename, >>> + strerror(errno)); >>> + return 1; >>> + } >>> + >>> + len += ret; >>> + if (len == finfo.st_size) { >>> + finfo.st_size *= 2; >>> + opregion = realloc(opregion, finfo.st_size); >>> + } >>> + } >>> + } else { >>> + opregion = mmap(NULL, finfo.st_size, PROT_READ, MAP_SHARED, >>> + fd, 0); >>> + if (opregion == MAP_FAILED) { >>> + printf("failed to map \"%s\": %s\n", filename, >>> + strerror(errno)); >>> + return 1; >>> + } >>> + } >>> + >>> + decode_opregion(opregion, finfo.st_size); >>> + >>> + return 0; >>> +} >>> -- >>> 1.7.10.4 >>> >>> _______________________________________________ >>> Intel-gfx mailing list >>> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx >>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx >> >> Thanks >> >> -- >> Rodrigo Vivi >> Blog: http://blog.vivi.eng.br > > -- > Jani Nikula, Intel Open Source Technology Center -- Rodrigo Vivi Blog: http://blog.vivi.eng.br _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx