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 <gre...@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_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to