ableos/sysdata/programs/svga_driver/src/device.hb
koniifer 1eee33ce8b fix icky pointer misalignment
move dt_api to stn for ease of use
do away with now redundant strobe example (colour example is basically strobe now)
2024-10-14 18:54:53 +01:00

157 lines
3.6 KiB
Plaintext

stn := @use("../../../libraries/stn/src/lib.hb");
.{string, memory, buffer, log} := stn
pci := @use("../../../libraries/pci/src/lib.hb");
.{PCIAddress, get_ids, config_read32} := pci
reg := @use("./reg.hb")
PCI_VENDOR_ID_VMWARE := 0x15AD
PCI_DEVICE_ID_VMWARE_SVGA2 := 1029
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
}
FIFO := struct {
reserved_size: u32,
using_bounce_buffer: u8,
//bounce_buffer: [u8; 1024 * 1024],
next_fence: u32,
}
new_fifo := fn(): FIFO {
//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)
}
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,
}
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)
}
// 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)
}
setup_device := fn(svga_dev: ^SVGADevice): void {
// 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)
pci_dev := pci.check_device(0, 3)
if pci_dev.device_id.vendor != PCI_VENDOR_ID_VMWARE {
log.error("SVGA device not found\0")
return
}
//| pci_dev.device_id.device != PCI_DEVICE_ID_VMWARE_SVGA2 {
svga_dev.ioBase = config_read32(svga_dev.pciAddr.bus, svga_dev.pciAddr.device, svga_dev.pciAddr.function, 0x10) & 0xFFFFFFF0
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)
// hardcode values for now
svga_dev.width = 1024
svga_dev.height = 768
svga_dev.bpp = 32
svga_dev.pitch = svga_dev.width * 4
svga_dev.fbSize = svga_dev.width * svga_dev.height * svga_dev.bpp / 8
svga_dev.vramSize = read_reg(svga_dev, 0x10)
log.info("SVGA device initialized successfully\0")
return
}
setup_framebuffer := fn(svga_dev: ^SVGADevice): void {
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)
log.info("Framebuffer setup complete\0")
return
}
draw_pixel := fn(svga_dev: ^SVGADevice, x: int, y: int, color: u32): void {
/*
if x >= svga_dev.width || y >= svga_dev.height {
return // what happens if we write outside here : )
}
*/
offset := y * svga_dev.pitch + x * svga_dev.bpp / 8
mem_addr := svga_dev.fbMem + offset
memory.outl(mem_addr, color)
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
}