Add FADT check for presence of i8042 controller.
authorMinep <zelong56@gmail.com>
Tue, 3 May 2022 15:25:45 +0000 (16:25 +0100)
committerMinep <zelong56@gmail.com>
Tue, 3 May 2022 15:29:10 +0000 (16:29 +0100)
lunaix-os/hal/acpi/acpi.c
lunaix-os/includes/hal/acpi/acpi.h
lunaix-os/includes/hal/acpi/fadt.h [new file with mode: 0644]
lunaix-os/includes/hal/acpi/madt.h
lunaix-os/includes/hal/acpi/sdt.h
lunaix-os/kernel/peripheral/ps2kbd.c

index a99827803a14e729bb9b4fdb07591fdd767ad57d..5713f9a95f2930b7a60c7e78cd8208346c9d76fd 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "parser/madt_parser.h"
 
-static acpi_context* toc = NULL;
+static acpi_context* ctx = NULL;
 
 LOG_MODULE("ACPI")
 
@@ -30,30 +30,34 @@ acpi_init(multiboot_info_t* mb_info)
 
     acpi_rsdt_t* rsdt = rsdp->rsdt;
 
-    toc = lxcalloc(1, sizeof(acpi_context));
-    assert_msg(toc, "Fail to create ACPI context");
+    ctx = lxcalloc(1, sizeof(acpi_context));
+    assert_msg(ctx, "Fail to create ACPI context");
 
-    strncpy(toc->oem_id, rsdt->header.oem_id, 6);
-    toc->oem_id[6] = '\0';
+    strncpy(ctx->oem_id, rsdt->header.oem_id, 6);
+    ctx->oem_id[6] = '\0';
 
     size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2;
     for (size_t i = 0; i < entry_n; i++) {
         acpi_sdthdr_t* sdthdr = ((acpi_apic_t**)&(rsdt->entry))[i];
         switch (sdthdr->signature) {
             case ACPI_MADT_SIG:
-                madt_parse((acpi_madt_t*)sdthdr, toc);
+                madt_parse((acpi_madt_t*)sdthdr, ctx);
+                break;
+            case ACPI_FADT_SIG:
+                // FADT just a plain structure, no need to parse.
+                ctx->fadt = *(acpi_fadt_t*)sdthdr;
                 break;
             default:
                 break;
         }
     }
 
