From: Minep Date: Tue, 3 May 2022 15:25:45 +0000 (+0100) Subject: Add FADT check for presence of i8042 controller. X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/ae23ad2227bd97df4b464937b1dd54a0f3702148 Add FADT check for presence of i8042 controller. --- diff --git a/lunaix-os/hal/acpi/acpi.c b/lunaix-os/hal/acpi/acpi.c index a998278..5713f9a 100644 --- a/lunaix-os/hal/acpi/acpi.c +++ b/lunaix-os/hal/acpi/acpi.c @@ -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); diff --git a/lunaix-os/includes/hal/acpi/acpi.h b/lunaix-os/includes/hal/acpi/acpi.h index 326a8d0..453e9f4 100644 --- a/lunaix-os/includes/hal/acpi/acpi.h +++ b/lunaix-os/includes/hal/acpi/acpi.h @@ -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 | 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 index 0000000..a613a6c --- /dev/null +++ b/lunaix-os/includes/hal/acpi/fadt.h @@ -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 */ diff --git a/lunaix-os/includes/hal/acpi/madt.h b/lunaix-os/includes/hal/acpi/madt.h index 72aca46..ef03bfd 100644 --- a/lunaix-os/includes/hal/acpi/madt.h +++ b/lunaix-os/includes/hal/acpi/madt.h @@ -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 */ diff --git a/lunaix-os/includes/hal/acpi/sdt.h b/lunaix-os/includes/hal/acpi/sdt.h index fb78097..fc4a332 100644 --- a/lunaix-os/includes/hal/acpi/sdt.h +++ b/lunaix-os/includes/hal/acpi/sdt.h @@ -3,7 +3,9 @@ #include -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 */ diff --git a/lunaix-os/kernel/peripheral/ps2kbd.c b/lunaix-os/kernel/peripheral/ps2kbd.c index 4e7fb63..0cd3f2c 100644 --- a/lunaix-os/kernel/peripheral/ps2kbd.c +++ b/lunaix-os/kernel/peripheral/ps2kbd.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -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);