@@ -206,6 +206,18 @@ pci_dev_t pci_get_device(uint16_t vendor_id, uint16_t device_id, int device_type
206206 */
207207pci_dev_t pci_get_best (uint16_t vendor_id , uint16_t device_id , int device_type , pci_score_fn score , void * ctx );
208208
209+ /**
210+ * @brief Get the Nth matching PCI device by vendor/device/type.
211+ *
212+ * Scans the enumerated device list and returns the Nth match in discovery
213+ * order (0-based). Any of the match fields may be wildcarded.
214+ *
215+ * @param vendor_id Vendor ID to match (0 = any).
216+ * @param device_id Device ID to match (0 = any).
217+ * @param device_type Device class/type to match (-1 = any).
218+ * @param nth Zero-based index into the matching set.
219+ * @return Matching PCI device, or dev_zero if not found.
220+ */
209221pci_dev_t pci_get_device_nth (uint16_t vendor_id , uint16_t device_id , int device_type , size_t nth );
210222
211223/**
@@ -317,14 +329,133 @@ bool pci_enable_msix(pci_dev_t device, uint32_t vector, uint16_t entry, uint32_t
317329 */
318330uint32_t pci_setup_interrupt (const char * name , pci_dev_t dev , uint8_t logical_cpu_id , isr_t handler , void * context );
319331
332+ /**
333+ * @brief Return the 64-bit MMIO base from a pair of BAR dwords.
334+ *
335+ * Helper for 64-bit memory BARs where both low and high dwords are available.
336+ *
337+ * @param lo Lower 32 bits of the BAR (as read from PCI configuration space).
338+ * @param hi Upper 32 bits of the BAR (as read from PCI configuration space).
339+ * @return 64-bit physical base address.
340+ */
341+ uint64_t pci_mem_base64 (uint32_t lo , uint32_t hi );
342+
343+ /**
344+ * @brief Determine if a BAR field denotes a 64-bit memory BAR.
345+ *
346+ * @param field Raw BAR field value.
347+ * @return true if the BAR is a 64-bit memory BAR, false otherwise.
348+ */
349+ bool pci_bar_is_mem64 (uint32_t field );
350+
351+ /**
352+ * @brief Probe and return the size of a BAR mapping.
353+ *
354+ * Uses the standard PCI size-probe dance on the requested BAR index to
355+ * determine the amount of address space the device decodes.
356+ *
357+ * @param dev PCI device.
358+ * @param bar_index BAR number (0..5).
359+ * @return Size in bytes (0 on failure or unsupported BAR type).
360+ *
361+ * @note May temporarily write to the device’s BAR during probing; callers
362+ * must ensure the device is idle and that probing is safe.
363+ */
320364uint64_t get_bar_size (pci_dev_t dev , int bar_index );
321365
366+ /**
367+ * @brief Disable PCI bus mastering on a device.
368+ *
369+ * Clears @ref PCI_COMMAND_BUS_MASTER in the device’s command register.
370+ *
371+ * @param device PCI device descriptor.
372+ * @return true if the bit was cleared by this call, false if it was already clear.
373+ */
322374bool pci_disable_bus_master (pci_dev_t device );
323375
376+ /**
377+ * @brief Enable I/O space decoding for a device.
378+ *
379+ * Sets @ref PCI_COMMAND_IOSPACE in the command register.
380+ *
381+ * @param device PCI device descriptor.
382+ * @return true if the bit was newly set, false if it was already set.
383+ */
324384bool pci_enable_iospace (pci_dev_t device );
325385
386+ /**
387+ * @brief Enable MMIO space decoding for a device.
388+ *
389+ * Sets @ref PCI_COMMAND_MEMSPACE in the command register.
390+ *
391+ * @param device PCI device descriptor.
392+ * @return true if the bit was newly set, false if it was already set.
393+ */
326394bool pci_enable_memspace (pci_dev_t device );
327395
396+ /**
397+ * @brief Disable I/O space decoding for a device.
398+ *
399+ * Clears @ref PCI_COMMAND_IOSPACE in the command register.
400+ *
401+ * @param device PCI device descriptor.
402+ * @return true if the bit was cleared by this call, false if it was already clear.
403+ */
328404bool pci_disable_iospace (pci_dev_t device );
329405
406+ /**
407+ * @brief Disable MMIO space decoding for a device.
408+ *
409+ * Clears @ref PCI_COMMAND_MEMSPACE in the command register.
410+ *
411+ * @param device PCI device descriptor.
412+ * @return true if the bit was cleared by this call, false if it was already clear.
413+ */
330414bool pci_disable_memspace (pci_dev_t device );
415+
416+ /**
417+ * @brief Configure one or more interrupt vectors for a PCI function.
418+ *
419+ * For @p requested_count == 1: attempts single-vector MSI and falls back to legacy INTx
420+ * if MSI cannot be enabled. On success, writes the assigned vector to @p start and @p end.
421+ *
422+ * For @p requested_count > 1: attempts to allocate a contiguous run of exactly that many
423+ * vectors and then enables plain MSI with Multiple Message Enable (MME) set via
424+ * @ref pci_enable_msi_multi. Handlers are installed before arming the device; on failure,
425+ * installed handlers are deregistered and the vectors freed. There is no legacy fallback
426+ * for multi-vector requests.
427+ *
428+ * @param name Human-readable device name (for logs).
429+ * @param dev PCI device handle.
430+ * @param logical_cpu_id Logical CPU that should receive the interrupts.
431+ * @param requested_count Number of vectors requested (caller should pass a power of two for MSI).
432+ * @param handler ISR to register on each vector.
433+ * @param context Opaque pointer passed to the ISR.
434+ * @param start [out] First vector in the assigned range.
435+ * @param end [out] Last vector in the assigned range (inclusive).
436+ * @return true on success; false if allocation/programming failed.
437+ *
438+ * @note This function does not round up non-power-of-two requests; if the device
439+ * cannot support the requested count, it fails. For multi-vector requests,
440+ * alignment and power-of-two constraints are enforced by @ref pci_enable_msi_multi.
441+ */
442+ bool pci_setup_multiple_interrupts (const char * name , pci_dev_t dev , uint8_t logical_cpu_id , uint8_t requested_count , isr_t handler , void * context , uint32_t * start , uint32_t * end );
443+
444+ /**
445+ * @brief Enable plain MSI for a contiguous, power-of-two range of vectors.
446+ *
447+ * Programs the device’s MSI capability with Message Address/Message Data and sets
448+ * the Multiple Message Enable (MME) bits to @c log2(count), using @p base_vector
449+ * as the first message’s vector. Disables legacy INTx on success.
450+ *
451+ * @param device PCI device descriptor.
452+ * @param base_vector First vector in the contiguous block (must be aligned to @p count).
453+ * @param count Number of messages (must be a power of two, e.g., 1,2,4,8,...,128).
454+ * @param lapic_id Local APIC ID to target.
455+ * @return true if MSI was enabled with the requested range; false otherwise.
456+ *
457+ * @warning This call does not allocate vectors or install handlers. Callers must
458+ * have already reserved a contiguous block and registered handlers for
459+ * all vectors before enabling MSI on the device.
460+ */
461+ bool pci_enable_msi_multi (pci_dev_t device , uint32_t base_vector , uint8_t count , uint32_t lapic_id );
0 commit comments