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>