Commit 8b1f50ad authored by David S. Miller's avatar David S. Miller

[SPARC]: Audit inline asm.

Check all inline asms for common bugs and things that prevent
gcc-3.3 builds from working, in particular:
1) Missing memory or cc clobbers.
2) Do not clobber registers explicitly assigned to input
   variables.
3) extern __inline__ --> static inline.

Also try to make the formatting more consistent so that
future audits are a bit easier.

Based upon work done by Keith W. and Meelis Roos.
parent b9dd83f2
...@@ -48,10 +48,13 @@ static __inline__ int atomic_read(const atomic_t *v) ...@@ -48,10 +48,13 @@ static __inline__ int atomic_read(const atomic_t *v)
#define atomic_set(v, i) (((v)->counter) = ((i) << 8)) #define atomic_set(v, i) (((v)->counter) = ((i) << 8))
#endif #endif
static __inline__ int __atomic_add(int i, atomic_t *v) static inline int __atomic_add(int i, atomic_t *v)
{ {
register volatile int *ptr asm("g1"); register volatile int *ptr asm("g1");
register int increment asm("g2"); register int increment asm("g2");
register int tmp1 asm("g3");
register int tmp2 asm("g4");
register int tmp3 asm("g7");
ptr = &v->counter; ptr = &v->counter;
increment = i; increment = i;
...@@ -60,17 +63,20 @@ static __inline__ int __atomic_add(int i, atomic_t *v) ...@@ -60,17 +63,20 @@ static __inline__ int __atomic_add(int i, atomic_t *v)
"mov %%o7, %%g4\n\t" "mov %%o7, %%g4\n\t"
"call ___atomic_add\n\t" "call ___atomic_add\n\t"
" add %%o7, 8, %%o7\n" " add %%o7, 8, %%o7\n"
: "=&r" (increment) : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
: "0" (increment), "r" (ptr) : "0" (increment), "r" (ptr)
: "g3", "g4", "g7", "memory", "cc"); : "memory", "cc");
return increment; return increment;
} }
static __inline__ int __atomic_sub(int i, atomic_t *v) static inline int __atomic_sub(int i, atomic_t *v)
{ {
register volatile int *ptr asm("g1"); register volatile int *ptr asm("g1");
register int increment asm("g2"); register int increment asm("g2");
register int tmp1 asm("g3");
register int tmp2 asm("g4");
register int tmp3 asm("g7");
ptr = &v->counter; ptr = &v->counter;
increment = i; increment = i;
...@@ -79,9 +85,9 @@ static __inline__ int __atomic_sub(int i, atomic_t *v) ...@@ -79,9 +85,9 @@ static __inline__ int __atomic_sub(int i, atomic_t *v)
"mov %%o7, %%g4\n\t" "mov %%o7, %%g4\n\t"
"call ___atomic_sub\n\t" "call ___atomic_sub\n\t"
" add %%o7, 8, %%o7\n" " add %%o7, 8, %%o7\n"
: "=&r" (increment) : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
: "0" (increment), "r" (ptr) : "0" (increment), "r" (ptr)
: "g3", "g4", "g7", "memory", "cc"); : "memory", "cc");
return increment; return increment;
} }
......
This diff is collapsed.
...@@ -42,7 +42,7 @@ extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned i ...@@ -42,7 +42,7 @@ extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned i
extern unsigned int __csum_partial_copy_sparc_generic (const char *, char *); extern unsigned int __csum_partial_copy_sparc_generic (const char *, char *);
extern __inline__ unsigned int static inline unsigned int
csum_partial_copy_nocheck (const char *src, char *dst, int len, csum_partial_copy_nocheck (const char *src, char *dst, int len,
unsigned int sum) unsigned int sum)
{ {
...@@ -52,13 +52,16 @@ csum_partial_copy_nocheck (const char *src, char *dst, int len, ...@@ -52,13 +52,16 @@ csum_partial_copy_nocheck (const char *src, char *dst, int len,
__asm__ __volatile__ ( __asm__ __volatile__ (
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t" "call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" mov %4, %%g7\n" " mov %6, %%g7\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (sum) : : "=&r" (ret), "=&r" (d), "=&r" (l)
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7"); : "0" (ret), "1" (d), "2" (l), "r" (sum)
: "o2", "o3", "o4", "o5", "o7",
"g2", "g3", "g4", "g5", "g7",
"memory", "cc");
return ret; return ret;
} }
extern __inline__ unsigned int static inline unsigned int
csum_partial_copy_from_user(const char *src, char *dst, int len, csum_partial_copy_from_user(const char *src, char *dst, int len,
unsigned int sum, int *err) unsigned int sum, int *err)
{ {
...@@ -79,14 +82,16 @@ csum_partial_copy_from_user(const char *src, char *dst, int len, ...@@ -79,14 +82,16 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
".previous\n" ".previous\n"
"1:\n\t" "1:\n\t"
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t" "call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" st %5, [%%sp + 64]\n" " st %8, [%%sp + 64]\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (s), "r" (err) : : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7"); : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
: "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
"cc", "memory");
return ret; return ret;
} }
} }
extern __inline__ unsigned int static inline unsigned int
csum_partial_copy_to_user(const char *src, char *dst, int len, csum_partial_copy_to_user(const char *src, char *dst, int len,
unsigned int sum, int *err) unsigned int sum, int *err)
{ {
...@@ -106,9 +111,12 @@ csum_partial_copy_to_user(const char *src, char *dst, int len, ...@@ -106,9 +111,12 @@ csum_partial_copy_to_user(const char *src, char *dst, int len,
".previous\n" ".previous\n"
"1:\n\t" "1:\n\t"
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t" "call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" st %5, [%%sp + 64]\n" " st %8, [%%sp + 64]\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (s), "r" (err) : : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7"); : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
: "o2", "o3", "o4", "o5", "o7",
"g2", "g3", "g4", "g5",
"cc", "memory");
return ret; return ret;
} }
} }
...@@ -119,7 +127,7 @@ csum_partial_copy_to_user(const char *src, char *dst, int len, ...@@ -119,7 +127,7 @@ csum_partial_copy_to_user(const char *src, char *dst, int len,
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned /* ihl is always 5 or greater, almost always is 5, and iph is word aligned
* the majority of the time. * the majority of the time.
*/ */
extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph, static inline unsigned short ip_fast_csum(const unsigned char *iph,
unsigned int ihl) unsigned int ihl)
{ {
unsigned short sum; unsigned short sum;
...@@ -157,7 +165,7 @@ extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph, ...@@ -157,7 +165,7 @@ extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph,
} }
/* Fold a partial checksum without adding pseudo headers. */ /* Fold a partial checksum without adding pseudo headers. */
extern __inline__ unsigned int csum_fold(unsigned int sum) static inline unsigned int csum_fold(unsigned int sum)
{ {
unsigned int tmp; unsigned int tmp;
...@@ -171,7 +179,7 @@ extern __inline__ unsigned int csum_fold(unsigned int sum) ...@@ -171,7 +179,7 @@ extern __inline__ unsigned int csum_fold(unsigned int sum)
return sum; return sum;
} }
extern __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr, static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
unsigned long daddr, unsigned long daddr,
unsigned int len, unsigned int len,
unsigned short proto, unsigned short proto,
...@@ -203,7 +211,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, ...@@ -203,7 +211,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
#define _HAVE_ARCH_IPV6_CSUM #define _HAVE_ARCH_IPV6_CSUM
static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
struct in6_addr *daddr, struct in6_addr *daddr,
__u32 len, __u32 len,
unsigned short proto, unsigned short proto,
...@@ -238,7 +246,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, ...@@ -238,7 +246,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
} }
/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */ /* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
extern __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len) static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
{ {
return csum_fold(csum_partial(buff, len, 0)); return csum_fold(csum_partial(buff, len, 0));
} }
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern __inline__ unsigned long sun4c_get_synchronous_error(void) static inline unsigned long sun4c_get_synchronous_error(void)
{ {
unsigned long sync_err; unsigned long sync_err;
...@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void) ...@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void)
return sync_err; return sync_err;
} }
extern __inline__ unsigned long sun4c_get_synchronous_address(void) static inline unsigned long sun4c_get_synchronous_address(void)
{ {
unsigned long sync_addr; unsigned long sync_addr;
...@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void) ...@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void)
} }
/* SUN4 pte, segmap, and context manipulation */ /* SUN4 pte, segmap, and context manipulation */
extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr) static inline unsigned long sun4c_get_segmap(unsigned long addr)
{ {
register unsigned long entry; register unsigned long entry;
...@@ -107,14 +107,15 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr) ...@@ -107,14 +107,15 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr)
return entry; return entry;
} }
extern __inline__ void sun4c_put_segmap(unsigned long addr, unsigned long entry) static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry)
{ {
__asm__ __volatile__("\n\tstha %1, [%0] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tstha %1, [%0] %2; nop; nop; nop;\n\t" : :
"r" (addr), "r" (entry), "r" (addr), "r" (entry),
"i" (ASI_SEGMAP)); "i" (ASI_SEGMAP)
: "memory");
} }
extern __inline__ unsigned long sun4c_get_pte(unsigned long addr) static inline unsigned long sun4c_get_pte(unsigned long addr)
{ {
register unsigned long entry; register unsigned long entry;
...@@ -124,14 +125,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr) ...@@ -124,14 +125,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr)
return entry; return entry;
} }
extern __inline__ void sun4c_put_pte(unsigned long addr, unsigned long entry) static inline void sun4c_put_pte(unsigned long addr, unsigned long entry)
{ {
__asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : :
"r" (addr), "r" (addr),
"r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)); "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)
: "memory");
} }
extern __inline__ int sun4c_get_context(void) static inline int sun4c_get_context(void)
{ {
register int ctx; register int ctx;
...@@ -142,10 +144,11 @@ extern __inline__ int sun4c_get_context(void) ...@@ -142,10 +144,11 @@ extern __inline__ int sun4c_get_context(void)
return ctx; return ctx;
} }
extern __inline__ int sun4c_set_context(int ctx) static inline int sun4c_set_context(int ctx)
{ {
__asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : :
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)); "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
: "memory");
return ctx; return ctx;
} }
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern __inline__ unsigned long sun4c_get_synchronous_error(void) static inline unsigned long sun4c_get_synchronous_error(void)
{ {
unsigned long sync_err; unsigned long sync_err;
...@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void) ...@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void)
return sync_err; return sync_err;
} }
extern __inline__ unsigned long sun4c_get_synchronous_address(void) static inline unsigned long sun4c_get_synchronous_address(void)
{ {
unsigned long sync_addr; unsigned long sync_addr;
...@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void) ...@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void)
} }
/* SUN4C pte, segmap, and context manipulation */ /* SUN4C pte, segmap, and context manipulation */
extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr) static inline unsigned long sun4c_get_segmap(unsigned long addr)
{ {
register unsigned long entry; register unsigned long entry;
...@@ -108,15 +108,16 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr) ...@@ -108,15 +108,16 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr)
return entry; return entry;
} }
extern __inline__ void sun4c_put_segmap(unsigned long addr, unsigned long entry) static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry)
{ {
__asm__ __volatile__("\n\tstba %1, [%0] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tstba %1, [%0] %2; nop; nop; nop;\n\t" : :
"r" (addr), "r" (entry), "r" (addr), "r" (entry),
"i" (ASI_SEGMAP)); "i" (ASI_SEGMAP)
: "memory");
} }
extern __inline__ unsigned long sun4c_get_pte(unsigned long addr) static inline unsigned long sun4c_get_pte(unsigned long addr)
{ {
register unsigned long entry; register unsigned long entry;
...@@ -126,14 +127,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr) ...@@ -126,14 +127,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr)
return entry; return entry;
} }
extern __inline__ void sun4c_put_pte(unsigned long addr, unsigned long entry) static inline void sun4c_put_pte(unsigned long addr, unsigned long entry)
{ {
__asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : :
"r" (addr), "r" (addr),
"r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)); "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)
: "memory");
} }
extern __inline__ int sun4c_get_context(void) static inline int sun4c_get_context(void)
{ {
register int ctx; register int ctx;
...@@ -144,10 +146,11 @@ extern __inline__ int sun4c_get_context(void) ...@@ -144,10 +146,11 @@ extern __inline__ int sun4c_get_context(void)
return ctx; return ctx;
} }
extern __inline__ int sun4c_set_context(int ctx) static inline int sun4c_set_context(int ctx)
{ {
__asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : : __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : :
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)); "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
: "memory");
return ctx; return ctx;
} }
......
...@@ -130,8 +130,12 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc, ...@@ -130,8 +130,12 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
"std\t%%g0, [%0 + %3 + 0x30]\n\t" "std\t%%g0, [%0 + %3 + 0x30]\n\t"
"st\t%1, [%0 + %3 + 0x38]\n\t" "st\t%1, [%0 + %3 + 0x38]\n\t"
"st\t%%g0, [%0 + %3 + 0x3c]" "st\t%%g0, [%0 + %3 + 0x3c]"
: : "r" (regs), "r" (sp - sizeof(struct reg_window)), "r" (zero), : /* no outputs */
"i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); : "r" (regs),
"r" (sp - sizeof(struct reg_window)),
"r" (zero),
"i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))
: "memory");
} }
/* Free all resources held by a thread. */ /* Free all resources held by a thread. */
......
...@@ -96,27 +96,29 @@ ...@@ -96,27 +96,29 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern __inline__ unsigned int get_ross_icr(void) static inline unsigned int get_ross_icr(void)
{ {
unsigned int icreg; unsigned int icreg;
__asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */ __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */
"mov %%g1, %0\n\t" : "mov %%g1, %0\n\t"
"=r" (icreg) : : : "=r" (icreg)
"g1", "memory"); : /* no inputs */
: "g1", "memory");
return icreg; return icreg;
} }
extern __inline__ void put_ross_icr(unsigned int icreg) static inline void put_ross_icr(unsigned int icreg)
{ {
__asm__ __volatile__("or %%g0, %0, %%g1\n\t" __asm__ __volatile__("or %%g0, %0, %%g1\n\t"
".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */ ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */
"nop\n\t" "nop\n\t"
"nop\n\t" "nop\n\t"
"nop\n\t" : : "nop\n\t"
"r" (icreg) : : /* no outputs */
"g1", "memory"); : "r" (icreg)
: "g1", "memory");
return; return;
} }
...@@ -124,52 +126,62 @@ extern __inline__ void put_ross_icr(unsigned int icreg) ...@@ -124,52 +126,62 @@ extern __inline__ void put_ross_icr(unsigned int icreg)
/* HyperSparc specific cache flushing. */ /* HyperSparc specific cache flushing. */
/* This is for the on-chip instruction cache. */ /* This is for the on-chip instruction cache. */
extern __inline__ void hyper_flush_whole_icache(void) static inline void hyper_flush_whole_icache(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_FLUSH_IWHOLE)); : /* no outputs */
: "i" (ASI_M_FLUSH_IWHOLE)
: "memory");
return; return;
} }
extern int vac_cache_size; extern int vac_cache_size;
extern int vac_line_size; extern int vac_line_size;
extern __inline__ void hyper_clear_all_tags(void) static inline void hyper_clear_all_tags(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size) for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_DATAC_TAG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_DATAC_TAG)
: "memory");
} }
extern __inline__ void hyper_flush_unconditional_combined(void) static inline void hyper_flush_unconditional_combined(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size) for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_FLUSH_CTX)); : /* no outputs */
: "r" (addr), "i" (ASI_M_FLUSH_CTX)
: "memory");
} }
extern __inline__ void hyper_flush_cache_user(void) static inline void hyper_flush_cache_user(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size) for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_FLUSH_USER)); : /* no outputs */
: "r" (addr), "i" (ASI_M_FLUSH_USER)
: "memory");
} }
extern __inline__ void hyper_flush_cache_page(unsigned long page) static inline void hyper_flush_cache_page(unsigned long page)
{ {
unsigned long end; unsigned long end;
page &= PAGE_MASK; page &= PAGE_MASK;
end = page + PAGE_SIZE; end = page + PAGE_SIZE;
while(page < end) { while (page < end) {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (page), "i" (ASI_M_FLUSH_PAGE)); : /* no outputs */
: "r" (page), "i" (ASI_M_FLUSH_PAGE)
: "memory");
page += vac_line_size; page += vac_line_size;
} }
} }
......
...@@ -27,68 +27,80 @@ ...@@ -27,68 +27,80 @@
#define SWIFT_EN 0x00000001 /* MMU enable */ #define SWIFT_EN 0x00000001 /* MMU enable */
/* Bits [13:5] select one of 512 instruction cache tags */ /* Bits [13:5] select one of 512 instruction cache tags */
extern __inline__ void swift_inv_insn_tag(unsigned long addr) static inline void swift_inv_insn_tag(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_TXTC_TAG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_TXTC_TAG)
: "memory");
} }
/* Bits [12:4] select one of 512 data cache tags */ /* Bits [12:4] select one of 512 data cache tags */
extern __inline__ void swift_inv_data_tag(unsigned long addr) static inline void swift_inv_data_tag(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_DATAC_TAG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_DATAC_TAG)
: "memory");
} }
extern __inline__ void swift_flush_dcache(void) static inline void swift_flush_dcache(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x2000; addr += 0x10) for (addr = 0; addr < 0x2000; addr += 0x10)
swift_inv_data_tag(addr); swift_inv_data_tag(addr);
} }
extern __inline__ void swift_flush_icache(void) static inline void swift_flush_icache(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20) for (addr = 0; addr < 0x4000; addr += 0x20)
swift_inv_insn_tag(addr); swift_inv_insn_tag(addr);
} }
extern __inline__ void swift_idflash_clear(void) static inline void swift_idflash_clear(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x2000; addr += 0x10) { for (addr = 0; addr < 0x2000; addr += 0x10) {
swift_inv_insn_tag(addr<<1); swift_inv_insn_tag(addr<<1);
swift_inv_data_tag(addr); swift_inv_data_tag(addr);
} }
} }
/* Swift is so broken, it isn't even safe to use the following. */ /* Swift is so broken, it isn't even safe to use the following. */
extern __inline__ void swift_flush_page(unsigned long page) static inline void swift_flush_page(unsigned long page)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (page), "i" (ASI_M_FLUSH_PAGE)); : /* no outputs */
: "r" (page), "i" (ASI_M_FLUSH_PAGE)
: "memory");
} }
extern __inline__ void swift_flush_segment(unsigned long addr) static inline void swift_flush_segment(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_FLUSH_SEG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_FLUSH_SEG)
: "memory");
} }
extern __inline__ void swift_flush_region(unsigned long addr) static inline void swift_flush_region(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_FLUSH_REGION)); : /* no outputs */
: "r" (addr), "i" (ASI_M_FLUSH_REGION)
: "memory");
} }
extern __inline__ void swift_flush_context(void) static inline void swift_flush_context(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_FLUSH_CTX)); : /* no outputs */
: "i" (ASI_M_FLUSH_CTX)
: "memory");
} }
#endif /* !(_SPARC_SWIFT_H) */ #endif /* !(_SPARC_SWIFT_H) */
...@@ -220,7 +220,7 @@ extern __inline__ unsigned long swap_pil(unsigned long __new_psr) ...@@ -220,7 +220,7 @@ extern __inline__ unsigned long swap_pil(unsigned long __new_psr)
"wr %0, %2, %%psr\n\t" "wr %0, %2, %%psr\n\t"
"nop; nop; nop;\n" "nop; nop; nop;\n"
"1:\n" "1:\n"
: "=r" (retval) : "=&r" (retval)
: "r" (__new_psr), "i" (PSR_PIL) : "r" (__new_psr), "i" (PSR_PIL)
: "g1", "g2", "memory", "cc"); : "g1", "g2", "memory", "cc");
...@@ -298,7 +298,8 @@ extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned ...@@ -298,7 +298,8 @@ extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
__asm__ __volatile__("swap [%2], %0" __asm__ __volatile__("swap [%2], %0"
: "=&r" (val) : "=&r" (val)
: "0" (val), "r" (m)); : "0" (val), "r" (m)
: "memory");
return val; return val;
#else #else
register unsigned long *ptr asm("g1"); register unsigned long *ptr asm("g1");
......
...@@ -45,16 +45,20 @@ ...@@ -45,16 +45,20 @@
#define TSUNAMI_NF 0x00000002 #define TSUNAMI_NF 0x00000002
#define TSUNAMI_ME 0x00000001 #define TSUNAMI_ME 0x00000001
extern __inline__ void tsunami_flush_icache(void) static inline void tsunami_flush_icache(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_IC_FLCLEAR) : "memory"); : /* no outputs */
: "i" (ASI_M_IC_FLCLEAR)
: "memory");
} }
extern __inline__ void tsunami_flush_dcache(void) static inline void tsunami_flush_dcache(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_DC_FLCLEAR) : "memory"); : /* no outputs */
: "i" (ASI_M_DC_FLCLEAR)
: "memory");
} }
#endif /* !(_SPARC_TSUNAMI_H) */ #endif /* !(_SPARC_TSUNAMI_H) */
...@@ -59,60 +59,64 @@ ...@@ -59,60 +59,64 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* Bits [13:5] select one of 512 instruction cache tags */ /* Bits [13:5] select one of 512 instruction cache tags */
extern __inline__ void turbosparc_inv_insn_tag(unsigned long addr) static inline void turbosparc_inv_insn_tag(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_TXTC_TAG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_TXTC_TAG)
: "memory");
} }
/* Bits [13:5] select one of 512 data cache tags */ /* Bits [13:5] select one of 512 data cache tags */
extern __inline__ void turbosparc_inv_data_tag(unsigned long addr) static inline void turbosparc_inv_data_tag(unsigned long addr)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (addr), "i" (ASI_M_DATAC_TAG)); : /* no outputs */
: "r" (addr), "i" (ASI_M_DATAC_TAG)
: "memory");
} }
extern __inline__ void turbosparc_flush_icache(void) static inline void turbosparc_flush_icache(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20) for (addr = 0; addr < 0x4000; addr += 0x20)
turbosparc_inv_insn_tag(addr); turbosparc_inv_insn_tag(addr);
} }
extern __inline__ void turbosparc_flush_dcache(void) static inline void turbosparc_flush_dcache(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20) for (addr = 0; addr < 0x4000; addr += 0x20)
turbosparc_inv_data_tag(addr); turbosparc_inv_data_tag(addr);
} }
extern __inline__ void turbosparc_idflash_clear(void) static inline void turbosparc_idflash_clear(void)
{ {
unsigned long addr; unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20) { for (addr = 0; addr < 0x4000; addr += 0x20) {
turbosparc_inv_insn_tag(addr); turbosparc_inv_insn_tag(addr);
turbosparc_inv_data_tag(addr); turbosparc_inv_data_tag(addr);
} }
} }
extern __inline__ void turbosparc_set_ccreg(unsigned long regval) static inline void turbosparc_set_ccreg(unsigned long regval)
{ {
__asm__ __volatile__("sta %0, [%1] %2\n\t" : : __asm__ __volatile__("sta %0, [%1] %2\n\t"
"r" (regval), "r" (0x600), : /* no outputs */
"i" (ASI_M_MMUREGS)); : "r" (regval), "r" (0x600), "i" (ASI_M_MMUREGS)
: "memory");
} }
extern __inline__ unsigned long turbosparc_get_ccreg(void) static inline unsigned long turbosparc_get_ccreg(void)
{ {
unsigned long regval; unsigned long regval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" : __asm__ __volatile__("lda [%1] %2, %0\n\t"
"=r" (regval) : : "=r" (regval)
"r" (0x600), : "r" (0x600), "i" (ASI_M_MMUREGS));
"i" (ASI_M_MMUREGS));
return regval; return regval;
} }
......
...@@ -108,26 +108,28 @@ struct sun4c_vac_props { ...@@ -108,26 +108,28 @@ struct sun4c_vac_props {
extern struct sun4c_vac_props sun4c_vacinfo; extern struct sun4c_vac_props sun4c_vacinfo;
/* sun4c_enable_vac() enables the sun4c virtual address cache. */ /* sun4c_enable_vac() enables the sun4c virtual address cache. */
extern __inline__ void sun4c_enable_vac(void) static inline void sun4c_enable_vac(void)
{ {
__asm__ __volatile__("lduba [%0] %1, %%g1\n\t" __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
"or %%g1, %2, %%g1\n\t" "or %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t" : : "stba %%g1, [%0] %1\n\t"
"r" ((unsigned int) AC_SENABLE), : /* no outputs */
"i" (ASI_CONTROL), "i" (SENABLE_CACHE) : : "r" ((unsigned int) AC_SENABLE),
"g1"); "i" (ASI_CONTROL), "i" (SENABLE_CACHE)
: "g1", "memory");
sun4c_vacinfo.on = 1; sun4c_vacinfo.on = 1;
} }
/* sun4c_disable_vac() disables the virtual address cache. */ /* sun4c_disable_vac() disables the virtual address cache. */
extern __inline__ void sun4c_disable_vac(void) static inline void sun4c_disable_vac(void)
{ {
__asm__ __volatile__("lduba [%0] %1, %%g1\n\t" __asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
"andn %%g1, %2, %%g1\n\t" "andn %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t" : : "stba %%g1, [%0] %1\n\t"
"r" ((unsigned int) AC_SENABLE), : /* no outputs */
"i" (ASI_CONTROL), "i" (SENABLE_CACHE) : : "r" ((unsigned int) AC_SENABLE),
"g1"); "i" (ASI_CONTROL), "i" (SENABLE_CACHE)
: "g1", "memory");
sun4c_vacinfo.on = 0; sun4c_vacinfo.on = 0;
} }
......
...@@ -110,48 +110,57 @@ ...@@ -110,48 +110,57 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern __inline__ void viking_flush_icache(void) static inline void viking_flush_icache(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_IC_FLCLEAR)); : /* no outputs */
: "i" (ASI_M_IC_FLCLEAR)
: "memory");
} }
extern __inline__ void viking_flush_dcache(void) static inline void viking_flush_dcache(void)
{ {
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
"i" (ASI_M_DC_FLCLEAR)); : /* no outputs */
: "i" (ASI_M_DC_FLCLEAR)
: "memory");
} }
extern __inline__ void viking_unlock_icache(void) static inline void viking_unlock_icache(void)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (0x80000000), "i" (ASI_M_IC_FLCLEAR)); : /* no outputs */
: "r" (0x80000000), "i" (ASI_M_IC_FLCLEAR)
: "memory");
} }
extern __inline__ void viking_unlock_dcache(void) static inline void viking_unlock_dcache(void)
{ {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
"r" (0x80000000), "i" (ASI_M_DC_FLCLEAR)); : /* no outputs */
: "r" (0x80000000), "i" (ASI_M_DC_FLCLEAR)
: "memory");
} }
extern __inline__ void viking_set_bpreg(unsigned long regval) static inline void viking_set_bpreg(unsigned long regval)
{ {
__asm__ __volatile__("sta %0, [%%g0] %1\n\t" : : __asm__ __volatile__("sta %0, [%%g0] %1\n\t"
"r" (regval), : /* no outputs */
"i" (ASI_M_ACTION)); : "r" (regval), "i" (ASI_M_ACTION)
: "memory");
} }
extern __inline__ unsigned long viking_get_bpreg(void) static inline unsigned long viking_get_bpreg(void)
{ {
unsigned long regval; unsigned long regval;
__asm__ __volatile__("lda [%%g0] %1, %0\n\t" : __asm__ __volatile__("lda [%%g0] %1, %0\n\t"
"=r" (regval) : : "=r" (regval)
"i" (ASI_M_ACTION)); : "i" (ASI_M_ACTION));
return regval; return regval;
} }
extern __inline__ void viking_get_dcache_ptag(int set, int block, static inline void viking_get_dcache_ptag(int set, int block,
unsigned long *data) unsigned long *data)
{ {
unsigned long ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) | unsigned long ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) |
...@@ -160,15 +169,15 @@ extern __inline__ void viking_get_dcache_ptag(int set, int block, ...@@ -160,15 +169,15 @@ extern __inline__ void viking_get_dcache_ptag(int set, int block,
__asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t" __asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t"
"or %%g0, %%g2, %0\n\t" "or %%g0, %%g2, %0\n\t"
"or %%g0, %%g3, %1\n\t" : "or %%g0, %%g3, %1\n\t"
"=r" (info), "=r" (page) : : "=r" (info), "=r" (page)
"r" (ptag), "i" (ASI_M_DATAC_TAG) : : "r" (ptag), "i" (ASI_M_DATAC_TAG)
"g2", "g3"); : "g2", "g3");
data[0] = info; data[0] = info;
data[1] = page; data[1] = page;
} }
extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp, static inline void viking_mxcc_turn_off_parity(unsigned long *mregp,
unsigned long *mxcc_cregp) unsigned long *mxcc_cregp)
{ {
unsigned long mreg = *mregp; unsigned long mreg = *mregp;
...@@ -190,30 +199,32 @@ extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp, ...@@ -190,30 +199,32 @@ extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp,
"2:\n\t" "2:\n\t"
"sta %0, [%%g0] %3\n\t" "sta %0, [%%g0] %3\n\t"
"sta %1, [%2] %4\n" "sta %1, [%2] %4\n"
"1:\n\t" : : "1:\n\t"
"r" (mreg), "r" (mxcc_creg), : /* no output */
: "r" (mreg), "r" (mxcc_creg),
"r" (MXCC_CREG), "i" (ASI_M_MMUREGS), "r" (MXCC_CREG), "i" (ASI_M_MMUREGS),
"i" (ASI_M_MXCC) : "g2", "cc"); "i" (ASI_M_MXCC)
: "g2", "memory", "cc");
*mregp = mreg; *mregp = mreg;
*mxcc_cregp = mxcc_creg; *mxcc_cregp = mxcc_creg;
} }
extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr) static inline unsigned long viking_hwprobe(unsigned long vaddr)
{ {
unsigned long val; unsigned long val;
vaddr &= PAGE_MASK; vaddr &= PAGE_MASK;
/* Probe all MMU entries. */ /* Probe all MMU entries. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" : __asm__ __volatile__("lda [%1] %2, %0\n\t"
"=r" (val) : : "=r" (val)
"r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); : "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
if (!val) if (!val)
return 0; return 0;
/* Probe region. */ /* Probe region. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" : __asm__ __volatile__("lda [%1] %2, %0\n\t"
"=r" (val) : : "=r" (val)
"r" (vaddr | 0x200), "i" (ASI_M_FLUSH_PROBE)); : "r" (vaddr | 0x200), "i" (ASI_M_FLUSH_PROBE));
if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) { if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
vaddr &= ~SRMMU_PGDIR_MASK; vaddr &= ~SRMMU_PGDIR_MASK;
vaddr >>= PAGE_SHIFT; vaddr >>= PAGE_SHIFT;
...@@ -221,9 +232,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr) ...@@ -221,9 +232,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr)
} }
/* Probe segment. */ /* Probe segment. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" : __asm__ __volatile__("lda [%1] %2, %0\n\t"
"=r" (val) : : "=r" (val)
"r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE)); : "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) { if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
vaddr &= ~SRMMU_PMD_MASK; vaddr &= ~SRMMU_PMD_MASK;
vaddr >>= PAGE_SHIFT; vaddr >>= PAGE_SHIFT;
...@@ -231,9 +242,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr) ...@@ -231,9 +242,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr)
} }
/* Probe page. */ /* Probe page. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" : __asm__ __volatile__("lda [%1] %2, %0\n\t"
"=r" (val) : : "=r" (val)
"r" (vaddr), "i" (ASI_M_FLUSH_PROBE)); : "r" (vaddr), "i" (ASI_M_FLUSH_PROBE));
return val; return val;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment