qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH 07/14] i8254: support NEC PC-9821 family


From: 武田 俊也
Subject: [Qemu-devel] Re: [PATCH 07/14] i8254: support NEC PC-9821 family
Date: Fri, 11 Sep 2009 01:48:47 +0900

Dear Juan,

>address@hidden (武田 俊也) wrote:
>> This patch is to add NEC PC-9821 family i/o to i8254.
>
>> +PITState *pc98_pit_init(int base, qemu_irq irq)
>> +{
>> +    PITState *pit = &pit_state;
>> +    PITChannelState *s;
>> +    int i;
>> +
>> +    pit_freq = PC98_PIT_FREQ;
>> +
>> +    s = &pit->channels[0];
>> +    /* the timer 0 is connected to an IRQ */
>> +    s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
>> +    s->irq = irq;
>> +
>> +    vmstate_register(base, &vmstate_pit, pit);
>> +    qemu_register_reset(pit_reset, pit);
>> +    for (i = 0; i < 4; i++) {
>> +        register_ioport_write(0x71 + (i << 1), 1, 1, pc98_pit_ioport_write, 
>> pit);
>> +        register_ioport_write(0x3fd9 + (i << 1), 1, 1, 
>> pc98_pit_ioport_write, pit);
>> +    }
>> +    for (i = 0; i < 3; i++) {
>> +        register_ioport_read(0x71 + (i << 1), 1, 1, pc98_pit_ioport_read, 
>> pit);
>> +        register_ioport_read(0x3fd9 + (i << 1), 1, 1, pc98_pit_ioport_read, 
>> pit);
>> +    }
>>  
>>      pit_reset(pit);
>>  
>
>You can create a pit_common_init() function, with everything except the
>register_ioport* functions and pit_freq value setup, that is what is different 
>between
>pc98_pit_init() and pit_init().
>
>Later, Juan.

Thank you very much for comments.

I modified the patch.
In this patch, pit_freq is put in struct PITChannelState and is renamed to 
frequency.
Now every channels' frequency are initialized to the same value,
but we can set to differenct frequencies for each channel, if we need in other 
machine.

Well, I will reply for other comments in this weekend.
I also need to convert some pc98 devices to qdev/isa.
After that, I will repost my patches to ML.


diff -ur a/hw/i8254.c b/hw/i8254.c
--- a/hw/i8254.c        Thu Sep 10 22:27:13 2009
+++ b/hw/i8254.c        Fri Sep 11 00:49:04 2009
@@ -47,6 +47,7 @@
     uint8_t bcd; /* not supported */
     uint8_t gate; /* timer start */
     int64_t count_load_time;
+    uint64_t frequency;
     /* irq handling */
     int64_t next_transition_time;
     QEMUTimer *irq_timer;
@@ -66,7 +67,7 @@
     uint64_t d;
     int counter;
 
-    d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, PIT_FREQ, 
ticks_per_sec);
+    d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, s->frequency, 
ticks_per_sec);
     switch(s->mode) {
     case 0:
     case 1:
@@ -91,7 +92,7 @@
     uint64_t d;
     int out;
 
-    d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
+    d = muldiv64(current_time - s->count_load_time, s->frequency, 
ticks_per_sec);
     switch(s->mode) {
     default:
     case 0:
@@ -130,7 +131,7 @@
     uint64_t d, next_time, base;
     int period2;
 
-    d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
+    d = muldiv64(current_time - s->count_load_time, s->frequency, 
ticks_per_sec);
     switch(s->mode) {
     default:
     case 0:
@@ -166,7 +167,7 @@
         break;
     }
     /* convert to timer units */
-    next_time = s->count_load_time + muldiv64(next_time, ticks_per_sec, 
PIT_FREQ);
+    next_time = s->count_load_time + muldiv64(next_time, ticks_per_sec, 
s->frequency);
     /* fix potential rounding problems */
     /* XXX: better solution: use a clock at PIT_FREQ Hz */
     if (next_time <= current_time)
@@ -494,22 +495,65 @@
     pit_load_count(s, 0);
 }
 
-PITState *pit_init(int base, qemu_irq irq)
+static void pit_init_common(PITState *pit, int base, qemu_irq irq, uint64_t 
frequency)
 {
-    PITState *pit = &pit_state;
     PITChannelState *s;
+    int i;
 
     s = &pit->channels[0];
     /* the timer 0 is connected to an IRQ */
     s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
     s->irq = irq;
 
+    for (i = 0; i < 3; i++) {
+        pit->channels[i].frequency = frequency;
+    }
+
     vmstate_register(base, &vmstate_pit, pit);
     qemu_register_reset(pit_reset, pit);
+
+    pit_reset(pit);
+}
+
+PITState *pit_init(int base, qemu_irq irq)
+{
+    PITState *pit = &pit_state;
+
+    pit_init_common(pit, base, irq, PIT_FREQ);
+
     register_ioport_write(base, 4, 1, pit_ioport_write, pit);
     register_ioport_read(base, 3, 1, pit_ioport_read, pit);
 
-    pit_reset(pit);
+    return pit;
+}
+
+/* NEC PC-98x1 */
+
+static void pc98_pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    pit_ioport_write(opaque, addr >> 1, val);
+}
+
+static uint32_t pc98_pit_ioport_read(void *opaque, uint32_t addr)
+{
+    return pit_ioport_read(opaque, addr >> 1);
+}
+
+PITState *pc98_pit_init(int base, qemu_irq irq)
+{
+    PITState *pit = &pit_state;
+    int i;
+
+    pit_init_common(pit, base, irq, PIT_FREQ);
+
+    for (i = 0; i < 4; i++) {
+        register_ioport_write(0x71 + (i << 1), 1, 1, pc98_pit_ioport_write, 
pit);
+        register_ioport_write(0x3fd9 + (i << 1), 1, 1, pc98_pit_ioport_write, 
pit);
+    }
+    for (i = 0; i < 3; i++) {
+        register_ioport_read(0x71 + (i << 1), 1, 1, pc98_pit_ioport_read, pit);
+        register_ioport_read(0x3fd9 + (i << 1), 1, 1, pc98_pit_ioport_read, 
pit);
+    }
 
     return pit;
 }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]