fwupd/plugins/flashrom/fu-flashrom-cmos.c
2021-10-06 20:38:43 +01:00

64 lines
1.4 KiB
C

/*
* Copyright (C) 2021 Sean Rhodes <sean@starlabs.systems>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#ifdef HAVE_IO_H
#include <sys/io.h>
#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 <sys/io.h> support");
return FALSE;
#endif
}