svn commit: r195871 - in projects/ppc64/sys: powerpc/include sys

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Jul 25 15:47:57 UTC 2009


Author: nwhitehorn
Date: Sat Jul 25 15:47:57 2009
New Revision: 195871
URL: http://svn.freebsd.org/changeset/base/195871

Log:
  Add in some more type-dependent definitions and define 64-bit atomic
  functions on powerpc64. This (a) manages to not break a 32-bit kernel
  and (b) gets all of the MI stuff in the 64-bit kernel compiling. The
  elf.h changes are a hack and should be revisited after a closer look at
  the 64-bit ABI.

Modified:
  projects/ppc64/sys/powerpc/include/_bus.h
  projects/ppc64/sys/powerpc/include/_types.h
  projects/ppc64/sys/powerpc/include/atomic.h
  projects/ppc64/sys/powerpc/include/db_machdep.h
  projects/ppc64/sys/powerpc/include/elf.h
  projects/ppc64/sys/powerpc/include/runq.h
  projects/ppc64/sys/sys/user.h

Modified: projects/ppc64/sys/powerpc/include/_bus.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/_bus.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/_bus.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -31,16 +31,18 @@
 #ifndef POWERPC_INCLUDE__BUS_H
 #define POWERPC_INCLUDE__BUS_H
 
+#include <vm/vm_param.h>
+
 /*
  * Bus address and size types
  */
-typedef u_int32_t bus_addr_t;
-typedef u_int32_t bus_size_t;
+typedef vm_paddr_t bus_addr_t;
+typedef vm_size_t bus_size_t;
 
 /*
  * Access methods for bus resources and address space.
  */
 typedef struct bus_space *bus_space_tag_t;
-typedef u_int32_t bus_space_handle_t;
+typedef vm_offset_t bus_space_handle_t;
 
 #endif /* POWERPC_INCLUDE__BUS_H */

Modified: projects/ppc64/sys/powerpc/include/_types.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/_types.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/_types.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -112,7 +112,6 @@ typedef	__int64_t	__time_t;		/* time()..
 typedef	__uint64_t	__uintfptr_t;
 typedef	__uint64_t	__uintptr_t;
 #else
-typedef	__uint64_t	__uintmax_t;
 typedef	__int32_t	__ptrdiff_t;		/* ptr1 - ptr2 */
 typedef	__int32_t	__register_t;
 typedef	__int32_t	__segsz_t;		/* segment size (in pages) */

Modified: projects/ppc64/sys/powerpc/include/atomic.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/atomic.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/atomic.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -65,8 +65,21 @@
 	: "cc", "memory")					\
     /* __ATOMIC_ADD_32 */
 
+#ifdef __powerpc64__
+#define __ATOMIC_ADD_64(p, v, t)				\
+    __asm __volatile(						\
+	"1:	ldarx	%0, 0, %2\n"				\
+	"	add	%0, %3, %0\n"				\
+	"	stdcx.	%0, 0, %2\n"				\
+	"	bne-	1b\n"					\
+	: "=&r" (t), "=m" (*p)					\
+	: "r" (p), "r" (v), "m" (*p)				\
+	: "cc", "memory")					\
+    /* __ATOMIC_ADD_64 */
+#else
 #define	__ATOMIC_ADD_64(p, v, t)				\
     64-bit atomic_add not implemented
+#endif
 
 #define	_ATOMIC_ADD(width, suffix, type)			\
     static __inline void					\
@@ -98,11 +111,13 @@ _ATOMIC_ADD(16, short, u_short)
 #endif
 _ATOMIC_ADD(32, 32, uint32_t)
 _ATOMIC_ADD(32, int, u_int)
+#ifdef __powerpc64__
+_ATOMIC_ADD(64, 64, uint64_t)
+_ATOMIC_ADD(64, long, u_long)
+_ATOMIC_ADD(64, ptr, uintptr_t)
+#else
 _ATOMIC_ADD(32, long, u_long)
 _ATOMIC_ADD(32, ptr, uintptr_t)
-#if 0
-_ATOMIC_ADD(64, 64, uint64_t)
-_ATOMIC_ADD(64, long_long, u_long_long)
 #endif
 
 #undef _ATOMIC_ADD
@@ -133,8 +148,21 @@ _ATOMIC_ADD(64, long_long, u_long_long)
 	: "cc", "memory")					\
     /* __ATOMIC_CLEAR_32 */
 
