/* SPDX-License-Identifier: GPL-2.0-only */ /* This file is part of the coreboot project. */ #include #include #include #include #include #include #include "pmutil.h" void alt_gpi_mask(u16 clr, u16 set) { u16 alt_gp = read_pmbase16(ALT_GP_SMI_EN); alt_gp &= ~clr; alt_gp |= set; write_pmbase16(ALT_GP_SMI_EN, alt_gp); } void gpe0_mask(u32 clr, u32 set) { u32 gpe0 = read_pmbase32(GPE0_EN); gpe0 &= ~clr; gpe0 |= set; write_pmbase32(GPE0_EN, gpe0); } /** * @brief read and clear PM1_STS * @return PM1_STS register */ u16 reset_pm1_status(void) { u16 reg16 = read_pmbase16(PM1_STS); /* set status bits are cleared by writing 1 to them */ write_pmbase16(PM1_STS, reg16); return reg16; } void dump_pm1_status(u16 pm1_sts) { printk(BIOS_SPEW, "PM1_STS: "); if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK "); if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK "); if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR "); if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC "); if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN "); if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL "); if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM "); if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF "); printk(BIOS_SPEW, "\n"); int reg16 = read_pmbase16(PM1_EN); printk(BIOS_SPEW, "PM1_EN: %x\n", reg16); } /** * @brief read and clear SMI_STS * @return SMI_STS register */ u32 reset_smi_status(void) { u32 reg32; reg32 = read_pmbase32(SMI_STS); /* set status bits are cleared by writing 1 to them */ write_pmbase32(SMI_STS, reg32); return reg32; } void dump_smi_status(u32 smi_sts) { printk(BIOS_DEBUG, "SMI_STS: "); if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI "); if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR "); if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI "); if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 "); if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 "); if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI "); if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI "); if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC "); if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO "); if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON "); if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI "); if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI "); if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 "); if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 "); if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR "); if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM "); if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI "); if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB "); if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS "); printk(BIOS_DEBUG, "\n"); } /** * @brief read and clear GPE0_STS * @return GPE0_STS register */ u64 reset_gpe0_status(void) { u32 reg_h, reg_l; reg_l = read_pmbase32(GPE0_STS); reg_h = read_pmbase32(GPE0_STS + 4); /* set status bits are cleared by writing 1 to them */ write_pmbase32(GPE0_STS, reg_l); write_pmbase32(GPE0_STS + 4, reg_h); return (((u64)reg_h) << 32) | reg_l; } void dump_gpe0_status(u64 gpe0_sts) { int i; printk(BIOS_DEBUG, "GPE0_STS: "); if (gpe0_sts & (1LL << 32)) printk(BIOS_DEBUG, "USB6 "); for (i=31; i>= 16; i--) { if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16)); } if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 "); if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 "); if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 "); if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME "); if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW "); if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP "); if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI "); if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK "); if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI "); if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "USB5 "); if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 "); if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 "); if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "SWGPE "); if (gpe0_sts & (1 << 1)) printk(BIOS_DEBUG, "HOT_PLUG "); if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM "); printk(BIOS_DEBUG, "\n"); } /** * @brief read and clear TCOx_STS * @return TCOx_STS registers */ u32 reset_tco_status(void) { u32 reg32; reg32 = read_pmbase32(TCO1_STS); /* * set status bits are cleared by writing 1 to them, but don't * clear BOOT_STS before SECOND_TO_STS. */ write_pmbase32(TCO1_STS, reg32 & ~BOOT_STS); if (reg32 & BOOT_STS) write_pmbase32(TCO1_STS, BOOT_STS); return reg32; } void dump_tco_status(u32 tco_sts) { printk(BIOS_DEBUG, "TCO_STS: "); if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV "); if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT "); if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO "); if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET "); if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR "); if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI "); if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI "); if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR "); if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY "); if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT "); if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT "); if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO "); if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI "); printk(BIOS_DEBUG, "\n"); } /** * @brief Set the EOS bit */ void smi_set_eos(void) { u8 reg8; reg8 = read_pmbase8(SMI_EN); reg8 |= EOS; write_pmbase8(SMI_EN, reg8); } void dump_alt_gp_smi_status(u16 alt_gp_smi_sts) { int i; printk(BIOS_DEBUG, "ALT_GP_SMI_STS: "); for (i=15; i>= 0; i--) { if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", i); } printk(BIOS_DEBUG, "\n"); } /** * @brief read and clear ALT_GP_SMI_STS * @return ALT_GP_SMI_STS register */ u16 reset_alt_gp_smi_status(void) { u16 reg16; reg16 = read_pmbase16(ALT_GP_SMI_STS); /* set status bits are cleared by writing 1 to them */ write_pmbase16(ALT_GP_SMI_STS, reg16); return reg16; }