xref: /illumos-gate/usr/src/cmd/bhyve/rtc.c (revision 32640292)
1bf21cd93STycho Nightingale /*-
2*32640292SAndy Fiddaman  * SPDX-License-Identifier: BSD-2-Clause
34c87aefeSPatrick Mooney  *
4bf21cd93STycho Nightingale  * Copyright (c) 2011 NetApp, Inc.
5bf21cd93STycho Nightingale  * All rights reserved.
6bf21cd93STycho Nightingale  *
7bf21cd93STycho Nightingale  * Redistribution and use in source and binary forms, with or without
8bf21cd93STycho Nightingale  * modification, are permitted provided that the following conditions
9bf21cd93STycho Nightingale  * are met:
10bf21cd93STycho Nightingale  * 1. Redistributions of source code must retain the above copyright
11bf21cd93STycho Nightingale  *    notice, this list of conditions and the following disclaimer.
12bf21cd93STycho Nightingale  * 2. Redistributions in binary form must reproduce the above copyright
13bf21cd93STycho Nightingale  *    notice, this list of conditions and the following disclaimer in the
14bf21cd93STycho Nightingale  *    documentation and/or other materials provided with the distribution.
15bf21cd93STycho Nightingale  *
16bf21cd93STycho Nightingale  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17bf21cd93STycho Nightingale  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18bf21cd93STycho Nightingale  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19bf21cd93STycho Nightingale  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20bf21cd93STycho Nightingale  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21bf21cd93STycho Nightingale  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22bf21cd93STycho Nightingale  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23bf21cd93STycho Nightingale  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24bf21cd93STycho Nightingale  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25bf21cd93STycho Nightingale  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bf21cd93STycho Nightingale  * SUCH DAMAGE.
27bf21cd93STycho Nightingale  */
28bf21cd93STycho Nightingale 
29bf21cd93STycho Nightingale #include <sys/cdefs.h>
30bf21cd93STycho Nightingale 
31bf21cd93STycho Nightingale #include <sys/types.h>
32bf21cd93STycho Nightingale 
33bf21cd93STycho Nightingale #include <time.h>
34bf21cd93STycho Nightingale #include <assert.h>
35bf21cd93STycho Nightingale 
36bf21cd93STycho Nightingale #include <machine/vmm.h>
37bf21cd93STycho Nightingale #include <vmmapi.h>
38bf21cd93STycho Nightingale 
39bf21cd93STycho Nightingale #include "acpi.h"
402b948146SAndy Fiddaman #include "config.h"
41bf21cd93STycho Nightingale #include "pci_lpc.h"
42bf21cd93STycho Nightingale #include "rtc.h"
43bf21cd93STycho Nightingale 
444c87aefeSPatrick Mooney #define	IO_RTC		0x70
45bf21cd93STycho Nightingale 
46bf21cd93STycho Nightingale #define	RTC_LMEM_LSB	0x34
47bf21cd93STycho Nightingale #define	RTC_LMEM_MSB	0x35
48bf21cd93STycho Nightingale #define	RTC_HMEM_LSB	0x5b
49bf21cd93STycho Nightingale #define	RTC_HMEM_SB	0x5c
50bf21cd93STycho Nightingale #define	RTC_HMEM_MSB	0x5d
51bf21cd93STycho Nightingale 
524c87aefeSPatrick Mooney #define	m_64KB		(64*1024)
53bf21cd93STycho Nightingale #define	m_16MB		(16*1024*1024)
54bf21cd93STycho Nightingale #define	m_4GB		(4ULL*1024*1024*1024)
55bf21cd93STycho Nightingale 
564c87aefeSPatrick Mooney /*
574c87aefeSPatrick Mooney  * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970
584c87aefeSPatrick Mooney  */
59a1d41cf9SPatrick Mooney #ifdef __FreeBSD__
604c87aefeSPatrick Mooney static time_t
rtc_time(void)6159d65d31SAndy Fiddaman rtc_time(void)
62bf21cd93STycho Nightingale {
634c87aefeSPatrick Mooney 	struct tm tm;
64bf21cd93STycho Nightingale 	time_t t;
65bf21cd93STycho Nightingale 
664c87aefeSPatrick Mooney 	time(&t);
672b948146SAndy Fiddaman 	if (get_config_bool_default("rtc.use_localtime", true)) {
68bf21cd93STycho Nightingale 		localtime_r(&t, &tm);
694c87aefeSPatrick Mooney 		t = timegm(&tm);
70bf21cd93STycho Nightingale 	}
714c87aefeSPatrick Mooney 	return (t);
72bf21cd93STycho Nightingale }
73a1d41cf9SPatrick Mooney #else /* __FreeBSD__ */
74a1d41cf9SPatrick Mooney static void
rtc_time(timespec_t * ts)75a1d41cf9SPatrick Mooney rtc_time(timespec_t *ts)
76a1d41cf9SPatrick Mooney {
77a1d41cf9SPatrick Mooney 	(void) clock_gettime(CLOCK_REALTIME, ts);
78a1d41cf9SPatrick Mooney 
79a1d41cf9SPatrick Mooney 	if (get_config_bool_default("rtc.use_localtime", true)) {
80a1d41cf9SPatrick Mooney 		struct tm tm;
81a1d41cf9SPatrick Mooney 
82a1d41cf9SPatrick Mooney 		localtime_r(&ts->tv_sec, &tm);
83a1d41cf9SPatrick Mooney 		ts->tv_sec = timegm(&tm);
84a1d41cf9SPatrick Mooney 	}
85a1d41cf9SPatrick Mooney }
86a1d41cf9SPatrick Mooney #endif /* __FreeBSD__ */
87bf21cd93STycho Nightingale 
88bf21cd93STycho Nightingale void
rtc_init(struct vmctx * ctx)892b948146SAndy Fiddaman rtc_init(struct vmctx *ctx)
906dc98349SAndy Fiddaman {
91bf21cd93STycho Nightingale 	size_t himem;
92bf21cd93STycho Nightingale 	size_t lomem;
93bf21cd93STycho Nightingale 	int err;
94bf21cd93STycho Nightingale 
95bf21cd93STycho Nightingale 	/* XXX init diag/reset code/equipment/checksum ? */
96bf21cd93STycho Nightingale 
97bf21cd93STycho Nightingale 	/*
98bf21cd93STycho Nightingale 	 * Report guest memory size in nvram cells as required by UEFI.
99bf21cd93STycho Nightingale 	 * Little-endian encoding.
100bf21cd93STycho Nightingale 	 * 0x34/0x35 - 64KB chunks above 16MB, below 4GB
101bf21cd93STycho Nightingale 	 * 0x5b/0x5c/0x5d - 64KB chunks above 4GB
102bf21cd93STycho Nightingale 	 */
103bf21cd93STycho Nightingale 	lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB;
1044c87aefeSPatrick Mooney 	err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem);
1054c87aefeSPatrick Mooney 	assert(err == 0);
1064c87aefeSPatrick Mooney 	err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8);
1074c87aefeSPatrick Mooney 	assert(err == 0);
108bf21cd93STycho Nightingale 
109bf21cd93STycho Nightingale 	himem = vm_get_highmem_size(ctx) / m_64KB;
1104c87aefeSPatrick Mooney 	err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem);
1114c87aefeSPatrick Mooney 	assert(err == 0);
1124c87aefeSPatrick Mooney 	err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8);
1134c87aefeSPatrick Mooney 	assert(err == 0);
1144c87aefeSPatrick Mooney 	err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16);
1154c87aefeSPatrick Mooney 	assert(err == 0);
116bf21cd93STycho Nightingale 
117a1d41cf9SPatrick Mooney #ifdef __FreeBSD__
11859d65d31SAndy Fiddaman 	err = vm_rtc_settime(ctx, rtc_time());
119a1d41cf9SPatrick Mooney #else
120a1d41cf9SPatrick Mooney 	timespec_t ts;
121a1d41cf9SPatrick Mooney 
122a1d41cf9SPatrick Mooney 	rtc_time(&ts);
123a1d41cf9SPatrick Mooney 	err = vm_rtc_settime(ctx, &ts);
124a1d41cf9SPatrick Mooney #endif
1254c87aefeSPatrick Mooney 	assert(err == 0);
1264c87aefeSPatrick Mooney }
127bf21cd93STycho Nightingale 
128bf21cd93STycho Nightingale static void
rtc_dsdt(void)129bf21cd93STycho Nightingale rtc_dsdt(void)
130bf21cd93STycho Nightingale {
131bf21cd93STycho Nightingale 
132bf21cd93STycho Nightingale 	dsdt_line("");
133bf21cd93STycho Nightingale 	dsdt_line("Device (RTC)");
134bf21cd93STycho Nightingale 	dsdt_line("{");
135bf21cd93STycho Nightingale 	dsdt_line("  Name (_HID, EisaId (\"PNP0B00\"))");
136bf21cd93STycho Nightingale 	dsdt_line("  Name (_CRS, ResourceTemplate ()");
137bf21cd93STycho Nightingale 	dsdt_line("  {");
138bf21cd93STycho Nightingale 	dsdt_indent(2);
139bf21cd93STycho Nightingale 	dsdt_fixed_ioport(IO_RTC, 2);
140bf21cd93STycho Nightingale 	dsdt_fixed_irq(8);
141bf21cd93STycho Nightingale 	dsdt_unindent(2);
142bf21cd93STycho Nightingale 	dsdt_line("  })");
143bf21cd93STycho Nightingale 	dsdt_line("}");
144bf21cd93STycho Nightingale }
145bf21cd93STycho Nightingale LPC_DSDT(rtc_dsdt);
146bf21cd93STycho Nightingale 
1474c87aefeSPatrick Mooney /*
1484c87aefeSPatrick Mooney  * Reserve the extended RTC I/O ports although they are not emulated at this
1494c87aefeSPatrick Mooney  * time.
1504c87aefeSPatrick Mooney  */
151bf21cd93STycho Nightingale SYSRES_IO(0x72, 6);
152