-
Notifications
You must be signed in to change notification settings - Fork 614
/
IntelFramebuffer.bt
972 lines (919 loc) · 46.7 KB
/
IntelFramebuffer.bt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
/**
* 010 Editor v8.0.1 Binary Template
*
* File: Intel Framebuffer kexts from 10.13.3
* Authors: vit9696
* Version: 0.6
* Purpose: Intel Framebuffer decoding
*
* Copyright (c) 2018 vit9696
*
* Thanks to bcc9, Piker-Alpha, joevt and all the others who reversed Intel Framebuffer code.
*/
LittleEndian();
/* There is various not so accurate information but it is worth checking:
* http://www.insanelymac.com/forum/topic/259705-editing-custom-connectorinfo-for-intel-hd-3000-graphics-sandy-bridge-osx-lion/
* https://github.com/Piker-Alpha/AppleIntelFramebufferAzul.sh/blob/master/AppleIntelFramebufferAzul.sh
* https://www.tonymacx86.com/threads/skylake-intel-hd-530-integrated-graphics-working-as-of-10-11-4.188891/page-29#post-1297155
* https://pikeralpha.wordpress.com/2013/08/02/appleintelframebufferazul-kext-part-ii/
*/
/**
* Please note, that CFL and onwards are in a very draft state, and may contain partially invalid data!!!
*/
typedef unsigned char uint8_t;
typedef uint16 uint16_t;
typedef uint32 uint32_t;
typedef uint64 uint64_t;
typedef char int8_t;
typedef int16 int16_t;
typedef int32 int32_t;
typedef int64 int64_t;
enum <uint32_t> FirstFramebuffer {
FirstSandyBridgeId = 0x00040201, /* note, this is just a marker */
DefSandyBridgeId = 0x00010200, /* note, this is just a marker */
FirstIvyBridgeId = 0x01660000,
FirstHaswellId = 0x0c060000,
FirstBroadwellId = 0x16060000,
FirstSkylakeId = 0x191e0000,
FirstKabyLakeId = 0x591e0000,
FirstCoffeeLakeId = 0x3ea50009,
FirstCannonLakeId = 0x5a510009,
FirstIceLakeId = 0xff050000, /* LP and HP share the table */
};
enum <uint32_t> CamelliaVersion {
CamelliaDisabled = 0, /* -nocam */
CamelliaV1 = 1, /* -forcecam1 */
CamelliaV2 = 2, /* -forcecam2, CamelliaTcon2 */
CamelliaV3 = 3, /* BanksiaTcon */
CamelliaUnsupported = 0xFF /* dummy value for snb */
};
union FramebufferFlags {
struct FramebufferFlagBits {
/* Discovered in AppleIntelFBController::LinkTraining. Disables the use of FastLinkTraining.
* According to joevt with zero SKL link training happens at 450 MHz else at 540 MHz */
uint8_t FBAvoidFastLinkTraining :1; /* 0x1 */
/* Sets the logic of minStolenMem calculation, when set fStolenMemorySize is not multiplied
* by fFBMemoryCount, assuming fStolenMemorySize counts all framebuffers at once.
*/
uint8_t FBFramebufferCommonMemory :1; /* 0x2 */
/* Discovered in AppleIntelFramebufferController::getFeatureControl.
* This is equivalent to setting FBC=1 in the plist FeatureControl section.
* Compression causes fFramebufferMemorySize to be added to minStolenMem.
*/
uint8_t FBFramebufferCompression :1; /* 0x4 */
/* Discovered in AppleIntelFramebufferController::getFeatureControl.
* This is equivalent to setting SliceSDEnable=1, EUSDEnable=1, DynamicSliceSwitch=1 in the plist FeatureControl section.
*/
uint8_t FBEnableSliceFeatures :1; /* 0x8 */
/* Discovered in AppleIntelFramebufferController::getFeatureControl.
* This is equivalent to setting DynamicFBCEnable=1 in the plist FeatureControl section.
*/
uint8_t FBDynamicFBCEnable :1; /* 0x10 */
/* This sets fUseVideoTurbo=1 and loads GPU turbo frequency from the specific field.
* Defaults to 14, can be overridden by VideoTurboFreq in the plist FeatureControl section.
*/
uint8_t FBUseVideoTurbo :1; /* 0x20 */
/* Discovered in AppleIntelFramebuffer::getDisplayStatus.
* Enforces display power reset even on always connected displays (see connector flags CNConnectorAlwaysConnected).
*/
uint8_t FBForcePowerAlwaysConnected :1; /* 0x40 */
/* According to joevt this enforces High Bitrate mode 1, which limits DP bitrate to 8.64 Gbit/s instead of normal 17.28 Gbit/s (HBR2).
* I do not think this is used on Skylake any longer.
*/
uint8_t FBDisableHighBitrateMode2 :1; /* 0x80 */
/* This bit is not used on Broadwell and newer but set when fPortCount > 0, i.e. for all online framebuffers.
* On Haswell it is used by AppleIntelFramebuffer::GetOnlineInfo and is set only on 0x0D260007 (MacBookPro11,3) and 0x0D26000E, which are top models.
* This appears to boost pixel frequency limit (aka pixel clock) to 540000000 Hz (from the usual 216000000, 320000000, 360000000, 450000000).
*/
uint8_t FBBoostPixelFrequencyLimit :1; /* 0x100 */
/* Discovered in AppleIntelFramebuffer::ValidateSourceSize.
* Limits source size to 4096x4096.
*/
uint8_t FBLimit4KSourceSize :1; /* 0x200 */
/* Discovered in AppleIntelFramebufferController::start.
* These bits appear to be entirely equivalent and could be used interchangeably. Result in setting:
* - PCH_LP_PARTITION_LEVEL_DISABLE (1 << 12) bit in SOUTH_DSPCLK_GATE_D (0xc2020)
* - LPT_PWM_GRANULARITY (1 << 5) bit in SOUTH_CHICKEN2 (0xc2004)
* See Linux driver sources (lpt_init_clock_gating, lpt_enable_backlight).
* Since these bits are setting backlight pulse width modularity, there is no sense in setting them without a built-in display (i.e. on desktop).
*/
uint8_t FBAlternatePWMIncrement1 :1; /* 0x400 */
uint8_t FBAlternatePWMIncrement2 :1; /* 0x800 */
/* Discovered in Broadwell AppleIntelFBController::start / AppleIntelFBController::getFeatureControl.
* This is equivalent to setting DisableFeatureIPS=1 in the plist FeatureControl section.
* IPS stands for Intermediate Pixel Storage
*/
uint8_t FBDisableFeatureIPS :1; /* 0x1000 */
uint8_t FBUnknownFlag_2000 :1; /* 0x2000 */
/* Discovered in Broadwell AppleIntelFBController::getOSInformation.
* Used by AppleIntelFramebufferController::LinkTraining for camellia version 2.
* Can be overridden by -notconrecover boot-arg, which effectively unsets this bit.
*/
uint8_t FBAllowConnectorRecover :1; /* 0x4000 */
uint8_t FBUnknownFlag_8000 :1; /* 0x8000 */
uint8_t FBUnknownFlag_10000 :1; /* 0x10000 */
uint8_t FBUnknownFlag_20000 :1; /* 0x20000 */
/* Discovered in AppleIntelFramebufferController::getFeatureControl.
* This takes its effect only if GFMPPFM in the plist FeatureControl section is set to 2, otherwise GFMPPFM is off.
*/
uint8_t FBDisableGFMPPFM :1; /* 0x40000 */
uint8_t FBUnknownFlag_80000 :1; /* 0x80000 */
uint8_t FBUnknownFlag_100000 :1; /* 0x100000 */
/* Discovered in AppleIntelFramebufferController::getFeatureControl.
* This takes its effect only if SupportDynamicCDClk in the plist FeatureControl section is set to 1, otherwise off.
* Also requires dc6config to be set to 3 (default).
*/
uint8_t FBEnableDynamicCDCLK :1; /* 0x200000 */
uint8_t FBUnknownFlag_400000 :1; /* 0x400000 */
/* Discovered in AppleIntelFramebuffer::enableController.
* Used by AppleIntelFramebuffer::ValidateSourceSize.
* Setting this bit increases the maximum source size from 4096x4096 to 5120x5120.
* Most likely this enables 5K support via Intel HD.
*/
uint8_t FBSupport5KSourceSize :1; /* 0x800000 */
uint8_t FBUknownZeroFlags;
Assert(FBUknownZeroFlags == 0, "FBUknownZeroFlags are not zero, new flags were added!");
} bits;
uint32_t value;
};
/* This is the same as ATI/AMD code.
* At this moment only 2, 4, 0x400, and 0x800 are somewhat supported.
* Interestingly connector type is not so important nowadays, e.g. VGA works fine on Kaby on DP.
* As of SKL and newer ConnectorType is converted to fPortType by the following algo:
* - connector with zero index (LVDS) gets fPortType 3.
* - connector with ConnectorHDMI type gets fPortType 1.
* - otherwise a connector has fPortType 2 (DisplayPort-like).
*/
enum <uint32_t> ConnectorType {
ConnectorZero = 0x0,
ConnectorDummy = 0x1, /* Always used as dummy, seems to sometimes work as VGA */
ConnectorLVDS = 0x2, /* Just like on AMD LVDS is used for eDP */
ConnectorDigitalDVI = 0x4, /* This is not eDP despite a common misbelief */
ConnectorSVID = 0x8,
ConnectorVGA = 0x10,
ConnectorDP = 0x400,
ConnectorHDMI = 0x800,
ConnectorAnalogDVI = 0x2000
};
/* I can see very few mentioned in the code (0x1, 0x8, 0x40), though connectors themselves define way more! */
union ConnectorFlags {
struct ConnectorFlagBits {
/* Bits 1, 2, 8 are mentioned in AppleIntelFramebufferController::GetGPUCapability */
/* Lets apperture memory to be not required AppleIntelFramebuffer::isApertureMemoryRequired */
uint8_t CNAlterAppertureRequirements :1; /* 0x1 */
uint8_t CNUnknownFlag_2 :1; /* 0x2 */
uint8_t CNUnknownFlag_4 :1; /* 0x4 */
/* Normally set for LVDS displays (i.e. built-in displays) */
uint8_t CNConnectorAlwaysConnected :1; /* 0x8 */
/* AppleIntelFramebuffer::maxSupportedDepths checks this and returns 2 IODisplayModeInformation::maxDepthIndex ?? */
uint8_t CNUnknownFlag_10 :1; /* 0x10 */
uint8_t CNUnknownFlag_20 :1; /* 0x20 */
/* Disable blit translation table? AppleIntelFramebufferController::ConfigureBufferTranslation */
uint8_t CNDisableBlitTranslationTable:1; /* 0x40 */
/* Used in AppleIntelFramebufferController::setPowerWellState */
/* Activates MISC IO power well (SKL_DISP_PW_MISC_IO) */
uint8_t CNUseMiscIoPowerWell :1; /* 0x80 */
/* Used in AppleIntelFramebufferController::setPowerWellState */
/* Activates Power Well 2 usage (SKL_PW_CTL_IDX_PW_2) */
/* May help with HDMI audio configuration issues */
/* REF: https://github.com/acidanthera/bugtracker/issues/1189 */
uint8_t CNUsePowerWell2 :1; /* 0x100 */
uint8_t CNUnknownFlag_200 :1; /* 0x200 */
uint8_t CNUnknownFlag_400 :1; /* 0x400 */
/* Sets fAvailableLaneCount to 30 instead of 20 when specified */
uint8_t CNIncreaseLaneCount :1; /* 0x800 */
uint8_t CNUnknownFlag_1000 :1; /* 0x1000 */
uint8_t CNUnknownFlag_2000 :1; /* 0x2000 */
uint8_t CNUnknownFlag_4000 :1; /* 0x4000 */
uint8_t CNUnknownFlag_8000 :1; /* 0x8000 */
uint16_t CNUnknownZeroFlags;
Assert(CNUnknownZeroFlags == 0, "CNUnknownZeroFlags are not zero, new flags were added!");
} bits;
uint32_t value;
};
struct ConnectorInfo {
/* Watch out, this is really messy (see AppleIntelFramebufferController::MapFBToPort).
* I am not fully sure why this exists, and recommend setting index to array index (i.e. the sequential number from 0).
*
* The only accepted values are 0, 1, 2, 3, and -1 (0xFF). When index is equal to array index the logic is simple:
* Port with index 0 is always considered built-in (of LVDS type) regardless of any other values.
* Ports with indexes 1~3 are checked against type, HDMI will allow the use of digital audio, otherwise DP is assumed.
* Port with index 0xFF is ignored and skipped.
*
* When index != array index port type will be read from connector[index].type.
* Say, we have 2 active ports:
* 0 - [1] busId 4 type LVDS
* 1 - [2] busId 5 type DP
* 2 - [3] busId 6 type HDMI
* 3 - [-1] busId 0 type Dummy
* This will result in 2 framebuffers which types will be shifted:
* 0 - busId 4 type DP
* 1 - busId 5 type HDMI
* In fact BusId values are also read as connector[index].busId, but are later mapped back via
* AppleIntelFramebufferController::getGMBusIDfromPort by looking up a connector with the specified index.
* The lookup will stop as soon as a special marker connector (-1) is found. To illustrate, if we have 2 active ports:
* 0 - [1] busId 4 type LVDS
* 1 - [2] busId 5 type DP
* 2 - [-1] busId 6 type HDMI
* 3 - [-1] busId 0 type Dummy
* The result will be 2 framebuffers which types and the second busId will be shifted:
* 0 - busId 4 type DP
* 1 - busId 6 type HDMI
* It is also used for port-number calculation.
* - LVDS displays (more precisely, displays with CNConnectorAlwaysConnected flag set) get port-number 0.
* - Other displays go through index - port-number mapping: 1 - 5, 2 - 6, 3 - 7, or fallback to 0.
*/
uint8_t index;
/* Proven by AppleIntelFramebufferController::MapFBToPort, by a call to AppleIntelFramebufferController::getGMBusIDfromPort.
* This is GMBUS (Graphic Management Bus) ID described in https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-hsw-display_0.pdf.
* The use could be found in Intel Linux Graphics Driver source code:
* https://github.com/torvalds/linux/blob/6481d5ed076e69db83ca75e751ad492a6fb669a7/drivers/gpu/drm/i915/intel_i2c.c#L43
* https://github.com/torvalds/linux/blob/605dc7761d2701f73c17183649de0e3044609817/drivers/gpu/drm/i915/i915_reg.h#L3053
* However, it should be noted that Apple identifiers are slightly different from Linux driver.
* In Linux 0 means disabled, however, for Apple it has some special meaning and is used for internal display.
* Other than that the values are the same:
* - GMBUS_PIN_DPC (4) HDMIC
* - GMBUS_PIN_DPB (5) SDVO, HDMIB
* - GMBUS_PIN_DPD (6) HDMID
* - GMBUS_PIN_VGADDC (2) VGA until Broadwell inclusive.
* So basically you could use 4, 5, 6 for arbitrary HDMI or DisplayPort displays.
* Since 5 supports SDVO (https://en.wikipedia.org/wiki/Serial_Digital_Video_Out), it may also be used to support DVI displays.
* Starting with Skylake VGA works via SDVO too (instead of a dedicated GMBUS_PIN_VGADDC id).
*/
uint8_t busId;
/* Appears to be used for grouping ports just like Piker says, but I cannot find the usage. */
uint8_t pipe;
uint8_t pad;
Assert(pad == 0, "Non-zero padding");
ConnectorType type <read=connectorTypeToPrintable>;
/* These are connector flags, they have nothing to do with delays regardless of what Piker says.
* I tried to describe some in ConnectorFlags.
*/
ConnectorFlags flags <read=connectorFlagsToPrintable>;
};
/* Wide connector type format */
struct ConnectorInfoICL {
uint32_t index;
uint32_t busId;
uint32_t pipe;
uint32_t pad;
ConnectorType type <read=connectorTypeToPrintable>;
ConnectorFlags flags <read=connectorFlagsToPrintable>;
};
/* It should be noted that some displays use more than 1 pipe, so maxPipes != maxDisplays. */
struct FramebufferSNB {
local uint32_t framebufferId = 0;
local string framebufferStr = "";
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount; /* also fNumFramebuffer */
uint8_t fFBMemoryCount;
/* 0 means unused. */
uint32_t fBacklightFrequency;
uint32_t fBacklightMax;
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
local uint32_t fStolenMemorySize = 0;
local uint32_t fFramebufferMemorySize = 0;
local uint32_t fUnifiedMemorySize = 0;
local uint8_t camelliaVersion = CamelliaUnsupported;
local uint32_t flags = 0;
local uint64_t fModelNameAddr = 0;
};
string frameIdFromIndex(uint32_t frame, uint32_t index) {
local string out;
if (frame != 0) {
/* Ivy and newer */
SPrintf(out, "%08X", frame);
} else {
/* Sandy Bridge has stupid frame detection logic.
* See board-id list below, which enable framebuffer fallbacks.
*/
switch (index) {
case 0: out="SNB0 0x10000"; break;
case 1: out="SNB1 0x20000"; break;
case 2: out="SNB2 0x30010 or 0x30020"; break;
case 3: out="SNB3 0x30030"; break;
case 4: out="SNB4 0x40000"; break;
case 5: out="SNB5 0x50000"; break;
case 6: out="SNB6 Not addressible"; break;
case 7: out="SNB7 Not addressible"; break;
/* There are 8 frames for sandy aside the default one, but only the first 6 are addressible. */
default: out="Error";
}
}
return out;
}
struct FramebufferIVB {
uint32_t framebufferId;
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount; /* also fNumFramebuffer */
uint8_t fFBMemoryCount;
uint32_t fStolenMemorySize <read=bytesToPrintable>;
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t fBacklightFrequency <read=frequencyToPrintable>;
uint32_t fBacklightMax <read=frequencyToPrintable>;
uint32_t unk1[2];
uint32_t unk2[2];
uint32_t unk3;
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
uint32_t pad2[26];
local uint8_t camelliaVersion = CamelliaUnsupported;
local uint32_t flags = 0;
local uint64_t fModelNameAddr = 0;
};
/* Some names are taken from 10.9 Azul driver. While they may not be the same names used in the struct, they are handy at least. */
struct FramebufferHSW {
uint32_t framebufferId;
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount; /* also fNumFramebuffer */
uint8_t fFBMemoryCount;
uint32_t fStolenMemorySize <read=bytesToPrintable>;
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fCursorMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t fBacklightFrequency <read=frequencyToPrintable>;
uint32_t fBacklightMax <read=frequencyToPrintable>;
uint32_t pad[2];
Assert(pad[0] == 0 && pad[1] == 0, "Non-zero padding");
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
uint8_t unk1[3];
uint8_t camelliaVersion <read=camelliaToPrintable>;
uint32_t unk2;
uint32_t fNumTransactionsThreshold;
uint32_t fVideoTurboFreq;
uint32_t unk3;
local uint64_t fModelNameAddr = 0;
};
struct FramebufferBDW {
uint32_t framebufferId;
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
uint32_t fStolenMemorySize <read=bytesToPrintable>;
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t fBacklightFrequency <read=frequencyToPrintable>;
uint32_t fBacklightMax <read=frequencyToPrintable>;
uint32_t pad[3];
Assert(pad[0] == 0 && pad[1] == 0 && pad[2] == 0, "Non-zero padding");
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
uint32_t unk1;
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint32_t unk2[6];
uint32_t fNumTransactionsThreshold;
uint32_t fVideoTurboFreq;
uint32_t fRC6_Threshold;
local uint64_t fModelNameAddr = 0;
};
struct FramebufferSKL {
uint32_t framebufferId;
/* Unclear what values really are, yet 4 stands for non-LP chipset.
* See AppleIntelFramebufferController::start.
*/
uint32_t fPchType;
Assert(fPchType == 0, "Non-zero PCH type");
uint64_t fModelNameAddr <read=modelNameAddrToPrintable>;
/* While it is hard to be sure, because having 0 here results in online=true returned by
* AppleIntelFramebuffer::GetOnlineInfo, after all it appears to be the case, and the unused
* so-called mobile framebufers are simply set to fail-safe defaults.
* For some reason it is often called fDisabled...
*/
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
/* This one is per framebuffer fStolenMemorySize * fFBMemoryCount */
uint32_t fStolenMemorySize <read=bytesToPrintable>;
/* This is for boot framebuffer from what I can understand */
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t fBacklightFrequency <read=frequencyToPrintable>;
uint32_t fBacklightMax <read=frequencyToPrintable>;
uint32_t pad1[2];
Assert(pad1[0] == 0 && pad1[1] == 0, "Non-zero sequence");
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
/* Check DDI Buffer Translations in Linux driver for details. */
uint8_t fBTTableOffsetIndexSlice; /* FBEnableSliceFeatures = 1 */
uint8_t fBTTableOffsetIndexNormal; /* FBEnableSliceFeatures = 0 */
uint8_t fBTTableOffsetIndexHDMI; /* fDisplayType = 1 */
uint8_t pad2;
Assert(pad2 == 0, "Non-zero sequence");
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint64_t unk3[3];
uint32_t fNumTransactionsThreshold;
/* Defaults to 14, used when UseVideoTurbo bit is set */
uint32_t fVideoTurboFreq;
uint32_t pad3;
Assert(pad3 == 0, "Non-zero sequence");
uint64_t fBTTArraySliceAddr;
uint64_t fBTTArrayNormalAddr;
uint64_t fBTTArrayHDMIAddr;
uint32_t fSliceCount;
uint32_t fEuCount;
uint32_t unk6[2];
};
struct FramebufferCFL {
uint32_t framebufferId;
/* Unclear what values really are, yet 4 stands for non-LP chipset.
* See AppleIntelFramebufferController::start.
*/
uint32_t fPchType;
Assert(fPchType == 0, "Non-zero PCH type");
uint64_t fModelNameAddr <read=modelNameAddrToPrintable>;
/* While it is hard to be sure, because having 0 here results in online=true returned by
* AppleIntelFramebuffer::GetOnlineInfo, after all it appears to be the case, and the unused
* so-called mobile framebufers are simply set to fail-safe defaults.
* For some reason it is often called fDisabled...
*/
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
/* This one is per framebuffer fStolenMemorySize * fFBMemoryCount */
uint32_t fStolenMemorySize <read=bytesToPrintable>;
/* This is for boot framebuffer from what I can understand */
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t pad1[2];
Assert(pad1[0] == 0 && pad1[1] == 0, "Non-zero sequence");
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
/* Check DDI Buffer Translations in Linux driver for details. */
uint8_t fBTTableOffsetIndexSlice; /* FBEnableSliceFeatures = 1 */
uint8_t fBTTableOffsetIndexNormal; /* FBEnableSliceFeatures = 0 */
uint8_t fBTTableOffsetIndexHDMI; /* fDisplayType = 1 */
uint8_t pad2;
Assert(pad2 == 0, "Non-zero sequence");
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint64_t unk3[3];
uint32_t fNumTransactionsThreshold;
/* Defaults to 14, used when UseVideoTurbo bit is set */
uint32_t fVideoTurboFreq;
uint32_t pad3;
Assert(pad3 == 0, "Non-zero sequence");
uint64_t fBTTArraySliceAddr;
uint64_t fBTTArrayNormalAddr;
uint64_t fBTTArrayHDMIAddr;
uint32_t fSliceCount;
uint32_t fEuCount;
uint32_t unk6[2];
local uint32_t fBacklightFrequency <read=frequencyToPrintable> = 0 ;
local uint32_t fBacklightMax <read=frequencyToPrintable> = 0;
};
/* Not sure what it is, in CNL value2 is a pointer, and value1 could be size. */
struct FramebufferCNLCurrents {
uint32_t value1;
uint32_t pad;
uint64_t valu2;
};
struct FramebufferCNL {
uint32_t framebufferId;
/* Unclear what values really are, yet 4 stands for non-LP chipset.
* See AppleIntelFramebufferController::start.
*/
uint32_t fPchType;
Assert(fPchType == 0, "Non-zero fPchType");
uint64_t fModelNameAddr <read=modelNameAddrToPrintable>;
/* While it is hard to be sure, because having 0 here results in online=true returned by
* AppleIntelFramebuffer::GetOnlineInfo, after all it appears to be the case, and the unused
* so-called mobile framebufers are simply set to fail-safe defaults.
* For some reason it is often called fDisabled...
*/
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
/* This one is per framebuffer fStolenMemorySize * fFBMemoryCount */
uint32_t fStolenMemorySize <read=bytesToPrintable>;
/* This is for boot framebuffer from what I can understand */
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t pad1[2];
Assert(pad1[0] == 0 && pad1[1] == 0, "Non-zero sequence");
ConnectorInfo connectors[4] <read=connectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
/* Check DDI Buffer Translations in Linux driver for details. */
uint8_t fBTTableOffsetIndexSlice; /* FBEnableSliceFeatures = 1 */
uint8_t fBTTableOffsetIndexNormal; /* FBEnableSliceFeatures = 0 */
uint8_t fBTTableOffsetIndexHDMI; /* fDisplayType = 1 */
uint8_t pad2;
Assert(pad2 == 0, "Non-zero sequence");
uint64_t unk1[5];
uint64_t fBTTArraySliceAddr;
uint64_t fBTTArrayNormalAddr;
uint64_t fBTTArrayHDMIAddr;
FramebufferCNLCurrents currents[8];
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint64_t unk2[3];
uint32_t fNumTransactionsThreshold;
/* Defaults to 14, used when UseVideoTurbo bit is set */
uint32_t fVideoTurboFreq;
uint32_t fSliceCount;
uint32_t fEuCount;
uint32_t unk4;
uint32_t unk5[2];
local uint32_t fBacklightFrequency <read=frequencyToPrintable> = 0 ;
local uint32_t fBacklightMax <read=frequencyToPrintable> = 0;
};
struct FramebufferICLHP {
uint32_t framebufferId;
/* Unclear what values really are, yet 4 stands for non-LP chipset.
* See AppleIntelFramebufferController::start.
*/
uint32_t fPchType;
uint64_t fModelNameAddr <read=modelNameAddrToPrintable>;
/* While it is hard to be sure, because having 0 here results in online=true returned by
* AppleIntelFramebuffer::GetOnlineInfo, after all it appears to be the case, and the unused
* so-called mobile framebufers are simply set to fail-safe defaults.
* For some reason it is often called fDisabled...
*/
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
/* This one is per framebuffer fStolenMemorySize * fFBMemoryCount */
uint32_t fStolenMemorySize <read=bytesToPrintable>;
/* This is for boot framebuffer from what I can understand */
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
uint32_t fBacklightFrequency <read=frequencyToPrintable>;
uint32_t fBacklightMax <read=frequencyToPrintable>;
uint32_t pad1[2];
Assert(pad1[0] == 0 && pad1[1] == 0, "Non-zero sequence");
ConnectorInfoICL connectors[3] <read=wideConnectorToPrintable, optimize=false>;
FramebufferFlags flags <read=framebufferFlagsToPrintable>;
FramebufferCNLCurrents currents[8];
uint32_t unk2[5];
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint32_t unk3[6];
/* Defaults to 14, used when UseVideoTurbo bit is set */
uint32_t fNumTransactionsThreshold;
uint32_t fVideoTurboFreq;
uint32_t fSliceCount;
uint32_t fEuCount;
uint32_t unk4;
};
struct FramebufferICLLP {
uint32_t framebufferId;
/* Unclear what values really are, yet 4 stands for non-LP chipset.
* See AppleIntelFramebufferController::start.
*/
uint32_t fPchType;
uint64_t fModelNameAddr <read=modelNameAddrToPrintable>;
/* While it is hard to be sure, because having 0 here results in online=true returned by
* AppleIntelFramebuffer::GetOnlineInfo, after all it appears to be the case, and the unused
* so-called mobile framebufers are simply set to fail-safe defaults.
* For some reason it is often called fDisabled...
*/
uint8_t fMobile;
uint8_t fPipeCount;
uint8_t fPortCount;
uint8_t fFBMemoryCount;
/* This one is per framebuffer fStolenMemorySize * fFBMemoryCount */
uint32_t fStolenMemorySize <read=bytesToPrintable>;
/* This is for boot framebuffer from what I can understand */
uint32_t fFramebufferMemorySize <read=bytesToPrintable>;
uint32_t fUnifiedMemorySize <read=bytesToPrintable>;
ConnectorInfoICL connectors[6] <optimize=false>;
/* Flags are quite different in ICL now */
uint32_t flags;
uint32_t unk2;
FramebufferCNLCurrents currents[3];
uint32_t unk3[2];
uint32_t camelliaVersion <read=camelliaToPrintable>;
uint32_t unk4[3];
uint32_t fNumTransactionsThreshold;
/* Defaults to 14, used when UseVideoTurbo bit is set */
uint32_t fVideoTurboFreq;
uint32_t fSliceCount;
uint32_t fEuCount;
uint32_t unk5;
uint8_t unk6;
uint8_t pad[3];
local uint32_t fBacklightFrequency <read=frequencyToPrintable> = 0 ;
local uint32_t fBacklightMax <read=frequencyToPrintable> = 0;
};
uint32_t calculateStolenHaswell(FramebufferFlags &flags, uint32_t fStolenMemorySize, uint32_t fFBMemoryCount, uint32_t fFramebufferMemorySize) {
local uint32_t fTotalStolen = 0x100000; /* a constant */
if (flags.bits.FBFramebufferCommonMemory) /* formerly FBUnknownFlag_2 */
fTotalStolen += fStolenMemorySize;
else
fTotalStolen += fStolenMemorySize * fFBMemoryCount;
/* Prior to Skylake fFramebufferMemorySize is taken into account unconditionally */
fTotalStolen += fFramebufferMemorySize;
return fTotalStolen;
}
uint32_t calculateStolenSkylake(FramebufferFlags &flags, uint32_t fStolenMemorySize, uint32_t fFBMemoryCount, uint32_t fFramebufferMemorySize) {
local uint32_t fTotalStolen = 0x100000; /* a constant */
if (flags.bits.FBFramebufferCommonMemory) /* formerly FBUnknownFlag_2 */
fTotalStolen += fStolenMemorySize;
else
fTotalStolen += fStolenMemorySize * fFBMemoryCount;
if (flags.bits.FBFramebufferCompression)
fTotalStolen += fFramebufferMemorySize;
return fTotalStolen;
}
uint32_t calculateStolenIceLake(uint32_t flags, uint32_t fStolenMemorySize, uint32_t fFBMemoryCount, uint32_t fFramebufferMemorySize) {
local uint32_t fTotalStolen = 0x100000; /* a constant */
if (flags & 0x2 /* FBFramebufferCommonMemory */)
fTotalStolen += fStolenMemorySize;
else
fTotalStolen += fStolenMemorySize * fFBMemoryCount;
if (flags & 0x4 /* FBFramebufferCompression */)
fTotalStolen += fFramebufferMemorySize;
return fTotalStolen;
}
string bytesToPrintable(uint32_t bytes) {
local string out;
if (bytes >= 1024*1024) {
if (bytes % (1024*1024) == 0) {
SPrintf(out, "%d MB", bytes/1024/1024);
} else {
SPrintf(out, "%d MB (%d bytes)", bytes/1024/1024, bytes);
}
} else if (bytes >= 1024) {
if (bytes % (1024) == 0) {
SPrintf(out, "%d KB", bytes/1024);
} else {
SPrintf(out, "%d KB (%d bytes)", bytes/1024, bytes);
}
} else {
SPrintf(out, "%d bytes", bytes);
}
return out;
}
string frequencyToPrintable(uint32_t freq) {
local string out;
SPrintf(out, "%d Hz", freq);
return out;
}
string camelliaToPrintable(CamelliaVersion cam) {
local string out;
SPrintf(out, "%s (%d)", EnumToString(cam), cam);
return out;
}
string connectorTypeToPrintable(ConnectorType type) {
local string out;
local string typename = EnumToString(type);
Assert(typename != "", "Unknown connector type discovered");
SPrintf(out, "0x%08X - %s", type, EnumToString(type));
return out;
}
string connectorToPrintable(ConnectorInfo &con) {
local string out;
SPrintf(out, "[%d] busId: 0x%02X, pipe: %d, type: 0x%08X, flags: 0x%08X - %s", con.index, con.busId, con.pipe, con.type, con.flags.value, EnumToString(con.type));
return out;
}
string wideConnectorToPrintable(ConnectorInfoICL &con) {
local string out;
SPrintf(out, "[%d] busId: 0x%02X, pipe: %d, type: 0x%08X, flags: 0x%08X - %s", con.index, con.busId, con.pipe, con.type, con.flags.value, EnumToString(con.type));
return out;
}
string connectorToHex(ConnectorInfo &c) {
local string out;
SPrintf(out, "%02X%02X%02X%02X %08X %08X", c.index, c.busId, c.pipe, c.pad,
((c.type>>24)&0xff) | ((c.type<<8)&0xff0000) | ((c.type>>8)&0xff00) | ((c.type<<24)&0xff000000),
((c.flags.value>>24)&0xff) | ((c.flags.value<<8)&0xff0000) | ((c.flags.value>>8)&0xff00) | ((c.flags.value<<24)&0xff000000));
return out;
}
string wideConnectorToHex(ConnectorInfoICL &c) {
local string out;
SPrintf(out, "%08X %08X %08X %08X %08X %08X",
((c.index>>24)&0xff) | ((c.index<<8)&0xff0000) | ((c.index>>8)&0xff00) | ((c.index<<24)&0xff000000),
((c.busId>>24)&0xff) | ((c.busId<<8)&0xff0000) | ((c.busId>>8)&0xff00) | ((c.busId<<24)&0xff000000),
((c.pipe>>24)&0xff) | ((c.pipe<<8)&0xff0000) | ((c.pipe>>8)&0xff00) | ((c.pipe<<24)&0xff000000),
((c.pad>>24)&0xff) | ((c.pad<<8)&0xff0000) | ((c.pad>>8)&0xff00) | ((c.pad<<24)&0xff000000),
((c.type>>24)&0xff) | ((c.type<<8)&0xff0000) | ((c.type>>8)&0xff00) | ((c.type<<24)&0xff000000),
((c.flags.value>>24)&0xff) | ((c.flags.value<<8)&0xff0000) | ((c.flags.value>>8)&0xff00) | ((c.flags.value<<24)&0xff000000));
return out;
}
string framebufferFlagsToPrintable(FramebufferFlags &flags) {
local string out;
SPrintf(out, "%08X", flags.value);
return out;
}
string connectorFlagsToPrintable(ConnectorFlags &flags) {
local string out;
SPrintf(out, "%08X", flags.value);
return out;
}
string modelNameAddrToPrintable(uint64_t addr) {
return ReadLine(addr - textSlide);
}
string framebufferSNBToPrintable(FramebufferSNB &fb) {
local string out;
SPrintf(out, "%s (%s, %d connectors%s)", fb.framebufferStr, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "");
return out;
}
string framebufferIVBToPrintable(FramebufferIVB &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(fb.fFramebufferMemorySize));
return out;
}
string framebufferHSWToPrintable(FramebufferHSW &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenHaswell(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferBDWToPrintable(FramebufferBDW &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenHaswell(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferSKLToPrintable(FramebufferSKL &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenSkylake(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferCFLToPrintable(FramebufferCFL &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenSkylake(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferCNLToPrintable(FramebufferCNL &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenSkylake(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferICLHPToPrintable(FramebufferICLHP &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenSkylake(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
string framebufferICLLPToPrintable(FramebufferICLLP &fb) {
local string out;
SPrintf(out, "0x%08X (%s, %d connectors%s, %s?)", fb.framebufferId, fb.fMobile ? "mobile" : "desktop",
fb.fPortCount, fb.fFramebufferMemorySize == 0 ? ", no fbmem" : "", bytesToPrintable(calculateStolenIceLake(fb.flags, fb.fStolenMemorySize, fb.fFBMemoryCount, fb.fFramebufferMemorySize)));
return out;
}
/* Skip a little data to speedup the search. */
local int64_t pos = 0x20000, size = FileSize();
local uint32_t i = 0, j = 0;
local uint32_t firstId = 0;
/* This value is a total maximum of preallocated memory that can be used with all flag combinations.
* I.e. if you want to change FBFramebufferCompression or FBFramebufferCommonMemory you may need
* as much memory as fMaxStolen. With the flags untouched refer to fTotalStolen. */
local uint32_t fMaxStolen = 0;
/* This value is a total maximum of preallocated memory that is necessary for current flag combinations.
* This value must be <= preallocated memory in BIOS settings, Apple also calls it minStolenSize.
* I.e. this is what the assertion panic checks during boot, it is compared against the BIOS value
* obtained via PCI Config 16-bit read from GMCH Control #0 (0x50): ((val << 17) & 0xFE000000) - 0x1000 */
local uint32_t fTotalStolen = 0;
/* This value is used for hardware cursor allocation, but is not checked. Bug? */
local uint32_t fTotalCursor = 0;
/* The absolute maximum with all flag combinations including cursor and framebuffer memory. */
local uint32_t fMaxOverall = 0;
local uint32_t magic = ReadUInt(0);
if (magic != 0xFEEDFACF) {
Printf("Invalid kext file!\n");
Exit(0);
}
local uint64_t textSlide = ReadUInt64(0x38);
local uint32_t isLowProfile = FindFirst("ICLLP") > 0;
while (pos < size) {
/* Skip to platforms... */
firstId = ReadUInt(pos);
if (firstId != FirstSandyBridgeId && firstId != FirstIvyBridgeId &&
firstId != FirstHaswellId && firstId != FirstBroadwellId &&
firstId != FirstSkylakeId && firstId != FirstKabyLakeId &&
firstId != FirstCoffeeLakeId && firstId != FirstCannonLakeId &&
firstId != FirstIceLakeId) {
pos += sizeof(uint32_t);
continue;
}
/* Read platforms from here... */
FSeek(pos);
while (ReadUInt() != 0xFFFFFFFF) {
if (firstId == FirstSandyBridgeId) {
FramebufferSNB frames <optimize=false, read=framebufferSNBToPrintable>;
frames[i].framebufferStr = frameIdFromIndex(frames[i].framebufferId, i);
} else if (firstId == FirstIvyBridgeId) {
FramebufferIVB frames <optimize=false, read=framebufferIVBToPrintable>;
} else if (firstId == FirstHaswellId) {
FramebufferHSW frames <optimize=false, read=framebufferHSWToPrintable>;
} else if (firstId == FirstBroadwellId) {
FramebufferBDW frames <optimize=false, read=framebufferBDWToPrintable>;
/* Skylake and Kaby Lake share the struct as of 10.13.3 */
} else if (firstId == FirstSkylakeId || firstId == FirstKabyLakeId) {
FramebufferSKL frames <optimize=false, read=framebufferSKLToPrintable>;
} else if (firstId == FirstCoffeeLakeId) {
FramebufferCFL frames <optimize=false, read=framebufferCFLToPrintable>;
} else if (firstId == FirstCannonLakeId) {
FramebufferCNL frames <optimize=false, read=framebufferCNLToPrintable>;
} else if (firstId == FirstIceLakeId && isLowProfile) {
FramebufferICLLP frames <optimize=false, read=framebufferICLLPToPrintable>;
} else if (firstId == FirstIceLakeId) {
FramebufferICLHP frames <optimize=false, read=framebufferICLHPToPrintable>;
}
Printf("ID: %s, STOLEN: %s, FBMEM: %s, VRAM: %s, Flags: 0x%08X\n", frameIdFromIndex(frames[i].framebufferId, i),
bytesToPrintable(frames[i].fStolenMemorySize), bytesToPrintable(frames[i].fFramebufferMemorySize),
bytesToPrintable(frames[i].fUnifiedMemorySize),
firstId == FirstSandyBridgeId || firstId == FirstIvyBridgeId ? 0 :
firstId == FirstIceLakeId ? frames[i].flags : frames[i].flags.value);
if (firstId == FirstSandyBridgeId || firstId == FirstIvyBridgeId) {
fMaxStolen = frames[i].fFramebufferMemorySize * frames[i].fFBMemoryCount;
fTotalStolen = frames[i].fFramebufferMemorySize; /* the assert here does not multiply, why? */
} else if (firstId == FirstHaswellId || firstId == FirstBroadwellId) {
fMaxStolen = frames[i].fStolenMemorySize * frames[i].fFBMemoryCount + frames[i].fFramebufferMemorySize + 0x100000;
fTotalStolen = calculateStolenHaswell(frames[i].flags, frames[i].fStolenMemorySize, frames[i].fFBMemoryCount, frames[i].fFramebufferMemorySize);
} else if (firstId == FirstIceLakeId) {
fMaxStolen = frames[i].fStolenMemorySize * frames[i].fFBMemoryCount + frames[i].fFramebufferMemorySize + 0x100000;
fTotalStolen = calculateStolenIceLake(frames[i].flags, frames[i].fStolenMemorySize, frames[i].fFBMemoryCount, frames[i].fFramebufferMemorySize);
} else {
fMaxStolen = frames[i].fStolenMemorySize * frames[i].fFBMemoryCount + frames[i].fFramebufferMemorySize + 0x100000;
fTotalStolen = calculateStolenSkylake(frames[i].flags, frames[i].fStolenMemorySize, frames[i].fFBMemoryCount, frames[i].fFramebufferMemorySize);
}
fTotalCursor = frames[i].fPipeCount * 0x80000;
fMaxOverall = fTotalCursor + fMaxStolen + frames[i].fPortCount * 0x1000;
Printf("TOTAL STOLEN: %s%s, TOTAL CURSOR: %s, MAX STOLEN: %s, MAX OVERALL: %s\n",
bytesToPrintable(fTotalStolen), firstId == FirstIceLakeId ? "?" : "",
bytesToPrintable(fTotalCursor), bytesToPrintable(fMaxStolen), bytesToPrintable(fMaxOverall));
if (frames[i].fModelNameAddr != 0)
Printf("Model name: %s\n", modelNameAddrToPrintable(frames[i].fModelNameAddr));
Printf("Camellia: %s, Freq: %s, FreqMax: %s\n", camelliaToPrintable(frames[i].camelliaVersion),
frequencyToPrintable(frames[i].fBacklightFrequency), frequencyToPrintable(frames[i].fBacklightMax));
Printf("Mobile: %d, PipeCount: %d, PortCount: %d, FBMemoryCount: %d\n", frames[i].fMobile, frames[i].fPipeCount,
frames[i].fPortCount, frames[i].fFBMemoryCount);
if (firstId == FirstIceLakeId) {
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", wideConnectorToPrintable(frames[i].connectors[j]));
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", wideConnectorToHex(frames[i].connectors[j]));
} else {
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", connectorToPrintable(frames[i].connectors[j]));
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", connectorToHex(frames[i].connectors[j]));
}
Printf("\n");
/* There is no -1 termination on Sandy */
if (firstId == FirstSandyBridgeId && i == 7) break;
i++;
}
break;
}
/* Additionally read the externally defined default FB on Sandy */
if (firstId == FirstSandyBridgeId) {
pos = 0x20000;
while (pos < size) {
firstId = ReadUInt(pos);
if (firstId == DefSandyBridgeId) {
FSeek(pos);
FramebufferSNB frames <optimize=false, read=framebufferSNBToPrintable>;
frames.framebufferStr = "Default";
Printf("Default SNB, DVMT: %s, FBMEM: %s, VRAM: %s, Flags: 0x00000000\n",
bytesToPrintable(frames[i].fStolenMemorySize), bytesToPrintable(frames[i].fFramebufferMemorySize), bytesToPrintable(frames[i].fUnifiedMemorySize));
Printf("Camellia: %s, Freq: %s, FreqMax: %s\n", camelliaToPrintable(frames[i].camelliaVersion),
frequencyToPrintable(frames[i].fBacklightFrequency), frequencyToPrintable(frames[i].fBacklightMax));
Printf("Mobile: %d, PipeCount: %d, PortCount: %d, FBMemoryCount: %d\n", frames[i].fMobile, frames[i].fPipeCount,
frames[i].fPortCount, frames[i].fFBMemoryCount);
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", connectorToPrintable(frames[i].connectors[j]));
for (j = 0; j < frames[i].fPortCount; j++)
Printf("%s\n", connectorToHex(frames[i].connectors[j]));
Printf("\n");
break;
} else {
pos += sizeof(uint32_t);
}
}
Printf("Note, that without AAPL,snb-platform-id the following models will use predefined IDs:\n");
Printf("Mac-94245B3640C91C81 -> SNB0 (MacBookPro8,1)\n");
Printf("Mac-94245AF5819B141B -> SNB0\n");
Printf("Mac-94245A3940C91C80 -> SNB0 (MacBookPro8,2)\n");
Printf("Mac-942459F5819B171B -> SNB0 (MacBookPro8,3)\n");
Printf("Mac-8ED6AF5B48C039E1 -> SNB2 (Macmini5,1)\n");
Printf("Mac-7BA5B2794B2CDB12 -> SNB2 (Macmini5,3)\n");
Printf("Mac-4BC72D62AD45599E -> SNB3 (Macmini5,2) -> no ports\n");
Printf("Mac-742912EFDBEE19B3 -> SNB4 (MacBookAir4,2)\n");
Printf("Mac-C08A6BB70A942AC2 -> SNB4 (MacBookAir4,1)\n");
Printf("Mac-942B5BF58194151B -> SNB5 (iMac12,1) -> no ports\n");
Printf("Mac-942B5B3A40C91381 -> SNB5 -> no ports\n");
Printf("Mac-942B59F58194171B -> SNB5 (iMac12,2) -> no ports\n");
} else if (firstId == FirstSkylakeId) {
Printf("Note, that without AAPL,ig-platform-id the following ID is assumed: 19120000\n");
} else if (firstId == FirstKabyLakeId) {
Printf("Note, that without AAPL,ig-platform-id the following ID is assumed: 59160000\n");
} else if (firstId == FirstCoffeeLakeId) {
Printf("Note, that without AAPL,ig-platform-id the following ID is assumed: 3EA50000\n");
} else if (firstId == FirstCannonLakeId) {
Printf("Note, that without AAPL,ig-platform-id the following ID is assumed: 5A520000\n");
} else if (firstId == FirstIceLakeId) {
Printf("Note, that without AAPL,ig-platform-id the following REAL ID is assumed: 8A520000\n");
Printf("Note, that without AAPL,ig-platform-id the following SIMULATOR ID is assumed: FF050000\n");
}