Jump to content

What are DVMT, stolenmem, fbmem, cursormem and why do we patch these for Broadwell and later?


Hervé
 Share

1 post in this topic

Recommended Posts

On 9/29/2021 at 7:46 PM, tonyx86 said:

Wanted to share a lesson learned after misinterpreting Dortania documentation here.  Bottom line is that framebuffer-stolenmem and framebuffer-fbmem were unnecessary on my rig and actually caused problems (my fault, not the documentation).  I ended up removing these parms from my config.plist with much better performance/stability.  See details below...

 

My HP Envy x360 15 / HackBookPro15,2 (i5-8250U / UHD620) does not allow any VRAM configuration in BIOS.  This was my first laptop hack since my Dell Latitude E6410.  After seeing similar hacks that defined framebuffer-stolenmem and framebuffer-fbmem in OC's config.plist DeviceProperties and after misinterpreting this Dortania guide, I assumed that I had to define framebuffer-stolenmem and framebuffer-fbmem because I couldn't configure VRAM in my BIOS config.  I chose the values 19MB and 9MB respectively as per the example in the guide.  After upgrading to BS 11.6, I started experiencing com.apple.driver.AppleIntelKBLGraphics kernel panics when streaming video in firefox and when establishing remote desktop via Tunnelblick OpenVPN.  After some experimentation, I increased framebuffer-stolenmem and framebuffer-fbmem to 39MB and 21MB respectively (based on my framebuffer memory utilization specified here) and found that the kernel panics stopped.  This lead me to realize that I did not need to constrain framebuffer-stolenmem and framebuffer-fbmem, so I deleted them from my config.plist.  My rig is now rock solid.  My lesson learned is that I should first test without framebuffer-stolenmem and framebuffer-fbmem before unnecessarily (and wrongly) defining these.  I suspect that if I booted Windows (not installed on my rig) and examined video memory, I would see that my rig has plenty of allocated VRAM for my chosen framebuffer (AAPL,ig-platform-id) and there is no need to constrain framebuffer-stolenmem and framebuffer-fbmem.

 

On 9/30/2021 at 3:45 PM, tonyx86 said:

Developers - at the risk of receiving your constructive criticism for this comment, I think it would be a good idea to add an example here where adding framebuffer-stolenmem and framebuffer-fbmem is determined to be unnecessary.  After reviewing many sample EFIs posted in InsanelyMac, it appears to me that the addition of framebuffer-stolenmem and framebuffer-fbmem has become somewhat "automatic" if VRAM can't be configured in BIOS.  Further, the automatic entry of these parms uses the 19MB and 9MB values from the Dortania example.  As I mentioned here, adding framebuffer-stolenmem and framebuffer-fbmem created problems for me in 11.6.  Advising people that these parms are unnecessary if there's enough allocated VRAM (and how to determine whether there's enough allocated VRAM even if not configurable in BIOS) might be helpful.  Thank you and thank you for all the great work you have done and continue to do.

 

On 10/2/2021 at 4:09 AM, joevt said:

Documentation is unclear.

 

It doesn't say where the the "32MB for the iGPU" comes from (maybe it's the STOLEN number but the last line infers something else) or what the framebuffer expects (maybe that's TOTAL STOLEN?).

It doesn't say why the solution is to reduce STOLEN and FBMEM instead of increasing something else (like what the motherboard allocates to the iGPU).

 

Ok, to answer a few recurring questions that were raised in the Opencore thread, the Dortania documentation refers to the DVMT pre-allocated memory or "stolen memory" when they mention "memory reserved for the iGPU". Years ago, Firewolf described the relationship between stolen memory and DVMT pre-allocated memory in details on his blog:

https://www.firewolf.science/2015/04/guide-intel-hd-graphics-5500-on-os-x-yosemite-10-10-3/

 

There's a more recent thread here:

https://www.insanelymac.com/forum/topic/345377-surface-pro-patch-the-framebuffer-properly-to-get-rid-of-the-dvmt-assertion-patch/

 

It can be difficult to understand and differentiate DVMT pre-allocated memory, stolen memory, framebuffer memory, cursor memory, framebuffer size, cursor bytes, etc. And all of these have got nothing to do with VRAM of course... Many of us are familiar with the information provided by Pike R Alpha many moons ago, the WhateverGreen User Manual or the Hackintool app though none of those clearly define what those various memory instances are. Several years ago, Rehabman also attempted to explain this and his writings somehow collided with most people's comprehension of things. For instance, when Pike, WEG or Hackintool refer to stolenmem and fbmem, Rehabman spoke of framebuffer memory size and cursor bytes. In the case of the Haswell Azul framebuffer layouts, Rehabman also spoke of the DVMT pre-alloc requirements when the others speak of stolenmem. Inevitably, this can lead to confusion...

 

Definitions:

See wikipedia and Google searches.

  • VRAM = Video RAM. Common definition is that it stores the pixels and other graphics data rendered on a computer screen.
  • DVMT = Dynamic Video Memory Technology. A technology used by Intel to dynamically allocate system memory to use as video memory to handle graphics. DVMT pre-allocated memory is the minimum amount, in multiples of 32MB, that will be allocated to the iGPU for handling graphics. By far and large, manufacturers set this to 32MB by default (or certainly used to).
  • Framebuffer = a memory buffer held in RAM and containing a bitmap of a video frame, i.e. all the data related to the pixels of an image to be displayed on screen (eg: colours, resolution, etc.).
  • Stolen memory = basically, this is the same as the DVMT pre-allocated memory.

As far as Apple's framebuffer drivers/kexts are concerned:

  • framebuffer size (aka stolenmem for WhateverGreen*) = the size, in bytes, of a framebuffer layout (it may change according to image characteristics), as defined in the driver/kext.
  • cursor bytes (aka fbmem for WhateverGreen*) = the size, in bytes, of a framebuffer layout's overlay used for handling mouse cursor (without modifying the framebuffer's data), as defined in the driver/kext.
  • framebuffer VRAM (aka unifiedmem for WhateverGreen) = the max. amount, in bytes, of VRAM allocated by a framebuffer layout, as defined in the driver/kext (since Haswell and Yosemite, this usually is 1536MB).

