qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: <mmogilvi@miniinfo.net>
To: Gleb Natapov <gleb@redhat.com>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>,
	Jan Kiszka <jan.kiszka@web.de>,
	Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>,
	kvm@vger.kernel.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH KVM v2 2/4] KVM: additional i8254 output fixes
Date: Mon, 07 Jan 2013 18:35:47 -0600	[thread overview]
Message-ID: <438a0025e6781a925614fd295fb52cbf@127.0.0.1> (raw)
In-Reply-To: <20130107120403.GY3440@redhat.com>

On Mon, 7 Jan 2013 14:04:03 +0200, Gleb Natapov <gleb@redhat.com> wrote:
> On Wed, Dec 26, 2012 at 10:39:54PM -0700, Matthew Ogilvie wrote:
>> Make git_get_out() consistent with spec.  Currently pit_get_out()
>> doesn't affect IRQ0, but it can be read by the guest in other ways.
>> This makes it consistent with proposed changes in qemu's i8254 model
>> as well.
>> 
>> See http://bochs.sourceforge.net/techspec/intel-82c54-timer.pdf.gz
>> or search the net for 23124406.pdf.
>> 
>> Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
>> ---
>>  arch/x86/kvm/i8254.c | 44 ++++++++++++++++++++++++++++++++++----------
>>  1 file changed, 34 insertions(+), 10 deletions(-)
>> 
>> diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
>> index cd4ec60..fd38938 100644
>> --- a/arch/x86/kvm/i8254.c
>> +++ b/arch/x86/kvm/i8254.c
>> @@ -144,6 +144,10 @@ static int pit_get_count(struct kvm *kvm, int
>> channel)
>>  
>>  	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
>>  
>> +	/* FIXME: Add some way to represent a paused timer and return
>> +	 *   the paused-at counter value, to better model gate pausing,
>> +	 *   "wait until next CLK pulse to load counter" logic, etc.
>> +	 */
>>  	t = kpit_elapsed(kvm, c, channel);
>>  	d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);
>>  
>> @@ -155,8 +159,7 @@ static int pit_get_count(struct kvm *kvm, int
>> channel)
>>  		counter = (c->count - d) & 0xffff;
>>  		break;
>>  	case 3:
>> -		/* XXX: may be incorrect for odd counts */
>> -		counter = c->count - (mod_64((2 * d), c->count));
>> +		counter = (c->count - (mod_64((2 * d), c->count))) & 0xfffe;
>>  		break;
>>  	default:
>>  		counter = c->count - mod_64(d, c->count);
>> @@ -180,20 +183,18 @@ static int pit_get_out(struct kvm *kvm, int
>> channel)
>>  	switch (c->mode) {
>>  	default:
>>  	case 0:
>> -		out = (d >= c->count);
>> -		break;
>>  	case 1:
>> -		out = (d < c->count);
>> +		out = (d >= c->count);
>>  		break;
>>  	case 2:
>> -		out = ((mod_64(d, c->count) == 0) && (d != 0));
>> +		out = (mod_64(d, c->count) != (c->count - 1) || c->gate == 0);
>>  		break;
>>  	case 3:
>> -		out = (mod_64(d, c->count) < ((c->count + 1) >> 1));
>> +		out = (mod_64(d, c->count) < ((c->count + 1) >> 1) || c->gate == 0);
>>  		break;
>>  	case 4:
>>  	case 5:
>> -		out = (d == c->count);
>> +		out = (d != c->count);
>>  		break;
>>  	}
>>  
>> @@ -367,7 +368,7 @@ static void pit_load_count(struct kvm *kvm, int
>> channel, u32 val)
>>  
>>  	/*
>>  	 * The largest possible initial count is 0; this is equivalent
>> -	 * to 216 for binary counting and 104 for BCD counting.
>> +	 * to pow(2,16) for binary counting and pow(10,4) for BCD counting.
>>  	 */
>>  	if (val == 0)
>>  		val = 0x10000;
>> @@ -376,6 +377,26 @@ static void pit_load_count(struct kvm *kvm, int
>> channel, u32 val)
>>  
>>  	if (channel != 0) {
>>  		ps->channels[channel].count_load_time = ktime_get();
>> +
>> +		/* In gate-triggered one-shot modes,
>> +		 * indirectly model some pit_get_out()
>> +		 * cases by setting the load time way
>> +		 * back until gate-triggered.
>> +		 * (Generally only affects reading status
>> +		 * from channel 2 speaker,
>> +		 * due to hard-wired gates on other
>> +		 * channels.)
>> +		 *
>> +		 * FIXME: This might be redesigned if a paused
>> +		 * timer state is added for pit_get_count().
>> +		 */
>> +		if (ps->channels[channel].mode == 1 ||
>> +		    ps->channels[channel].mode == 5) {
>> +	            u64 delta = muldiv64(val+2, NSEC_PER_SEC, KVM_PIT_FREQ);
>> +		    ps->channels[channel].count_load_time =
>> +                           
>> ktime_sub(ps->channels[channel].count_load_time,
>> +                                      ns_to_ktime(delta));
> I do not understand what are you trying to do here. You assume that
> trigger will happen 2 clocks after counter is loaded?
> 

Modes 1 and 5 are single-shot, and they do not start counting until GATE
is triggered, potentially well after count is loaded.  So this is
attempting to model the "start of countdown has not been triggered"
state as being mostly identical to the "already triggered and also
expired some number of clocks (2) ago" state.

It might be clearer to have a way to explicitly model a
paused countdown, but such a mechanism doesn't currently exist.

Note that modeling modes 1 and 5 is fairly low priority,
because channel 0's GATE line is generally hard-wired such that
GATE edges/triggers are impossible.  But it may still be
somewhat relevant to the PC speaker channel, or if someone
might want to use this in a model of non-PC hardware.

>> +		}
>>  		return;
>>  	}
>>  
>> @@ -383,7 +404,6 @@ static void pit_load_count(struct kvm *kvm, int
>> channel, u32 val)
>>  	 * mode 1 is one shot, mode 2 is period, otherwise del timer */
>>  	switch (ps->channels[0].mode) {
>>  	case 0:
>> -	case 1:
>>          /* FIXME: enhance mode 4 precision */
>>  	case 4:
>>  		create_pit_timer(kvm, val, 0);
>> @@ -393,6 +413,10 @@ static void pit_load_count(struct kvm *kvm, int
>> channel, u32 val)
>>  		create_pit_timer(kvm, val, 1);
>>  		break;
>>  	default:
>> +		/* Modes 1 and 5 are triggered by gate leading edge,
>> +		 * but channel 0's gate is hard-wired high and has
>> +		 * no edges (on normal real hardware).
>> +		 */
>>  		destroy_pit_timer(kvm->arch.vpit);
>>  	}
>>  }
>> -- 
>> 1.7.10.2.484.gcd07cc5
> 
> --
> 			Gleb.

  reply	other threads:[~2013-01-08  0:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-27  5:39 [Qemu-devel] [PATCH KVM v2 0/4] fix KVM i8259 IRQ trailing-edge logic Matthew Ogilvie
2012-12-27  5:39 ` [Qemu-devel] [PATCH KVM v2 1/4] KVM: fix i8254 IRQ0 to be normally high Matthew Ogilvie
2013-01-07  9:39   ` Gleb Natapov
2013-01-07 12:48     ` Gleb Natapov
2013-01-08  0:17     ` mmogilvi
2013-01-08  7:31       ` Gleb Natapov
2013-01-11  6:40         ` Matthew Ogilvie
2013-01-11 15:45           ` Gleb Natapov
2013-01-15  9:49             ` Matthew Ogilvie
2012-12-27  5:39 ` [Qemu-devel] [PATCH KVM v2 2/4] KVM: additional i8254 output fixes Matthew Ogilvie
2013-01-07 12:04   ` Gleb Natapov
2013-01-08  0:35     ` mmogilvi [this message]
2013-01-08  7:41       ` Gleb Natapov
2013-01-11  6:33         ` Matthew Ogilvie
2012-12-27  5:39 ` [Qemu-devel] [PATCH KVM v2 3/4] KVM: fix i8259 interrupt high to low transition logic Matthew Ogilvie
2012-12-27  5:39 ` [Qemu-devel] [PATCH KVM v2 4/4] KVM: i8259: refactor pic_set_irq level logic Matthew Ogilvie
2013-01-06 15:54 ` [Qemu-devel] [PATCH KVM v2 0/4] fix KVM i8259 IRQ trailing-edge logic Gleb Natapov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=438a0025e6781a925614fd295fb52cbf@127.0.0.1 \
    --to=mmogilvi@miniinfo.net \
    --cc=gleb@redhat.com \
    --cc=jan.kiszka@web.de \
    --cc=kvm@vger.kernel.org \
    --cc=macro@linux-mips.org \
    --cc=mmogilvi_qemu@miniinfo.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).