@@ -19,6 +19,8 @@ extern size_t aps_online;
1919
2020buddy_allocator_t acpi_pool = { 0 };
2121
22+ static bool uacpi_claim_phase = false;
23+
2224static uint64_t pm_timer_port = 0 ;
2325static bool pm_timer_32bit = 0 ;
2426static bool pm_timer_is_io = 0 ;
@@ -37,6 +39,18 @@ uint32_t cpu_id_mapping[MAX_CPUS] = { 0 };
3739
3840uint64_t mhz = 0 , tsc_per_sec = 1 ;
3941
42+ typedef struct uacpi_irq_req {
43+ uint32_t gsi ; /* GSI from uACPI (not a vector). */
44+ uacpi_interrupt_handler handler ; /* uACPI handler: handler(ctx). */
45+ uacpi_handle ctx ;
46+ uint8_t vector ; /* Bound vector once claimed. */
47+ bool claimed ;
48+ } uacpi_irq_req ;
49+
50+ #define UACPI_DEFER_MAX 16
51+ static uacpi_irq_req * uacpi_deferred [UACPI_DEFER_MAX ];
52+ static size_t uacpi_deferred_count = 0 ;
53+
4054void enumerate_all_gsis (void );
4155
4256uint32_t get_lapic_id_from_cpu_id (uint8_t cpu_id ) {
@@ -496,29 +510,153 @@ void uacpi_kernel_signal_event(uacpi_handle) {}
496510
497511void uacpi_kernel_reset_event (uacpi_handle ) {}
498512
499- uacpi_thread_id uacpi_kernel_get_thread_id (void ) { return 1 ; }
513+ uacpi_thread_id uacpi_kernel_get_thread_id (void ) {
514+ return 1 ;
515+ }
500516
501- // Optional no-op spinlock support
502- uacpi_handle uacpi_kernel_create_spinlock (void ) { return (uacpi_handle ) last_handle ++ ; }
517+ uacpi_handle uacpi_kernel_create_spinlock (void ) {
518+ spinlock_t * lock = (spinlock_t * )buddy_malloc (& acpi_pool , sizeof (spinlock_t ));
519+ if (lock == NULL ) {
520+ return (uacpi_handle )0 ;
521+ }
522+ init_spinlock (lock );
523+ return (uacpi_handle )(uintptr_t )lock ;
524+ }
503525
504- void uacpi_kernel_free_spinlock (uacpi_handle handle ) {}
526+ void uacpi_kernel_free_spinlock (uacpi_handle handle ) {
527+ spinlock_t * lock = (spinlock_t * )(uintptr_t )handle ;
528+ if (lock == NULL ) {
529+ return ;
530+ }
531+ __atomic_store_n (lock , 0 , __ATOMIC_RELEASE );
532+ buddy_free (& acpi_pool , lock );
533+ }
505534
506- uacpi_cpu_flags uacpi_kernel_lock_spinlock (uacpi_handle handle ) { return 0 ; }
535+ uacpi_cpu_flags uacpi_kernel_lock_spinlock (uacpi_handle handle ) {
536+ spinlock_t * lock = (spinlock_t * )(uintptr_t )handle ;
537+ uint64_t saved_flags = 0 ;
538+ if (lock == NULL ) {
539+ return 0 ;
540+ }
541+ lock_spinlock_irq (lock , & saved_flags );
542+ return saved_flags ;
543+ }
507544
508- void uacpi_kernel_unlock_spinlock (uacpi_handle handle , uacpi_cpu_flags flags ) {}
545+ void uacpi_kernel_unlock_spinlock (uacpi_handle handle , uacpi_cpu_flags flags ) {
546+ spinlock_t * lock = (spinlock_t * )(uintptr_t )handle ;
547+ if (lock == NULL ) {
548+ return ;
549+ }
550+ unlock_spinlock_irq (lock , flags );
551+ }
509552
510- // RSDP (you already have this)
511553uacpi_status uacpi_kernel_get_rsdp (uacpi_phys_addr * out_rsdp_address ) {
512554 * out_rsdp_address = rsdp_request .response -> address ;
513555 return UACPI_STATUS_OK ;
514556}
515557
558+ static void uacpi_irq_trampoline (uint8_t isr , uint64_t error , uint64_t vec , void * opaque ) {
559+ uacpi_irq_req * r = (uacpi_irq_req * )opaque ;
560+ if (r != NULL ) {
561+ r -> handler (r -> ctx );
562+ }
563+ }
564+
516565uacpi_status uacpi_kernel_install_interrupt_handler (uacpi_u32 irq , uacpi_interrupt_handler handler , uacpi_handle ctx , uacpi_handle * out_irq_handle ) {
566+
567+ if (!out_irq_handle ) {
568+ return UACPI_STATUS_INVALID_ARGUMENT ;
569+ }
570+ if (uacpi_deferred_count >= UACPI_DEFER_MAX ) {
571+ return UACPI_STATUS_INTERNAL_ERROR ;
572+ }
573+
574+ uacpi_irq_req * r = buddy_malloc (& acpi_pool , sizeof (uacpi_irq_req ));
575+ if (r == NULL ) {
576+ return UACPI_STATUS_OUT_OF_MEMORY ;
577+ }
578+
579+ r -> gsi = irq ;
580+ r -> handler = handler ;
581+ r -> ctx = ctx ;
582+ r -> vector = 0 ;
583+ r -> claimed = false;
584+
585+ /* If claim phase already started, bind immediately using pci_irq_routes[]. */
586+ if (uacpi_claim_phase ) {
587+ for (size_t j = 0 ; j < MAX_PCI_ROUTES ; j ++ ) {
588+ pci_irq_route_t * route = & pci_irq_routes [j ];
589+ if (!route -> exists || route -> gsi != r -> gsi ) {
590+ continue ;
591+ }
592+ uint8_t vector = (uint8_t )(IRQ_START + (uint32_t )j );
593+ dprintf ("[uACPI] Attached interrupt on GSI %d (ISR %d)\n" , r -> gsi , vector );
594+ if (register_interrupt_handler (vector , uacpi_irq_trampoline , (pci_dev_t ){0 }, r )) {
595+ r -> vector = vector ;
596+ r -> claimed = true;
597+ } else {
598+ dprintf ("acpi: failed to register vector %u for GSI %u\n" , vector , route -> gsi );
599+ }
600+ break ;
601+ }
602+ } else {
603+ dprintf ("[uACPI] Attached interrupt on GSI %d (deferred)\n" , r -> gsi );
604+ }
605+
606+ uacpi_deferred [uacpi_deferred_count ++ ] = r ;
607+
608+ * out_irq_handle = (uacpi_handle )(uintptr_t )r ;
517609 return UACPI_STATUS_OK ;
518610}
519611
520612uacpi_status uacpi_kernel_uninstall_interrupt_handler (uacpi_interrupt_handler handler , uacpi_handle irq_handle ) {
521- return UACPI_STATUS_OK ;
613+
614+ uacpi_irq_req * r = (uacpi_irq_req * )(uintptr_t )irq_handle ;
615+ if (r == NULL ) {
616+ return UACPI_STATUS_INVALID_ARGUMENT ;
617+ }
618+
619+ for (size_t i = 0 ; i < uacpi_deferred_count ; i ++ ) {
620+ if (uacpi_deferred [i ] == r ) {
621+ if (r -> claimed ) {
622+ deregister_interrupt_handler (r -> vector , uacpi_irq_trampoline );
623+ }
624+ uacpi_deferred [i ] = uacpi_deferred [uacpi_deferred_count - 1 ];
625+ uacpi_deferred [uacpi_deferred_count - 1 ] = NULL ;
626+ uacpi_deferred_count -- ;
627+ buddy_free (& acpi_pool , r );
628+ return UACPI_STATUS_OK ;
629+ }
630+ }
631+
632+ return UACPI_STATUS_INTERNAL_ERROR ;
633+ }
634+
635+ void acpi_claim_deferred_irqs (void ) {
636+ if (uacpi_claim_phase ) {
637+ return ;
638+ }
639+ for (size_t i = 0 ; i < uacpi_deferred_count ; i ++ ) {
640+ uacpi_irq_req * r = uacpi_deferred [i ];
641+ if (r == NULL || r -> claimed ) {
642+ continue ;
643+ }
644+ for (size_t j = 0 ; j < MAX_PCI_ROUTES ; j ++ ) {
645+ pci_irq_route_t * route = & pci_irq_routes [j ];
646+ if (!route -> exists || route -> gsi != r -> gsi ) {
647+ continue ;
648+ }
649+ uint8_t vector = (uint8_t )(IRQ_START + (uint32_t )j );
650+ if (register_interrupt_handler (vector , uacpi_irq_trampoline , (pci_dev_t ){0 }, r )) {
651+ r -> vector = vector ;
652+ r -> claimed = true;
653+ } else {
654+ dprintf ("acpi: failed to register vector %u for GSI %u\n" , vector , route -> gsi );
655+ }
656+ break ;
657+ }
658+ }
659+ uacpi_claim_phase = true;
522660}
523661
524662uacpi_status uacpi_kernel_handle_firmware_request (uacpi_firmware_request * req ) {
0 commit comments