* As stated above, I believe that Whatevergreen only got it right for Haswell Azul framebuffer layouts with which stolenmem, fbmem and cursormem match their target. Thereafter, I'm of the opinion that WhateverGreen used incorrect names where stolenmem means the actual framebuffer size and fbmem means the actual cursor bytes (size), as stated by Rehabman.

 

Mac OS X/OS X/macOS graphics framebuffers:

Let's start by looking at a few examples as illustrated in the WhateverGreen User Manual.

 

1) Haswell Azul mobile framebuffer 0x0a260006 (used for HD4200/HD4400/HD4600 iGPUs on laptops):

ID: 0A260006, STOLEN: 32 MB, FBMEM: 19 MB, VRAM: 1536 MB, Flags: 0x0000000F
TOTAL STOLEN: 52 MB, TOTAL CURSOR: 1 MB (1572864 bytes), MAX STOLEN: 116 MB, MAX OVERALL: 117 MB (123219968 bytes)
Camellia: CamelliaDisabled (0), Freq: 2777 Hz, FreqMax: 2777 Hz
Mobile: 1, PipeCount: 3, PortCount: 3, FBMemoryCount: 3
[0] busId: 0x00, pipe: 8, type: 0x00000002, flags: 0x00000030 - ConnectorLVDS
[1] busId: 0x05, pipe: 9, type: 0x00000400, flags: 0x00000087 - ConnectorDP
[2] busId: 0x04, pipe: 9, type: 0x00000400, flags: 0x00000087 - ConnectorDP
00000800 02000000 30000000
01050900 00040000 87000000
02040900 00040000 87000000

If we look inside the binary code of the Haswell Azul framebuffer kext, we'll find:

0600260A 01030303 00000002 00003001
00006000 00000060 D90A0000 D90A0000
00000000 00000000 00000800 02000000
30000000 01050900 00040000 87000000
02040900 00040000 87000000 FF000000
01000000 40000000 0F000000 01010000
04000000 00000000 0E000000 00000000

which translates to:

