-/* $OpenBSD: qcrtc.c,v 1.2 2023/01/16 20:12:38 patrick Exp $ */
+/* $OpenBSD: qcrtc.c,v 1.3 2023/07/22 22:48:35 patrick Exp $ */
/*
* Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
*
#include <dev/fdt/spmivar.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_misc.h>
#include <dev/ofw/fdt.h>
#include <dev/clock_subr.h>
return error;
}
- /* Retrieve RTC offset stored in UEFI. */
- if (qcscm_uefi_rtc_get(&off) != 0)
- return EIO;
+ /* Retrieve RTC offset from either NVRAM or UEFI. */
+ error = nvmem_read_cell(sc->sc_node, "offset", &off, sizeof(off));
+ if (error == ENXIO || (!error && off == 0))
+ error = qcscm_uefi_rtc_get(&off);
+ if (error)
+ return error;
- /* Add RTC counter and 10y+1w to get seconds from epoch. */
- tv->tv_sec = off + (reg + (10 * 365 * 86400 + 7 * 86400));
+ tv->tv_sec = off + reg;
tv->tv_usec = 0;
return 0;
}
return error;
}
- /* Subtract RTC counter and 10y+1w to get offset for UEFI. */
- off = tv->tv_sec - (reg + (10 * 365 * 86400 + 7 * 86400));
+ /* Store RTC offset in either NVRAM or UEFI. */
+ off = tv->tv_sec - reg;
+ error = nvmem_write_cell(sc->sc_node, "offset", &off, sizeof(off));
+ if (error == ENXIO)
+ error = qcscm_uefi_rtc_set(off);
- /* Store offset in UEFI. */
- return qcscm_uefi_rtc_set(off);
+ return error;
}
-/* $OpenBSD: qcscm.c,v 1.4 2023/05/17 23:12:04 patrick Exp $ */
+/* $OpenBSD: qcscm.c,v 1.5 2023/07/22 22:48:35 patrick Exp $ */
/*
* Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
*
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define UNIX_GPS_EPOCH_OFFSET 315964800
+
struct qcscm_dmamem {
bus_dmamap_t qdm_map;
bus_dma_segment_t qdm_seg;
&rtcinfosize) != 0)
return EIO;
- *off = rtcinfo[0];
+ /* UEFI stores the offset based on GPS epoch */
+ *off = rtcinfo[0] + UNIX_GPS_EPOCH_OFFSET;
return 0;
}
&rtcinfosize) != 0)
return EIO;
+ /* UEFI stores the offset based on GPS epoch */
+ off -= UNIX_GPS_EPOCH_OFFSET;
+
/* No need to set if we're not changing anything */
if (rtcinfo[0] == off)
return 0;