xref: /aosp_15_r20/external/igt-gpu-tools/tools/intel_opregion_decode.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*d83cc019SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  * Authors:
24*d83cc019SAndroid Build Coastguard Worker  *    Jani Nikula <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  *
26*d83cc019SAndroid Build Coastguard Worker  */
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
29*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
30*d83cc019SAndroid Build Coastguard Worker #include <getopt.h>
31*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
32*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
33*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
34*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
35*d83cc019SAndroid Build Coastguard Worker #include <string.h>
36*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
39*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
40*d83cc019SAndroid Build Coastguard Worker 
41*d83cc019SAndroid Build Coastguard Worker #include "intel_io.h"
42*d83cc019SAndroid Build Coastguard Worker #include "drmtest.h"
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker #define OPREGION_HEADER_OFFSET		0
45*d83cc019SAndroid Build Coastguard Worker #define OPREGION_ACPI_OFFSET		0x100
46*d83cc019SAndroid Build Coastguard Worker #define OPREGION_SWSCI_OFFSET		0x200
47*d83cc019SAndroid Build Coastguard Worker #define OPREGION_ASLE_OFFSET		0x300
48*d83cc019SAndroid Build Coastguard Worker #define OPREGION_VBT_OFFSET		0x400
49*d83cc019SAndroid Build Coastguard Worker #define OPREGION_ASLE_EXT_OFFSET	0x1C00
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker #define MBOX_ACPI	(1 << 0)
52*d83cc019SAndroid Build Coastguard Worker #define MBOX_SWSCI	(1 << 1)
53*d83cc019SAndroid Build Coastguard Worker #define MBOX_ASLE	(1 << 2)
54*d83cc019SAndroid Build Coastguard Worker #define MBOX_VBT	(1 << 3)
55*d83cc019SAndroid Build Coastguard Worker #define MBOX_ASLE_EXT	(1 << 4)
56*d83cc019SAndroid Build Coastguard Worker 
57*d83cc019SAndroid Build Coastguard Worker struct opregion_header {
58*d83cc019SAndroid Build Coastguard Worker 	char sign[16];
59*d83cc019SAndroid Build Coastguard Worker 	uint32_t size;
60*d83cc019SAndroid Build Coastguard Worker 	uint32_t over;
61*d83cc019SAndroid Build Coastguard Worker 	char sver[32];
62*d83cc019SAndroid Build Coastguard Worker 	char vver[16];
63*d83cc019SAndroid Build Coastguard Worker 	char gver[16];
64*d83cc019SAndroid Build Coastguard Worker 	uint32_t mbox;
65*d83cc019SAndroid Build Coastguard Worker 	uint32_t dmod;
66*d83cc019SAndroid Build Coastguard Worker 	uint32_t pcon;
67*d83cc019SAndroid Build Coastguard Worker 	char dver[32];
68*d83cc019SAndroid Build Coastguard Worker 	uint8_t rsv1[124];
69*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker /* OpRegion mailbox #1: public ACPI methods */
72*d83cc019SAndroid Build Coastguard Worker struct opregion_acpi {
73*d83cc019SAndroid Build Coastguard Worker 	uint32_t drdy;		/* driver readiness */
74*d83cc019SAndroid Build Coastguard Worker 	uint32_t csts;		/* notification status */
75*d83cc019SAndroid Build Coastguard Worker 	uint32_t cevt;		/* current event */
76*d83cc019SAndroid Build Coastguard Worker 	uint8_t rsvd1[20];
77*d83cc019SAndroid Build Coastguard Worker 	uint32_t didl[8];	/* supported display devices ID list */
78*d83cc019SAndroid Build Coastguard Worker 	uint32_t cpdl[8];	/* currently presented display list */
79*d83cc019SAndroid Build Coastguard Worker 	uint32_t cadl[8];	/* currently active display list */
80*d83cc019SAndroid Build Coastguard Worker 	uint32_t nadl[8];	/* next active devices list */
81*d83cc019SAndroid Build Coastguard Worker 	uint32_t aslp;		/* ASL sleep time-out */
82*d83cc019SAndroid Build Coastguard Worker 	uint32_t tidx;		/* toggle table index */
83*d83cc019SAndroid Build Coastguard Worker 	uint32_t chpd;		/* current hotplug enable indicator */
84*d83cc019SAndroid Build Coastguard Worker 	uint32_t clid;		/* current lid state*/
85*d83cc019SAndroid Build Coastguard Worker 	uint32_t cdck;		/* current docking state */
86*d83cc019SAndroid Build Coastguard Worker 	uint32_t sxsw;		/* Sx state resume */
87*d83cc019SAndroid Build Coastguard Worker 	uint32_t evts;		/* ASL supported events */
88*d83cc019SAndroid Build Coastguard Worker 	uint32_t cnot;		/* current OS notification */
89*d83cc019SAndroid Build Coastguard Worker 	uint32_t nrdy;		/* driver status */
90*d83cc019SAndroid Build Coastguard Worker 	uint32_t did2[7];
91*d83cc019SAndroid Build Coastguard Worker 	uint32_t cpd2[7];
92*d83cc019SAndroid Build Coastguard Worker 	uint8_t rsvd2[4];
93*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker /* OpRegion mailbox #2: SWSCI */
96*d83cc019SAndroid Build Coastguard Worker struct opregion_swsci {
97*d83cc019SAndroid Build Coastguard Worker 	uint32_t scic;		/* SWSCI command|status|data */
98*d83cc019SAndroid Build Coastguard Worker 	uint32_t parm;		/* command parameters */
99*d83cc019SAndroid Build Coastguard Worker 	uint32_t dslp;		/* driver sleep time-out */
100*d83cc019SAndroid Build Coastguard Worker 	uint8_t rsvd[244];
101*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
102*d83cc019SAndroid Build Coastguard Worker 
103*d83cc019SAndroid Build Coastguard Worker /* OpRegion mailbox #3: ASLE */
104*d83cc019SAndroid Build Coastguard Worker struct opregion_asle {
105*d83cc019SAndroid Build Coastguard Worker 	uint32_t ardy;		/* driver readiness */
106*d83cc019SAndroid Build Coastguard Worker 	uint32_t aslc;		/* ASLE interrupt command */
107*d83cc019SAndroid Build Coastguard Worker 	uint32_t tche;		/* technology enabled indicator */
108*d83cc019SAndroid Build Coastguard Worker 	uint32_t alsi;		/* current ALS illuminance reading */
109*d83cc019SAndroid Build Coastguard Worker 	uint32_t bclp;		/* backlight brightness to set */
110*d83cc019SAndroid Build Coastguard Worker 	uint32_t pfit;		/* panel fitting state */
111*d83cc019SAndroid Build Coastguard Worker 	uint32_t cblv;		/* current brightness level */
112*d83cc019SAndroid Build Coastguard Worker 	uint16_t bclm[20];	/* backlight level duty cycle mapping table */
113*d83cc019SAndroid Build Coastguard Worker 	uint32_t cpfm;		/* current panel fitting mode */
114*d83cc019SAndroid Build Coastguard Worker 	uint32_t epfm;		/* enabled panel fitting modes */
115*d83cc019SAndroid Build Coastguard Worker 	uint8_t plut_header;    /* panel LUT and identifier */
116*d83cc019SAndroid Build Coastguard Worker 	uint8_t plut_identifier[10];	/* panel LUT and identifier */
117*d83cc019SAndroid Build Coastguard Worker 	uint8_t plut[63];	/* panel LUT and identifier */
118*d83cc019SAndroid Build Coastguard Worker 	uint32_t pfmb;		/* PWM freq and min brightness */
119*d83cc019SAndroid Build Coastguard Worker 	uint32_t ccdv;
120*d83cc019SAndroid Build Coastguard Worker 	uint32_t pcft;
121*d83cc019SAndroid Build Coastguard Worker 	uint32_t srot;
122*d83cc019SAndroid Build Coastguard Worker 	uint32_t iuer;
123*d83cc019SAndroid Build Coastguard Worker 	uint8_t fdss[8];
124*d83cc019SAndroid Build Coastguard Worker 	uint32_t fdsp;
125*d83cc019SAndroid Build Coastguard Worker 	uint32_t stat;
126*d83cc019SAndroid Build Coastguard Worker 	uint64_t rvda;		/* Physical address of raw vbt data */
127*d83cc019SAndroid Build Coastguard Worker 	uint32_t rvds;		/* Size of raw vbt data */
128*d83cc019SAndroid Build Coastguard Worker 	uint8_t rsvd[58];
129*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker /* OpRegion mailbox #4: VBT */
132*d83cc019SAndroid Build Coastguard Worker struct opregion_vbt {
133*d83cc019SAndroid Build Coastguard Worker 	char product_string[20];
134*d83cc019SAndroid Build Coastguard Worker 	/* rest ignored */
135*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
136*d83cc019SAndroid Build Coastguard Worker 
137*d83cc019SAndroid Build Coastguard Worker /* OpRegion mailbox #5: ASLE extension */
138*d83cc019SAndroid Build Coastguard Worker struct opregion_asle_ext {
139*d83cc019SAndroid Build Coastguard Worker 	uint32_t phed;
140*d83cc019SAndroid Build Coastguard Worker 	uint8_t bddc[256];
141*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
142*d83cc019SAndroid Build Coastguard Worker 
decode_header(const void * buffer)143*d83cc019SAndroid Build Coastguard Worker static uint32_t decode_header(const void *buffer)
144*d83cc019SAndroid Build Coastguard Worker {
145*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_header *header = buffer;
146*d83cc019SAndroid Build Coastguard Worker 	char *s;
147*d83cc019SAndroid Build Coastguard Worker 
148*d83cc019SAndroid Build Coastguard Worker 	if (strncmp("IntelGraphicsMem", header->sign, sizeof(header->sign))) {
149*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "invalid opregion signature\n");
150*d83cc019SAndroid Build Coastguard Worker 		return 0;
151*d83cc019SAndroid Build Coastguard Worker 	}
152*d83cc019SAndroid Build Coastguard Worker 
153*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Header:\n");
154*d83cc019SAndroid Build Coastguard Worker 
155*d83cc019SAndroid Build Coastguard Worker 	s = strndup(header->sign, sizeof(header->sign));
156*d83cc019SAndroid Build Coastguard Worker 	printf("\tsign:\t%s\n", s);
157*d83cc019SAndroid Build Coastguard Worker 	free(s);
158*d83cc019SAndroid Build Coastguard Worker 
159*d83cc019SAndroid Build Coastguard Worker 	printf("\tsize:\t0x%08x\n", header->size);
160*d83cc019SAndroid Build Coastguard Worker 	printf("\tover:\t0x%08x\n", header->over);
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	s = strndup(header->sver, sizeof(header->sver));
163*d83cc019SAndroid Build Coastguard Worker 	printf("\tsver:\t%s\n", s);
164*d83cc019SAndroid Build Coastguard Worker 	free(s);
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	s = strndup(header->vver, sizeof(header->vver));
167*d83cc019SAndroid Build Coastguard Worker 	printf("\tvver:\t%s\n", s);
168*d83cc019SAndroid Build Coastguard Worker 	free(s);
169*d83cc019SAndroid Build Coastguard Worker 
170*d83cc019SAndroid Build Coastguard Worker 	s = strndup(header->gver, sizeof(header->gver));
171*d83cc019SAndroid Build Coastguard Worker 	printf("\tgver:\t%s\n", s);
172*d83cc019SAndroid Build Coastguard Worker 	free(s);
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	printf("\tmbox:\t0x%08x\n", header->mbox);
175*d83cc019SAndroid Build Coastguard Worker 
176*d83cc019SAndroid Build Coastguard Worker 	printf("\tdmod:\t0x%08x\n", header->dmod);
177*d83cc019SAndroid Build Coastguard Worker 	printf("\tpcon:\t0x%08x\n", header->pcon);
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	s = strndup(header->dver, sizeof(header->dver));
180*d83cc019SAndroid Build Coastguard Worker 	printf("\tdver:\t%s\n", s);
181*d83cc019SAndroid Build Coastguard Worker 	free(s);
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
184*d83cc019SAndroid Build Coastguard Worker 
185*d83cc019SAndroid Build Coastguard Worker 	return header->mbox;
186*d83cc019SAndroid Build Coastguard Worker }
187*d83cc019SAndroid Build Coastguard Worker 
decode_acpi(const void * buffer)188*d83cc019SAndroid Build Coastguard Worker static void decode_acpi(const void *buffer)
189*d83cc019SAndroid Build Coastguard Worker {
190*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_acpi *acpi = buffer;
191*d83cc019SAndroid Build Coastguard Worker 	int i;
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Mailbox 1: Public ACPI Methods:\n");
194*d83cc019SAndroid Build Coastguard Worker 
195*d83cc019SAndroid Build Coastguard Worker 	printf("\tdrdy:\t0x%08x\n", acpi->drdy);
196*d83cc019SAndroid Build Coastguard Worker 	printf("\tcsts:\t0x%08x\n", acpi->csts);
197*d83cc019SAndroid Build Coastguard Worker 	printf("\tcevt:\t0x%08x\n", acpi->cevt);
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker 	printf("\tdidl:\n");
200*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->didl); i++)
201*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tdidl[%d]:\t0x%08x\n", i, acpi->didl[i]);
202*d83cc019SAndroid Build Coastguard Worker 
203*d83cc019SAndroid Build Coastguard Worker 	printf("\tcpdl:\n");
204*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->cpdl); i++)
205*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tcpdl[%d]:\t0x%08x\n", i, acpi->cpdl[i]);
206*d83cc019SAndroid Build Coastguard Worker 
207*d83cc019SAndroid Build Coastguard Worker 	printf("\tcadl:\n");
208*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->cadl); i++)
209*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tcadl[%d]:\t0x%08x\n", i, acpi->cadl[i]);
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	printf("\tnadl:\n");
212*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->nadl); i++)
213*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tnadl[%d]:\t0x%08x\n", i, acpi->nadl[i]);
214*d83cc019SAndroid Build Coastguard Worker 
215*d83cc019SAndroid Build Coastguard Worker 	printf("\taslp:\t0x%08x\n", acpi->aslp);
216*d83cc019SAndroid Build Coastguard Worker 	printf("\ttidx:\t0x%08x\n", acpi->tidx);
217*d83cc019SAndroid Build Coastguard Worker 	printf("\tchpd:\t0x%08x\n", acpi->chpd);
218*d83cc019SAndroid Build Coastguard Worker 	printf("\tclid:\t0x%08x\n", acpi->clid);
219*d83cc019SAndroid Build Coastguard Worker 	printf("\tcdck:\t0x%08x\n", acpi->cdck);
220*d83cc019SAndroid Build Coastguard Worker 	printf("\tsxsw:\t0x%08x\n", acpi->sxsw);
221*d83cc019SAndroid Build Coastguard Worker 	printf("\tevts:\t0x%08x\n", acpi->evts);
222*d83cc019SAndroid Build Coastguard Worker 	printf("\tcnot:\t0x%08x\n", acpi->cnot);
223*d83cc019SAndroid Build Coastguard Worker 	printf("\tnrdy:\t0x%08x\n", acpi->nrdy);
224*d83cc019SAndroid Build Coastguard Worker 
225*d83cc019SAndroid Build Coastguard Worker 	printf("\tdid2:\n");
226*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->did2); i++)
227*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tdid2[%d]:\t0x%08x\n", i, acpi->did2[i]);
228*d83cc019SAndroid Build Coastguard Worker 
229*d83cc019SAndroid Build Coastguard Worker 	printf("\tcpd2:\n");
230*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(acpi->cpd2); i++)
231*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tcpd2[%d]:\t0x%08x\n", i, acpi->cpd2[i]);
232*d83cc019SAndroid Build Coastguard Worker 
233*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
234*d83cc019SAndroid Build Coastguard Worker }
235*d83cc019SAndroid Build Coastguard Worker 
decode_swsci(const void * buffer)236*d83cc019SAndroid Build Coastguard Worker static void decode_swsci(const void *buffer)
237*d83cc019SAndroid Build Coastguard Worker {
238*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_swsci *swsci = buffer;
239*d83cc019SAndroid Build Coastguard Worker 
240*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Mailbox 2: Software SCI Interface (SWSCI):\n");
241*d83cc019SAndroid Build Coastguard Worker 
242*d83cc019SAndroid Build Coastguard Worker 	printf("\tscic:\t0x%08x\n", swsci->scic);
243*d83cc019SAndroid Build Coastguard Worker 	printf("\tparm:\t0x%08x\n", swsci->parm);
244*d83cc019SAndroid Build Coastguard Worker 	printf("\tdslp:\t0x%08x\n", swsci->dslp);
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
247*d83cc019SAndroid Build Coastguard Worker }
248*d83cc019SAndroid Build Coastguard Worker 
decode_asle(const void * buffer)249*d83cc019SAndroid Build Coastguard Worker static void decode_asle(const void *buffer)
250*d83cc019SAndroid Build Coastguard Worker {
251*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_asle *asle = buffer;
252*d83cc019SAndroid Build Coastguard Worker 	int i;
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Mailbox 3: BIOS to Driver Notification (ASLE):\n");
255*d83cc019SAndroid Build Coastguard Worker 
256*d83cc019SAndroid Build Coastguard Worker 	printf("\tardy:\t0x%08x\n", asle->ardy);
257*d83cc019SAndroid Build Coastguard Worker 	printf("\taslc:\t0x%08x\n", asle->aslc);
258*d83cc019SAndroid Build Coastguard Worker 	printf("\ttche:\t0x%08x\n", asle->tche);
259*d83cc019SAndroid Build Coastguard Worker 	printf("\talsi:\t0x%08x\n", asle->alsi);
260*d83cc019SAndroid Build Coastguard Worker 	printf("\tbclp:\t0x%08x\n", asle->bclp);
261*d83cc019SAndroid Build Coastguard Worker 	printf("\tpfit:\t0x%08x\n", asle->pfit);
262*d83cc019SAndroid Build Coastguard Worker 	printf("\tcblv:\t0x%08x\n", asle->cblv);
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 	printf("\tbclm:\n");
265*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(asle->bclm); i++) {
266*d83cc019SAndroid Build Coastguard Worker 		int valid = asle->bclm[i] & (1 << 15);
267*d83cc019SAndroid Build Coastguard Worker 		int percentage = (asle->bclm[i] & 0x7f00) >> 8;
268*d83cc019SAndroid Build Coastguard Worker 		int duty_cycle = asle->bclm[i] & 0xff;
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker 		printf("\t\tbclm[%d]:\t0x%04x", i, asle->bclm[i]);
271*d83cc019SAndroid Build Coastguard Worker 		if (valid)
272*d83cc019SAndroid Build Coastguard Worker 			printf(" (%3d%% -> 0x%02x)\n", percentage, duty_cycle);
273*d83cc019SAndroid Build Coastguard Worker 		else
274*d83cc019SAndroid Build Coastguard Worker 			printf("\n");
275*d83cc019SAndroid Build Coastguard Worker 
276*d83cc019SAndroid Build Coastguard Worker 	}
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker 	printf("\tcpfm:\t0x%08x\n", asle->cpfm);
279*d83cc019SAndroid Build Coastguard Worker 	printf("\tepfm:\t0x%08x\n", asle->epfm);
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker 	printf("\tplut header:\t0x%02x\n", asle->plut_header);
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	printf("\tplut identifier:");
284*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(asle->plut_identifier); i++)
285*d83cc019SAndroid Build Coastguard Worker 		printf(" %02x", asle->plut_identifier[i]);
286*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 	printf("\tplut:\n");
289*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(asle->plut); i++) {
290*d83cc019SAndroid Build Coastguard Worker 		const int COLUMNS = 7;
291*d83cc019SAndroid Build Coastguard Worker 
292*d83cc019SAndroid Build Coastguard Worker 		if (i % COLUMNS == 0)
293*d83cc019SAndroid Build Coastguard Worker 			printf("\t\tplut[%d]:\t", i / COLUMNS);
294*d83cc019SAndroid Build Coastguard Worker 
295*d83cc019SAndroid Build Coastguard Worker 		printf("%02x ", asle->plut[i]);
296*d83cc019SAndroid Build Coastguard Worker 
297*d83cc019SAndroid Build Coastguard Worker 		if (i % COLUMNS == COLUMNS - 1)
298*d83cc019SAndroid Build Coastguard Worker 			printf("\n");
299*d83cc019SAndroid Build Coastguard Worker 	}
300*d83cc019SAndroid Build Coastguard Worker 
301*d83cc019SAndroid Build Coastguard Worker 	printf("\tpfmb:\t0x%08x\n", asle->pfmb);
302*d83cc019SAndroid Build Coastguard Worker 	printf("\tccdv:\t0x%08x\n", asle->ccdv);
303*d83cc019SAndroid Build Coastguard Worker 	printf("\tpcft:\t0x%08x\n", asle->pcft);
304*d83cc019SAndroid Build Coastguard Worker 	printf("\tsrot:\t0x%08x\n", asle->srot);
305*d83cc019SAndroid Build Coastguard Worker 	printf("\tiuer:\t0x%08x\n", asle->iuer);
306*d83cc019SAndroid Build Coastguard Worker 
307*d83cc019SAndroid Build Coastguard Worker 	printf("\tfdss:\t");
308*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(asle->fdss); i++)
309*d83cc019SAndroid Build Coastguard Worker 		printf("%02x ", asle->fdss[i]);
310*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	printf("\tfdsp:\t0x%08x\n", asle->fdsp);
313*d83cc019SAndroid Build Coastguard Worker 	printf("\tstat:\t0x%08x\n", asle->stat);
314*d83cc019SAndroid Build Coastguard Worker 	printf("\trvda:\t0x%016"PRIx64"\n", asle->rvda);
315*d83cc019SAndroid Build Coastguard Worker 	printf("\trvds:\t0x%08x\n", asle->rvds);
316*d83cc019SAndroid Build Coastguard Worker 
317*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
318*d83cc019SAndroid Build Coastguard Worker }
319*d83cc019SAndroid Build Coastguard Worker 
decode_vbt(const void * buffer)320*d83cc019SAndroid Build Coastguard Worker static void decode_vbt(const void *buffer)
321*d83cc019SAndroid Build Coastguard Worker {
322*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_vbt *vbt = buffer;
323*d83cc019SAndroid Build Coastguard Worker 	char *s;
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Mailbox 4: Video BIOS Table (VBT):\n");
326*d83cc019SAndroid Build Coastguard Worker 
327*d83cc019SAndroid Build Coastguard Worker 	s = strndup(vbt->product_string, sizeof(vbt->product_string));
328*d83cc019SAndroid Build Coastguard Worker 	printf("\tproduct string:\t%s\n", s);
329*d83cc019SAndroid Build Coastguard Worker 	free(s);
330*d83cc019SAndroid Build Coastguard Worker 
331*d83cc019SAndroid Build Coastguard Worker 	printf("\t(use intel_vbt_decode to decode the VBT)\n");
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
334*d83cc019SAndroid Build Coastguard Worker }
335*d83cc019SAndroid Build Coastguard Worker 
decode_asle_ext(const void * buffer)336*d83cc019SAndroid Build Coastguard Worker static void decode_asle_ext(const void *buffer)
337*d83cc019SAndroid Build Coastguard Worker {
338*d83cc019SAndroid Build Coastguard Worker 	const struct opregion_asle_ext *asle_ext = buffer;
339*d83cc019SAndroid Build Coastguard Worker 	int i;
340*d83cc019SAndroid Build Coastguard Worker 
341*d83cc019SAndroid Build Coastguard Worker 	printf("OpRegion Mailbox 5: BIOS to Driver Notification Extension:\n");
342*d83cc019SAndroid Build Coastguard Worker 
343*d83cc019SAndroid Build Coastguard Worker 	printf("\tphed:\t0x%08x\n", asle_ext->phed);
344*d83cc019SAndroid Build Coastguard Worker 
345*d83cc019SAndroid Build Coastguard Worker 	printf("\tbddc:\n");
346*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(asle_ext->bddc); i++) {
347*d83cc019SAndroid Build Coastguard Worker 		const int COLUMNS = 16;
348*d83cc019SAndroid Build Coastguard Worker 
349*d83cc019SAndroid Build Coastguard Worker 		if (i % COLUMNS == 0)
350*d83cc019SAndroid Build Coastguard Worker 			printf("\t\tbddc[0x%02x]:\t", i);
351*d83cc019SAndroid Build Coastguard Worker 
352*d83cc019SAndroid Build Coastguard Worker 		printf("%02x ", asle_ext->bddc[i]);
353*d83cc019SAndroid Build Coastguard Worker 
354*d83cc019SAndroid Build Coastguard Worker 		if (i % COLUMNS == COLUMNS - 1)
355*d83cc019SAndroid Build Coastguard Worker 			printf("\n");
356*d83cc019SAndroid Build Coastguard Worker 	}
357*d83cc019SAndroid Build Coastguard Worker 
358*d83cc019SAndroid Build Coastguard Worker 	printf("\n");
359*d83cc019SAndroid Build Coastguard Worker }
360*d83cc019SAndroid Build Coastguard Worker 
decode_opregion(const uint8_t * opregion,int size)361*d83cc019SAndroid Build Coastguard Worker static void decode_opregion(const uint8_t *opregion, int size)
362*d83cc019SAndroid Build Coastguard Worker {
363*d83cc019SAndroid Build Coastguard Worker 	uint32_t mbox;
364*d83cc019SAndroid Build Coastguard Worker 
365*d83cc019SAndroid Build Coastguard Worker 	/* XXX: allow decoding up to size */
366*d83cc019SAndroid Build Coastguard Worker 	if (OPREGION_ASLE_EXT_OFFSET + sizeof(struct opregion_asle_ext) > size) {
367*d83cc019SAndroid Build Coastguard Worker 		fprintf(stderr, "buffer too small\n");
368*d83cc019SAndroid Build Coastguard Worker 		return;
369*d83cc019SAndroid Build Coastguard Worker 	}
370*d83cc019SAndroid Build Coastguard Worker 
371*d83cc019SAndroid Build Coastguard Worker 	mbox = decode_header(opregion + OPREGION_HEADER_OFFSET);
372*d83cc019SAndroid Build Coastguard Worker 	if (mbox & MBOX_ACPI)
373*d83cc019SAndroid Build Coastguard Worker 		decode_acpi(opregion + OPREGION_ACPI_OFFSET);
374*d83cc019SAndroid Build Coastguard Worker 	if (mbox & MBOX_SWSCI)
375*d83cc019SAndroid Build Coastguard Worker 		decode_swsci(opregion + OPREGION_SWSCI_OFFSET);
376*d83cc019SAndroid Build Coastguard Worker 	if (mbox & MBOX_ASLE)
377*d83cc019SAndroid Build Coastguard Worker 		decode_asle(opregion + OPREGION_ASLE_OFFSET);
378*d83cc019SAndroid Build Coastguard Worker 	if (mbox & MBOX_VBT)
379*d83cc019SAndroid Build Coastguard Worker 		decode_vbt(opregion + OPREGION_VBT_OFFSET);
380*d83cc019SAndroid Build Coastguard Worker 	if (mbox & MBOX_ASLE_EXT)
381*d83cc019SAndroid Build Coastguard Worker 		decode_asle_ext(opregion + OPREGION_ASLE_EXT_OFFSET);
382*d83cc019SAndroid Build Coastguard Worker }
383*d83cc019SAndroid Build Coastguard Worker 
main(int argc,char * argv[])384*d83cc019SAndroid Build Coastguard Worker int main(int argc, char *argv[])
385*d83cc019SAndroid Build Coastguard Worker {
386*d83cc019SAndroid Build Coastguard Worker 	const char *filename = "/sys/kernel/debug/dri/0/i915_opregion";
387*d83cc019SAndroid Build Coastguard Worker 	int fd;
388*d83cc019SAndroid Build Coastguard Worker 	struct stat finfo;
389*d83cc019SAndroid Build Coastguard Worker 	uint8_t *opregion;
390*d83cc019SAndroid Build Coastguard Worker 	int c, option_index = 0;
391*d83cc019SAndroid Build Coastguard Worker 
392*d83cc019SAndroid Build Coastguard Worker 	static struct option long_options[] = {
393*d83cc019SAndroid Build Coastguard Worker 		{ "file", required_argument, 0, 'f' },
394*d83cc019SAndroid Build Coastguard Worker 		{ "help", no_argument, 0, 'h' },
395*d83cc019SAndroid Build Coastguard Worker 		{ 0 },
396*d83cc019SAndroid Build Coastguard Worker 	};
397*d83cc019SAndroid Build Coastguard Worker 
398*d83cc019SAndroid Build Coastguard Worker 	while ((c = getopt_long(argc, argv, "hf:",
399*d83cc019SAndroid Build Coastguard Worker 				long_options, &option_index)) != -1) {
400*d83cc019SAndroid Build Coastguard Worker 		switch (c) {
401*d83cc019SAndroid Build Coastguard Worker 		case 'h':
402*d83cc019SAndroid Build Coastguard Worker 			printf("usage: intel_opregion_decode [-f|--file=<input>]\n");
403*d83cc019SAndroid Build Coastguard Worker 			return 0;
404*d83cc019SAndroid Build Coastguard Worker 		case 'f':
405*d83cc019SAndroid Build Coastguard Worker 			filename = optarg;
406*d83cc019SAndroid Build Coastguard Worker 			break;
407*d83cc019SAndroid Build Coastguard Worker 		default:
408*d83cc019SAndroid Build Coastguard Worker 			fprintf(stderr, "unkown command options\n");
409*d83cc019SAndroid Build Coastguard Worker 			return 1;
410*d83cc019SAndroid Build Coastguard Worker 		}
411*d83cc019SAndroid Build Coastguard Worker 	}
412*d83cc019SAndroid Build Coastguard Worker 
413*d83cc019SAndroid Build Coastguard Worker 	fd = open(filename, O_RDONLY);
414*d83cc019SAndroid Build Coastguard Worker 	if (fd == -1) {
415*d83cc019SAndroid Build Coastguard Worker 		printf("Couldn't open \"%s\": %s\n", filename, strerror(errno));
416*d83cc019SAndroid Build Coastguard Worker 		return 1;
417*d83cc019SAndroid Build Coastguard Worker 	}
418*d83cc019SAndroid Build Coastguard Worker 
419*d83cc019SAndroid Build Coastguard Worker 	if (stat(filename, &finfo)) {
420*d83cc019SAndroid Build Coastguard Worker 		printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
421*d83cc019SAndroid Build Coastguard Worker 		return 1;
422*d83cc019SAndroid Build Coastguard Worker 	}
423*d83cc019SAndroid Build Coastguard Worker 
424*d83cc019SAndroid Build Coastguard Worker 	if (finfo.st_size == 0) {
425*d83cc019SAndroid Build Coastguard Worker 		int len = 0, ret;
426*d83cc019SAndroid Build Coastguard Worker 		finfo.st_size = 8192;
427*d83cc019SAndroid Build Coastguard Worker 		opregion = malloc(finfo.st_size);
428*d83cc019SAndroid Build Coastguard Worker 		while ((ret = read(fd, opregion + len, finfo.st_size - len))) {
429*d83cc019SAndroid Build Coastguard Worker 			if (ret < 0) {
430*d83cc019SAndroid Build Coastguard Worker 				printf("failed to read \"%s\": %s\n", filename,
431*d83cc019SAndroid Build Coastguard Worker 				       strerror(errno));
432*d83cc019SAndroid Build Coastguard Worker 				return 1;
433*d83cc019SAndroid Build Coastguard Worker 			}
434*d83cc019SAndroid Build Coastguard Worker 
435*d83cc019SAndroid Build Coastguard Worker 			len += ret;
436*d83cc019SAndroid Build Coastguard Worker 			if (len == finfo.st_size) {
437*d83cc019SAndroid Build Coastguard Worker 				finfo.st_size *= 2;
438*d83cc019SAndroid Build Coastguard Worker 				opregion = realloc(opregion, finfo.st_size);
439*d83cc019SAndroid Build Coastguard Worker 			}
440*d83cc019SAndroid Build Coastguard Worker 		}
441*d83cc019SAndroid Build Coastguard Worker 	} else {
442*d83cc019SAndroid Build Coastguard Worker 		opregion = mmap(NULL, finfo.st_size, PROT_READ, MAP_SHARED,
443*d83cc019SAndroid Build Coastguard Worker 				fd, 0);
444*d83cc019SAndroid Build Coastguard Worker 		if (opregion == MAP_FAILED) {
445*d83cc019SAndroid Build Coastguard Worker 			printf("failed to map \"%s\": %s\n", filename,
446*d83cc019SAndroid Build Coastguard Worker 			       strerror(errno));
447*d83cc019SAndroid Build Coastguard Worker 			return 1;
448*d83cc019SAndroid Build Coastguard Worker 		}
449*d83cc019SAndroid Build Coastguard Worker 	}
450*d83cc019SAndroid Build Coastguard Worker 
451*d83cc019SAndroid Build Coastguard Worker 	decode_opregion(opregion, finfo.st_size);
452*d83cc019SAndroid Build Coastguard Worker 
453*d83cc019SAndroid Build Coastguard Worker 	return 0;
454*d83cc019SAndroid Build Coastguard Worker }
455