Files
ViperOS/VKernel/Kernel/drivers/usb/pci.vp
T
TermiNexus a518f75b24 chore(vkernel): 重置基线 — 纳入 TPV codegen 修复配合的内核侧调整与既有工作区内容
- devfs.vp: string.split 传 PATH_BUFFER_SIZE(配合 split 新增容量参数)

- fat32_types.vp: lfn_extract 越界钳制(base+i > MAX_LFN 返回 -1)

- sheet.vp: gfx.Renderer 实参修正为 (fb, zb, w, h)(原单参导致 w/h=0 渲染空操作)

- 同批包含 VKernel 其余既有移植改动与 vpsdk/Apps/Libs 工作区内容
2026-09-11 14:27:01 +08:00

94 lines
3.5 KiB
Plaintext

import t, c
import asm
PCI_CONFIG_ADDR: t.CDefine = 0xCF8
PCI_CONFIG_DATA: t.CDefine = 0xCFC
PCI_CLASS_SERIAL_USB: t.CDefine = 0x0C03
PCI_CLASS_SERIAL_UHCI: t.CDefine = 0x0C0300
PCI_CLASS_SERIAL_OHCI: t.CDefine = 0x0C0310
PCI_CLASS_SERIAL_EHCI: t.CDefine = 0x0C0320
PCI_CLASS_SERIAL_XHCI: t.CDefine = 0x0C0330
PCI_CMD_IO_SPACE: t.CDefine = 0x0001
PCI_CMD_BUS_MASTER: t.CDefine = 0x0004
class pci_device(t.CStruct):
bus: uint8
dev: uint8
func: uint8
vendor_id: uint16
device_id: uint16
class_code: uint32
irq: uint8
bar: t.CArray[uint32, 6]
def pci_read32(bus: uint8, dev: uint8, func: uint8, offset: uint8) -> uint32:
addr: uint32 = 0x80000000 | (uint32(bus) << 16) | (uint32(dev) << 11) | (uint32(func) << 8) | (uint32(offset) & 0xFC)
asm.outl(PCI_CONFIG_ADDR, addr)
return asm.inl(PCI_CONFIG_DATA)
def pci_write32(bus: uint8, dev: uint8, func: uint8, offset: uint8, value: uint32):
addr: uint32 = 0x80000000 | (uint32(bus) << 16) | (uint32(dev) << 11) | (uint32(func) << 8) | (uint32(offset) & 0xFC)
asm.outl(PCI_CONFIG_ADDR, addr)
asm.outl(PCI_CONFIG_DATA, value)
def pci_read16(bus: uint8, dev: uint8, func: uint8, offset: uint8) -> uint16:
val: uint32 = pci_read32(bus, dev, func, offset)
shift: uint32 = (uint32(offset) & 0x02) * 8
return uint16((val >> shift) & 0xFFFF)
def pci_read8(bus: uint8, dev: uint8, func: uint8, offset: uint8) -> uint8:
val: uint32 = pci_read32(bus, dev, func, offset)
shift: uint32 = (uint32(offset) & 0x03) * 8
return uint8((val >> shift) & 0xFF)
def pci_get_class(bus: uint8, dev: uint8, func: uint8) -> uint32:
cls: uint8 = pci_read8(bus, dev, func, 0x0B)
sub: uint8 = pci_read8(bus, dev, func, 0x0A)
proto: uint8 = pci_read8(bus, dev, func, 0x09)
return (uint32(cls) << 16) | (uint32(sub) << 8) | uint32(proto)
def pci_get_bar(bus: uint8, dev: uint8, func: uint8, bar_idx: uint8) -> uint32:
return pci_read32(bus, dev, func, 0x10 + bar_idx * 4)
def pci_enable_device(dev: pci_device | t.CPtr):
cmd: uint16 = pci_read16(dev.bus, dev.dev, dev.func, 0x04)
cmd = cmd | PCI_CMD_IO_SPACE | PCI_CMD_BUS_MASTER
pci_write32(dev.bus, dev.dev, dev.func, 0x04, uint32(cmd))
def pci_fill_device(bus: uint8, dev_n: uint8, func: uint8, out: pci_device | t.CPtr):
out.bus = bus
out.dev = dev_n
out.func = func
out.vendor_id = pci_read16(bus, dev_n, func, 0x00)
out.device_id = pci_read16(bus, dev_n, func, 0x02)
out.class_code = pci_get_class(bus, dev_n, func)
out.irq = pci_read8(bus, dev_n, func, 0x3C)
i: int
for i in range(6):
out.bar[i] = pci_get_bar(bus, dev_n, func, uint8(i))
_uhci_dev: pci_device
_uhci_found: int = 0
def find_uhci() -> uint16:
global _uhci_dev, _uhci_found
bus: uint8
dev_n: uint8
func: uint8
for bus in range(1):
for dev_n in range(32):
for func in range(8):
vendor: uint16 = pci_read16(bus, dev_n, func, 0x00)
if vendor == 0xFFFF: continue
cls: uint32 = pci_get_class(bus, dev_n, func)
if cls == PCI_CLASS_SERIAL_UHCI:
pci_fill_device(bus, dev_n, func, c.Addr(_uhci_dev))
pci_enable_device(c.Addr(_uhci_dev))
_uhci_found = 1
bar: uint32 = _uhci_dev.bar[4]
io_base: uint16 = uint16(bar & 0xFFFE)
return io_base
return 0