qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] PL181 write problem


From: Hans-Erik Floryd
Subject: [Qemu-devel] PL181 write problem
Date: Thu, 29 Jan 2009 19:37:13 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b3pre) Gecko/20081204 Thunderbird/3.0b1

Hello,

The PL181 sdcard module (hw/pl181.c) doesn't seem to handle writes correctly. Only every fourth byte gets written to the card. I've tracked the problem down to the following loop in pl181_fifo_run():

        limit = is_read ? PL181_FIFO_LEN : 0;
        n = 0;
        value = 0;
        while (s->datacnt && s->fifo_len != limit) {
            if (is_read) {
                value |= (uint32_t)sd_read_data(s->card) << (n * 8);
                n++;
                if (n == 4) {
                    pl181_fifo_push(s, value);
                    value = 0;
                    n = 0;
                }
            } else {
                if (n == 0) {
                    value = pl181_fifo_pop(s);
                    n = 4;
                }
                sd_write_data(s->card, value & 0xff);
                value >>= 8;
                n--;
            }
            s->datacnt--;
        }

When writing, a 32-bit value is popped from the fifo, followed by a write of 1 byte. If there was only one value in the fifo, fifo_len will now be 0. This causes the loop to terminate and the remaining three bytes will not be written.

The following patch fixes this by writing all four bytes before checking fifo_len.

Let me know if there's anything else I need to do to get the patch accepted.

Thanks

Index: hw/pl181.c
===================================================================
--- hw/pl181.c  (revision 5648)
+++ hw/pl181.c  (working copy)
@@ -202,16 +202,20 @@
                     value = 0;
                     n = 0;
                 }
+                s->datacnt--;
             } else {
                 if (n == 0) {
                     value = pl181_fifo_pop(s);
                     n = 4;
                 }
-                sd_write_data(s->card, value & 0xff);
-                value >>= 8;
-                n--;
+                while (s->datacnt && n != 0)
+                {
+                   sd_write_data(s->card, value & 0xff);
+                   value >>= 8;
+                   n--;
+                   s->datacnt--;
+                }
             }
-            s->datacnt--;
         }
         if (n && is_read) {
             pl181_fifo_push(s, value);




reply via email to

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