[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: allow Dom0 to drive PC speaker
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1189607578 -3600 # Node ID 9dd580b8b056860fe7634bb964e2bcf201e87bd6 # Parent 45dbef0ab7a6cb108d6db36392d9ee3661efbb59 x86: allow Dom0 to drive PC speaker as long as Xen doesn't itself make use of PIT channel 2. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/i8254.c | 8 +++++--- xen/arch/x86/time.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- xen/include/asm-x86/time.h | 13 ++++++++----- 3 files changed, 57 insertions(+), 9 deletions(-) diff -r 45dbef0ab7a6 -r 9dd580b8b056 xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Wed Sep 12 09:58:16 2007 +0100 +++ b/xen/arch/x86/hvm/i8254.c Wed Sep 12 15:32:58 2007 +0100 @@ -598,11 +598,13 @@ int pv_pit_handler(int port, int data, i .size = 1, .type = IOREQ_TYPE_PIO, .addr = port, - .dir = write ? 0 : 1, - .data = write ? data : 0, + .dir = write ? IOREQ_WRITE : IOREQ_READ, + .data = data }; - if ( port == 0x61 ) + if ( (current->domain->domain_id == 0) && dom0_pit_access(&ioreq) ) + /* nothing to do */; + else if ( port == 0x61 ) handle_speaker_io(&ioreq); else handle_pit_io(&ioreq); diff -r 45dbef0ab7a6 -r 9dd580b8b056 xen/arch/x86/time.c --- a/xen/arch/x86/time.c Wed Sep 12 09:58:16 2007 +0100 +++ b/xen/arch/x86/time.c Wed Sep 12 15:32:58 2007 +0100 @@ -177,7 +177,6 @@ static u64 init_pit_and_calibrate_tsc(vo unsigned long count; /* Set PIT channel 0 to HZ Hz. */ -#define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */ #define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ) outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ outb_p(LATCH & 0xff, PIT_CH0); /* LSB */ @@ -972,6 +971,50 @@ int time_resume(void) return 0; } +int dom0_pit_access(struct ioreq *ioreq) +{ + /* Is Xen using Channel 2? Then disallow direct dom0 access. */ + if ( plt_src.read_counter == read_pit_count ) + return 0; + + switch ( ioreq->addr ) + { + case PIT_CH2: + if ( ioreq->dir == IOREQ_READ ) + ioreq->data = inb(PIT_CH2); + else + outb(ioreq->data, PIT_CH2); + return 1; + + case PIT_MODE: + if ( ioreq->dir == IOREQ_READ ) + return 0; /* urk! */ + switch ( ioreq->data & 0xc0 ) + { + case 0xc0: /* Read Back */ + if ( ioreq->data & 0x08 ) /* Select Channel 2? */ + outb(ioreq->data & 0xf8, PIT_MODE); + if ( !(ioreq->data & 0x06) ) /* Select Channel 0/1? */ + return 1; /* no - we're done */ + /* Filter Channel 2 and reserved bit 0. */ + ioreq->data &= ~0x09; + return 0; /* emulate ch0/1 readback */ + case 0x80: /* Select Counter 2 */ + outb(ioreq->data, PIT_MODE); + return 1; + } + + case 0x61: + if ( ioreq->dir == IOREQ_READ ) + ioreq->data = inb(0x61); + else + outb((inb(0x61) & ~3) | (ioreq->data & 3), 0x61); + return 1; + } + + return 0; +} + /* * Local variables: * mode: C diff -r 45dbef0ab7a6 -r 9dd580b8b056 xen/include/asm-x86/time.h --- a/xen/include/asm-x86/time.h Wed Sep 12 09:58:16 2007 +0100 +++ b/xen/include/asm-x86/time.h Wed Sep 12 15:32:58 2007 +0100 @@ -4,8 +4,8 @@ #include <asm/msr.h> -extern void calibrate_tsc_bp(void); -extern void calibrate_tsc_ap(void); +void calibrate_tsc_bp(void); +void calibrate_tsc_ap(void); typedef u64 cycles_t; @@ -21,9 +21,12 @@ mktime (unsigned int year, unsigned int unsigned int day, unsigned int hour, unsigned int min, unsigned int sec); -extern int time_suspend(void); -extern int time_resume(void); +int time_suspend(void); +int time_resume(void); -extern void init_percpu_time(void); +void init_percpu_time(void); + +struct ioreq; +int dom0_pit_access(struct ioreq *ioreq); #endif /* __X86_TIME_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |