x86: allow Dom0 to drive PC speaker
PATCH 1/1 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 <[email protected]>
xen/arch/x86/domain_build.c +2 -0
@@ -967,6 +967,8 @@ int __init construct_dom0( rc |=ioports_deny_access (dom0,0xA0 ,0xA1 );/* Interval Timer (PIT). */ rc |=ioports_deny_access (dom0,0x40 ,0x43 ); +if ( !using_pit ) + rc |=ioports_permit_access (dom0,0x42 ,0x42 );/* PIT Channel 2 / PC Speaker Control. */ rc |=ioports_deny_access (dom0,0x61 ,0x61 );/* Command-line I/O ranges. */
xen/arch/x86/hvm/i8254.c +31 -2
@@ -592,20 +592,49 @@ static int handle_speaker_io(ioreq_t *p)return 1 ; } +#include <io_ports.h> +int pv_pit_handler (int port,int data,int write) {ioreq_t ioreq = { .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 ( !using_pit && current->domain->domain_id ==0 ) + { +if ( !write ) +return inb (0x61 ); +outb ((inb (0x61 ) & ~3 ) | (data &3 ),0x61 ); +return 0 ; + }handle_speaker_io (&ioreq); + }else + { +if ( !using_pit && current->domain->domain_id ==0 && + port ==PIT_MODE && write ) + { +switch ( data &0xc0 ) + { +case 0xc0 :/* read back */ +outb (data &0xf8 ,PIT_MODE ); +if ( !(data &0x07 ) ) +return 0 ; + data &= ~0x08 ; +break ; +case 0x80 :/* counter 2 latch */ +outb (data,PIT_MODE ); +return 0 ; + } + }handle_pit_io (&ioreq); + }return !write ? ioreq.data :0 ; }
xen/arch/x86/time.c +2 -1
@@ -38,6 +38,7 @@ string_param("clocksource", opt_clocksou#define EPOCH MILLISECS(1000)unsigned long cpu_khz;/* CPU clock frequency in kHz. */ +int using_pit;unsigned long hpet_address;DEFINE_SPINLOCK (rtc_lock);volatile unsigned long jiffies;
@@ -177,7 +178,6 @@ static u64 init_pit_and_calibrate_tsc(vounsigned 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 */
@@ -308,6 +308,7 @@ static void init_pit(struct platform_tim pts->frequency =CLOCK_TICK_RATE ; pts->read_counter = read_pit_count; pts->counter_bits =16 ; + using_pit =1 ; }/************************************************************
xen/include/asm-x86/time.h +2 -0
@@ -4,6 +4,8 @@#include <asm/msr.h> +extern int using_pit; +extern void calibrate_tsc_bp (void );extern void calibrate_tsc_ap (void );