mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
This is a rather large commit that is widely focused on cleaning things out of the 'junk drawer' that is src/include. Most notably, several things that were put in there because they needed somewhere where both the kernel, boot, and init could read them have been moved to a new lib, 'bootproto'. - Moved kernel_args.h and init_args.h to bootproto as kernel.h and init.h, respectively. - Moved counted.h and pointer_manipulation.h into util, renaming the latter to util/pointers.h. - Created a new src/include/arch for very arch-dependent definitions, and moved some kernel_memory.h constants like frame size, page table entry count, etc to arch/amd64/memory.h. Also created arch/memory.h which detects platform and includes the former. - Got rid of kernel_memory.h entirely in favor of a new, cog-based approach. The new definitions/memory_layout.csv lists memory regions in descending order from the top of memory, their sizes, and whether they are shared outside the kernel (ie, boot needs to know them). The new header bootproto/memory.h exposes the addresses of the shared regions, while the kernel's memory.h gains the start and size of all the regions. Also renamed the badly-named page-offset area the linear area. - The python build scripts got a few new features: the ability to parse the csv mentioned above in a new memory.py module; the ability to add dependencies to existing source files (The list of files that I had to pull out of the main list just to add them with the dependency on memory.h was getting too large. So I put them back into the sources list, and added the dependency post-hoc.); and the ability to reference 'source_root', 'build_root', and 'module_root' variables in .module files. - Some utility functions that were in the kernel's memory.h got moved to util/pointers.h and util/misc.h, and misc.h's byteswap was renamed byteswap32 to be more specific.
142 lines
4.2 KiB
C++
142 lines
4.2 KiB
C++
#pragma once
|
|
/// \file pci.h
|
|
/// PCI devices and groups
|
|
|
|
#include <stdint.h>
|
|
#include <util/pointers.h>
|
|
|
|
struct pci_group;
|
|
enum class isr : uint8_t;
|
|
|
|
struct pci_cap
|
|
{
|
|
enum class type : uint8_t
|
|
{
|
|
msi = 0x05,
|
|
msix = 0x11
|
|
};
|
|
|
|
type id;
|
|
uint8_t next;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/// Information about a discovered PCIe device
|
|
class pci_device
|
|
{
|
|
public:
|
|
/// Default constructor creates an empty object.
|
|
pci_device();
|
|
|
|
/// Constructor
|
|
/// \arg group The group of this device's bus
|
|
/// \arg bus The bus number this device is on
|
|
/// \arg device The device number of this device
|
|
/// \arg func The function number of this device
|
|
pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t func);
|
|
|
|
/// Check if this device is multi-function.
|
|
/// \returns True if this device is multi-function
|
|
inline bool multi() const { return m_multi; }
|
|
|
|
/// Get the bus number this device is on.
|
|
/// \returns The bus number
|
|
inline uint8_t bus() const { return (m_bus_addr >> 8); }
|
|
|
|
/// Get the device number of this device on its bus
|
|
/// \returns The device number
|
|
inline uint8_t device() const { return (m_bus_addr >> 3) & 0x1f; }
|
|
|
|
/// Get the function number of this device on its device
|
|
/// \returns The function number
|
|
inline uint8_t function() const { return m_bus_addr & 0x7; }
|
|
|
|
/// Get the device class
|
|
/// \returns The PCI device class
|
|
inline uint8_t devclass() const { return m_class; }
|
|
|
|
/// Get the device subclass
|
|
/// \returns The PCI device subclass
|
|
inline uint8_t subclass() const { return m_subclass; }
|
|
|
|
/// Get the device program interface
|
|
/// \returns The PCI device program interface
|
|
inline uint8_t progif() const { return m_progif; }
|
|
|
|
/// Read one of the device's Base Address Registers
|
|
/// \arg i Which BAR to read (up to 5 for non-bridges)
|
|
/// \returns The contents of the BAR
|
|
uint32_t get_bar(unsigned i);
|
|
|
|
/// Write one of the device's Base Address Registers
|
|
/// \arg i Which BAR to read (up to 5 for non-bridges)
|
|
/// \arg val The value to write
|
|
void set_bar(unsigned i, uint32_t val);
|
|
|
|
/// Write to the MSI registers
|
|
/// \arg addr The address to write to the MSI address registers
|
|
/// \arg data The value to write to the MSI data register
|
|
void write_msi_regs(uintptr_t addr, uint16_t data);
|
|
|
|
/// Get a bus address, given the bus/device/function numbers.
|
|
/// \arg bus Number of the bus
|
|
/// \arg device Index of the device on the bus
|
|
/// \arg func The function number within the device
|
|
/// \returns The computed bus_addr
|
|
static inline uint16_t bus_addr(uint8_t bus, uint8_t device, uint8_t func)
|
|
{
|
|
return bus << 8 | device << 3 | func;
|
|
}
|
|
|
|
private:
|
|
uint32_t *m_base;
|
|
pci_cap *m_msi;
|
|
|
|
/// Bus address: 15:8 bus, 7:3 device, 2:0 device
|
|
uint16_t m_bus_addr;
|
|
|
|
uint16_t m_vendor;
|
|
uint16_t m_device;
|
|
|
|
uint8_t m_class;
|
|
uint8_t m_subclass;
|
|
uint8_t m_progif;
|
|
uint8_t m_revision;
|
|
bool m_multi;
|
|
|
|
// Might as well cache these to fill out the struct align
|
|
isr m_irq;
|
|
uint8_t m_header_type;
|
|
};
|
|
|
|
|
|
/// Represents data about a PCI bus group from the ACPI MCFG
|
|
struct pci_group
|
|
{
|
|
uint16_t group;
|
|
uint16_t bus_start;
|
|
uint16_t bus_end;
|
|
|
|
uint32_t *base;
|
|
|
|
/// Get the base address of the MMIO configuration registers for a device
|
|
/// \arg bus The bus number of the device (relative to this group)
|
|
/// \arg device The device number on the given bus
|
|
/// \arg func The function number on the device
|
|
/// \returns A pointer to the memory-mapped configuration registers
|
|
inline uint32_t * base_for(uint8_t bus, uint8_t device, uint8_t func)
|
|
{
|
|
return util::offset_pointer(base,
|
|
pci_device::bus_addr(bus, device, func) << 12);
|
|
}
|
|
|
|
/// Check if the given device function is present.
|
|
/// \arg bus The bus number of the device (relative to this group)
|
|
/// \arg device The device number on the given bus
|
|
/// \arg func The function number on the device
|
|
/// \returns True if the device function is present
|
|
bool has_device(uint8_t bus, uint8_t device, uint8_t func);
|
|
};
|
|
|
|
|