55 if (phys >= domain->
start && phys < domain->end)
90 if (revIrq ==
NULL || revIrq->
domain != newDomain)
135 panic(
NULL,
"Unexpected vector 0x%x dispatched through IRQ system", frame->
vector);
142 LOG_WARN(
"unhandled IRQ 0x%x received with no domain\n", frame->
vector);
235 irq->
virt = targetVirt;
387 if (domain->
chip != chip)
403 if (irq->
domain == domain)
445 if (iter->
func == func)
459 handler->
func = func;
461 handler->
virt = virt;
492 if (iter->
func == func)
505 LOG_WARN(
"attempted to unregister non-registered irq handler %p for irq 0x%x", func, virt);
#define assert(expression)
@ VECTOR_EXTERNAL_END
Exclusive end of external interrupts.
@ VECTOR_EXTERNAL_START
Inclusive start of external interrupts (handled by the IRQ system).
void irq_chip_unregister(irq_chip_t *chip, irq_phys_t start, irq_phys_t end)
Unregister all instances of the given IRQ chip within the specified range.
void irq_virt_free(irq_virt_t virt)
Free a previously allocated virtual IRQ.
void irq_handler_unregister(irq_func_t func, irq_virt_t virt)
Unregister an IRQ handler.
void irq_init(void)
Initialize the IRQ subsystem.
#define IRQ_PHYS_NONE
Constant representing no physical IRQ.
uint64_t irq_virt_set_affinity(irq_virt_t virt, cpu_t *cpu)
Change the CPU responsible for an IRQ.
uint32_t irq_phys_t
Physical IRQ numbers.
uint64_t irq_handler_register(irq_virt_t virt, irq_func_t func, void *private)
Register an IRQ handler for a virtual IRQ.
uint64_t irq_chip_amount(void)
Get the number of registered IRQ chips.
void(* irq_func_t)(irq_func_data_t *data)
Callback function type for IRQs.
void irq_dispatch(interrupt_frame_t *frame, cpu_t *self)
Dispatch an IRQ.
uint64_t irq_chip_register(irq_chip_t *chip, irq_phys_t start, irq_phys_t end, void *private)
Register an IRQ chip for a range of physical IRQs.
uint64_t irq_virt_alloc(irq_virt_t *out, irq_phys_t phys, irq_flags_t flags, cpu_t *cpu)
Allocate a virtual IRQ mapped to the given physical IRQ.
uint8_t irq_virt_t
Virtual IRQ numbers.
@ IRQ_EXCLUSIVE
If set, the IRQ is exclusive (not shared).
static cpu_t * cpu_get_unsafe(void)
Gets the current CPU structure without disabling interrupts.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
#define LOG_WARN(format,...)
#define LOG_INFO(format,...)
void rwlock_write_acquire(rwlock_t *lock)
Acquires a rwlock for writing, blocking until it is available.
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
void rwlock_write_release(rwlock_t *lock)
Releases a rwlock from writing.
void rwlock_init(rwlock_t *lock)
Initializes a rwlock.
#define RWLOCK_CREATE()
Create a rwlock initializer.
#define RWLOCK_WRITE_SCOPE(lock)
Acquires a rwlock for writing for the reminder of the current scope.
#define ENOENT
No such file or directory.
#define ENOSPC
No space left on device.
#define EEXIST
File exists.
#define EINVAL
Invalid argument.
#define ENOMEM
Out of memory.
#define EBUSY
Device or resource busy.
#define errno
Error number variable.
#define ENODEV
No such device.
#define LIST_FOR_EACH(elem, list, member)
Iterates over a list.
static list_entry_t * list_first(list_t *list)
Gets the first entry in the list without removing it.
static uint64_t list_length(list_t *list)
Gets the length of the list.
static void list_push_back(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
#define LIST_CREATE(name)
Creates a list initializer.
#define LIST_FOR_EACH_SAFE(elem, temp, list, member)
Safely iterates over a list, allowing for element removal during iteration.
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
static bool list_is_empty(list_t *list)
Checks if a list is empty.
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
static void list_init(list_t *list)
Initializes a list.
#define NULL
Pointer error value.
#define ERR
Integer error value.
#define CONTAINER_OF(ptr, type, member)
Container of macro.
static irq_domain_t * irq_domain_lookup(irq_phys_t phys)
static irq_t irqs[VECTOR_EXTERNAL_AMOUNT]
static rwlock_t domainsLock
static uint64_t irq_domain_rebind_orphaned_irqs(irq_domain_t *newDomain)
static irq_t * irq_get(irq_virt_t virt)
static uint64_t irq_update(irq_t *irq)
static const path_flag_t flags[]
_PUBLIC void * malloc(size_t size)
_PUBLIC void free(void *ptr)
void(* disable)(irq_t *irq)
Disable the given IRQ, must be defined.
uint64_t(* enable)(irq_t *irq)
Enable the given IRQ, must be defined.
void(* eoi)(irq_t *irq)
Send End-Of-Interrupt for the given IRQ.
void(* ack)(irq_t *irq)
Send a acknowledge for the given IRQ.
irq_phys_t start
Inclusive.
Data passed to IRQ functions.
interrupt_frame_t * frame
Structure to hold an IRQ function and its data.
cpu_t * cpu
The CPU with affinity for this IRQ, may be NULL.
Read-Write Ticket Lock structure.