-    kprintf(KINFO "OEM: %s\n", toc->oem_id);
-    kprintf(KINFO "IOAPIC address: %p\n", toc->madt.ioapic->ioapic_addr);
-    kprintf(KINFO "APIC address: %p\n", toc->madt.apic_addr);
+    kprintf(KINFO "OEM: %s\n", ctx->oem_id);
+    kprintf(KINFO "IOAPIC address: %p\n", ctx->madt.ioapic->ioapic_addr);
+    kprintf(KINFO "APIC address: %p\n", ctx->madt.apic_addr);
 
     for (size_t i = 0; i < 24; i++) {
-        acpi_intso_t* intso = toc->madt.irq_exception[i];
+        acpi_intso_t* intso = ctx->madt.irq_exception[i];
         if (!intso)
             continue;
 
@@ -64,8 +68,8 @@ acpi_init(multiboot_info_t* mb_info)
 acpi_context*
 acpi_get_context()
 {
-    assert_msg(toc, "ACPI is not initialized");
-    return toc;
+    assert_msg(ctx, "ACPI is not initialized");
+    return ctx;
 }
 
 int
@@ -117,6 +121,7 @@ acpi_locate_rsdp(multiboot_info_t* mb_info)
     uint8_t* mem_start = 0x4000;
     for (; mem_start < 0x100000; mem_start += 16) {
         uint32_t sig_low = *((uint32_t*)(mem_start));
+        // XXX: do we need to compare this as well?
         // uint32_t sig_high = *((uint32_t*)(mem_start+j) + 1);
         if (sig_low == ACPI_RSDP_SIG_L) {
             rsdp = (acpi_rsdp_t*)(mem_start);
index 326a8d04aad1712bee3ae15c24cdfdac914f5c14..453e9f438f8d3366e5e4a5fbdf19c63ee19fee92 100644 (file)
@@ -7,11 +7,16 @@
 
 #include "sdt.h"
 #include "madt.h"
+#include "fadt.h"
+
+// * for quick conversion from a table name into ACPI favoured signature
+// * use `echo <TableName> | xxd -eg4`
 
 #define ACPI_RSDP_SIG_L       0x20445352      // 'RSD '
 #define ACPI_RSDP_SIG_H      0x20525450       // 'PTR '
 
 #define ACPI_MADT_SIG        0x43495041       // 'APIC'
+#define ACPI_FADT_SIG        0x50434146       // 'FACP' Notice that it is not 'FADT'.
 
 typedef struct {
     uint32_t signature_l;
@@ -36,6 +41,7 @@ typedef struct
     // Make it as null terminated
     char oem_id[7];
     acpi_madt_toc_t madt;
+    acpi_fadt_t fadt;
 } acpi_context;
 
 int
diff --git a/lunaix-os/includes/hal/acpi/fadt.h b/lunaix-os/includes/hal/acpi/fadt.h
new file mode 100644 (file)
index 0000000..a613a6c
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __LUNAIX_FADT_H
+#define __LUNAIX_FADT_H
+
+#include "sdt.h"
+
+// Pulled from ACPI Specification (v6.4) section 5.2.9
+
+enum PMProfile {
+    Desktop = 1,
+    Mobile = 2,
+    Workstation = 3,
+    EnterpriseServer = 4,
+    SOHOServer = 5,
+    AppliancePC = 6,
+    PerformanceServer = 7,
+    Tablet = 8,
+};
+
+#define IPM1AEVT_BLK_PORT 0
+#define IPM1BEVT_BLK_PORT 1
+#define IPM1ACNT_BLK_PORT 2
+#define IPM1BCNT_BLK_PORT 3
+#define IPM2CNT_BLK_PORT 4
+#define IPMTMR_BLK_PORT 5
+
+#define IPM1EVT_BLK_LEN 0
+#define IPM1CNT_BLK_LEN 1
+#define IPM2CNT_BLK_LEN 2
+#define IPMTMR_BLK_LEN 3
+
+#define ITIME_DAY_ALARM 0
+#define ITIME_MON_ALARM 1
+#define ITIME_CENTURY 2
+
+#define IAPC_ARCH_LEGACY   0x1
+#define IAPC_ARCH_8042     0x2
+#define IAPC_ARCH_NO_VGA   0x4
+#define IAPC_ARCH_NO_MSI   0x8
+#define IAPC_ARCH_ASPM     0x10
+#define IAPC_ARCH_NO_RTC   0x20
+
+typedef struct acpi_fadt {
+    acpi_sdthdr_t header;
+    uint32_t firmware_controller_addr;
+    uint32_t dsdt_addr;
+    uint8_t pm_profile;
+    uint16_t sci_int;
+    uint32_t smi_cmd_port_addr;
+    uint8_t smi_acpi_enable;
+    uint8_t smi_acpi_disable;
+    uint8_t smi_s4bios_state;
+    uint8_t smi_pstate;
+    uint32_t pm_reg_ports[6];
+    uint32_t gpe0_port_addr;
+    uint32_t gpe1_port_addr;
+    uint8_t pm_reg_lens[4];
+    uint8_t gpe0_len;
+    uint8_t gpe1_len;
+    uint8_t gpe1_base;
+    uint8_t cst_cnt;
+    uint16_t p_lvl2_lat;
+    uint16_t p_lvl3_lat;
+    uint16_t flush_size;
+    uint16_t flush_stride;
+    uint8_t duty_offset;
+    uint8_t duty_width;
+    uint8_t time_info[3];
+    uint16_t boot_arch;
+} ACPI_TABLE_PACKED acpi_fadt_t;
+
+
+// TODO: FADT parser & support
+
+#endif /* __LUNAIX_FADT_H */
index 72aca46158af180a83657b235fd258275e8931df..ef03bfd5b013dc74ef97dec0c60e3d394faec940 100644 (file)
@@ -15,7 +15,7 @@ typedef struct
 {
     uint8_t type;
     uint8_t length;
-} __attribute__((packed)) acpi_ics_hdr_t;
+} ACPI_TABLE_PACKED acpi_ics_hdr_t;
 
 /**
  * @brief ACPI Processor Local APIC Structure (PLAS)
@@ -29,7 +29,7 @@ typedef struct
     uint8_t processor_id;
     uint8_t apic_id;
     uint32_t flags;
-} __attribute__((packed)) acpi_apic_t;
+} ACPI_TABLE_PACKED acpi_apic_t;
 
 /**
  * @brief ACPI IO APIC Structure (IOAS)
@@ -46,7 +46,7 @@ typedef struct
     uint32_t ioapic_addr;
     // The global system interrupt offset for this IOAPIC. (Kind of IRQ offset for a slave IOAPIC)
     uint32_t gis_offset;
-} __attribute__((packed)) acpi_ioapic_t;
+} ACPI_TABLE_PACKED acpi_ioapic_t;
 
 /**
  * @brief ACPI Interrupt Source Override (INTSO)
@@ -67,7 +67,7 @@ typedef struct
     // global system interrupt. The override of source in APIC mode
     uint32_t gsi;
     uint16_t flags;
-} __attribute__((packed)) acpi_intso_t;
+} ACPI_TABLE_PACKED acpi_intso_t;
 
 typedef struct
 {
@@ -75,7 +75,7 @@ typedef struct
     void* apic_addr;
     uint32_t flags;
     // Here is a bunch of packed ICS reside here back-to-back.
-} __attribute__((packed)) acpi_madt_t;
+} ACPI_TABLE_PACKED acpi_madt_t;
 
 typedef struct
 {
@@ -83,6 +83,6 @@ typedef struct
     acpi_apic_t* apic;
     acpi_ioapic_t* ioapic;
     acpi_intso_t** irq_exception;
-} __attribute__((packed)) acpi_madt_toc_t;
+} ACPI_TABLE_PACKED acpi_madt_toc_t;
 
 #endif /* __LUNAIX_ACPI_MADT_H */
index fb7809771945861212bbe35b249fe019741508d7..fc4a332428e4424da18c4a1088ffc1b9dfaacc1f 100644 (file)
@@ -3,7 +3,9 @@
 
 #include <stdint.h>
 
-typedef struct
+#define ACPI_TABLE_PACKED   __attribute__((packed))
+
+typedef struct acpi_sdthdr
 {
     uint32_t signature;
     uint32_t length;
@@ -15,12 +17,12 @@ typedef struct
     uint32_t oem_rev;
     uint32_t vendor_id;
     uint32_t vendor_rev;
-} __attribute__((packed)) acpi_sdthdr_t;
+} ACPI_TABLE_PACKED acpi_sdthdr_t;
 
-typedef struct
+typedef struct acpi_rsdt
 {
     acpi_sdthdr_t header;
     acpi_sdthdr_t* entry;
-} __attribute__((packed)) acpi_rsdt_t;
+} ACPI_TABLE_PACKED acpi_rsdt_t;
 
 #endif /* __LUNAIX_ACPI_SDT_H */
