ia64/xen-unstable

changeset 15906:9dd580b8b056

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@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Sep 12 15:32:58 2007 +0100 (2007-09-12)
parents 45dbef0ab7a6
children ca495837a722
files xen/arch/x86/hvm/i8254.c xen/arch/x86/time.c xen/include/asm-x86/time.h
line diff
     1.1 --- a/xen/arch/x86/hvm/i8254.c	Wed Sep 12 09:58:16 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/i8254.c	Wed Sep 12 15:32:58 2007 +0100
     1.3 @@ -598,11 +598,13 @@ int pv_pit_handler(int port, int data, i
     1.4          .size = 1,
     1.5          .type = IOREQ_TYPE_PIO,
     1.6          .addr = port,
     1.7 -        .dir  = write ? 0 : 1,
     1.8 -        .data = write ? data : 0,
     1.9 +        .dir  = write ? IOREQ_WRITE : IOREQ_READ,
    1.10 +        .data = data
    1.11      };
    1.12  
    1.13 -    if ( port == 0x61 )
    1.14 +    if ( (current->domain->domain_id == 0) && dom0_pit_access(&ioreq) )
    1.15 +        /* nothing to do */;
    1.16 +    else if ( port == 0x61 )
    1.17          handle_speaker_io(&ioreq);
    1.18      else
    1.19          handle_pit_io(&ioreq);
     2.1 --- a/xen/arch/x86/time.c	Wed Sep 12 09:58:16 2007 +0100
     2.2 +++ b/xen/arch/x86/time.c	Wed Sep 12 15:32:58 2007 +0100
     2.3 @@ -177,7 +177,6 @@ static u64 init_pit_and_calibrate_tsc(vo
     2.4      unsigned long count;
     2.5  
     2.6      /* Set PIT channel 0 to HZ Hz. */
     2.7 -#define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */
     2.8  #define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ)
     2.9      outb_p(0x34, PIT_MODE);        /* binary, mode 2, LSB/MSB, ch 0 */
    2.10      outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
    2.11 @@ -972,6 +971,50 @@ int time_resume(void)
    2.12      return 0;
    2.13  }
    2.14  
    2.15 +int dom0_pit_access(struct ioreq *ioreq)
    2.16 +{
    2.17 +    /* Is Xen using Channel 2? Then disallow direct dom0 access. */
    2.18 +    if ( plt_src.read_counter == read_pit_count )
    2.19 +        return 0;
    2.20 +
    2.21 +    switch ( ioreq->addr )
    2.22 +    {
    2.23 +    case PIT_CH2:
    2.24 +        if ( ioreq->dir == IOREQ_READ )
    2.25 +            ioreq->data = inb(PIT_CH2);
    2.26 +        else
    2.27 +            outb(ioreq->data, PIT_CH2);
    2.28 +        return 1;
    2.29 +
    2.30 +    case PIT_MODE:
    2.31 +        if ( ioreq->dir == IOREQ_READ )
    2.32 +            return 0; /* urk! */
    2.33 +        switch ( ioreq->data & 0xc0 )
    2.34 +        {
    2.35 +        case 0xc0: /* Read Back */
    2.36 +            if ( ioreq->data & 0x08 )    /* Select Channel 2? */
    2.37 +                outb(ioreq->data & 0xf8, PIT_MODE);
    2.38 +            if ( !(ioreq->data & 0x06) ) /* Select Channel 0/1? */
    2.39 +                return 1; /* no - we're done */
    2.40 +            /* Filter Channel 2 and reserved bit 0. */
    2.41 +            ioreq->data &= ~0x09;
    2.42 +            return 0; /* emulate ch0/1 readback */
    2.43 +        case 0x80: /* Select Counter 2 */
    2.44 +            outb(ioreq->data, PIT_MODE);
    2.45 +            return 1;
    2.46 +        }
    2.47 +
    2.48 +    case 0x61:
    2.49 +        if ( ioreq->dir == IOREQ_READ )
    2.50 +            ioreq->data = inb(0x61);
    2.51 +        else
    2.52 +            outb((inb(0x61) & ~3) | (ioreq->data & 3), 0x61);
    2.53 +        return 1;
    2.54 +    }
    2.55 +
    2.56 +    return 0;
    2.57 +}
    2.58 +
    2.59  /*
    2.60   * Local variables:
    2.61   * mode: C
     3.1 --- a/xen/include/asm-x86/time.h	Wed Sep 12 09:58:16 2007 +0100
     3.2 +++ b/xen/include/asm-x86/time.h	Wed Sep 12 15:32:58 2007 +0100
     3.3 @@ -4,8 +4,8 @@
     3.4  
     3.5  #include <asm/msr.h>
     3.6  
     3.7 -extern void calibrate_tsc_bp(void);
     3.8 -extern void calibrate_tsc_ap(void);
     3.9 +void calibrate_tsc_bp(void);
    3.10 +void calibrate_tsc_ap(void);
    3.11  
    3.12  typedef u64 cycles_t;
    3.13  
    3.14 @@ -21,9 +21,12 @@ mktime (unsigned int year, unsigned int 
    3.15          unsigned int day, unsigned int hour,
    3.16          unsigned int min, unsigned int sec);
    3.17  
    3.18 -extern int time_suspend(void);
    3.19 -extern int time_resume(void);
    3.20 +int time_suspend(void);
    3.21 +int time_resume(void);
    3.22  
    3.23 -extern void init_percpu_time(void);
    3.24 +void init_percpu_time(void);
    3.25 +
    3.26 +struct ioreq;
    3.27 +int dom0_pit_access(struct ioreq *ioreq);
    3.28  
    3.29  #endif /* __X86_TIME_H__ */