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 }
pci_find_device
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
pci_read32
uint32_t pci_read32(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset)
Чтение данных из шины PCI.
Definition: pci.c:54