+#ifdef __powerpc64__
+#define __ATOMIC_CLEAR_64(p, v, t)				\
+    __asm __volatile(						\
+	"1:	ldarx	%0, 0, %2\n"				\
+	"	andc	%0, %0, %3\n"				\
+	"	stdcx.	%0, 0, %2\n"				\
+	"	bne-	1b\n"					\
+	: "=&r" (t), "=m" (*p)					\
+	: "r" (p), "r" (v), "m" (*p)				\
+	: "cc", "memory")					\
+    /* __ATOMIC_CLEAR_64 */
+#else
 #define	__ATOMIC_CLEAR_64(p, v, t)				\
     64-bit atomic_clear not implemented
+#endif
 
 #define	_ATOMIC_CLEAR(width, suffix, type)			\
     static __inline void					\
@@ -166,11 +194,13 @@ _ATOMIC_CLEAR(16, short, u_short)
 #endif
 _ATOMIC_CLEAR(32, 32, uint32_t)
 _ATOMIC_CLEAR(32, int, u_int)
+#ifdef __powerpc64__
+_ATOMIC_CLEAR(64, 64, uint64_t)
+_ATOMIC_CLEAR(64, long, u_long)
+_ATOMIC_CLEAR(64, ptr, uintptr_t)
+#else
 _ATOMIC_CLEAR(32, long, u_long)
 _ATOMIC_CLEAR(32, ptr, uintptr_t)
-#if 0
-_ATOMIC_CLEAR(64, 64, uint64_t)
-_ATOMIC_CLEAR(64, long_long, u_long_long)
 #endif
 
 #undef _ATOMIC_CLEAR
@@ -216,8 +246,21 @@ _ATOMIC_CLEAR(64, long_long, u_long_long
 	: "cc", "memory")					\
     /* __ATOMIC_SET_32 */
 
+#ifdef __powerpc64__
+#define __ATOMIC_SET_64(p, v, t)				\
+    __asm __volatile(						\
+	"1:	ldarx	%0, 0, %2\n"				\
+	"	or	%0, %3, %0\n"				\
+	"	stdcx.	%0, 0, %2\n"				\
+	"	bne-	1b\n"					\
+	: "=&r" (t), "=m" (*p)					\
+	: "r" (p), "r" (v), "m" (*p)				\
+	: "cc", "memory")					\
+    /* __ATOMIC_SET_64 */
+#else
 #define	__ATOMIC_SET_64(p, v, t)				\
     64-bit atomic_set not implemented
+#endif
 
 #define	_ATOMIC_SET(width, suffix, type)			\
     static __inline void					\
@@ -249,11 +292,13 @@ _ATOMIC_SET(16, short, u_short)
 #endif
 _ATOMIC_SET(32, 32, uint32_t)
 _ATOMIC_SET(32, int, u_int)
+#ifdef __powerpc64__
+_ATOMIC_SET(64, 64, uint64_t)
+_ATOMIC_SET(64, long, u_long)
+_ATOMIC_SET(64, ptr, uintptr_t)
+#else
 _ATOMIC_SET(32, long, u_long)
 _ATOMIC_SET(32, ptr, uintptr_t)
-#if 0
-_ATOMIC_SET(64, 64, uint64_t)
-_ATOMIC_SET(64, long_long, u_long_long)
 #endif
 
 #undef _ATOMIC_SET
@@ -284,8 +329,21 @@ _ATOMIC_SET(64, long_long, u_long_long)
 	: "cc", "memory")					\
     /* __ATOMIC_SUBTRACT_32 */
 
+#ifdef __powerpc64__
+#define __ATOMIC_SUBTRACT_64(p, v, t)				\
+    __asm __volatile(						\
+	"1:	ldarx	%0, 0, %2\n"				\
+	"	subf	%0, %3, %0\n"				\
+	"	stdcx.	%0, 0, %2\n"				\
+	"	bne-	1b\n"					\
+	: "=&r" (t), "=m" (*p)					\
+	: "r" (p), "r" (v), "m" (*p)				\
+	: "cc", "memory")					\
+    /* __ATOMIC_SUBTRACT_64 */
+#else
 #define	__ATOMIC_SUBTRACT_64(p, v, t)				\
     64-bit atomic_subtract not implemented
