On 07.02.2015 19:49, Stefan Tauner wrote:
Was implemented by SPARC newbies, does (cross-)compile but is not run-tested.
Signed-off-by: Stefan Tauner stefan.tauner@alumni.tuwien.ac.at
Thanks!
Quoting wikipedia:
The endianness of the 32-bit SPARC V8 architecture is purely big-endian. The 64-bit SPARC V9 architecture uses big-endian instructions, but can access data in either big-endian or little-endian byte order, chosen either at the application instruction (load/store) level or at the memory page level (via an MMU setting). The latter is often used for accessing data from inherently little-endian devices, such as those on PCI buses.
If that is true, we are totally screwed. How can we even begin to influence the instructions emitted by the compiler? And if the compiler emits bigendian instructions by default, can that be overridden via MMU setting? If yes, does Linux use the endianness manipulation via MMU for PCI devices, in which case we'd have to treat the architecture as littleendian from a flashrom POV?
This is a nightmare.
Does anyone on this mailing list have access to a real SPARC machine with PCI or PCIe slots running Linux?
Regards, Carl-Daniel
Well, it is NOT compile-tested yet... because 64b gcc for SPARC seems to be kind of broken... but I am working on it and it will be before I commit it.
Makefile | 2 +- hwaccess.c | 24 ++++++++++++++++++++---- hwaccess.h | 8 ++++++++ platform.h | 5 ++++- 4 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile index bf79866..edd85cc 100644 --- a/Makefile +++ b/Makefile @@ -318,7 +318,7 @@ endif # below uses CC itself. override ARCH := $(strip $(shell LC_ALL=C $(CC) $(CPPFLAGS) -E archtest.c 2>/dev/null | grep -v '^#' | grep '"' | cut -f 2 -d'"'))
-# PCI port I/O support is unimplemented on PPC/MIPS and unavailable on ARM. +# PCI port I/O support is unimplemented on PPC/MIPS/SPARC and unavailable on ARM. # Right now this means the drivers below only work on x86. ifneq ($(ARCH), x86) ifeq ($(CONFIG_NIC3COM), yes) diff --git a/hwaccess.c b/hwaccess.c index c90490b..0b7d7c3 100644 --- a/hwaccess.c +++ b/hwaccess.c @@ -49,13 +49,29 @@ int io_fd; */ static inline void sync_primitive(void) { -/* This is needed only on PowerPC because...
- x86 uses uncached accesses which have a strongly ordered memory model and
- MIPS uses uncached accesses in mode 2 on /dev/mem which has also a strongly ordered memory model
- ARM uses a strongly ordered memory model for device memories.
+/* This is not needed for...
- x86: uses uncached accesses which have a strongly ordered memory model.
- MIPS: uses uncached accesses in mode 2 on /dev/mem which has also a strongly ordered memory model.
- ARM: uses a strongly ordered memory model for device memories.
- */
#if IS_PPC // cf. http://lxr.free-electrons.com/source/arch/powerpc/include/asm/barrier.h asm("eieio" : : : "memory"); +#elif IS_SPARC +#ifdef defined(__sparc_v9__) || defined(__sparcv9)
- /* Sparc V9 CPUs support three different memory orderings that range from x86-like TSO to PowerPC-like
* RMO. The modes can be switched at runtime thus to make sure we maintain the right order of access we
* use the strongest hardware memory barriers that exist on Sparc V9. */
- asm volatile ("membar #Sync" ::: "memory");
+#elif defined(__sparc_v8__) || defined(__sparcv8)
- /* On SPARC V8 there is no RMO just PSO and that does not apply to I/O accesses... but if V8 code is run
* on V9 CPUs it might apply... or not... we issue a write barrier anyway. That's the most suitable
* operation in the V8 instruction set anyway. If you know better then please tell us. */
- asm volatile ("stbar");
+#else
- #error Unknown and/or unsupported SPARC instruction set version detected.
+#endif #endif }
diff --git a/hwaccess.h b/hwaccess.h index a4fd502..5378361 100644 --- a/hwaccess.h +++ b/hwaccess.h @@ -89,6 +89,10 @@ #define __FLASHROM_LITTLE_ENDIAN__ 1 #endif
+#elif IS_SPARC +/* SPARC is big endian in general (but allows to access data in little endian too). */ +#define __FLASHROM_BIG_ENDIAN__ 1
#endif /* IS_? */
#if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__) @@ -357,6 +361,10 @@ int libpayload_wrmsr(int addr, msr_t msr);
/* PCI port I/O is not yet implemented on MIPS. */
+#elif IS_SPARC
+/* PCI port I/O is not yet implemented on SPARC. */
#elif IS_ARM
/* Non memory mapped I/O is not supported on ARM. */ diff --git a/platform.h b/platform.h index f57fd12..9cde054 100644 --- a/platform.h +++ b/platform.h @@ -45,9 +45,12 @@ defined(__aarch64__) #define __FLASHROM_ARCH__ "arm" #define IS_ARM 1 +#elif defined (__sparc__) || defined (__sparc)
- #define __FLASHROM_ARCH__ "sparc"
- #define IS_SPARC 1
#endif
-#if !(IS_X86 || IS_MIPS || IS_PPC || IS_ARM) +#if !(IS_X86 || IS_MIPS || IS_PPC || IS_ARM || IS_SPARC) #error Unknown architecture #endif