0600260A                    -> layout id       (AAPL,ig-platform-id)
01                          -> mobile type     (framebuffer-mobile) 
03                          -> 3 x pipes       (framebuffer-pipecount)
03                          -> 3 x ports       (framebuffer-portcount)
03                          -> 3 x memories    (framebuffer-memorycount)
00000002                    -> 32MB stolen mem (framebuffer-stolenmem)      // Rehabman's DVMT-prealloc requirement
00003001                    -> 19MB FB mem     (framebuffer-fbmem)          // Rehabman's framebuffer size
00006000                    -> 6MB Cursor mem  (framebuffer-cursormem)      // Rehabman's cursor bytes
00000060                    -> 1536MB VRAM     (framebuffer-unifiedmem)
D90A0000                    -> Backlight freq 2777MHz
D90A0000                    -> Max. backlight freq 2777MHz
00000000 00000000
00000800 02000000 30000000  -> port #1/FB@0: index 00, busid 00, pipe 0800, type 02000000=LVDS/eDP (framebuffer-con0-type), flags 30020000
01050900 00040000 87000000  -> port #2/FB@1: index 01, busid 05, pipe 0900, type 00040000=DP       (framebuffer-con1-type), flags 87000000
02040900 00040000 87000000  -> port #3/FB@2: index 02, busid 04, pipe 0900, type 00040000=DP       (framebuffer-con2-type), flags 87000000
FF000000 01000000 40000000 0F000000
01010000 04000000 00000000 0E000000
00000000

 

2) Broadwell BDW mobile framebuffer 0x1626006 (used for HD5300/HD5500/HD5600 iGPUs on laptops):

ID: 16260006, STOLEN: 34 MB, FBMEM: 21 MB, VRAM: 1536 MB, Flags: 0x00000B0B
TOTAL STOLEN: 56 MB, TOTAL CURSOR: 1 MB (1572864 bytes), MAX STOLEN: 124 MB, MAX OVERALL: 125 MB (131608576 bytes)
Camellia: CamelliaDisabled (0), Freq: 2777 Hz, FreqMax: 2777 Hz
Mobile: 1, PipeCount: 3, PortCount: 3, FBMemoryCount: 3
[0] busId: 0x00, pipe: 8, type: 0x00000002, flags: 0x00000230 - ConnectorLVDS
[1] busId: 0x05, pipe: 11, type: 0x00000400, flags: 0x00000507 - ConnectorDP
[2] busId: 0x04, pipe: 11, type: 0x00000400, flags: 0x00000507 - ConnectorDP
00000800 02000000 30020000
01050B00 00040000 07050000
02040B00 00040000 07050000

If we look inside the binary code of the Broadwell BDW framebuffer kext, we'll find:

06002616 01030303 00002002 00005001
00000060 D90A0000 D90A0000 00000000
00000000 00000000 00000800 02000000
30020000 01050B00 00040000 07050000
02040B00 00040000 07050000 FF000000
01000000 40000000 0B0B0000 01010500
00000000 05000000 00000000 04000000
00000000 00000000 00000000 00000000
00000000 C8000000

which translates to:

06002616                    -> layout id       (AAPL,ig-platform-id)
01                          -> mobile type     (framebuffer-mobile) 
03                          -> 3 x pipes       (framebuffer-pipecount)
03                          -> 3 x ports       (framebuffer-portcount)
03                          -> 3 x memories    (framebuffer-memorycount)
00002002                    -> 34MB stolen mem (framebuffer-stolenmem)     // Rehabman's framebuffer size
00005001                    -> 21MB FB mem     (framebuffer-fbmem)         // Rehabman's cursor bytes
00000060                    -> 1536MB VRAM     (framebuffer-unifiedmem)
D90A0000                    -> Backlight freq 2777MHz
D90A0000                    -> Max. backlight freq 2777MHz
00000000 00000000 00000000
00000800 02000000 30020000  -> port #1/FB@0: index 00, busid 00, pipe 0800, type 02000000=LVDS/eDP (framebuffer-con0-type), flags 30020000
01050B00 00040000 07050000  -> port #2/FB@1: index 01, busid 05, pipe 0B00, type 00040000=DP       (framebuffer-con1-type), flags 07050000
02040B00 00040000 07050000  -> port #3/FB@2: index 02, busid 04, pipe 0B00, type 00040000=DP       (framebuffer-con2-type), flags 07050000
FF000000 01000000 40000000 0B0B0000
01010500 00000000 05000000 00000000
04000000 00000000 00000000 00000000
00000000 00000000 C8000000

 

3) Skylake SKL mobile framebuffer 0x19160000 (used for HD520/HD530/HD540 iGPU on laptops):

ID: 19160000, STOLEN: 34 MB, FBMEM: 21 MB, VRAM: 1536 MB, Flags: 0x0000090F
TOTAL STOLEN: 56 MB, TOTAL CURSOR: 1 MB (1572864 bytes), MAX STOLEN: 124 MB, MAX OVERALL: 125 MB (131608576 bytes)
Model name: Intel HD Graphics SKL CRB
Camellia: CamelliaDisabled (0), Freq: 1388 Hz, FreqMax: 1388 Hz
Mobile: 1, PipeCount: 3, PortCount: 3, FBMemoryCount: 3
[0] busId: 0x00, pipe: 8, type: 0x00000002, flags: 0x00000098 - ConnectorLVDS
[1] busId: 0x05, pipe: 9, type: 0x00000400, flags: 0x00000187 - ConnectorDP
[2] busId: 0x04, pipe: 10, type: 0x00000400, flags: 0x00000187 - ConnectorDP
00000800 02000000 98000000
01050900 00040000 87010000
02040A00 00040000 87010000

