1
0
Fork 0
forked from AbleOS/ableos
ableos/sysdata/programs/svga_driver/src/device.hb

161 lines
3.7 KiB
Plaintext
Raw Normal View History

2024-09-17 12:08:19 -05:00
stn := @use("../../../libraries/stn/src/lib.hb");
.{string, memory, buffer, log} := stn
2024-09-14 03:51:57 -05:00
pci := @use("../../../libraries/pci/src/lib.hb");
2024-09-19 14:40:10 -05:00
.{PCIAddress, get_ids, config_read32} := pci;
.{dt_get} := @use("../../../libraries/dt_api/src/lib.hb")
reg := @use("./reg.hb")
PCI_VENDOR_ID_VMWARE := 0x15AD
2024-09-20 05:06:08 -05:00
PCI_DEVICE_ID_VMWARE_SVGA2 := 1029
2024-09-19 14:40:10 -05:00
read_reg := fn(svga_dev: ^SVGADevice, index: u32): u32 {
memory.outl(svga_dev.ioBase, index)
return memory.inl(svga_dev.ioBase + 4)
}
write_reg := fn(svga_dev: ^SVGADevice, index: u32, value: u32): void {
memory.outl(svga_dev.ioBase, index)
memory.outl(svga_dev.ioBase + 4, value)
return
}
2024-09-14 03:51:57 -05:00
FIFO := struct {
reserved_size: u32,
using_bounce_buffer: u8,
2024-09-17 12:08:19 -05:00
//bounce_buffer: [u8; 1024 * 1024],
next_fence: u32,
}
new_fifo := fn(): FIFO {
2024-09-17 12:08:19 -05:00
//bounce_buffer := @as([u8; 1024 * 1024], idk)
/*bounce_buffer,*/
return FIFO.(0, 0, 0)
}
IRQ := struct {
pending: u32,
switchContext: u32,
//IntrContext oldContext;
//IntrContext newContext;
count: u32,
}
new_irq := fn(): IRQ {
return IRQ.(0, 0, 0)
}
2024-09-14 03:51:57 -05:00
SVGADevice := struct {
pciAddr: PCIAddress,
ioBase: u32,
fifoMem: ^u32,
fbMem: ^u8,
fifoSize: int,
fbSize: int,
vramSize: int,
deviceVersionId: int,
capabilities: int,
width: int,
height: int,
bpp: int,
pitch: int,
fifo: FIFO,
irq: IRQ,
2024-09-14 03:51:57 -05:00
}
svga_device := fn(): SVGADevice {
pci_addr := PCIAddress.(0, 0, 0)
fifo := new_fifo()
irq := new_irq()
return SVGADevice.(pci_addr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fifo, irq)
2024-09-19 14:40:10 -05:00
}
2024-09-20 05:06:08 -05:00
// TODO : this function is broken
GetBARAddr := fn(addr: PCIAddress, index: int): u32 {
//bar := config_read32(addr, offsetof(PCIConfigSpace, BAR[index]));
bar := config_read32(0, 3, 0, 0)
PCI_CONF_BAR_IO := 0
mask := 0xF
/*
if bar & PCI_CONF_BAR_IO {
0x3
} else {
}*/
return bar & (mask ^ 0xFFFFFFFF)
}
2024-09-19 14:40:10 -05:00
setup_device := fn(svga_dev: ^SVGADevice): void {
2024-09-20 05:06:08 -05:00
// TODO: Fix this
// refer to https://git.ablecorp.us/able/vmware-svga/src/commit/eea7ddcd0d34702f8f0a33c1933718706c6318c5/lib/refdriver/svga.c#L55
svga_dev.pciAddr = PCIAddress.(0, 3, 0)
/*
2024-09-19 14:40:10 -05:00
pci_id := get_ids(svga_dev.pciAddr.bus, svga_dev.pciAddr.device, svga_dev.pciAddr.function)
2024-09-20 05:06:08 -05:00
2024-09-19 14:40:10 -05:00
if pci_id.vendor != PCI_VENDOR_ID_VMWARE | pci_id.device != PCI_DEVICE_ID_VMWARE_SVGA2 {
log.error("SVGA device not found\0")
return
}
2024-09-20 05:06:08 -05:00
*/
2024-09-19 14:40:10 -05:00
svga_dev.ioBase = config_read32(svga_dev.pciAddr.bus, svga_dev.pciAddr.device, svga_dev.pciAddr.function, 0x10) & 0xFFFFFFF0
2024-09-20 05:06:08 -05:00
write_reg(svga_dev, reg.SVGA_REG_ENABLE, reg.SVGA_REG_ENABLE_ENABLE)
svga_dev.capabilities = read_reg(svga_dev, 0x1)
svga_dev.deviceVersionId = read_reg(svga_dev, 0x2)
svga_dev.fbMem = GetBARAddr(svga_dev.pciAddr, 1)
2024-09-19 14:40:10 -05:00
// hardcode values for now
svga_dev.width = 1024
svga_dev.height = 768
svga_dev.bpp = 32
svga_dev.pitch = svga_dev.width * 4
2024-09-20 05:06:08 -05:00
2024-09-19 14:40:10 -05:00
svga_dev.fbSize = svga_dev.width * svga_dev.height * svga_dev.bpp / 8
2024-09-20 05:06:08 -05:00
svga_dev.vramSize = read_reg(svga_dev, 0x10)
2024-09-19 14:40:10 -05:00
log.info("SVGA device initialized successfully\0")
2024-09-20 05:06:08 -05:00
2024-09-19 14:40:10 -05:00
return
}
setup_framebuffer := fn(svga_dev: ^SVGADevice): void {
2024-09-20 05:06:08 -05:00
write_reg(svga_dev, reg.SVGA_REG_WIDTH, svga_dev.width)
write_reg(svga_dev, reg.SVGA_REG_HEIGHT, svga_dev.height)
write_reg(svga_dev, reg.SVGA_REG_BITS_PER_PIXEL, svga_dev.bpp)
2024-09-19 14:40:10 -05:00
log.info("Framebuffer setup complete\0")
return
}
draw_pixel := fn(svga_dev: ^SVGADevice, x: int, y: int, color: u32): void {
2024-09-20 05:06:08 -05:00
/*
2024-09-19 14:40:10 -05:00
if x >= svga_dev.width || y >= svga_dev.height {
return // what happens if we write outside here : )
}
2024-09-20 05:06:08 -05:00
*/
2024-09-19 14:40:10 -05:00
offset := y * svga_dev.pitch + x * svga_dev.bpp / 8
mem_addr := svga_dev.fbMem + offset
memory.outl(mem_addr, color)
2024-09-20 05:06:08 -05:00
2024-09-19 14:40:10 -05:00
return
}
clear_screen := fn(svga_dev: ^SVGADevice, color: u32): void {
y := 0
loop if y == svga_dev.height break else {
x := 0
loop if x == svga_dev.width break else {
draw_pixel(svga_dev, x, y, color)
x += 1
}
y += 1
}
return
}