Advertisement
TimothyMadden

Set straps bits for 8GB BAR size on GTX 1080

Nov 14th, 2023 (edited)
224
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.78 KB | Source Code | 0 0
  1. #include <stdint.h>
  2. #include <limits.h>
  3. #include <sys/io.h>
  4.  
  5. enum BARSizeSelect
  6. {
  7.     _256M = 0,
  8.     _512M = 1,
  9.     _1G = 2,
  10.     _2G = 3,
  11.     _4G = 4,
  12.     _8G = 5,
  13.     _16G = 6,
  14.     _32G = 7
  15. };
  16.  
  17. #define TARGET_PCI_VENDOR_ID 0x10DEu
  18. #define TARGET_PCI_DEVICE_ID_GTX_1080 0x1B80u
  19.  
  20. inline uint32_t ReadDWORD(uint32_t addressSelector)
  21. {
  22.     return outl(addressSelector, 0x0cf8U), (uint32_t) inl(0x0cfcU);
  23. }
  24.  
  25. inline void WriteDWORD(uint32_t addressSelector, uint32_t outputValue)
  26. {
  27.     outl(addressSelector, 0x0cf8U), outl(outputValue, 0x0cfcU);
  28. }
  29.  
  30. void DebuggerWriteOutputLED(uint8_t ledValue)
  31. {
  32.     outb(ledValue, 0x0080);
  33.    
  34.     while (int i = (uint32_t)0x8000_0000; --i)
  35.         ;   // could be a delay after the port write, to allow seing the output on the physical LEDs
  36. }
  37.  
  38. uint32_t configure_bridge_for_GTX_1080_Straps(uint64_t save_area[4u])
  39. {
  40.     uint32_t addressSelector =      // 0x80001804   (PCI vendor ID: 8086, PCI device ID: 6f08)
  41.           1u << 31              // Cmd
  42.         | 0u << 16              // Bus
  43.         | 3u << 11              // Dev
  44.         | 0u <<  8              // Fun
  45.         | 4u <<  0;             // Reg
  46.        
  47.     // register offset 0x04
  48.     save_area[0u] = ReadDWORD(addressSelector);
  49.     WriteDWORD(addressSelector,  save_area[0u] | 0x0007u);
  50.    
  51.     // register offset 0x18
  52.     addressSelector +=  0x0014u;
  53.     save_area[1u] = ReadDWORD(addressSelector);
  54.     WriteDWORD(addressSelector,  save_area[1u] | 0x00030300u);
  55.    
  56.     // register offset 0x1c
  57.     addressSelector += 0x0004u;
  58.     save_area[2u] = ReadDWORD(addressSelector) ;
  59.     WriteDWORD(addressSelector, save_area[2u] & 0xFFFF0000u | 0xe0e0u);
  60.    
  61.     // register offset 0x20
  62.     addressSelector += 0x0004u;
  63.     save_area[3u] = ReadDWORD(addressSelector);
  64.     WriteDWORD(addressSelector, 0xfb00fa00u);
  65.    
  66.     return addressSelector;
  67. }
  68.  
  69. void restore_bridge_config(uint32_t lastAddressSelector, uint64_t const save_area[4])
  70. {
  71.     WriteDWORD(lastAddressSelector, save_area[3u]);
  72.    
  73.     lastAddressSelector -= 0x0004u;
  74.     WriteDWORD(lastAddressSelector, save_area[2u]);
  75.    
  76.     lastAddressSelector -= 0x0004u;
  77.     WriteDWORD(lastAddressSelector, save_area[1u]);
  78.    
  79.     lastAddressSelector -= 0x0014u;
  80.     WriteDWORD(lastAddressSelector, save_area[0u]);
  81. }
  82.  
  83. uint32_t configure_gtx_1080_for_Straps(uint64_t save_area[2u])
  84. {
  85.     uint32_t addressSelector =      // 80030004h  (PCI vendor ID: 10de, PCI device ID: 1b80)
  86.           1 << 31               // Cmd
  87.         | 3 << 16               // Bus
  88.         | 0 << 11               // Dev
  89.         | 0 <<  8               // Fun
  90.         | 4 <<  0;              // Reg
  91.    
  92.     // register offset 0x04
  93.     save_area[0u] = ReadDWORD(addressSelector);
  94.     WriteDWORD(addressSelector, save_area[0u] | 0x0003u);
  95.    
  96.     // register offset 0x10
  97.     addressSelector += 0x000Cu;
  98.                                                     // this call here appears to be missing !!! -- looks like a BUG
  99.     save_area[1u] = save_area[0u] | 0x0003u;        // save_area[1u] = ReadDWORD(addressSelector);
  100.     WriteDWORD(addressSelector, 0xfa000000u);
  101.    
  102.     return addressSelector;
  103. }
  104.  
  105. void restore_gtx_1080_config(uint32_t lastAddressSelector, uint64_t const save_area[2])
  106. {
  107.     WriteDWORD(lastAddressSelector, save_area[1u]);
  108.    
  109.     lastAddressSelector -= 0x000Cu;
  110.     WriteDWORD(lastAddressSelector, save_area[0u]);
  111. }
  112.  
  113. void set_gtx_1080_straps_to_config_rebar()
  114. {
  115.     uint32_t *straps_address = (uint32_t *)(void *)0xfa10100cu;
  116.  
  117.     *straps_address = *straps_address & 0xff8fffff | (BARSizeSelect::_8G << 20 | 0x80000000);
  118. }
  119.  
  120. void configure_GTX_1080_Straps()
  121. {
  122.     if (vid != TARGET_PCI_VENDOR_ID && did != TARGET_PCI_DEVICE_ID_GTX_1080)
  123.         return;
  124.  
  125.     DebuggerWriteOutputLED(0x77u);
  126.    
  127.     uint64_t bridge_config_save[4];
  128.     uint64_t gtx_1080_config_save[2];
  129.    
  130.     uint32_t bridgeAddressSelector = configure_bridge_for_GTX_1080_Straps(bridge_config_save);
  131.     uint32_t gtx1080AddressSelector = configure_gtx_1080_for_Straps(gtx_1080_config_save);
  132.  
  133.     set_gtx_1080_straps_to_config_rebar();
  134.    
  135.     restore_gtx_1080_config(gtx1080AddressSelector, gtx_1080_config_save);
  136.     restore_bridge_config(bridgeAddressSelector, bridge_config_save);
  137. }
Tags: uefi
Advertisement
Comments
  • TimothyMadden
    178 days
    # text 0.12 KB | 0 0
    1. Manually translated from the assembly listing at https://github.com/xCuri0/ReBarUEFI/discussions/89#discussioncomment-7231298
Add Comment
Please, Sign In to add comment
Advertisement