Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Jul 2013 03:54:36 +0000 (UTC)
From:      Peter Grehan <grehan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253181 - head/usr.sbin/bhyve
Message-ID:  <201307110354.r6B3saLY009583@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grehan
Date: Thu Jul 11 03:54:35 2013
New Revision: 253181
URL: http://svnweb.freebsd.org/changeset/base/253181

Log:
  Implement RTC CMOS nvram. Init some fields that are used
  by FreeBSD and UEFI.
  Tested with nvram(4).
  
  Reviewed by:	neel

Added:
  head/usr.sbin/bhyve/rtc.h   (contents, props changed)
Modified:
  head/usr.sbin/bhyve/bhyverun.c
  head/usr.sbin/bhyve/rtc.c

Modified: head/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- head/usr.sbin/bhyve/bhyverun.c	Thu Jul 11 03:49:14 2013	(r253180)
+++ head/usr.sbin/bhyve/bhyverun.c	Thu Jul 11 03:54:35 2013	(r253181)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
 #include "xmsr.h"
 #include "ioapic.h"
 #include "spinup_ap.h"
+#include "rtc.h"
 
 #define	DEFAULT_GUEST_HZ	100
 #define	DEFAULT_GUEST_TSLICE	200
@@ -735,6 +736,8 @@ main(int argc, char *argv[])
 	init_mem();
 	init_inout();
 
+	rtc_init(ctx);
+
 	/*
 	 * Exit if a device emulation finds an error in it's initilization
 	 */

Modified: head/usr.sbin/bhyve/rtc.c
==============================================================================
--- head/usr.sbin/bhyve/rtc.c	Thu Jul 11 03:49:14 2013	(r253180)
+++ head/usr.sbin/bhyve/rtc.c	Thu Jul 11 03:54:35 2013	(r253181)
@@ -33,10 +33,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/time.h>
 
 #include <stdio.h>
+#include <string.h>
 #include <time.h>
 #include <assert.h>
 
+#include <machine/vmm.h>
+#include <vmmapi.h>
+
 #include "inout.h"
+#include "rtc.h"
 
 #define	IO_RTC	0x70
 
@@ -64,16 +69,30 @@ __FBSDID("$FreeBSD$");
 #define RTC_STATUSD	0x0d	/* status register D (R) Lost Power */
 #define  RTCSD_PWR	 0x80	/* clock power OK */
 
-#define	RTC_DIAG	0x0e
+#define	RTC_NVRAM_START	0x0e
+#define	RTC_NVRAM_END	0x7f
+#define RTC_NVRAM_SZ	(128 - RTC_NVRAM_START)
+#define	nvoff(x)	((x) - RTC_NVRAM_START)
 
+#define	RTC_DIAG	0x0e
 #define RTC_RSTCODE	0x0f
-
 #define	RTC_EQUIPMENT	0x14
+#define	RTC_LMEM_LSB	0x34
+#define	RTC_LMEM_MSB	0x35
+#define	RTC_HMEM_LSB	0x5b
+#define	RTC_HMEM_SB	0x5c
+#define	RTC_HMEM_MSB	0x5d
+
+#define m_64KB		(64*1024)
+#define	m_16MB		(16*1024*1024)
+#define	m_4GB		(4ULL*1024*1024*1024)
 
 static int addr;
 
+static uint8_t rtc_nvram[RTC_NVRAM_SZ];
+
 /* XXX initialize these to default values as they would be from BIOS */