index 4e7fb63c27d394dc18ec7fdfa6cf640e1270a401..0cd3f2cb52b8076c192022bdf8ffd2443774bde2 100644 (file)
@@ -3,6 +3,7 @@
 #include <lunaix/timer.h>
 #include <lunaix/common.h>
 #include <lunaix/syslog.h>
+#include <hal/acpi/acpi.h>
 
 #include <hal/cpu.h>
 #include <arch/x86/interrupts.h>
@@ -104,10 +105,15 @@ void ps2_kbd_init() {
     kbd_state.translation_table = scancode_set2;
     kbd_state.state = KBD_STATE_KWAIT;
 
+    acpi_context* acpi_ctx = acpi_get_context();
+    if (!(acpi_ctx->fadt.boot_arch & IAPC_ARCH_8042)) {
+        kprintf(KERROR "No PS/2 controller detected.\n");
+        // FUTURE: Some alternative fallback on this? Check PCI bus for USB controller instead?
+        return;
+    }
+    
     cpu_disable_interrupt();
 
-    // XXX: 是否需要使用FADT探测PS/2控制器的存在?
-
     // 1、禁用任何的PS/2设备
     ps2_post_cmd(PS2_PORT_CTRL_CMDREG, PS2_CMD_PORT1_DISABLE, PS2_NO_ARG);
     ps2_post_cmd(PS2_PORT_CTRL_CMDREG, PS2_CMD_PORT2_DISABLE, PS2_NO_ARG);