From owner-svn-src-all@FreeBSD.ORG Fri Apr 18 00:02:08 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DF8E3430; Fri, 18 Apr 2014 00:02:07 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CB9731392; Fri, 18 Apr 2014 00:02:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3I027cc024628; Fri, 18 Apr 2014 00:02:07 GMT (envelope-from tychon@svn.freebsd.org) Received: (from tychon@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3I027GQ024622; Fri, 18 Apr 2014 00:02:07 GMT (envelope-from tychon@svn.freebsd.org) Message-Id: <201404180002.s3I027GQ024622@svn.freebsd.org> From: Tycho Nightingale Date: Fri, 18 Apr 2014 00:02:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264631 - in head: sys/amd64/vmm sys/amd64/vmm/io usr.sbin/bhyve X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Apr 2014 00:02:08 -0000 Author: tychon Date: Fri Apr 18 00:02:06 2014 New Revision: 264631 URL: http://svnweb.freebsd.org/changeset/base/264631 Log: Add support for reading the PIT Counter 2 output signal via the NMI Status and Control register at port 0x61. Be more conservative about "catching up" callouts that were supposed to fire in the past by skipping an interrupt if it was scheduled too far in the past. Restore the PIT ACPI DSDT entries and add an entry for NMISC too. Approved by: neel (co-mentor) Modified: head/sys/amd64/vmm/io/vatpit.c head/sys/amd64/vmm/io/vatpit.h head/sys/amd64/vmm/vmm_ioport.c head/usr.sbin/bhyve/pci_lpc.c Modified: head/sys/amd64/vmm/io/vatpit.c ============================================================================== --- head/sys/amd64/vmm/io/vatpit.c Thu Apr 17 23:31:50 2014 (r264630) +++ head/sys/amd64/vmm/io/vatpit.c Fri Apr 18 00:02:06 2014 (r264631) @@ -56,6 +56,8 @@ static MALLOC_DEFINE(M_VATPIT, "atpit", #define TIMER_MODE_MASK 0x0f #define TIMER_SEL_READBACK 0xc0 +#define TMR2_OUT_STS 0x20 + #define PIT_8254_FREQ 1193182 #define TIMER_DIV(freq, hz) (((freq) + (hz) / 2) / (hz)) @@ -88,22 +90,29 @@ struct vatpit { struct channel channel[3]; }; -#define VATPIT_CTR0(vatpit, fmt) \ - VM_CTR0((vatpit)->vm, fmt) - -#define VATPIT_CTR1(vatpit, fmt, a1) \ - VM_CTR1((vatpit)->vm, fmt, a1) +static void pit_timer_start_cntr0(struct vatpit *vatpit); -#define VATPIT_CTR2(vatpit, fmt, a1, a2) \ - VM_CTR2((vatpit)->vm, fmt, a1, a2) +static int +vatpit_get_out(struct vatpit *vatpit, int channel) +{ + struct channel *c; + sbintime_t delta_ticks; + int out; -#define VATPIT_CTR3(vatpit, fmt, a1, a2, a3) \ - VM_CTR3((vatpit)->vm, fmt, a1, a2, a3) + c = &vatpit->channel[channel]; -#define VATPIT_CTR4(vatpit, fmt, a1, a2, a3, a4) \ - VM_CTR4((vatpit)->vm, fmt, a1, a2, a3, a4) + switch (c->mode) { + case TIMER_INTTC: + delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt; + out = ((c->initial - delta_ticks) <= 0); + break; + default: + out = 0; + break; + } -static void pit_timer_start_cntr0(struct vatpit *vatpit); + return (out); +} static void vatpit_callout_handler(void *a) @@ -117,7 +126,7 @@ vatpit_callout_handler(void *a) c = &vatpit->channel[arg->channel_num]; callout = &c->callout; - VATPIT_CTR1(vatpit, "atpit t%d fired", arg->channel_num); + VM_CTR1(vatpit->vm, "atpit t%d fired", arg->channel_num); VATPIT_LOCK(vatpit); @@ -145,7 +154,7 @@ static void pit_timer_start_cntr0(struct vatpit *vatpit) { struct channel *c; - sbintime_t delta, precision; + sbintime_t now, delta, precision; c = &vatpit->channel[0]; if (c->initial != 0) { @@ -153,6 +162,15 @@ pit_timer_start_cntr0(struct vatpit *vat precision = delta >> tc_precexp; c->callout_sbt = c->callout_sbt + delta; + /* + * Reset 'callout_sbt' if the time that the callout + * was supposed to fire is more than 'c->initial' + * ticks in the past. + */ + now = sbinuptime(); + if (c->callout_sbt < now) + c->callout_sbt = now + delta; + callout_reset_sbt(&c->callout, c->callout_sbt, precision, vatpit_callout_handler, &c->callout_arg, C_ABSOLUTE); @@ -252,8 +270,8 @@ vatpit_handler(void *vm, int vcpuid, str port = vmexit->u.inout.port; if (port == TIMER_MODE) { - if (vmexit->u.inout.in != 0) { - VATPIT_CTR0(vatpit, "vatpit attempt to read mode"); + if (vmexit->u.inout.in) { + VM_CTR0(vatpit->vm, "vatpit attempt to read mode"); return (-1); } @@ -310,6 +328,26 @@ vatpit_handler(void *vm, int vcpuid, str return (0); } +int +vatpit_nmisc_handler(void *vm, int vcpuid, struct vm_exit *vmexit) +{ + struct vatpit *vatpit; + + vatpit = vm_atpit(vm); + + if (vmexit->u.inout.in) { + VATPIT_LOCK(vatpit); + if (vatpit_get_out(vatpit, 2)) + vmexit->u.inout.eax = TMR2_OUT_STS; + else + vmexit->u.inout.eax = 0; + + VATPIT_UNLOCK(vatpit); + } + + return (0); +} + struct vatpit * vatpit_init(struct vm *vm) { Modified: head/sys/amd64/vmm/io/vatpit.h ============================================================================== --- head/sys/amd64/vmm/io/vatpit.h Thu Apr 17 23:31:50 2014 (r264630) +++ head/sys/amd64/vmm/io/vatpit.h Fri Apr 18 00:02:06 2014 (r264631) @@ -32,9 +32,12 @@ #include +#define NMISC_PORT 0x61 + struct vatpit *vatpit_init(struct vm *vm); void vatpit_cleanup(struct vatpit *vatpit); int vatpit_handler(void *vm, int vcpuid, struct vm_exit *vmexit); +int vatpit_nmisc_handler(void *vm, int vcpuid, struct vm_exit *vmexit); #endif /* _VATPIT_H_ */ Modified: head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- head/sys/amd64/vmm/vmm_ioport.c Thu Apr 17 23:31:50 2014 (r264630) +++ head/sys/amd64/vmm/vmm_ioport.c Fri Apr 18 00:02:06 2014 (r264631) @@ -46,6 +46,7 @@ ioport_handler_func_t ioport_handler[MAX [TIMER_CNTR0] = vatpit_handler, [TIMER_CNTR1] = vatpit_handler, [TIMER_CNTR2] = vatpit_handler, + [NMISC_PORT] = vatpit_nmisc_handler, [IO_ICU1] = vatpic_master_handler, [IO_ICU1 + ICU_IMR_OFFSET] = vatpic_master_handler, [IO_ICU2] = vatpic_slave_handler, Modified: head/usr.sbin/bhyve/pci_lpc.c ============================================================================== --- head/usr.sbin/bhyve/pci_lpc.c Thu Apr 17 23:31:50 2014 (r264630) +++ head/usr.sbin/bhyve/pci_lpc.c Fri Apr 18 00:02:06 2014 (r264631) @@ -55,6 +55,11 @@ SET_DECLARE(lpc_sysres_set, struct lpc_s #define ELCR_PORT 0x4d0 SYSRES_IO(ELCR_PORT, 2); +#define IO_TIMER1_PORT 0x40 + +#define NMISC_PORT 0x61 +SYSRES_IO(NMISC_PORT, 1); + static struct pci_devinst *lpc_bridge; #define LPC_UART_NUM 2 @@ -226,6 +231,19 @@ pci_lpc_write_dsdt(struct pci_devinst *p dsdt_line("}"); dsdt_unindent(1); + dsdt_line(""); + dsdt_line("Device (TIMR)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0100\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(IO_TIMER1_PORT, 4); + dsdt_fixed_irq(0); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + dsdt_line("}"); }