-static uint8_t status_a, status_b, rstcode;
+static uint8_t status_a, status_b;
 
 static u_char const bin2bcd_data[] = {
 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
@@ -135,14 +154,11 @@ rtc_addr_handler(struct vmctx *ctx, int 
 	case RTC_DAY:
 	case RTC_MONTH:
 	case RTC_YEAR:
-	case RTC_CENTURY:
 	case RTC_STATUSA:
 	case RTC_STATUSB:
 	case RTC_INTR:
 	case RTC_STATUSD:
-	case RTC_DIAG:
-	case RTC_RSTCODE:
-	case RTC_EQUIPMENT:
+	case RTC_NVRAM_START ... RTC_NVRAM_END:
 		break;
 	default:
 		return (-1);
@@ -217,9 +233,6 @@ rtc_data_handler(struct vmctx *ctx, int 
 		case RTC_YEAR:
 			*eax = rtcout(tm.tm_year % 100);
 			return (0);
-		case RTC_CENTURY:
-			*eax = rtcout(tm.tm_year / 100);
-			break;
 		case RTC_STATUSA:
 			*eax = status_a;
 			return (0);
@@ -232,14 +245,8 @@ rtc_data_handler(struct vmctx *ctx, int 
 		case RTC_STATUSD:
 			*eax = RTCSD_PWR;
 			return (0);
-		case RTC_DIAG:
-			*eax = 0;
-			return (0);
-		case RTC_RSTCODE:
-			*eax = rstcode;
-			return (0);
-		case RTC_EQUIPMENT:
-			*eax = 0;
+		case RTC_NVRAM_START ... RTC_NVRAM_END:
+			*eax = rtc_nvram[addr - RTC_NVRAM_START];
 			return (0);
 		default:
 			return (-1);
@@ -259,9 +266,6 @@ rtc_data_handler(struct vmctx *ctx, int 
 	case RTC_STATUSD:
 		/* ignore write */
 		break;
-	case RTC_RSTCODE:
-		rstcode = *eax;
-		break;
 	case RTC_SEC:
 	case RTC_MIN:
 	case RTC_HRS:
@@ -269,16 +273,58 @@ rtc_data_handler(struct vmctx *ctx, int 
 	case RTC_DAY:
 	case RTC_MONTH:
 	case RTC_YEAR:
-	case RTC_CENTURY:
 		/*
 		 * Ignore writes to the time of day registers
 		 */
 		break;
+	case RTC_NVRAM_START ... RTC_NVRAM_END:
+		rtc_nvram[addr - RTC_NVRAM_START] = *eax;
+		break;
 	default:
 		return (-1);
 	}
 	return (0);
 }
 
+void
+rtc_init(struct vmctx *ctx)
+{	
+	struct timeval cur;
+	struct tm tm;
+	size_t himem;
+	size_t lomem;
+	int err;
+
+	err = gettimeofday(&cur, NULL);
+	assert(err == 0);
+	(void) localtime_r(&cur.tv_sec, &tm);
+
+	memset(rtc_nvram, 0, sizeof(rtc_nvram));
+
+	rtc_nvram[nvoff(RTC_CENTURY)] = rtcout(tm.tm_year / 100);
+
+	/* XXX init diag/reset code/equipment/checksum ? */
+
+	/*
+	 * Report guest memory size in nvram cells as required by UEFI.
+	 * Little-endian encoding.
+	 * 0x34/0x35 - 64KB chunks above 16MB, below 4GB
+	 * 0x5b/0x5c/0x5d - 64KB chunks above 4GB
+	 */
+	err = vm_get_memory_seg(ctx, 0, &lomem);
+	assert(err == 0);
+
+	lomem = (lomem - m_16MB) / m_64KB;
+	rtc_nvram[nvoff(RTC_LMEM_LSB)] = lomem;
+	rtc_nvram[nvoff(RTC_LMEM_MSB)] = lomem >> 8;
+
+	if (vm_get_memory_seg(ctx, m_4GB, &himem) == 0) {	  
+		himem /= m_64KB;
+		rtc_nvram[nvoff(RTC_HMEM_LSB)] = himem;
+		rtc_nvram[nvoff(RTC_HMEM_SB)]  = himem >> 8;
+		rtc_nvram[nvoff(RTC_NVRAM_START)] = himem >> 16;
+	}
+}
+
 INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler);
 INOUT_PORT(rtc, IO_RTC + 1, IOPORT_F_INOUT, rtc_data_handler);

Added: head/usr.sbin/bhyve/rtc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bhyve/rtc.h	Thu Jul 11 03:54:35 2013	(r253181)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013  Peter Grehan <grehan@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _RTC_H_
+#define _RTC_H_
+
+void	rtc_init(struct vmctx *ctx);
+
+#endif /* _RTC_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307110354.r6B3saLY009583>