We can't look at the binary code of the Skylake SKL framebuffer because Apple changed the way things are coded inside but it basically translates as follows:

00001619                    -> layout id       (AAPL,ig-platform-id)
01                          -> mobile type     (framebuffer-mobile) 
03                          -> 3 x pipes       (framebuffer-pipecount)
03                          -> 3 x ports       (framebuffer-portcount)
03                          -> 3 x memories    (framebuffer-memorycount)
00002002                    -> 34MB stolen mem (framebuffer-stolenmem)     // Rehabman's framebuffer size
00005001                    -> 21MB FB mem     (framebuffer-fbmem)         // Rehabman's cursor bytes
00000060                    -> 1536MB VRAM     (framebuffer-unifiedmem)
6C050000                    -> Backlight freq 1388MHz
6C050000                    -> Max. backlight freq 1388MHz

00000800 02000000 98000000  -> port #1/FB@0: index 00, busid 00, pipe 0800, type 02000000=LVDS/eDP (framebuffer-con0-type), flags 98000000
01050900 00040000 87010000  -> port #2/FB@1: index 01, busid 05, pipe 0900, type 00040000=DP       (framebuffer-con1-type), flags 87010000
02040a00 00040000 87010000  -> port #3/FB@2: index 02, busid 04, pipe 0a00, type 00040000=DP       (framebuffer-con2-type), flags 87010000

 

With the exception of the Haswell Azul framebuffer, we can see that Broadwell BDW and Skylake SKL framebuffers define framebuffer size (WEG's stolenmem) and cursor bytes (WEG's fbmem) characteristics and no DVMT pre-allocated memory (i.e. proper stolen memory). This extends to Kaby Lake KBL framebuffers and later. In my opinion, it's fair to say that Rehabman's description and wording are the most appropriate/best ones when the WEG view of things got somehow misled by following through on the Haswell framebuffer decoding. To me, there was some mixup, leading to confusion and the said confusion has remained ever since...

 

Confusion... why?

Because of several things:

1) the observation that the Haswell Azul framebuffers used on Hacks (0x0D220003 for desktops and 0x0A260006 for laptops) defined:

  • a DVMT pre-allocated memory (=Stolen memory) requirement of 32MB
  • a framebuffer size of 19MB
  • a cursor bytes of 0MB (desktops) and 6MB (laptops; required to be increased to 9MB to fix a minor graphics glitch on some systems)

2) the observation that the Broadwell BDW framebuffers used on Hacks (0x16220007 for desktops and 0x16160006 for laptops) defined:

  • no DVMT pre-allocated memory requirement at all
  • framebuffer sizes of 38MB and 34MB respectively
  • cursor bytes of 38MB and 21MB respectively

3) the observation that framebuffer size + cursor bytes must be lower than the size of the DVMT pre-allocated memory, failing which a KP occurs at graphics initialization during startup/boot.

 

4) In the case of the Haswell Azul framebuffers:

  1. DVMT pre-allocated memory requirement is set at 32MB
  2. framebuffer size + cursor bytes = 19+0 | 19+6 (or 19+9) = 19MB | 25MB (or 28MB) which is lower than DVMT pre-allocated memory 32MB

=> All is Ok by default.

 

5) In the case of the Broadwell BDW framebuffers:

  1. framebuffer size + cursor bytes for desktops = 38+38 = 76MB which is greater than the usual/default 32MB DVMT pre-allocated memory of most desktops, unless adjusted in BIOS
  2. framebuffer size + cursor bytes for laptops = 34+21 = 55MB which is greater than the usual/default 32MB DVMT pre-allocated memory of most laptops, unless adjusted in BIOS

=> Not Ok by default, KP encountered.

 

6) And the story is the same with subsequent Skylake, Kaby Lake, etc. framebuffers.

 

Solution:

