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
|
|
|
|
2024-09-17 10:02:43 -05:00
|
|
|
FIFO := struct {
|
|
|
|
reserved_size: u32,
|
|
|
|
using_bounce_buffer: u8,
|
2024-09-17 12:08:19 -05:00
|
|
|
//bounce_buffer: [u8; 1024 * 1024],
|
2024-09-17 10:02:43 -05:00
|
|
|
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)
|
2024-09-17 10:02:43 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
2024-09-17 10:02:43 -05:00
|
|
|
fifo: FIFO,
|
|
|
|
irq: IRQ,
|
2024-09-14 03:51:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
svga_device := fn(): SVGADevice {
|
|
|
|
pci_addr := PCIAddress.(0, 0, 0)
|
2024-09-17 10:02:43 -05:00
|
|
|
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
|
2024-09-17 10:02:43 -05:00
|
|
|
}
|