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

login
register
mail settings
Submitter 武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?=
Date Sept. 10, 2009, 4:48 p.m.
Message ID <200909101648.AA00101@YOUR-BD18D6DD63.m1.interq.or.jp>
Download mbox | patch
Permalink /patch/33375/
State Superseded
Headers show

Comments

武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?= - Sept. 10, 2009, 4:48 p.m.
Dear Juan,

>t-takeda@m1.interq.or.jp (武田 俊也) 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.

Patch

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;
 }