2 x solutions were engineered to address the issue of KP at graphics initialisation.

  1. increase the DVMT pre-allocated memory set in BIOS. Could be complicated and tricky for PCs that do not offer this in BIOS Setup but made easy with Grub Shell if DVMT pre-allocated memory can be identified in BIOS.
  2. patch the Broadwell, Skylake, Kaby Lake, etc. framebuffer layouts to reduce framebuffer size and cursor bytes so that the sum of them totals less than the usual default DVMT pre-allocated memory of 32MB.

Although some people do opt for the 1st solution, most people just adopt the 2nd one.

 

How were the framebuffer patches derived?

If we look at the framebuffer patches that are commonly and generally used, we can observe that they set:

  • WEG's framebuffer-stolenmem property , i.e. framebuffer size to 0x01300000 = 19MB (DATA type set to 00003001)
  • WEG's framebuffer-fbmem property, i.e. cursor bytes to 0x00900000 = 9MB (DATA type set to 00009000)

i.e. the values typically used on laptops with Haswell iGPUs, this simply because 19+9=28MB which is < 32MB. This is where it all appears to come from.

 

Is this correct?

By far and large, it is.

 

But the need to apply such patches depends entirely on the host PC's default DVMT pre-allocated memory. On desktop and laptop PCs where DVMT pre-allocated memory can be adjusted in BIOS setup, the patches are unnecessary as long as the DVMT value that is set exceeds the total of the framebuffer size + cursor bytes of the selected/target graphics framebuffer. Typically, a value of 64MB or 96MB takes care of things perfectly. Of course, those PCs manufactured with DVMT pre-allocated memory set to 64MB or more are unlikely to encounter any issue at all.

 

The patches are also unnecessary if the default DVMT pre-allocated memory is increased either though BIOS binmod (difficult and risky) or through Grub shell mod (easy and quickly reversible). This is well illustrated on Firewolf's blog, linked above (there are other places too). To give an example, on some Dell laptops (eg. Skylake Latitude E7x70), DVMT pre-allocated memory can be increased by booting a Grub shell and entering the following command:

setup_var 0x432 0x3

This sets DVMT pre-allocated memory parameter located at offset 0x432 to 96MB (0x1 for 32MB, 0x2 for 64MB, 0x3 for 96MB, etc.), the default setting for the laptop in this example being 32MB. This setting will remain valid/in place until BIOS is reset to default settings. Of course, different computers will have different locations/offsets for DVMT pre-allocated memory.

 

What should I do then?

As stated above, the above patches apply to most cases. Those who feel adventurous or who are computing-literate may opt for the BIOS adjustment alternative. In all cases, the 1st thing to do is to look at the default framebuffer size and cursor bytes settings of the targeted graphics framebuffer, then decide if the sum of them both fits or not in 32MB or any other value set in BIOS for DVMT pre-allocated memory.

 

Can I use different values?

Absolutely! As long as the golden rule is respected: framebuffer size + cursor bytes < DVMT pre-alloc mem or, in WEG's conventions, stolenmem + fbmem < DVMT pre-alloc mem.

 

To give an example, I experimented on my Skylake/HD520 Dell Latitude E7270 Hackintosh laptop:

  • default DVMT pre-allocated memory value set in BIOS: 32MB
  • target SKL framebuffer layout: 0x19160000
  • default framebuffer size: 34MB
  • default cursor bytes: 21MB
  • sum of framebuffer size + cursor bytes: 55MB (i.e. > 32MB)
  1. Booting with default DVMT pre-alloc mem + no framebuffer patches -> KP/freeze
  2. Booting with default DVMT pre-alloc mem + framebuffer size 20MB + cursor bytes 12MB -> KP
  3. Booting with default DVMT pre-alloc mem + framebuffer size 19MB + cursor bytes 9MB -> Ok, full graphics acceleration
  4. Booting with default DVMT pre-alloc mem + framebuffer size 20MB + cursor bytes 10MB -> Ok, full graphics acceleration
  5. Booting with DVMT pre-alloc mem set to 64MB (Grub shell) + no framebuffer patches -> Ok, full graphics acceleration
  6. Booting with DVMT pre-alloc mem set to 96MB (Grub shell) + no framebuffer patches -> Ok, full graphics acceleration + 4K output
  • Like 4
  • Thanks 5
Link to comment
Share on other sites

  • Hervé changed the title to What are DVMT, stolenmem, fbmem, cursormem and why do we patch these?
  • Hervé changed the title to What are DVMT, stolenmem, fbmem, cursormem and why do we patch these for Broadwell and later?
  • Hervé locked and unlocked this topic
 Share

×
×
  • Create New...