2222 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2323 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2424 */
25- #ifndef KTF_ACPICA
2625#include <acpi_ktf.h>
27- #include <errno.h>
2826#include <ioapic.h>
29- #include <ktf.h>
30- #include <lib.h>
31- #include <mm/pmm.h>
32- #include <page.h>
33- #include <pagetable.h>
3427#include <percpu.h>
3528#include <setup.h>
3629#include <string.h>
3730
38- acpi_table_t * acpi_tables [128 ];
39- unsigned max_acpi_tables ;
31+ static const char * madt_int_bus_names [] = {
32+ [ACPI_MADT_INT_BUS_ISA ] = "ISA" ,
33+ };
34+
35+ static const char * madt_int_polarity_names [] = {
36+ [ACPI_MADT_INT_POLARITY_BS ] = "Bus Spec" ,
37+ [ACPI_MADT_INT_POLARITY_AH ] = "Active High" ,
38+ [ACPI_MADT_INT_POLARITY_RSVD ] = "Reserved" ,
39+ [ACPI_MADT_INT_POLARITY_AL ] = "Active Low" ,
40+ };
41+
42+ static const char * madt_int_trigger_names [] = {
43+ [ACPI_MADT_INT_TRIGGER_BS ] = "Bus Spec" ,
44+ [ACPI_MADT_INT_TRIGGER_ET ] = "Edge" ,
45+ [ACPI_MADT_INT_TRIGGER_RSVD ] = "Reserved" ,
46+ [ACPI_MADT_INT_TRIGGER_LT ] = "Level" ,
47+ };
4048
4149static unsigned nr_cpus ;
4250
4351unsigned acpi_get_nr_cpus (void ) { return nr_cpus ; }
4452
53+ #ifndef KTF_ACPICA
54+ #include <errno.h>
55+ #include <page.h>
56+ #include <pagetable.h>
57+ #include <string.h>
58+
59+ acpi_table_t * acpi_tables [128 ];
60+ unsigned max_acpi_tables ;
61+
4562/* Calculate number of entries in the ACPI table.
4663 * Formula: (table_length - header_length) / entry_size
4764 */
@@ -202,24 +219,6 @@ static inline void acpi_dump_tables(void) {
202219 acpi_dump_table (acpi_tables [i ], & acpi_tables [i ]-> header );
203220}
204221
205- static const char * madt_int_bus_names [] = {
206- [ACPI_MADT_INT_BUS_ISA ] = "ISA" ,
207- };
208-
209- static const char * madt_int_polarity_names [] = {
210- [ACPI_MADT_INT_POLARITY_BS ] = "Bus Spec" ,
211- [ACPI_MADT_INT_POLARITY_AH ] = "Active High" ,
212- [ACPI_MADT_INT_POLARITY_RSVD ] = "Reserved" ,
213- [ACPI_MADT_INT_POLARITY_AL ] = "Active Low" ,
214- };
215-
216- static const char * madt_int_trigger_names [] = {
217- [ACPI_MADT_INT_TRIGGER_BS ] = "Bus Spec" ,
218- [ACPI_MADT_INT_TRIGGER_ET ] = "Edge" ,
219- [ACPI_MADT_INT_TRIGGER_RSVD ] = "Reserved" ,
220- [ACPI_MADT_INT_TRIGGER_LT ] = "Level" ,
221- };
222-
223222static int process_fadt (void ) {
224223 acpi_fadt_rev1_t * fadt = (acpi_fadt_rev1_t * ) acpi_find_table (FADT_SIGNATURE );
225224
@@ -441,15 +440,8 @@ int init_acpi(unsigned bsp_cpu_id) {
441440 return process_madt_entries (bsp_cpu_id );
442441}
443442#else /* KTF_ACPICA */
444- #include <acpi_ktf.h>
445- #include <ioapic.h>
446- #include <ktf.h>
447- #include <percpu.h>
448-
449443#include "acpi.h"
450444
451- static unsigned nr_cpus ;
452-
453445/* ACPI initialization and termination functions */
454446
455447static ACPI_STATUS InitializeFullAcpi (void ) {
@@ -484,7 +476,231 @@ static ACPI_STATUS InitializeFullAcpi(void) {
484476 return AE_OK ;
485477}
486478
487- unsigned acpi_get_nr_cpus (void ) { return nr_cpus ; }
479+ static void madt_parser (ACPI_SUBTABLE_HEADER * entry , void * arg ) {
480+ bus_t * isa_bus =
481+ add_system_bus (ACPI_MADT_INT_BUS_ISA , madt_int_bus_names [ACPI_MADT_INT_BUS_ISA ],
482+ strlen (madt_int_bus_names [ACPI_MADT_INT_BUS_ISA ]));
483+
484+ BUG_ON (!isa_bus );
485+
486+ switch (entry -> Type ) {
487+ case ACPI_MADT_TYPE_LOCAL_APIC : {
488+ ACPI_MADT_LOCAL_APIC * lapic = (ACPI_MADT_LOCAL_APIC * ) entry ;
489+ uint32_t bsp_cpu_id = (uint32_t ) _ul (arg );
490+ percpu_t * percpu ;
491+ bool enabled ;
492+
493+ /* Some systems report all CPUs, marked as disabled */
494+ enabled = !!(lapic -> LapicFlags & 0x1 );
495+ if (!enabled )
496+ break ;
497+
498+ percpu = get_percpu_page (lapic -> ProcessorId );
499+ percpu -> cpu_id = lapic -> ProcessorId ;
500+ percpu -> apic_id = lapic -> Id ;
501+ percpu -> bsp = !!(lapic -> ProcessorId == bsp_cpu_id );
502+ percpu -> enabled = enabled ;
503+
504+ nr_cpus ++ ;
505+ printk ("ACPI: [MADT] APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n" ,
506+ percpu -> cpu_id , percpu -> apic_id , lapic -> LapicFlags );
507+ break ;
508+ }
509+ case ACPI_MADT_TYPE_IO_APIC : {
510+ ACPI_MADT_IO_APIC * ioapic = (ACPI_MADT_IO_APIC * ) entry ;
511+
512+ add_ioapic (ioapic -> Id , 0x00 , true, ioapic -> Address , ioapic -> GlobalIrqBase );
513+
514+ printk ("ACPI: [MADT] IOAPIC ID: %u, Base Address: 0x%08x, GSI Base: 0x%08x\n" ,
515+ ioapic -> Id , ioapic -> Address , ioapic -> GlobalIrqBase );
516+
517+ break ;
518+ }
519+ case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE : {
520+ ACPI_MADT_INTERRUPT_OVERRIDE * irq_src = (ACPI_MADT_INTERRUPT_OVERRIDE * ) entry ;
521+ irq_override_t override ;
522+
523+ memset (& override , 0 , sizeof (override ));
524+ override .type = ACPI_MADT_IRQ_TYPE_INT ;
525+ override .src = irq_src -> SourceIrq ;
526+ override .dst = irq_src -> GlobalIrq ;
527+ /* Destination to be found. Each IOAPIC has GSI base and Max Redir Entry
528+ * register */
529+ override .dst_id = IOAPIC_DEST_ID_UNKNOWN ;
530+
531+ inti_flags_t flags = (inti_flags_t ) irq_src -> IntiFlags ;
532+ override .polarity = flags .polarity ;
533+ override .trigger_mode = flags .trigger_mode ;
534+ add_system_bus_irq_override (irq_src -> Bus , & override );
535+
536+ printk ("ACPI: [MADT] IRQ Src Override: Bus: %3s, IRQ: 0x%02x, GSI: 0x%08x, "
537+ "Polarity: %11s, Trigger: %9s\n" ,
538+ madt_int_bus_names [irq_src -> Bus ], irq_src -> SourceIrq , irq_src -> GlobalIrq ,
539+ madt_int_polarity_names [flags .polarity ],
540+ madt_int_trigger_names [flags .trigger_mode ]);
541+ break ;
542+ }
543+ case ACPI_MADT_TYPE_NMI_SOURCE : {
544+ ACPI_MADT_NMI_SOURCE * nmi_src = (ACPI_MADT_NMI_SOURCE * ) entry ;
545+ irq_override_t override ;
546+
547+ memset (& override , 0 , sizeof (override ));
548+ override .type = ACPI_MADT_IRQ_TYPE_NMI ;
549+ override .src = nmi_src -> GlobalIrq ;
550+
551+ inti_flags_t flags = (inti_flags_t ) nmi_src -> IntiFlags ;
552+ override .polarity = flags .polarity ;
553+ override .trigger_mode = flags .trigger_mode ;
554+ add_system_bus_irq_override (ACPI_MADT_INT_BUS_ISA , & override );
555+
556+ printk ("ACPI: [MADT] NMI Src: GSI: 0x%08x, Polarity: %11s, Trigger: %9s\n" ,
557+ nmi_src -> GlobalIrq , madt_int_polarity_names [flags .polarity ],
558+ madt_int_trigger_names [flags .trigger_mode ]);
559+ break ;
560+ }
561+ case ACPI_MADT_TYPE_LOCAL_APIC_NMI : {
562+ ACPI_MADT_LOCAL_APIC_NMI * lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI * ) entry ;
563+ irq_override_t override ;
564+
565+ memset (& override , 0 , sizeof (override ));
566+ override .type = ACPI_MADT_IRQ_TYPE_NMI ;
567+ override .dst_id = lapic_nmi -> ProcessorId ;
568+ override .dst = lapic_nmi -> Lint ;
569+
570+ inti_flags_t flags = (inti_flags_t ) lapic_nmi -> IntiFlags ;
571+ override .polarity = flags .polarity ;
572+ override .trigger_mode = flags .trigger_mode ;
573+ add_system_bus_irq_override (ACPI_MADT_INT_BUS_ISA , & override );
574+
575+ printk ("ACPI: [MADT] Local APIC NMI LINT#: CPU UID: %02x, Polarity: %11s, "
576+ "Trigger: %9s, LINT#: 0x%02x\n" ,
577+ lapic_nmi -> ProcessorId , madt_int_polarity_names [flags .polarity ],
578+ madt_int_trigger_names [flags .trigger_mode ], lapic_nmi -> Lint );
579+ break ;
580+ }
581+ case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE : {
582+ ACPI_MADT_LOCAL_APIC_OVERRIDE * lapic_addr =
583+ (ACPI_MADT_LOCAL_APIC_OVERRIDE * ) entry ;
584+
585+ /* FIXME: set for each Per-CPU apic_base */
586+ printk ("ACPI: [MADT] Local APIC Address: 0x%016lx\n" , lapic_addr -> Address );
587+ break ;
588+ }
589+ case ACPI_MADT_TYPE_IO_SAPIC : {
590+ ACPI_MADT_IO_SAPIC * iosapic = (ACPI_MADT_IO_SAPIC * ) entry ;
591+
592+ add_ioapic (iosapic -> Id , 0x00 , true, iosapic -> Address , iosapic -> GlobalIrqBase );
593+
594+ printk ("ACPI: [MADT] IOSAPIC ID: %u, Base Address: %p, GSI Base: 0x%08x\n" ,
595+ iosapic -> Id , _ptr (iosapic -> Address ), iosapic -> GlobalIrqBase );
596+ break ;
597+ }
598+ case ACPI_MADT_TYPE_LOCAL_SAPIC : {
599+ ACPI_MADT_LOCAL_SAPIC * slapic = (ACPI_MADT_LOCAL_SAPIC * ) entry ;
600+ percpu_t * percpu = get_percpu_page (slapic -> ProcessorId );
601+ uint32_t bsp_cpu_id = (uint32_t ) _ul (arg );
602+
603+ percpu -> cpu_id = slapic -> ProcessorId ;
604+ percpu -> sapic_id = slapic -> Id ;
605+ percpu -> sapic_eid = slapic -> Eid ;
606+
607+ percpu -> sapic_uid = slapic -> Uid ;
608+ percpu -> sapic_uid_str [0 ] = slapic -> UidString [0 ];
609+
610+ percpu -> bsp = !!(slapic -> ProcessorId == bsp_cpu_id );
611+ percpu -> enabled = !!(slapic -> LapicFlags & 0x1 );
612+
613+ if (percpu -> enabled ) {
614+ nr_cpus ++ ;
615+ printk ("ACPI: [MADT] SAPIC Processor ID: %u, SAPIC ID: %u, SAPIC EID: %u, "
616+ "SAPIC UID: %u, SAPIC UID Str: %c Flags: %08x\n" ,
617+ percpu -> cpu_id , slapic -> Id , slapic -> Eid , slapic -> Uid ,
618+ slapic -> UidString [0 ], slapic -> LapicFlags );
619+ }
620+ break ;
621+ }
622+ case ACPI_MADT_TYPE_INTERRUPT_SOURCE : {
623+ /* TODO: to be implemented */
624+ break ;
625+ }
626+ case ACPI_MADT_TYPE_LOCAL_X2APIC : {
627+ ACPI_MADT_LOCAL_X2APIC * x2lapic = (ACPI_MADT_LOCAL_X2APIC * ) entry ;
628+ percpu_t * percpu = get_percpu_page (x2lapic -> Uid );
629+ uint32_t bsp_cpu_id = (uint32_t ) _ul (arg );
630+
631+ percpu -> cpu_id = x2lapic -> Uid ;
632+ percpu -> apic_id = x2lapic -> LocalApicId ;
633+ percpu -> bsp = !!(x2lapic -> Uid == bsp_cpu_id );
634+ percpu -> enabled = !!(x2lapic -> LapicFlags & 0x1 );
635+
636+ if (percpu -> enabled ) {
637+ nr_cpus ++ ;
638+ printk ("ACPI: [MADT] X2APIC Processor ID: %u, APIC ID: %u, Flags: %08x\n" ,
639+ percpu -> cpu_id , percpu -> apic_id , x2lapic -> LapicFlags );
640+ }
641+ break ;
642+ }
643+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI : {
644+ ACPI_MADT_LOCAL_X2APIC_NMI * x2lapic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI * ) entry ;
645+ irq_override_t override ;
646+
647+ memset (& override , 0 , sizeof (override ));
648+ override .type = ACPI_MADT_IRQ_TYPE_NMI ;
649+ override .dst_id = x2lapic_nmi -> Uid ;
650+ override .dst = x2lapic_nmi -> Lint ;
651+
652+ inti_flags_t flags = (inti_flags_t ) x2lapic_nmi -> IntiFlags ;
653+ override .polarity = flags .polarity ;
654+ override .trigger_mode = flags .trigger_mode ;
655+ add_system_bus_irq_override (ACPI_MADT_INT_BUS_ISA , & override );
656+
657+ printk ("ACPI: [MADT] Local X2APIC NMI LINT#: CPU UID: %02x, Polarity: %11s, "
658+ "Trigger: %9s, LINT#: 0x%02x\n" ,
659+ x2lapic_nmi -> Uid , madt_int_polarity_names [flags .polarity ],
660+ madt_int_trigger_names [flags .trigger_mode ], x2lapic_nmi -> Lint );
661+ break ;
662+ }
663+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT : {
664+ /* TODO: to be implemented */
665+ break ;
666+ }
667+ case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR : {
668+ /* TODO: to be implemented */
669+ break ;
670+ }
671+ case ACPI_MADT_TYPE_GENERIC_MSI_FRAME : {
672+ /* TODO: to be implemented */
673+ break ;
674+ }
675+ case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR : {
676+ /* TODO: to be implemented */
677+ break ;
678+ }
679+ case ACPI_MADT_TYPE_GENERIC_TRANSLATOR : {
680+ /* TODO: to be implemented */
681+ break ;
682+ }
683+ case ACPI_MADT_TYPE_MULTIPROC_WAKEUP : {
684+ /* TODO: to be implemented */
685+ break ;
686+ }
687+ default :
688+ panic ("ACPI [MADT]: Unsupported subtable entry type: %x\n" , entry -> Type );
689+ break ;
690+ }
691+ }
692+
693+ static ACPI_STATUS init_madt (unsigned bsp_cpu_id ) {
694+ ACPI_TABLE_MADT * madt = acpi_find_table (ACPI_SIG_MADT );
695+ ACPI_SUBTABLE_HEADER * subtbl = (void * ) madt + sizeof (* madt );
696+ uint32_t length = madt -> Header .Length - sizeof (* madt );
697+
698+ if (!madt || !subtbl )
699+ return AE_ERROR ;
700+
701+ acpi_walk_subtables (subtbl , length , madt_parser , (void * ) _ul (bsp_cpu_id ));
702+ return AE_OK ;
703+ }
488704
489705void * acpi_find_table (char * signature ) {
490706 ACPI_TABLE_HEADER * hdr ;
@@ -509,6 +725,10 @@ ACPI_STATUS init_acpi(unsigned bsp_cpu_id) {
509725 printk ("Initializing ACPI support\n" );
510726
511727 status = InitializeFullAcpi ();
728+ if (status != AE_OK )
729+ return status ;
730+
731+ status = init_madt (bsp_cpu_id );
512732 return status ;
513733}
514734
0 commit comments