forked from AbleOS/ableos
koniifer
1eee33ce8b
move dt_api to stn for ease of use do away with now redundant strobe example (colour example is basically strobe now)
157 lines
3.6 KiB
Plaintext
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
|
|
} |