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