SayoriOS  0.3.3
intel.c
1 // Intel HD Graphics (8086:2a42) driver by NDRAEY (c) 2024
2 // WARNING: Driver is in WIP STAGE
3 // For SayoriOS ;)
4 
5 #include "drv/pci.h"
6 #include "io/ports.h"
7 #include "io/tty.h"
8 #include "mem/pmm.h"
9 #include "mem/vmm.h"
10 #include "gfx/intel.h"
11 #include "net/endianess.h"
12 
13 
14 uint8_t igfx_bus = 0,
15  igfx_slot = 0,
16  igfx_func = 0;
17 
18 size_t igfx_addr = 0;
19 
20 size_t igfx_width = 0;
21 size_t igfx_height = 0;
22 
23 #define IGFX_READ(reg) (*(volatile uint32_t*)(igfx_addr + reg))
24 #define IGFX_WRITE(reg, val) (*(volatile uint32_t*)(igfx_addr + reg) = (uint32_t)val)
25 
26 #define IGFX_READ8(reg) (*(volatile uint8_t*)(igfx_addr + reg))
27 #define IGFX_WRITE8(reg, val) (*(volatile uint8_t*)(igfx_addr + reg) = (uint8_t)val)
28 
29 
30 volatile size_t igfx_edid_buffer[32] = {0};
31 
32 void igfx_gmbus_reset() {
33  IGFX_WRITE(IGFX_GMBUS1, 0x80000000);
34  IGFX_WRITE(IGFX_GMBUS1, 0);
35 
36  while(IGFX_READ(IGFX_GMBUS2) & (1 << 9))
37  ;
38 }
39 
40 void igfx_wait() {
41  while (!(IGFX_READ(IGFX_GMBUS2) & (1 << 11)))
42  ;
43 }
44 
45 void igfx_init() {
46  // TODO: Add 0x5a85 support
47  pci_find_device(0x8086, 0x2a42, &igfx_bus, &igfx_slot, &igfx_func);
48 
49  if(igfx_bus == 0xFF) {
50  qemu_err("NO INTEL GFX!");
51  tty_printf("NO INTEL GFX!\n");
52 
53  return;
54  } else {
55  qemu_ok("INTEL GFX!");
56  tty_printf("INTEL GFX!\n");
57  }
58 
59  pci_enable_bus_mastering(igfx_bus, igfx_slot, igfx_func);
60 
61  igfx_addr = pci_read32(igfx_bus, igfx_slot, igfx_func, PCI_BAR0) & ~0xF;
62 
63  map_pages(
64  get_kernel_page_directory(),
65  igfx_addr,
66  igfx_addr,
67  0x100000,
68  PAGE_WRITEABLE | PAGE_CACHE_DISABLE
69  );
70 
71  tty_printf("IGFX: %d.%d.%d AT %x\n", igfx_bus, igfx_slot, igfx_func, igfx_addr);
72 
73 
74  // HERE GOES THE HELL
75 
76  size_t gmbus1 = (1 << 30) /* Ready */
77  | (1 << 26) /* Index used = 0 */
78  | (1 << 25) /* Cycle ends in WAIT */
79  | (128 << 16) /* EDID is 128 bytes long */
80  | (0x50 << 1) /* IDK why offset is 0x50 */
81  | 1; /* Read direction */
82 
83  tty_printf("RESETTING\n");
84 
85  igfx_gmbus_reset();
86 
87  tty_printf("OK\n");
88 
89  IGFX_WRITE(IGFX_GMBUS0, 3);
90  IGFX_WRITE(IGFX_GMBUS1, gmbus1);
91 
92  tty_printf("Sent READ to controller!\n");
93 
94  for(int i = 0; i < 32; i++) {
95  igfx_wait();
96 
97  uint32_t our_dword = IGFX_READ(IGFX_GMBUS3);
98 
99  igfx_edid_buffer[i] = our_dword;
100  // tty_printf("%x %x %x %x ",
101  // (our_dword >> 24) & 0xff,
102  // (our_dword >> 16) & 0xff,
103  // (our_dword >> 8) & 0xff,
104  // our_dword & 0xff);
105  }
106 
107  tty_printf("\nSTOPPING TRANSACTIONS\n");
108 
109  IGFX_WRITE(IGFX_GMBUS1, (1 << 30) | (1 << 27));
110 
111  tty_printf("\nOKAY!\n");
112 
113 
114 
115  uint8_t* data = (uint8_t*)igfx_edid_buffer;
116 
117  igfx_width = ((data[0x3a] >> 4) << 8) | (data[0x38]);
118  igfx_height = ((data[0x3d] >> 4) << 8) | (data[0x3b]);
119 
120  tty_printf("WIDTH: %d; HEIGHT: %d\n", igfx_width, igfx_height);
121 
122 
123  asm volatile("cli");
124 
125 
126  // START
127  IGFX_WRITE(0x70080, IGFX_READ(0x70080) & ~0x27);
128  IGFX_WRITE(0x70084, 0);
129 
130  IGFX_WRITE(0x700c0, IGFX_READ(0x700c0) & ~0x27);
131  IGFX_WRITE(0x700c4, 0);
132 
133  IGFX_WRITE(0x70180, IGFX_READ(0x70180) & ~(1 << 31));
134  IGFX_WRITE(0x70184, 0);
135 
136  IGFX_WRITE(0x71180, IGFX_READ(0x71180) & ~(1 << 31));
137  IGFX_WRITE(0x71184, 0);
138 
139  // MIDDLE
140 
141  IGFX_WRITE(0x70024, IGFX_READ(0x70024) | 0x2);
142  IGFX_WRITE(0x71024, IGFX_READ(0x71024) | 0x2);
143 
144  IGFX_WRITE(0x70008, IGFX_READ(0x70008) & ~(1 << 31)); // disable pipe
145  IGFX_WRITE(0x71008, IGFX_READ(0x71008) & ~(1 << 31)); // disable pipe
146 
147  while(IGFX_READ(0x70008) & (1 << 30)) {}
148  while(IGFX_READ(0x71008) & (1 << 30)) {}
149 
150  size_t xaddr = 0x60000;
151 
152  if((IGFX_READ(0x61180) & (1 << 30))) {
153  xaddr += 0x1000;
154  }
155 
156  uint32_t command = (igfx_width - 1);
157  command <<= 16;
158  command |= (igfx_height - 1);
159 
160  // uint32_t command_old = ((command & 0xffff) << 16) | ((command >> 16) & 0xffff);
161 
162  IGFX_WRITE(xaddr + 0x1C, command);
163  // IGFX_WRITE(xaddr + 0x10190, command_old);
164 
165  uint32_t scanline_w = ((igfx_width + 15) & ~15) << 2;
166 
167  IGFX_WRITE(xaddr + 0x10188, scanline_w);
168  IGFX_WRITE(xaddr + 0x10184, 0);
169  IGFX_WRITE(xaddr + 0x1019c, (uint32_t)framebuffer_addr); // addr
170  IGFX_WRITE(xaddr + 0x10184, 0);
171 
172  // END
173  IGFX_WRITE(0x61230, IGFX_READ(0x61230) & ~(1 << 31)); // disable panel fitting
174  IGFX_WRITE(xaddr + 0x10008, IGFX_READ(xaddr + 0x10008) | (1 << 31)); // enable pipe
175  IGFX_WRITE(xaddr + 0x10180, IGFX_READ(xaddr + 0x10180) | (1 << 31)); // enable Display Plane A
176 
177 
178 // unmap_pages_overlapping(get_kernel_page_directory(), (virtual_addr_t)framebuffer_addr, framebuffer_size);
179 //
180 // framebuffer_size = ALIGN((igfx_width + 32) * igfx_height * 4, PAGE_SIZE);
181 //
182 // map_pages(get_kernel_page_directory(),
183 // (physical_addr_t)framebuffer_addr,
184 // (virtual_addr_t)framebuffer_addr,
185 // framebuffer_size,
186 // PAGE_WRITEABLE);
187 //
188 // memset(framebuffer_addr, 0xff, framebuffer_size);
189 //
190 // extern uint32_t framebuffer_width;
191 // extern uint32_t framebuffer_height;
192 //
193 // framebuffer_width = igfx_width;
194 // framebuffer_height = igfx_height;
195 // framebuffer_pitch = scanline_w;
196 //
197 // back_framebuffer_addr = krealloc(back_framebuffer_addr, framebuffer_size);
198 // memset(back_framebuffer_addr, 0x00, framebuffer_size);
199 
200  graphics_update(igfx_width, igfx_height, scanline_w);
201 
202  clean_tty_screen();
203 
204  tty_printf("Screen now tuned to: %dx%d; Size: %d; BackFB: %x\n", igfx_width, igfx_height, framebuffer_size, back_framebuffer_addr);
205 
206  asm volatile("sti");
207 }
void pci_find_device(uint16_t vendor, uint16_t device, uint8_t *bus_ret, uint8_t *slot_ret, uint8_t *func_ret)
[PCI] Поиск устройства по ID-поставшика и устройства
Definition: pci.c:362
uint32_t pci_read32(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset)
Чтение данных из шины PCI.
Definition: pci.c:54