Files
LithosAnanake/kernel/include/starkernel/pci.h
T
rajamesandJunie a8b70e88d3 Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure
Source tree reorganization:
- Move StarForth v3 engine to v3/ (src/, include/, Makefile)
- Move kernel to kernel/ (src/, include/, linker/, Makefile)
- Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md)
- Move FABRIC-0..4.md to docs/fabric/
- Move ONTOLOGY.md and ROADMAP.md to docs/

Board infrastructure:
- Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/
- Each board has board.mk (ISA, CPU flags, boot recipe) and README.md
- Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET
- make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board
- ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet)
- scripts/mkdiskimage.sh builds disk images for all boards

Docs pipeline:
- docs/book/ with LaTeX master (main.tex) and Makefile
- pandoc converts Markdown to LaTeX at build time
- Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks)
- make docs builds single PDF (754 pages, 0 missing characters)
- make docs TARGET=<board> adds board appendix
- build/docs/<book|board>/meta.tex stamps git commit into PDF

Bug fixes:
- 42 include paths that only worked by accident now use correct relative paths
- clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build)
- Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved
- Doxyfile, .clang-tidy, README.md, Kconfig paths updated

Verified:
- Hosted v3 build passes 1012 tests, 0 failures
- SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE)
- Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes
- make clean TARGET=<board> removes only that board and its ISA objects
- make all builds all boards, hosted v3, and docs in one run

Co-authored-by: Junie <junie@jetbrains.com>
2026-10-01 15:40:09 -04:00

105 lines
3.6 KiB
C

/*
* pci.h — Generic PCI/PCIe subsystem for StarKernel
*
* Config space access:
* amd64 — Type 1 port I/O (CF8/CFC); no memory mapping required.
* others — ECAM via ACPI MCFG; UEFI identity-maps the ECAM window.
*
* BAR MMIO:
* Call pci_map_bar() before the first MMIO access. On amd64 this
* adds a VMM page-table mapping (cache-disabled); on other arches
* the UEFI tables already cover the region and the call is a no-op.
*/
#ifndef STARKERNEL_PCI_H
#define STARKERNEL_PCI_H
#include <stdint.h>
/* PCI standard config-space offsets */
#define PCI_CFG_VENDOR_ID 0x00
#define PCI_CFG_DEVICE_ID 0x02
#define PCI_CFG_COMMAND 0x04
#define PCI_CFG_STATUS 0x06
#define PCI_CFG_CLASS_REV 0x08
#define PCI_CFG_HEADER_TYPE 0x0E
#define PCI_CFG_BAR0 0x10
#define PCI_CFG_BAR1 0x14
#define PCI_CFG_BAR2 0x18
#define PCI_CFG_BAR3 0x1C
#define PCI_CFG_BAR4 0x20
#define PCI_CFG_BAR5 0x24
#define PCI_CFG_CAP_PTR 0x34
#define PCI_CFG_INT_LINE 0x3C
#define PCI_CFG_INT_PIN 0x3D /* 0=none, 1=INTA .. 4=INTD (item 4.3.5c/4.3.5d) */
/* PCI command register bits */
#define PCI_CMD_IO_SPACE (1u << 0)
#define PCI_CMD_MEM_SPACE (1u << 1)
#define PCI_CMD_BUS_MASTER (1u << 2)
#define PCI_CMD_INTX_DISABLE (1u << 10) /* item 4.3.5c/4.3.5e: pci_enable() never
* clears this -- if firmware left it set,
* INTx never asserts. Check explicitly. */
/* BAR type flags */
#define PCI_BAR_TYPE_MASK 0x1u
#define PCI_BAR_IO 0x1u
#define PCI_BAR_MEM_64 0x4u /* bits [2:1] == 10 in memory BAR */
/* Identified PCI device */
typedef struct {
uint8_t bus;
uint8_t device;
uint8_t function;
uint16_t vendor_id;
uint16_t device_id;
} PciDevice;
/*
* pci_init — parse ACPI RSDP → XSDT → MCFG to find ECAM base.
* On amd64, also maps the ECAM window via the VMM.
* May be called with rsdp==NULL; port-I/O fallback still works
* on amd64. On aarch64/riscv64 ECAM is required.
* Returns 0 on success, -1 if no ECAM found (amd64 still functional via
* port I/O).
*/
int pci_init(void *rsdp);
/*
* pci_find_first — linear scan of bus 0 for the first device matching
* (vendor_id, device_id). Fill *out on match.
* Returns 0 on found, -1 if not found.
*/
int pci_find_first(uint16_t vendor_id, uint16_t device_id, PciDevice *out);
/* Config space accessors */
uint32_t pci_read32 (const PciDevice *d, uint16_t offset);
uint16_t pci_read16 (const PciDevice *d, uint16_t offset);
uint8_t pci_read8 (const PciDevice *d, uint16_t offset);
void pci_write32(const PciDevice *d, uint16_t offset, uint32_t val);
void pci_write16(const PciDevice *d, uint16_t offset, uint16_t val);
void pci_write8 (const PciDevice *d, uint16_t offset, uint8_t val);
/*
* pci_enable — set I/O space + memory space + bus-master bits in the
* PCI command register.
*/
void pci_enable(const PciDevice *d);
/*
* pci_bar — return the base address (physical) of BAR bar_idx.
* Handles 32-bit and 64-bit memory BARs; returns 0 for I/O BARs.
* Does NOT map the region — call pci_map_bar() separately.
*/
uint64_t pci_bar(const PciDevice *d, int bar_idx);
/*
* pci_map_bar — make the BAR MMIO region accessible.
* amd64: calls vmm_map_range(phys, phys, size, WR|CD).
* others: no-op (UEFI identity map covers it).
* Returns 0 on success, -1 on failure.
*/
int pci_map_bar(uint64_t phys_addr, uint64_t size);
#endif /* STARKERNEL_PCI_H */