/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2011 NetApp, Inc.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/types.h>2930#include <time.h>31#include <assert.h>3233#include <machine/vmm.h>34#include <vmmapi.h>3536#include "acpi.h"37#include "config.h"38#include "pci_lpc.h"39#include "rtc.h"4041#define IO_RTC 0x704243#define RTC_LMEM_LSB 0x3444#define RTC_LMEM_MSB 0x3545#define RTC_HMEM_LSB 0x5b46#define RTC_HMEM_SB 0x5c47#define RTC_HMEM_MSB 0x5d4849#define m_64KB (64*1024)50#define m_16MB (16*1024*1024)51#define m_4GB (4ULL*1024*1024*1024)5253/*54* Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 197055*/56static time_t57rtc_time(void)58{59struct tm tm;60time_t t;6162time(&t);63if (get_config_bool_default("rtc.use_localtime", true)) {64localtime_r(&t, &tm);65t = timegm(&tm);66}67return (t);68}6970void71rtc_init(struct vmctx *ctx)72{73size_t himem;74size_t lomem;75int err;7677/* XXX init diag/reset code/equipment/checksum ? */7879/*80* Report guest memory size in nvram cells as required by UEFI.81* Little-endian encoding.82* 0x34/0x35 - 64KB chunks above 16MB, below 4GB83* 0x5b/0x5c/0x5d - 64KB chunks above 4GB84*/85lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB;86err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem);87assert(err == 0);88err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8);89assert(err == 0);9091himem = vm_get_highmem_size(ctx) / m_64KB;92err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem);93assert(err == 0);94err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8);95assert(err == 0);96err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16);97assert(err == 0);9899err = vm_rtc_settime(ctx, rtc_time());100assert(err == 0);101}102103static void104rtc_dsdt(void)105{106107dsdt_line("");108dsdt_line("Device (RTC)");109dsdt_line("{");110dsdt_line(" Name (_HID, EisaId (\"PNP0B00\"))");111dsdt_line(" Name (_CRS, ResourceTemplate ()");112dsdt_line(" {");113dsdt_indent(2);114dsdt_fixed_ioport(IO_RTC, 2);115dsdt_fixed_irq(8);116dsdt_unindent(2);117dsdt_line(" })");118dsdt_line("}");119}120LPC_DSDT(rtc_dsdt);121122/*123* Reserve the extended RTC I/O ports although they are not emulated at this124* time.125*/126SYSRES_IO(0x72, 6);127128129