/* * Copyright (C) 2021 Sean Rhodes * * SPDX-License-Identifier: LGPL-2.1+ */ #include "config.h" #ifdef HAVE_IO_H #include #endif #include "fu-flashrom-cmos.h" #ifdef HAVE_IO_H static gboolean fu_flashrom_cmos_write(guint8 addr, guint8 val) { guint8 tmp; /* Reject addresses in the second bank */ if (addr >= 128) return FALSE; /* Write the value to CMOS */ outb(addr, RTC_BASE_PORT); outb(val, RTC_BASE_PORT + 1); /* Read the value back from CMOS */ outb(addr, RTC_BASE_PORT); tmp = inb(RTC_BASE_PORT + 1); /* Check the read value against the written */ return (tmp == val); } #endif gboolean fu_flashrom_cmos_reset(GError **error) { #ifdef HAVE_IO_H /* Call ioperm() to grant us access to ports 0x70 and 0x71 */ if (ioperm(RTC_BASE_PORT, 2, TRUE) < 0) { g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_READ, "failed to gain access to ports 0x70 and 0x71"); return FALSE; } /* Write a default value to the CMOS checksum */ if ((!fu_flashrom_cmos_write(CMOS_CHECKSUM_OFFSET, 0xff)) || (!fu_flashrom_cmos_write(CMOS_CHECKSUM_OFFSET + 1, 0xff))) { g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_READ, "failed to reset CMOS"); return FALSE; } /* success */ return TRUE; #else g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "no support"); return FALSE; #endif }