+#endif
 
 #define	_ATOMIC_SUBTRACT(width, suffix, type)			\
     static __inline void					\
@@ -317,11 +375,13 @@ _ATOMIC_SUBTRACT(16, short, u_short)
 #endif
 _ATOMIC_SUBTRACT(32, 32, uint32_t)
 _ATOMIC_SUBTRACT(32, int, u_int)
+#ifdef __powerpc64__
+_ATOMIC_SUBTRACT(64, 64, uint64_t)
+_ATOMIC_SUBTRACT(64, long, u_long)
+_ATOMIC_SUBTRACT(64, ptr, uintptr_t)
+#else
 _ATOMIC_SUBTRACT(32, long, u_long)
 _ATOMIC_SUBTRACT(32, ptr, uintptr_t)
-#if 0
-_ATOMIC_SUBTRACT(64, 64, uint64_t)
-_ATOMIC_SUBTRACT(64, long_long, u_long_long)
 #endif
 
 #undef _ATOMIC_SUBTRACT
@@ -359,9 +419,37 @@ atomic_readandclear_32(volatile uint32_t
 	return (result);
 }
 
+#ifdef __powerpc64__
+static __inline uint64_t
+atomic_readandclear_64(volatile uint64_t *addr)
+{
+	uint64_t result,temp;
+
+#ifdef __GNUCLIKE_ASM
+	__asm __volatile (
+		"\tsync\n"			/* drain writes */
+		"1:\tldarx %0, 0, %3\n\t"	/* load old value */
+		"li %1, 0\n\t"			/* load new value */
+		"stdcx. %1, 0, %3\n\t"      	/* attempt to store */
+		"bne- 1b\n\t"			/* spin if failed */
+		: "=&r"(result), "=&r"(temp), "=m" (*addr)
+		: "r" (addr), "m" (*addr)
+		: "cc", "memory");
+#endif
+
+	return (result);
+}
+#endif
+
 #define	atomic_readandclear_int		atomic_readandclear_32
+
+#ifdef __powerpc64__
+#define	atomic_readandclear_long	atomic_readandclear_64
+#define	atomic_readandclear_ptr		atomic_readandclear_64
+#else
 #define	atomic_readandclear_long	atomic_readandclear_32
 #define	atomic_readandclear_ptr		atomic_readandclear_32
+#endif
 
 /*
  * We assume that a = b will do atomic loads and stores.
@@ -404,11 +492,21 @@ atomic_store_rel_##TYPE(volatile u_##TYP
 ATOMIC_STORE_LOAD(char,		8)
 ATOMIC_STORE_LOAD(short,	16)
 ATOMIC_STORE_LOAD(int,		32)
+#ifdef __powerpc64__
+ATOMIC_STORE_LOAD(long,		64)
+#endif
 
+#ifdef __powerpc64__
+#define	atomic_load_acq_long	atomic_load_acq_64
+#define	atomic_store_rel_long	atomic_store_rel_64
+#define	atomic_load_acq_ptr	atomic_load_acq_64
+#define	atomic_store_rel_ptr	atomic_store_rel_64
+#else
 #define	atomic_load_acq_long	atomic_load_acq_32
 #define	atomic_store_rel_long	atomic_store_rel_32
 #define	atomic_load_acq_ptr	atomic_load_acq_32
 #define	atomic_store_rel_ptr	atomic_store_rel_32
+#endif
 
 #undef ATOMIC_STORE_LOAD
 
@@ -446,19 +544,30 @@ atomic_cmpset_32(volatile uint32_t* p, u
 static __inline u_long
 atomic_cmpset_long(volatile u_long* p, u_long cmpval, u_long newval)
 {
-	uint32_t	ret;
+	u_long	ret;
 
 #ifdef __GNUCLIKE_ASM
 	__asm __volatile (
+	    #ifdef __powerpc64__
+		"1:\tldarx %0, 0, %2\n\t"	/* load old value */
+		"cmpld %3, %0\n\t"		/* compare */
+		"bne 2f\n\t"			/* exit if not equal */
+		"stdcx. %4, 0, %2\n\t"      	/* attempt to store */
+	    #else
 		"1:\tlwarx %0, 0, %2\n\t"	/* load old value */
 		"cmplw %3, %0\n\t"		/* compare */
 		"bne 2f\n\t"			/* exit if not equal */
 		"stwcx. %4, 0, %2\n\t"      	/* attempt to store */
