diff mbox

Fix curses on big endian hosts

Message ID 1293658029-10184-1-git-send-email-aurelien@aurel32.net
State New
Headers show

Commit Message

Aurelien Jarno Dec. 29, 2010, 9:27 p.m. UTC
On big endian hosts, the curses interface is unusable: the emulated
graphic card only displays garbage, while the monitor interface displays
nothing (or rather only spaces).

The curses interface is waiting for data in native endianness, so
console_write_ch() should not do any conversion. The conversion should
be done when reading the video buffer in hw/vga.c. I supposed this
buffer is in little endian mode, though it's not impossible that the
data is actually in guest endianness. I currently have no big endian
guest to way (they all switch to graphic mode immediately).

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 console.h |    2 +-
 hw/vga.c  |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

Comments

Blue Swirl Dec. 30, 2010, 5:42 p.m. UTC | #1
On Wed, Dec 29, 2010 at 9:27 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On big endian hosts, the curses interface is unusable: the emulated
> graphic card only displays garbage, while the monitor interface displays
> nothing (or rather only spaces).
>
> The curses interface is waiting for data in native endianness, so
> console_write_ch() should not do any conversion. The conversion should
> be done when reading the video buffer in hw/vga.c. I supposed this
> buffer is in little endian mode, though it's not impossible that the
> data is actually in guest endianness. I currently have no big endian
> guest to way (they all switch to graphic mode immediately).

First versions of OpenBIOS for Sparc64 used text console, I switched
to VBE frame buffer later.

I'm also puzzled by the uses of TARGET_WORDS_BIGENDIAN in
hw/vga_template.h. I'd suppose that VGA (especially PCI devices) would
be always little endian, so why the checks?
Aurelien Jarno Dec. 31, 2010, 7:10 p.m. UTC | #2
On Thu, Dec 30, 2010 at 05:42:43PM +0000, Blue Swirl wrote:
> On Wed, Dec 29, 2010 at 9:27 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> > On big endian hosts, the curses interface is unusable: the emulated
> > graphic card only displays garbage, while the monitor interface displays
> > nothing (or rather only spaces).
> >
> > The curses interface is waiting for data in native endianness, so
> > console_write_ch() should not do any conversion. The conversion should
> > be done when reading the video buffer in hw/vga.c. I supposed this
> > buffer is in little endian mode, though it's not impossible that the
> > data is actually in guest endianness. I currently have no big endian
> > guest to way (they all switch to graphic mode immediately).
> 
> First versions of OpenBIOS for Sparc64 used text console, I switched
> to VBE frame buffer later.

Do you know if it is easy to switch back to text console? That would be
an easy way to check what is correct.

> I'm also puzzled by the uses of TARGET_WORDS_BIGENDIAN in
> hw/vga_template.h. I'd suppose that VGA (especially PCI devices) would
> be always little endian, so why the checks?
> 

I also don't explain them. I have tried to remove them, and powerpc and
sparc target still seems to work.
Andreas Färber Dec. 31, 2010, 11:41 p.m. UTC | #3
Am 31.12.2010 um 20:10 schrieb Aurelien Jarno:

> On Thu, Dec 30, 2010 at 05:42:43PM +0000, Blue Swirl wrote:
>> I'm also puzzled by the uses of TARGET_WORDS_BIGENDIAN in
>> hw/vga_template.h. I'd suppose that VGA (especially PCI devices)  
>> would
>> be always little endian, so why the checks?
>>
>
> I also don't explain them. I have tried to remove them, and powerpc  
> and
> sparc target still seems to work.

Does it have any effect on the penguin colors? Blue and me once  
fiddled to remedy Tux' foot-and-beak disease on Darwin/i386, and I  
remember seeing apparently random colors for ppc guests on various  
hosts:

http://afaerber.planche.de/#ppc_2009_12_20

Andreas
Aurelien Jarno Jan. 1, 2011, 12:05 a.m. UTC | #4
On Sat, Jan 01, 2011 at 12:41:10AM +0100, Andreas Färber wrote:
> Am 31.12.2010 um 20:10 schrieb Aurelien Jarno:
>
>> On Thu, Dec 30, 2010 at 05:42:43PM +0000, Blue Swirl wrote:
>>> I'm also puzzled by the uses of TARGET_WORDS_BIGENDIAN in
>>> hw/vga_template.h. I'd suppose that VGA (especially PCI devices)  
>>> would
>>> be always little endian, so why the checks?
>>>
>>
>> I also don't explain them. I have tried to remove them, and powerpc  
>> and
>> sparc target still seems to work.
>
> Does it have any effect on the penguin colors? Blue and me once fiddled 
> to remedy Tux' foot-and-beak disease on Darwin/i386, and I remember 
> seeing apparently random colors for ppc guests on various hosts:
>
> http://afaerber.planche.de/#ppc_2009_12_20
>

No, it doesn't change anything related to the graphic mode, it only
affects curses.
diff mbox

Patch

diff --git a/console.h b/console.h
index b2fc908..3157330 100644
--- a/console.h
+++ b/console.h
@@ -329,7 +329,7 @@  static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 {
     if (!(ch & 0xff))
         ch |= ' ';
-    cpu_to_le32wu((uint32_t *) dest, ch);
+    *dest = ch;
 }
 
 typedef void (*vga_hw_update_ptr)(void *);
diff --git a/hw/vga.c b/hw/vga.c
index c632fd7..e2151a2 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2073,14 +2073,14 @@  static void vga_update_text(void *opaque, console_ch_t *chardata)
 
         if (full_update) {
             for (i = 0; i < size; src ++, dst ++, i ++)
-                console_write_ch(dst, VMEM2CHTYPE(*src));
+                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
 
             dpy_update(s->ds, 0, 0, width, height);
         } else {
             c_max = 0;
 
             for (i = 0; i < size; src ++, dst ++, i ++) {
-                console_write_ch(&val, VMEM2CHTYPE(*src));
+                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                 if (*dst != val) {
                     *dst = val;
                     c_max = i;
@@ -2089,7 +2089,7 @@  static void vga_update_text(void *opaque, console_ch_t *chardata)
             }
             c_min = i;
             for (; i < size; src ++, dst ++, i ++) {
-                console_write_ch(&val, VMEM2CHTYPE(*src));
+                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                 if (*dst != val) {
                     *dst = val;
                     c_max = i;