I'm wondering about this part: cmd64x 0000:00:05.0: 100% native mode on irq 1 ide0: BM-DMA at 0x1fe02000700-0x1fe02000707 ide1: BM-DMA at 0x1fe02000708-0x1fe0200070f hda: EQUMH RADDSI K, ATA DISK drive hdc: EQUMD DVR-MO, ATAPI cdrom or floppy?, assuming FLOPPY drive
Why the drive names are swapped? Currently bytes are swapped at APB/PBM PCI config, apb_pci_config_readw etc. Actual data goes via pci_apb_iowritew etc unswapped. Now, I tried to change this so that instead of just apb_pci_config_readw, pci_apb_iowritew and friends do swapping globally for all IO ports. This would require also a few changes to OpenBIOS, patches attached. But Linux is even less happy: cmd64x 0000:00:05.0: IDE controller (0x1095:0x0646 rev 0x01) cmd64x 0000:00:05.0: unable to enable IDE controller cmd64x 0000:00:05.0: IDE controller (0x1095:0x0646 rev 0x01) CMD64x_IDE 0000:00:05.0: BAR 0: can't reserve I/O region [0x1fe02000500-0x1fe02000507] cmd64x 0000:00:05.0: can't reserve resources CMD64x_IDE: probe of 0000:00:05.0 failed with error -16 So I don't think this approach is correct either. It could be possible that individual devices would need byte swaps. But CMD64x is used successfully also on PPC and the same code is used for both Sparc64 and PPC OpenBIOS and Linux.
From a47082debfb9c179fd488e84ddf2cc7cc14311de Mon Sep 17 00:00:00 2001 From: Blue Swirl <blauwirbel@gmail.com> Date: Thu, 28 Jan 2010 21:45:33 +0000 Subject: [PATCH] Sparc64: change the location of byte swapping Signed-off-by: Blue Swirl <blauwirbel@gmail.com> --- hw/apb_pci.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 7f458c6..1eb66fd 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -128,7 +128,7 @@ static void apb_pci_config_writel(void *opaque, target_phys_addr_t addr, { APBState *s = opaque; - apb_pci_config_write(s, addr, bswap32(val), 4); + apb_pci_config_write(s, addr, val, 4); } static void apb_pci_config_writew(void *opaque, target_phys_addr_t addr, @@ -136,7 +136,7 @@ static void apb_pci_config_writew(void *opaque, target_phys_addr_t addr, { APBState *s = opaque; - apb_pci_config_write(s, addr, bswap16(val), 2); + apb_pci_config_write(s, addr, val, 2); } static void apb_pci_config_writeb(void *opaque, target_phys_addr_t addr, @@ -151,14 +151,14 @@ static uint32_t apb_pci_config_readl(void *opaque, target_phys_addr_t addr) { APBState *s = opaque; - return bswap32(apb_pci_config_read(s, addr, 4)); + return apb_pci_config_read(s, addr, 4); } static uint32_t apb_pci_config_readw(void *opaque, target_phys_addr_t addr) { APBState *s = opaque; - return bswap16(apb_pci_config_read(s, addr, 2)); + return apb_pci_config_read(s, addr, 2); } static uint32_t apb_pci_config_readb(void *opaque, target_phys_addr_t addr) @@ -189,13 +189,13 @@ static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr, static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr, uint32_t val) { - cpu_outw(addr & IOPORTS_MASK, val); + cpu_outw(addr & IOPORTS_MASK, bswap16(val)); } static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr, uint32_t val) { - cpu_outl(addr & IOPORTS_MASK, val); + cpu_outl(addr & IOPORTS_MASK, bswap32(val)); } static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr) @@ -210,7 +210,7 @@ static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr) { uint32_t val; - val = cpu_inw(addr & IOPORTS_MASK); + val = bswap16(cpu_inw(addr & IOPORTS_MASK)); return val; } @@ -218,7 +218,7 @@ static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr) { uint32_t val; - val = cpu_inl(addr & IOPORTS_MASK); + val = bswap32(cpu_inl(addr & IOPORTS_MASK)); return val; } -- 1.5.6.5
From 541d945110751c61aff17a1fa2a747b6750e70f1 Mon Sep 17 00:00:00 2001 From: Blue Swirl <blauwirbel@gmail.com> Date: Thu, 28 Jan 2010 21:47:28 +0000 Subject: [PATCH] QEMU changed PCI/IO port byte swapping, adapt OpenBIOS to new way Signed-off-by: Blue Swirl <blauwirbel@gmail.com> --- arch/sparc64/entry.S | 4 +- include/sparc64/io.h | 52 +++++++++++++++++++++++++------------------------ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S index 750f7b1..91a550b 100644 --- a/arch/sparc64/entry.S +++ b/arch/sparc64/entry.S @@ -58,7 +58,7 @@ entry: ! Check signature "QEMU" setx CFG_ADDR, %g2, %g5 - mov FW_CFG_SIGNATURE, %g2 + mov FW_CFG_SIGNATURE << 8, %g2 stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E inc %g5 lduba [%g5] ASI_PHYS_BYPASS_EC_E, %g2 @@ -97,7 +97,7 @@ entry: ! Get memory size from configuration device ! NB: little endian format - mov FW_CFG_RAM_SIZE, %g2 + mov FW_CFG_RAM_SIZE << 8, %g2 dec %g5 stha %g2, [%g5] ASI_PHYS_BYPASS_EC_E inc %g5 diff --git a/include/sparc64/io.h b/include/sparc64/io.h index ea709d8..8b55793 100644 --- a/include/sparc64/io.h +++ b/include/sparc64/io.h @@ -75,29 +75,36 @@ static inline void out_8(volatile unsigned char *addr, int val) static inline int in_le16(volatile unsigned short *addr) { - int ret, tmp; + int ret; // XXX __asm__ __volatile__("lduha [%1] 0x15, %0\n\t" :"=r"(ret):"r"(addr):"memory"); - tmp = (ret << 8) & 0xff00; - tmp |= (ret >> 8) & 0xff; - return tmp; + return ret; } static inline int in_be16(volatile unsigned short *addr) { - int ret; + int ret, tmp; __asm__ __volatile__("lduha [%1] 0x15, %0\n\t" :"=r"(ret):"r"(addr):"memory"); - return ret; + tmp = (ret << 8) & 0xff00; + tmp |= (ret >> 8) & 0xff; + return tmp; } static inline void out_le16(volatile unsigned short *addr, int val) { + + __asm__ __volatile__("stha %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); +} + +static inline void out_be16(volatile unsigned short *addr, int val) +{ unsigned tmp; // XXX @@ -107,40 +114,41 @@ static inline void out_le16(volatile unsigned short *addr, int val) : : "r"(tmp), "r"(addr):"memory"); } -static inline void out_be16(volatile unsigned short *addr, int val) +static inline unsigned in_le32(volatile unsigned *addr) { - __asm__ __volatile__("stha %0, [%1] 0x15\n\t" - : : "r"(val), "r"(addr):"memory"); + unsigned ret; + + __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" + :"=r"(ret):"r"(addr):"memory"); + + return ret; } -static inline unsigned in_le32(volatile unsigned *addr) +static inline unsigned in_be32(volatile unsigned *addr) { unsigned ret, tmp; // XXX __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" :"=r"(ret):"r"(addr):"memory"); - tmp = ret << 24; tmp |= (ret << 8) & 0xff0000; tmp |= (ret >> 8) & 0xff00; tmp |= (ret >> 24) & 0xff; + return tmp; } -static inline unsigned in_be32(volatile unsigned *addr) +static inline void out_le32(volatile unsigned *addr, int val) { - unsigned ret; - - __asm__ __volatile__("lduwa [%1] 0x15, %0\n\t" - :"=r"(ret):"r"(addr):"memory"); - - return ret; + __asm__ __volatile__("stwa %0, [%1] 0x15\n\t" + : : "r"(val), "r"(addr):"memory"); } -static inline void out_le32(volatile unsigned *addr, int val) +static inline void out_be32(volatile unsigned *addr, int val) { unsigned tmp; + // XXX tmp = val << 24; tmp |= (val << 8) & 0xff0000; @@ -150,12 +158,6 @@ static inline void out_le32(volatile unsigned *addr, int val) : : "r"(tmp), "r"(addr):"memory"); } -static inline void out_be32(volatile unsigned *addr, int val) -{ - __asm__ __volatile__("stwa %0, [%1] 0x15\n\t" - : : "r"(val), "r"(addr):"memory"); -} - static inline void _insw_ns(volatile uint16_t * port, void *buf, int ns) { uint16_t *b = (uint16_t *) buf; -- 1.5.6.5