+	    #endif
 		"bne- 1b\n\t"			/* spin if failed */
 		"li %0, 1\n\t"			/* success - retval = 1 */
 		"b 3f\n\t"			/* we've succeeded */
 		"2:\n\t"
+	    #ifdef __powerpc64__
+		"stdcx. %0, 0, %2\n\t"       	/* clear reservation (74xx) */
+	    #else
 		"stwcx. %0, 0, %2\n\t"       	/* clear reservation (74xx) */
+	    #endif
 		"li %0, 0\n\t"			/* failure - retval = 0 */
 		"3:\n\t"
 		: "=&r" (ret), "=m" (*p)
@@ -471,8 +580,13 @@ atomic_cmpset_long(volatile u_long* p, u
 
 #define	atomic_cmpset_int	atomic_cmpset_32
 
+#ifdef __powerpc64__
+#define	atomic_cmpset_ptr(dst, old, new)	\
+    atomic_cmpset_long((volatile u_long *)(dst), (u_long)(old), (u_long)(new))
+#else
 #define	atomic_cmpset_ptr(dst, old, new)	\
     atomic_cmpset_32((volatile u_int *)(dst), (u_int)(old), (u_int)(new))
+#endif
 
 static __inline uint32_t
 atomic_cmpset_acq_32(volatile uint32_t *p, uint32_t cmpval, uint32_t newval)
@@ -511,10 +625,17 @@ atomic_cmpset_rel_long(volatile u_long *
 #define	atomic_cmpset_acq_int	atomic_cmpset_acq_32
 #define	atomic_cmpset_rel_int	atomic_cmpset_rel_32
 
+#ifdef __powerpc64__
+#define	atomic_cmpset_acq_ptr(dst, old, new)	\
+    atomic_cmpset_acq_long((volatile u_long *)(dst), (u_long)(old), (u_long)(new))
+#define	atomic_cmpset_rel_ptr(dst, old, new)	\
+    atomic_cmpset_rel_long((volatile u_long *)(dst), (u_long)(old), (u_long)(new))
+#else
 #define	atomic_cmpset_acq_ptr(dst, old, new)	\
     atomic_cmpset_acq_32((volatile u_int *)(dst), (u_int)(old), (u_int)(new))
 #define	atomic_cmpset_rel_ptr(dst, old, new)	\
     atomic_cmpset_rel_32((volatile u_int *)(dst), (u_int)(old), (u_int)(new))
+#endif
 
 static __inline uint32_t
 atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
@@ -528,7 +649,23 @@ atomic_fetchadd_32(volatile uint32_t *p,
 }
 
 #define	atomic_fetchadd_int	atomic_fetchadd_32
+
+#ifdef __powerpc64__
+static __inline uint64_t
+atomic_fetchadd_64(volatile uint64_t *p, uint64_t v)
+{
+	uint64_t value;
+
+	do {
+		value = *p;
+	} while (!atomic_cmpset_long(p, value, value + v));
+	return (value);
+}
+
+#define	atomic_fetchadd_long	atomic_fetchadd_64
+#else
 #define	atomic_fetchadd_long(p, v)	\
     (u_long)atomic_fetchadd_32((volatile u_int *)(p), (u_int)(v))
+#endif
 
 #endif /* ! _MACHINE_ATOMIC_H_ */

Modified: projects/ppc64/sys/powerpc/include/db_machdep.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/db_machdep.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/db_machdep.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -42,7 +42,7 @@
 #define BYTE_MSF        (1)
 
 typedef	vm_offset_t	db_addr_t;	/* address - unsigned */
-typedef	int		db_expr_t;	/* expression - signed */
+typedef	intptr_t	db_expr_t;	/* expression - signed */
 
 #define	PC_REGS(regs)	((db_addr_t)kdb_thrctx->pcb_lr)
 

Modified: projects/ppc64/sys/powerpc/include/elf.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/elf.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/elf.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -36,14 +36,23 @@
  * [ppc-eabi-1995-01.pdf] for details.
  */
 
-#include <sys/elf32.h>	/* Definitions common to all 32 bit architectures. */
-
+#ifdef __powerpc64__
+#define	__ELF_WORD_SIZE	64	/* Used by <sys/elf_generic.h> */
+#else
 #define	__ELF_WORD_SIZE	32	/* Used by <sys/elf_generic.h> */
+#endif
+
+#include <sys/elf32.h>	/* Definitions common to all 32 bit architectures. */
+#include <sys/elf64.h>	/* Definitions common to all 64 bit architectures. */
 #include <sys/elf_generic.h>
 
+#ifdef __powerpc64__
+#define	ELF_ARCH	EM_PPC64
+#define	ELF_MACHINE_OK(x) ((x) == EM_PPC64)
+#else
 #define	ELF_ARCH	EM_PPC
-
 #define	ELF_MACHINE_OK(x) ((x) == EM_PPC)
+#endif
 
 /*
  * Auxiliary vector entries for passing information to the interpreter.
@@ -61,6 +70,18 @@ typedef struct {	/* Auxiliary vector ent
 	} a_un;
 } Elf32_Auxinfo;
 
+#ifdef __powerpc64__
+/* XXX: check ABI */
+typedef struct {	/* Auxiliary vector entry on initial stack */
+	int	a_type;			/* Entry type. */
+	union {
+		long	a_val;		/* Integer value. */
+		void	*a_ptr;		/* Address. */
+		void	(*a_fcn)(void);	/* Function pointer (not used). */
+	} a_un;
+} Elf64_Auxinfo;
+#endif
+
 __ElfType(Auxinfo);
 
 /* Values for a_type. */
@@ -91,9 +112,16 @@ __ElfType(Auxinfo);
 #define	R_PPC_EMB_COUNT		(R_PPC_EMB_RELSDA - R_PPC_EMB_NADDR32 + 1)
 
 /* Define "machine" characteristics */
+#ifdef __powerpc64__
+#define	ELF_TARG_CLASS	ELFCLASS64
+#define	ELF_TARG_DATA	ELFDATA2MSB
+#define	ELF_TARG_MACH	EM_PPC64
+#define	ELF_TARG_VER	1
+#else
 #define	ELF_TARG_CLASS	ELFCLASS32
 #define	ELF_TARG_DATA	ELFDATA2MSB
 #define	ELF_TARG_MACH	EM_PPC
 #define	ELF_TARG_VER	1
+#endif
 
 #endif /* !_MACHINE_ELF_H_ */

Modified: projects/ppc64/sys/powerpc/include/runq.h
==============================================================================
--- projects/ppc64/sys/powerpc/include/runq.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/powerpc/include/runq.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -29,8 +29,13 @@
 #ifndef	_MACHINE_RUNQ_H_
 #define	_MACHINE_RUNQ_H_
 
+#ifdef __powerpc64__
+#define	RQB_LEN		(1)		/* Number of priority status words. */
+#define	RQB_L2BPW	(6)		/* Log2(sizeof(rqb_word_t) * NBBY)). */
+#else
 #define	RQB_LEN		(2)		/* Number of priority status words. */
 #define	RQB_L2BPW	(5)		/* Log2(sizeof(rqb_word_t) * NBBY)). */
+#endif
 #define	RQB_BPW		(1<<RQB_L2BPW)	/* Bits in an rqb_word_t. */
 
 #define	RQB_BIT(pri)	(1 << ((pri) & (RQB_BPW - 1)))
@@ -41,6 +46,10 @@
 /*
  * Type of run queue status word.
  */
+#ifdef __powerpc64__
+typedef	u_int64_t	rqb_word_t;
+#else
 typedef	u_int32_t	rqb_word_t;
+#endif
 
 #endif

Modified: projects/ppc64/sys/sys/user.h
==============================================================================
--- projects/ppc64/sys/sys/user.h	Sat Jul 25 14:48:57 2009	(r195870)
+++ projects/ppc64/sys/sys/user.h	Sat Jul 25 15:47:57 2009	(r195871)
@@ -105,6 +105,10 @@
 #ifdef __powerpc__
 #define	KINFO_PROC_SIZE	768
 #endif
+#ifdef __powerpc64__
+#undef KINFO_PROC_SIZE /* __powerpc__ is also defined on powerpc64 */
+#define	KINFO_PROC_SIZE 1088
+#endif
 #ifdef __sparc64__
 #define	KINFO_PROC_SIZE 1088
 #endif


More information about the svn-src-projects mailing list