xref: /freebsd-src/usr.sbin/bhyve/amd64/rtc.c (revision 4d65a7c6951cea0333f1a0c1b32c38489cdfa6c5)
1*a7f6c2ffSMark Johnston /*-
2*a7f6c2ffSMark Johnston  * SPDX-License-Identifier: BSD-2-Clause
3*a7f6c2ffSMark Johnston  *
4*a7f6c2ffSMark Johnston  * Copyright (c) 2011 NetApp, Inc.
5*a7f6c2ffSMark Johnston  * All rights reserved.
6*a7f6c2ffSMark Johnston  *
7*a7f6c2ffSMark Johnston  * Redistribution and use in source and binary forms, with or without
8*a7f6c2ffSMark Johnston  * modification, are permitted provided that the following conditions
9*a7f6c2ffSMark Johnston  * are met:
10*a7f6c2ffSMark Johnston  * 1. Redistributions of source code must retain the above copyright
11*a7f6c2ffSMark Johnston  *    notice, this list of conditions and the following disclaimer.
12*a7f6c2ffSMark Johnston  * 2. Redistributions in binary form must reproduce the above copyright
13*a7f6c2ffSMark Johnston  *    notice, this list of conditions and the following disclaimer in the
14*a7f6c2ffSMark Johnston  *    documentation and/or other materials provided with the distribution.
15*a7f6c2ffSMark Johnston  *
16*a7f6c2ffSMark Johnston  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17*a7f6c2ffSMark Johnston  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*a7f6c2ffSMark Johnston  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*a7f6c2ffSMark Johnston  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20*a7f6c2ffSMark Johnston  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*a7f6c2ffSMark Johnston  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*a7f6c2ffSMark Johnston  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*a7f6c2ffSMark Johnston  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*a7f6c2ffSMark Johnston  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*a7f6c2ffSMark Johnston  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*a7f6c2ffSMark Johnston  * SUCH DAMAGE.
27*a7f6c2ffSMark Johnston  */
28*a7f6c2ffSMark Johnston 
29*a7f6c2ffSMark Johnston #include <sys/types.h>
30*a7f6c2ffSMark Johnston 
31*a7f6c2ffSMark Johnston #include <time.h>
32*a7f6c2ffSMark Johnston #include <assert.h>
33*a7f6c2ffSMark Johnston 
34*a7f6c2ffSMark Johnston #include <machine/vmm.h>
35*a7f6c2ffSMark Johnston #include <vmmapi.h>
36*a7f6c2ffSMark Johnston 
37*a7f6c2ffSMark Johnston #include "acpi.h"
38*a7f6c2ffSMark Johnston #include "config.h"
39*a7f6c2ffSMark Johnston #include "pci_lpc.h"
40*a7f6c2ffSMark Johnston #include "rtc.h"
41*a7f6c2ffSMark Johnston 
42*a7f6c2ffSMark Johnston #define	IO_RTC		0x70
43*a7f6c2ffSMark Johnston 
44*a7f6c2ffSMark Johnston #define	RTC_LMEM_LSB	0x34
45*a7f6c2ffSMark Johnston #define	RTC_LMEM_MSB	0x35
46*a7f6c2ffSMark Johnston #define	RTC_HMEM_LSB	0x5b
47*a7f6c2ffSMark Johnston #define	RTC_HMEM_SB	0x5c
48*a7f6c2ffSMark Johnston #define	RTC_HMEM_MSB	0x5d
49*a7f6c2ffSMark Johnston 
50*a7f6c2ffSMark Johnston #define	m_64KB		(64*1024)
51*a7f6c2ffSMark Johnston #define	m_16MB		(16*1024*1024)
52*a7f6c2ffSMark Johnston #define	m_4GB		(4ULL*1024*1024*1024)
53*a7f6c2ffSMark Johnston 
54*a7f6c2ffSMark Johnston /*
55*a7f6c2ffSMark Johnston  * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970
56*a7f6c2ffSMark Johnston  */
57*a7f6c2ffSMark Johnston static time_t
rtc_time(void)58*a7f6c2ffSMark Johnston rtc_time(void)
59*a7f6c2ffSMark Johnston {
60*a7f6c2ffSMark Johnston 	struct tm tm;
61*a7f6c2ffSMark Johnston 	time_t t;
62*a7f6c2ffSMark Johnston 
63*a7f6c2ffSMark Johnston 	time(&t);
64*a7f6c2ffSMark Johnston 	if (get_config_bool_default("rtc.use_localtime", true)) {
65*a7f6c2ffSMark Johnston 		localtime_r(&t, &tm);
66*a7f6c2ffSMark Johnston 		t = timegm(&tm);
67*a7f6c2ffSMark Johnston 	}
68*a7f6c2ffSMark Johnston 	return (t);
69*a7f6c2ffSMark Johnston }
70*a7f6c2ffSMark Johnston 
71*a7f6c2ffSMark Johnston void
rtc_init(struct vmctx * ctx)72*a7f6c2ffSMark Johnston rtc_init(struct vmctx *ctx)
73*a7f6c2ffSMark Johnston {
74*a7f6c2ffSMark Johnston 	size_t himem;
75*a7f6c2ffSMark Johnston 	size_t lomem;
76*a7f6c2ffSMark Johnston 	int err;
77*a7f6c2ffSMark Johnston 
78*a7f6c2ffSMark Johnston 	/* XXX init diag/reset code/equipment/checksum ? */
79*a7f6c2ffSMark Johnston 
80*a7f6c2ffSMark Johnston 	/*
81*a7f6c2ffSMark Johnston 	 * Report guest memory size in nvram cells as required by UEFI.
82*a7f6c2ffSMark Johnston 	 * Little-endian encoding.
83*a7f6c2ffSMark Johnston 	 * 0x34/0x35 - 64KB chunks above 16MB, below 4GB
84*a7f6c2ffSMark Johnston 	 * 0x5b/0x5c/0x5d - 64KB chunks above 4GB
85*a7f6c2ffSMark Johnston 	 */
86*a7f6c2ffSMark Johnston 	lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB;
87*a7f6c2ffSMark Johnston 	err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem);
88*a7f6c2ffSMark Johnston 	assert(err == 0);
89*a7f6c2ffSMark Johnston 	err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8);
90*a7f6c2ffSMark Johnston 	assert(err == 0);
91*a7f6c2ffSMark Johnston 
92*a7f6c2ffSMark Johnston 	himem = vm_get_highmem_size(ctx) / m_64KB;
93*a7f6c2ffSMark Johnston 	err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem);
94*a7f6c2ffSMark Johnston 	assert(err == 0);
95*a7f6c2ffSMark Johnston 	err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8);
96*a7f6c2ffSMark Johnston 	assert(err == 0);
97*a7f6c2ffSMark Johnston 	err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16);
98*a7f6c2ffSMark Johnston 	assert(err == 0);
99*a7f6c2ffSMark Johnston 
100*a7f6c2ffSMark Johnston 	err = vm_rtc_settime(ctx, rtc_time());
101*a7f6c2ffSMark Johnston 	assert(err == 0);
102*a7f6c2ffSMark Johnston }
103*a7f6c2ffSMark Johnston 
104*a7f6c2ffSMark Johnston static void
rtc_dsdt(void)105*a7f6c2ffSMark Johnston rtc_dsdt(void)
106*a7f6c2ffSMark Johnston {
107*a7f6c2ffSMark Johnston 
108*a7f6c2ffSMark Johnston 	dsdt_line("");
109*a7f6c2ffSMark Johnston 	dsdt_line("Device (RTC)");
110*a7f6c2ffSMark Johnston 	dsdt_line("{");
111*a7f6c2ffSMark Johnston 	dsdt_line("  Name (_HID, EisaId (\"PNP0B00\"))");
112*a7f6c2ffSMark Johnston 	dsdt_line("  Name (_CRS, ResourceTemplate ()");
113*a7f6c2ffSMark Johnston 	dsdt_line("  {");
114*a7f6c2ffSMark Johnston 	dsdt_indent(2);
115*a7f6c2ffSMark Johnston 	dsdt_fixed_ioport(IO_RTC, 2);
116*a7f6c2ffSMark Johnston 	dsdt_fixed_irq(8);
117*a7f6c2ffSMark Johnston 	dsdt_unindent(2);
118*a7f6c2ffSMark Johnston 	dsdt_line("  })");
119*a7f6c2ffSMark Johnston 	dsdt_line("}");
120*a7f6c2ffSMark Johnston }
121*a7f6c2ffSMark Johnston LPC_DSDT(rtc_dsdt);
122*a7f6c2ffSMark Johnston 
123*a7f6c2ffSMark Johnston /*
124*a7f6c2ffSMark Johnston  * Reserve the extended RTC I/O ports although they are not emulated at this
125*a7f6c2ffSMark Johnston  * time.
126*a7f6c2ffSMark Johnston  */
127*a7f6c2ffSMark Johnston SYSRES_IO(0x72, 6);
128