This page tries to give an overview of all the facts that are used in the SKB.
SKB (System Knowledge Base)
Adrian gave a presentation at the Barcelona Workshop (2010) which is helpful as an introduction: http://wiki.barrelfish.org/BarcelonaWorkshop2010?action=AttachFile&do=view&target=skb.pdf
Check Adrians Phd Thesis for a good introduction of what the SKB does and how it does it.
Checklist
- What does the name of the fact stand for
- What information is contained in this fact (what is in the first, second, third argument)
- Where does this information come from (e.g., ACPI tables, generated based on other facts etc.) and who adds it to the SKB?
- Feel free to add anything I missed
- Bonus (for when we have the above questions for all the facts): How is this information used for in BF (or is it not used at all?) and for what can it be used for in the future?
Fact: addr(arg1, arg2, arg3)
Description: <insert text>
arg1: <insert text>
arg2: <insert text>
arg3: <insert text>
Static
These facts provide a basic representation of the hardware and are initialized upon boot.
apic(ApicProcessorID, ApicID, Usable)
- Description: Registration of each CPU and its APIC ID.
- ApicProcessorID [int] - The processor's Processor ID.
- ApicID [int] - The processor's local APIC ID.
- Usable [int] - "If zero, this processor is unusable, and the operating system support will not attempt to use it."
These details originate from the ACPI APIC table (MADT: Multiple APIC Description Table). Section 5.2.12.2, page 137 of the ACPI Specification) contains additional details.
If you are interested in the mapping between barrelfish CoreID and this entries, use corename
- Description: Registration of each CPU and its APIC ID.
ioapic(Id, Address, GlobalIrqBase)
Description: Registration of each I/O APIC device with its Id and the Address where it can be accessed.
- Id [uint8] - I/O APIC ID
- Address [uint32] - APIC physical address where this I/O APIC can be accessed
FlobalIrqBase [uint32] - Flobal system interrupt where INITI (interrupt inputs) lines start.
- defined in struct ACPI_MADT_IO_APIC (usr/acpi/acpica/include.h)
- added to SKB in usr/acpi/interrupts.c
more details can be found at Section 5.2.12.3 I/O APIC Structure of the ACPI Specs.
apic_nmi(ProcessorID, IntiFlags, Lint)
- Description: Registers the LINT (Local APIC interrupt input) that is NMI (non-maskable) for the given ProcessorID.
- ProcessorID [uint8] - ACPI processor id
IntiFlags [uint16] - MPS INTI flags. Encodes trigger mode/polarity.
- Lint [uint8] - LINTn to which NMI is connected
- defined in struct ACPI_MADT_LOCAL_APIC_NMI (usr/acpi/acpica/include.h)
more details can be found at Sections 5.2.12.6 and 5.2.12.7 (MADT) of the ACPI Specs.
- Description: Registers the LINT (Local APIC interrupt input) that is NMI (non-maskable) for the given ProcessorID.
interrupt_override(Bus, SourceIRQ, GlobalIRQ, IntiFlags)
- Description: Relation between legacy ISA interrupts and GSI
- Bus[int] - Bus number. Always 0 according to specs.
SourceIrq[int] - ISA interrupt number
- GSI[int] - GSI number
IntiFlags - MPS INTI flags. Encodes trigger mode/polarity.
- It is added by the ACPI service, it originates from the ACPI MADT table.
See section 5.2.12.5, (MADT) of the ACPI Specs.
- Description: Relation between legacy ISA interrupts and GSI
cpu_affinity(ApicID, LocalSapicEid, ProximityDomain)
- Description: Mapping from APIC or SAPIC ID to NUMA domain.
ApicID [int] - join with apic fact.
LocalSapicEid [int] - not generally used; most use cases will have an APIC ID.
ProximityDomain [uint32] - NUMA domain number (starting from 0), join with memory_affinity.
This information is added by the ACPI service and comes from SRAT (System Resource Affinity Table). For more details see section 5.2.16, page 151 of the ACPI Specification).
- Warning: these facts may not be available if the corresponding ACPI table is not present.
- Description: Mapping from APIC or SAPIC ID to NUMA domain.
node_distance(ProximityDomainFrom, ProximityDomainTo, !Distance)
- Description: Distance information between two NUMA nodes
ProximityDomainFrom [int] - NUMA ID of sender.
ProximityDomainTo [int] - NUMA ID of receiver.
- !Distance [uint8] - distance information.
- This information is added by the ACPI service and comes from SLIT see ACPI specification.
- Warning: this facts may not be added when the table is not present
- Description: Distance information between two NUMA nodes
memory_affinity(BaseAddress, Length, ProximityDomain)
- Description: association between physical memory and the NUMA domain it belongs to.
BaseAddress [uint64] - these two fields denote a range of physical memory [BaseAddress, BaseAddress+Length)
- Length[uint64]
ProximityDomain [uint32] - NUMA domain number
- Use case: implementation of NUMA-aware memory allocator.
As with cpu_affinity, this is also taken from the ACPI SRAT table.
- There is also some extra flags which is not exported (bool hotpluggable, bool nonvolatile)
- Description: association between physical memory and the NUMA domain it belongs to.
mem_region_type(Type, Name)
Description: set of predefined values for the Type field of memory_region.
Type [int] - integer values corresponding to 'enum region_type' in <barrelfish_kpi/init.h>.
- Name [atom] - convenience name for use from Prolog.
- Example content:
mem_region_type(0, ram). # RegionType_Empty mem_region_type(1, roottask). # RegionType_RootTask mem_region_type(2, phyaddr). # RegionType_PhyAddr mem_region_type(4, multiboot_module). # RegionType_Module mem_region_type(3, platform_data). # RegionType_PlatformData mem_region_type(5, apic). # RegionType_LocalAPIC mem_region_type(6, ioapic). # RegionType_IOAPIC
Intel Vt-d
These facts are discovered by ACPI upon boot and describe the I/OMMUs found in the system. The ACPI tables are described in vt-directed-io.pdf.
dmar(Flags)
- Description: Indicates the presence of a DMAR table in ACPI.
- Flags - A bitfield.
- Bit 0 - intr_remap - If set, the I/OMMU supports interrupt remapping
- Bit 1 - x2apic_opt_out - If set, the OS should not go into x2apic mode.
- Flags - A bitfield.
- Description: Indicates the presence of a DMAR table in ACPI.
dmar_hardware_unit(Index, Flags, Segment, Address)
- Description: Indicates the presence of a DMA remapping hardware for the
- Index[int] - index matching index in dmar_device
- Flags - A bitfield.
- Bit 0 - Include PCI all?
- Segment[uint16] - The PCI segment this remapping unit is for
- Address - The Register Base Address where this unit can be accessed.
- Description: Indicates the presence of a DMA remapping hardware for the
dmar_device(Index, AcpiDmarType, EntryType, Addr(_,_,_,_), EnumerationId).
- Description: The result of parsing the device scope ACPI tables. It describes the mapping of devices to, for example, DMAR devices.
- Index - Index for matching it with other dmar_facts
AcpiDmarType[uint8] = Remapping Structure Type
- 0 - DRHD - DMA Hardware Remapping unit definition
- 1 - RMRR - Reserved memory Region reporting structure
- 2 - ATSR - Root Port ATS Capability Reporting
- 3 - RHSA - Remapping Hardware Static Affinity Structure
- 4 - ANDD - ACPI Name-space Device Declaration Structure
EntryType[uint8]
- 1 - PCI Endpoint device, addr describes PCI address
- 2 - PCI Sub hierarchy, addr describes PCI sub hierarchy
3 - IOAPIC, EnumerationId contains IOAPIC ID
4 - MSI capable HPET, EnumerationId contains HPET Number
- 5 - ACPI Namespace device, addr contains ACPI name(? Not sure how this is encoded).
- Addr is a 4 tuple of Segment, Bus, Device, Function, describing the PCI address.
EnumerationId[uint8] - see 2.
- Description: The result of parsing the device scope ACPI tables. It describes the mapping of devices to, for example, DMAR devices.
dmar_reserved_memory(Index, Segment, BaseAdress, EndAdress)
- Description: Indicates Reserved BIOS Memory Regions that may be targets for DMA. Used for legacy devices (USB, ...). The devices that need access to this area are given using the dmar_device predicate. If not present, there are no such devices.
- Index - Index for matching it with other dmar_facts
- Segment[uint16] - PCI segment
BaseAddress[uint64] - 64bit memory base address
LimitAddress[uint64] - 64bit memory limit
- Description: Indicates Reserved BIOS Memory Regions that may be targets for DMA. Used for legacy devices (USB, ...). The devices that need access to this area are given using the dmar_device predicate. If not present, there are no such devices.
dmar_atsr(Index, Flags, Segment)
- Description: An ATSR structure is provided for each PCI segment supporting Device-TLBs. If not present, there are no such devices.
- Index - Index for matching it with other dmar_facts
- Flags - Bitfield
- Bit 0 - ALL_PORTS. When set, all devices support ATS transactions, otherwise, those described through dmar_device.
- Segment[uint16] - PCI segment.
- Description: An ATSR structure is provided for each PCI segment supporting Device-TLBs. If not present, there are no such devices.
dmar_rhsa(Index, BaseAddress, ProximityDomain)
- Description: Optional. Remapping Hardware Static Affinity structure.
- Index - Index for matching it with other dmar_facts
BaseAddress[uint64] - The base address
ProximityDomain[uint32] - Proximity Domain
- Description: Optional. Remapping Hardware Static Affinity structure.
dmar_andd(Index, DeviceNumber, ObjectName)
- Description: ACPI Name-space Device Declaration structure (ANDD). This
provides a lookup for dmar_device entries that have EntryType=ACPI Namespace.
- Index - Index for matching it with other dmar_facts
DeviceNumber[uint8] - The device number. Unique.
ObjectName[string] - The ACPI path
- Description: ACPI Name-space Device Declaration structure (ANDD). This
Dynamic
These facts describe the current state of the system and are updated periodically at runtime.
device
- Addr/3
- Vendor
DeviceId
- Class
- Subclass
- Programming Interface
InterruptPin: Four of the physical pins on the PCI card carry interrupts from the card to the PCI bus. The standard labels these as A, B, C and D. The Interrupt Pin field describes which of these pins this PCI device uses. Generally it is hardwired for a pariticular device. That is, every time the system boots the device uses the same interrupt pin. This information allows the interrupt handling subsystem to manage interrupts from this device. Value is read from PCI HW registers.
memory_region(BaseAddress, Bits, Size, Type, Data)
Description: representation of 'struct mem_region' in <barrelfish_kpi/init.h>.
BaseAddress [GENPADDR] - this together with 'Size' defines a region of memory [BaseAddress, BaseAddress+Size). TODO: clarify if these are physical or virtual addresses.
Bits [uint] - If Bits == 0, then Size == 1 << Bits. May not always be the case for non power-of-two memory regions.
- Size [size_t]
Type [uint] - enum values defined in mem_region_type.
- Data [ptrdiff_t?]
binding(Id, EventBinding, RpcBinding)
- Octopus uses two bindings to communicate with one client. This fact is used to store the pointer for RPC and Event binding structs and map from one to the other. Event or RPC binding can also be 0 in case the client has only registered one binding (yet).
- Id [uint] - Unique number for every binding fact stores
EventBinding [uint64] - Value of Pointer to in-memory C binding structure created by flounder
RpcBinding [uint64] - Value of Pointer to in-memory C binding structure created by flounder
- Octopus uses two bindings to communicate with one client. This fact is used to store the pointer for RPC and Event binding structs and map from one to the other. Event or RPC binding can also be 0 in case the client has only registered one binding (yet).
corename(CoreID, Architecture, apic(ApicID))
- CoreID [uint8] - assigned sequentially starting from 0 as each core is booted, but may have hole if a core is not present.
- Architecture [atom] - currently hardcoded as 'x86_64', there is an open TODO comment.
ApicID [uint64] - see fact apic.
- Notes:
Stored by 'usr/kaluga/start_cpu.c' and 'usr/spawnd/bsp_bootup.c', but unsure which is actually active. ApicID retrieved from Octopus or with another SKB query (get_apic_id_list).
Used by 'usr/acpi/interrupts.c' (enable_and_route_interrupt) and 'usr/skb/programs/queries.pl' (1. get_core_id_list exports this as a sorted list, 2. in implementation of ram_closest_to query)
assignedGsi(Addr, Pin, Gsi)
- Assigned Global System Interrupt (see 5.2.11 in [1]). This fact is added during the PCI bus enumeration. The PCI service calls the function assigndeviceirq(Addr) for each device it finds which in turn stores the assignedGsi fact to cache the GSI assignments. Global System Interrupts can be thought of as ACPI Plug and Play IRQ numbers. They are used to virtualize interrupts in tables and in ASL methods that perform resource allocation of interrupts. (i.e., they give a unique number for each interrupt pin in a system).
- Addr [addr/3] - Address of the Device (addr in device fact).
- Pin [Integer] - Pin of the Device (see Interrupt Pin in device fact)
- Gsi [Integer] -
- Assigned Global System Interrupt (see 5.2.11 in [1]). This fact is added during the PCI bus enumeration. The PCI service calls the function assigndeviceirq(Addr) for each device it finds which in turn stores the assignedGsi fact to cache the GSI assignments. Global System Interrupts can be thought of as ACPI Plug and Play IRQ numbers. They are used to virtualize interrupts in tables and in ASL methods that perform resource allocation of interrupts. (i.e., they give a unique number for each interrupt pin in a system).
usedGsi(Int, fixedGsi)
- Fact to cache already assigned GSIs.
pir(Source, Gsi)
- For each link device, pir facts are added describing the possible GSIs that may be selected for a given device.
- Source [String] - Name of Link Device
- Gsi [int] - Global System Interrupt Number
- Example: pir("\\_SB_.PCI0.LSMB", 20).
- For each link device, pir facts are added describing the possible GSIs that may be selected for a given device.
prt(Addr, Pin, pir(Int) | gsi(Int))
- At start-up, the PCI and ACPI drivers add a fact for every PCI interrupt routing table entry, mapping a device address and interrupt pin to a source.
- Addr/3 - Address of PCI device
- Pin [int 0-3] - Pin of the PCI device
- pir(int) | gsi(int) - Interrupt link device or GSI that this interrupt is allocated to.
- At start-up, the PCI and ACPI drivers add a fact for every PCI interrupt routing table entry, mapping a device address and interrupt pin to a source.
setPir(String, Gsi)
Used to store already allocated GSI <-> Link device mappings.
- Name of Link Device
- Global System Interrupt
addr(Bus,Device,Function) [pci,acpi]
- Describes PCI addresses. Only used in other facts.
Bus bus on which the device lives
Device PCI device id (per bus) on which the device lives
Function PCI device function (per device id) on which the device lives
- Describes PCI addresses. Only used in other facts.
ahci_device(Id) [ahcid]
- Provides an enumeration of all available SATA ports in the system. Not used anywhere
Id SATA port id
- Provides an enumeration of all available SATA ports in the system. Not used anywhere
bar(addr(Bus,Device,Function), Id, BaseAddr, Size, Space, IsPrefetchable, Type) [pci]
- Description: Base Address Register for PCI device
addr: Device address, see addr/3
Id: BAR id for that device
BaseAddr: Base address of region indicated by BAR
Size: Size of region
Space: ["mem", "io"], Indicates whether BAR refers to IO space or
- {{{Memory.
IsPrefetchable: ["prefetchable", "nonprefetchable"], Indicates whether SW can prefetch data in region
Type: [32, 64], Indicates whether BAR is 32 bit or 64 bit wide
- Description: Base Address Register for PCI device
bridge(Type, addr(Bus, Device, Function), Vendor, DeviceId, Class, SubClass, ProgIf, secondary(BusNum)) [pci]
- Describes a PCI (express) bridge device
Type: ["pcie", "pci"], Distinguish between PCI and PCI express bridges
addr: Device address, see addr/3.
Vendor: Device vendor
DeviceId: Device DeviceId
Class: Device class
SubClass: Device subclass
ProgIf: Device programming interface
secondary(BusNum): secondary bus number (XXX: get info on this)
- Describes a PCI (express) bridge device
device(Type, addr(Bus,Device,Function), Vendor, DeviceId, Class, SubClass, ProgIf, IrqPin) [pci]
- Describes a PCI (express) device
Type: ["pcie","pci"], Indicates whether device is PCI or PCI express.
addr: Device address, see addr/3.
Vendor: Device vendor
DeviceId: Device Id
Class: Device class
SubClass: Device subclass
ProgIf: Device programming interface
IrqPin: interrupt pin for device
- Describes a PCI (express) device
currentbar(addr(Bus,Device,Function), BAR, Base, High, Size) [pci, doesn't occur in any call skb_add_fact()]
- Used in Prolog queries, returns the current BAR for a device
addr: Device address, see addr/3.
BAR: current base address register of device at addr.
Base: current base address
High: end of region indicated by BAR
Size: size of region
- Used in Prolog queries, returns the current BAR for a device
rootbridge(addr(Bus,Device,Function), childbus(Min,Max), mem(Min,Max)) [acpi]
- Describes a PCI (express) root bridge in the system
addr: Device address, see addr/3.
childbus(Min,Max): bus numbers of children of this bus are between Min and Max.
mem(Min,Max): memory region covered by this rootbridge is [Min, Max]
- Describes a PCI (express) root bridge in the system
rootbridge_address_window(addr(Bus,Device,Function), mem(Min,Max)) [acpi]
- Describes the memory region covered by a PCI (express) root bridge.
addr: Device address, see addr/3.
mem(Min,Max): memory region belonging to device at addr is [Min, Max]
- Describes the memory region covered by a PCI (express) root bridge.
childbus(MinBus,MaxBus) [acpi]
- bus numbers of children of the current bus are between the input values
MinBus: The minimum bus number that is assigned
MaxBus: The maximum bus number that is assigned
- used in SKB for root and rootbridge related functions.
- bus numbers of children of the current bus are between the input values
secondary(Busnum) [pci]
- refers to the secondary bus
Busnum: bus number of the secondary bus
- used in the SKB for bridge / device related programs
- refers to the secondary bus
Other Notes
- This list is taken from Adrian's PhD Thesis (section 3.5.2) and may be useful as a starting point:
apic_nmi(ACPI_ProcessorID, IntiFlags, Lint). bar(addr(Bus, Dev, Fun), BARNr, Base, Size, mem|io, (non)prefetchable, Bits (64|32)). bridge(pcie|pci, addr(Bus, Dev, Fun), VendorID, DeviceID, Class, SubClass, ProgIf, secondary(Sec)). currentbar(addr(Bus, Dev, Fun), BARNr, Base, Limit, Size). device(pcie|pci, addr(Bus, Dev, Fun), VendorID, DeviceID, Class, SubClass, ProgIf, IntPin). fixed_memory(Base, Limit). interrupt_override(Bus, SourceIRQ, GlobalIRQ, IntiFlags). ioapic(APICID, Base, Global_IRQ_Base). message_rtt(StartCore, DestCore, Avg, Var, Min, Max). nr_running_cores(Nr). rootbridge(addr(Bus, Dev, Fun), childbus(MinBus, MaxBus), mem(Base, Limit)). -> Can join first parameter of 'mem' with memory_region fact. rootbridge_address_window(addr(Bus, Dev, Fun), mem(Min, Max)).
CPU Information
Updated CPU information based on the SKB datagatherer /usr/skb/measurement
vendor(Core_ID,[Vendor_String]). cpu_family(Core_ID, Vendor_String, Family, Model, Stepping). cpu_thread(Core_ID, Package, Core, HyperThread). cpu_cache(Core_ID, Name, Level, data|instr|unified, Size, Associativity, LineSize, Shared, Inclusive). cpu_tlb(Core_ID, data|instr|unified, level, PageSize, Entries, Associativity). cpu_addrspace(Core_ID, BitsPhys, BitsVirt, BitsGuest).
- Proposed changes:
Rename some facts to better reflect what they stand for (e.g. cpu_affinity -> apic_to_numa_mapping).
It seems APIC IDs have a structure which reflects the topology (NUMA domain, chip, core, hyperthread). This is useful to know and could be easily exposed with some utility functions. See: http://wiki.osdev.org/Detecting_CPU_Topology_(80x86)
CPUID: only available if datagatherer activated, differing codepaths and facts for AMD/Intel. Seems somewhat standardized [1] and would be useful to have cache layout.
- Is there a desire for lazily-loaded facts? Rich data model, while offsetting cost for harvesting information (e.g. inter-core RTT microbenchmarks).
References
[1] Advanced Configuration and Power Interface Revision 2.0c, http://www.acpi.info/DOWNLOADS/ACPIspec-2-0c.pdf