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)
#define atomic_set(v, i) (((v)->counter) = ((i) << 8))
#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 int increment asm("g2");
register int tmp1 asm("g3");
register int tmp2 asm("g4");
register int tmp3 asm("g7");
ptr = &v->counter;
increment = i;
......@@ -60,17 +63,20 @@ static __inline__ int __atomic_add(int i, atomic_t *v)
"mov %%o7, %%g4\n\t"
"call ___atomic_add\n\t"
" add %%o7, 8, %%o7\n"
: "=&r" (increment)
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
: "0" (increment), "r" (ptr)
: "g3", "g4", "g7", "memory", "cc");
: "memory", "cc");
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 int increment asm("g2");
register int tmp1 asm("g3");
register int tmp2 asm("g4");
register int tmp3 asm("g7");
ptr = &v->counter;
increment = i;
......@@ -79,9 +85,9 @@ static __inline__ int __atomic_sub(int i, atomic_t *v)
"mov %%o7, %%g4\n\t"
"call ___atomic_sub\n\t"
" add %%o7, 8, %%o7\n"
: "=&r" (increment)
: "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
: "0" (increment), "r" (ptr)
: "g3", "g4", "g7", "memory", "cc");
: "memory", "cc");
return increment;
}
......
This diff is collapsed.
......@@ -42,23 +42,26 @@ 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 __inline__ unsigned int
static inline unsigned int
csum_partial_copy_nocheck (const char *src, char *dst, int len,
unsigned int sum)
{
register unsigned int ret asm("o0") = (unsigned int)src;
register char *d asm("o1") = dst;
register int l asm("g1") = len;
__asm__ __volatile__ (
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" mov %4, %%g7\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (sum) :
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7");
" mov %6, %%g7\n"
: "=&r" (ret), "=&r" (d), "=&r" (l)
: "0" (ret), "1" (d), "2" (l), "r" (sum)
: "o2", "o3", "o4", "o5", "o7",
"g2", "g3", "g4", "g5", "g7",
"memory", "cc");
return ret;
}
extern __inline__ unsigned int
static inline unsigned int
csum_partial_copy_from_user(const char *src, char *dst, int len,
unsigned int sum, int *err)
{
......@@ -79,14 +82,16 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
".previous\n"
"1:\n\t"
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" st %5, [%%sp + 64]\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (s), "r" (err) :
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7");
" st %8, [%%sp + 64]\n"
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
: "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
"cc", "memory");
return ret;
}
}
extern __inline__ unsigned int
static inline unsigned int
csum_partial_copy_to_user(const char *src, char *dst, int len,
unsigned int sum, int *err)
{
......@@ -106,9 +111,12 @@ csum_partial_copy_to_user(const char *src, char *dst, int len,
".previous\n"
"1:\n\t"
"call " C_LABEL_STR(__csum_partial_copy_sparc_generic) "\n\t"
" st %5, [%%sp + 64]\n"
: "=r" (ret) : "0" (ret), "r" (d), "r" (l), "r" (s), "r" (err) :
"o1", "o2", "o3", "o4", "o5", "o7", "g1", "g2", "g3", "g4", "g5", "g7");
" st %8, [%%sp + 64]\n"
: "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
: "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
: "o2", "o3", "o4", "o5", "o7",
"g2", "g3", "g4", "g5",
"cc", "memory");
return ret;
}
}
......@@ -119,8 +127,8 @@ 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
* the majority of the time.
*/
extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph,
unsigned int ihl)
static inline unsigned short ip_fast_csum(const unsigned char *iph,
unsigned int ihl)
{
unsigned short sum;
......@@ -157,7 +165,7 @@ extern __inline__ unsigned short ip_fast_csum(__const__ unsigned char *iph,
}
/* 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;
......@@ -171,11 +179,11 @@ extern __inline__ unsigned int csum_fold(unsigned int sum)
return sum;
}
extern __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
unsigned long daddr,
unsigned int len,
unsigned short proto,
unsigned int sum)
static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
unsigned long daddr,
unsigned int len,
unsigned short proto,
unsigned int sum)
{
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
"addxcc\t%2, %0, %0\n\t"
......@@ -203,11 +211,11 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
struct in6_addr *daddr,
__u32 len,
unsigned short proto,
unsigned int sum)
static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
struct in6_addr *daddr,
__u32 len,
unsigned short proto,
unsigned int sum)
{
__asm__ __volatile__ (
"addcc %3, %4, %%g4\n\t"
......@@ -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 */
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));
}
......
......@@ -76,7 +76,7 @@
#ifndef __ASSEMBLY__
extern __inline__ unsigned long sun4c_get_synchronous_error(void)
static inline unsigned long sun4c_get_synchronous_error(void)
{
unsigned long sync_err;
......@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void)
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;
......@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void)
}
/* 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;
......@@ -107,14 +107,15 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr)
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" : :
"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;
......@@ -124,14 +125,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr)
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" : :
"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;
......@@ -142,10 +144,11 @@ extern __inline__ int sun4c_get_context(void)
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" : :
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL));
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
: "memory");
return ctx;
}
......
......@@ -76,7 +76,7 @@
#ifndef __ASSEMBLY__
extern __inline__ unsigned long sun4c_get_synchronous_error(void)
static inline unsigned long sun4c_get_synchronous_error(void)
{
unsigned long sync_err;
......@@ -86,7 +86,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_error(void)
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;
......@@ -97,7 +97,7 @@ extern __inline__ unsigned long sun4c_get_synchronous_address(void)
}
/* 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;
......@@ -108,15 +108,16 @@ extern __inline__ unsigned long sun4c_get_segmap(unsigned long addr)
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" : :
"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;
......@@ -126,14 +127,15 @@ extern __inline__ unsigned long sun4c_get_pte(unsigned long addr)
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" : :
"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;
......@@ -144,10 +146,11 @@ extern __inline__ int sun4c_get_context(void)
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" : :
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL));
"r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
: "memory");
return ctx;
}
......
......@@ -130,8 +130,12 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
"std\t%%g0, [%0 + %3 + 0x30]\n\t"
"st\t%1, [%0 + %3 + 0x38]\n\t"
"st\t%%g0, [%0 + %3 + 0x3c]"
: : "r" (regs), "r" (sp - sizeof(struct reg_window)), "r" (zero),
"i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
: /* no outputs */
: "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. */
......
......@@ -96,27 +96,29 @@
#ifndef __ASSEMBLY__
extern __inline__ unsigned int get_ross_icr(void)
static inline unsigned int get_ross_icr(void)
{
unsigned int icreg;
__asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */
"mov %%g1, %0\n\t" :
"=r" (icreg) : :
"g1", "memory");
"mov %%g1, %0\n\t"
: "=r" (icreg)
: /* no inputs */
: "g1", "memory");
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"
".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */
"nop\n\t"
"nop\n\t"
"nop\n\t" : :
"r" (icreg) :
"g1", "memory");
"nop\n\t"
: /* no outputs */
: "r" (icreg)
: "g1", "memory");
return;
}
......@@ -124,52 +126,62 @@ extern __inline__ void put_ross_icr(unsigned int icreg)
/* HyperSparc specific cache flushing. */
/* 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" : :
"i" (ASI_M_FLUSH_IWHOLE));
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* no outputs */
: "i" (ASI_M_FLUSH_IWHOLE)
: "memory");
return;
}
extern int vac_cache_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;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_DATAC_TAG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_CTX));
for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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;
for(addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (addr), "i" (ASI_M_FLUSH_USER));
for (addr = 0; addr < vac_cache_size; addr += vac_line_size)
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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;
page &= PAGE_MASK;
end = page + PAGE_SIZE;
while(page < end) {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
"r" (page), "i" (ASI_M_FLUSH_PAGE));
while (page < end) {
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* no outputs */
: "r" (page), "i" (ASI_M_FLUSH_PAGE)
: "memory");
page += vac_line_size;
}
}
......
......@@ -27,68 +27,80 @@
#define SWIFT_EN 0x00000001 /* MMU enable */
/* 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" : :
"r" (addr), "i" (ASI_M_TXTC_TAG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* no outputs */
: "r" (addr), "i" (ASI_M_TXTC_TAG)
: "memory");
}
/* 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" : :
"r" (addr), "i" (ASI_M_DATAC_TAG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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;
for(addr = 0; addr < 0x2000; addr += 0x10)
for (addr = 0; addr < 0x2000; addr += 0x10)
swift_inv_data_tag(addr);
}
extern __inline__ void swift_flush_icache(void)
static inline void swift_flush_icache(void)
{
unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20)
for (addr = 0; addr < 0x4000; addr += 0x20)
swift_inv_insn_tag(addr);
}
extern __inline__ void swift_idflash_clear(void)
static inline void swift_idflash_clear(void)
{
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_data_tag(addr);
}
}
/* 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" : :
"r" (page), "i" (ASI_M_FLUSH_PAGE));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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" : :
"r" (addr), "i" (ASI_M_FLUSH_SEG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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" : :
"r" (addr), "i" (ASI_M_FLUSH_REGION));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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" : :
"i" (ASI_M_FLUSH_CTX));
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* no outputs */
: "i" (ASI_M_FLUSH_CTX)
: "memory");
}
#endif /* !(_SPARC_SWIFT_H) */
......@@ -220,7 +220,7 @@ extern __inline__ unsigned long swap_pil(unsigned long __new_psr)
"wr %0, %2, %%psr\n\t"
"nop; nop; nop;\n"
"1:\n"
: "=r" (retval)
: "=&r" (retval)
: "r" (__new_psr), "i" (PSR_PIL)
: "g1", "g2", "memory", "cc");
......@@ -298,7 +298,8 @@ extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned
#ifdef CONFIG_SMP
__asm__ __volatile__("swap [%2], %0"
: "=&r" (val)
: "0" (val), "r" (m));
: "0" (val), "r" (m)
: "memory");
return val;
#else
register unsigned long *ptr asm("g1");
......
......@@ -45,16 +45,20 @@
#define TSUNAMI_NF 0x00000002
#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" : :
"i" (ASI_M_IC_FLCLEAR) : "memory");
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* 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" : :
"i" (ASI_M_DC_FLCLEAR) : "memory");
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* no outputs */
: "i" (ASI_M_DC_FLCLEAR)
: "memory");
}
#endif /* !(_SPARC_TSUNAMI_H) */
......@@ -59,60 +59,64 @@
#ifndef __ASSEMBLY__
/* 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" : :
"r" (addr), "i" (ASI_M_TXTC_TAG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* no outputs */
: "r" (addr), "i" (ASI_M_TXTC_TAG)
: "memory");
}
/* 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" : :
"r" (addr), "i" (ASI_M_DATAC_TAG));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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;
for(addr = 0; addr < 0x4000; addr += 0x20)
for (addr = 0; addr < 0x4000; addr += 0x20)
turbosparc_inv_insn_tag(addr);
}
extern __inline__ void turbosparc_flush_dcache(void)
static inline void turbosparc_flush_dcache(void)
{
unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20)
for (addr = 0; addr < 0x4000; addr += 0x20)
turbosparc_inv_data_tag(addr);
}
extern __inline__ void turbosparc_idflash_clear(void)
static inline void turbosparc_idflash_clear(void)
{
unsigned long addr;
for(addr = 0; addr < 0x4000; addr += 0x20) {
for (addr = 0; addr < 0x4000; addr += 0x20) {
turbosparc_inv_insn_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" : :
"r" (regval), "r" (0x600),
"i" (ASI_M_MMUREGS));
__asm__ __volatile__("sta %0, [%1] %2\n\t"
: /* no outputs */
: "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;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (regval) :
"r" (0x600),
"i" (ASI_M_MMUREGS));
__asm__ __volatile__("lda [%1] %2, %0\n\t"
: "=r" (regval)
: "r" (0x600), "i" (ASI_M_MMUREGS));
return regval;
}
......
......@@ -108,27 +108,29 @@ struct sun4c_vac_props {
extern struct sun4c_vac_props sun4c_vacinfo;
/* 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"
"or %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t" : :
"r" ((unsigned int) AC_SENABLE),
"i" (ASI_CONTROL), "i" (SENABLE_CACHE) :
"g1");
sun4c_vacinfo.on = 1;
__asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
"or %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t"
: /* no outputs */
: "r" ((unsigned int) AC_SENABLE),
"i" (ASI_CONTROL), "i" (SENABLE_CACHE)
: "g1", "memory");
sun4c_vacinfo.on = 1;
}
/* 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"
"andn %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t" : :
"r" ((unsigned int) AC_SENABLE),
"i" (ASI_CONTROL), "i" (SENABLE_CACHE) :
"g1");
sun4c_vacinfo.on = 0;
__asm__ __volatile__("lduba [%0] %1, %%g1\n\t"
"andn %%g1, %2, %%g1\n\t"
"stba %%g1, [%0] %1\n\t"
: /* no outputs */
: "r" ((unsigned int) AC_SENABLE),
"i" (ASI_CONTROL), "i" (SENABLE_CACHE)
: "g1", "memory");
sun4c_vacinfo.on = 0;
}
#endif /* !(_SPARC_VAC_OPS_H) */
......@@ -110,48 +110,57 @@
#ifndef __ASSEMBLY__
extern __inline__ void viking_flush_icache(void)
static inline void viking_flush_icache(void)
{
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
"i" (ASI_M_IC_FLCLEAR));
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* 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" : :
"i" (ASI_M_DC_FLCLEAR));
__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"
: /* 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" : :
"r" (0x80000000), "i" (ASI_M_IC_FLCLEAR));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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" : :
"r" (0x80000000), "i" (ASI_M_DC_FLCLEAR));
__asm__ __volatile__("sta %%g0, [%0] %1\n\t"
: /* 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" : :
"r" (regval),
"i" (ASI_M_ACTION));
__asm__ __volatile__("sta %0, [%%g0] %1\n\t"
: /* no outputs */
: "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;
__asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
"=r" (regval) :
"i" (ASI_M_ACTION));
__asm__ __volatile__("lda [%%g0] %1, %0\n\t"
: "=r" (regval)
: "i" (ASI_M_ACTION));
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 ptag = ((set & 0x7f) << 5) | ((block & 0x3) << 26) |
......@@ -160,15 +169,15 @@ extern __inline__ void viking_get_dcache_ptag(int set, int block,
__asm__ __volatile__ ("ldda [%2] %3, %%g2\n\t"
"or %%g0, %%g2, %0\n\t"
"or %%g0, %%g3, %1\n\t" :
"=r" (info), "=r" (page) :
"r" (ptag), "i" (ASI_M_DATAC_TAG) :
"g2", "g3");
"or %%g0, %%g3, %1\n\t"
: "=r" (info), "=r" (page)
: "r" (ptag), "i" (ASI_M_DATAC_TAG)
: "g2", "g3");
data[0] = info;
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 mreg = *mregp;
......@@ -190,30 +199,32 @@ extern __inline__ void viking_mxcc_turn_off_parity(unsigned long *mregp,
"2:\n\t"
"sta %0, [%%g0] %3\n\t"
"sta %1, [%2] %4\n"
"1:\n\t" : :
"r" (mreg), "r" (mxcc_creg),
"r" (MXCC_CREG), "i" (ASI_M_MMUREGS),
"i" (ASI_M_MXCC) : "g2", "cc");
"1:\n\t"
: /* no output */
: "r" (mreg), "r" (mxcc_creg),
"r" (MXCC_CREG), "i" (ASI_M_MMUREGS),
"i" (ASI_M_MXCC)
: "g2", "memory", "cc");
*mregp = mreg;
*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;
vaddr &= PAGE_MASK;
/* Probe all MMU entries. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (val) :
"r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
__asm__ __volatile__("lda [%1] %2, %0\n\t"
: "=r" (val)
: "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
if (!val)
return 0;
/* Probe region. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (val) :
"r" (vaddr | 0x200), "i" (ASI_M_FLUSH_PROBE));
__asm__ __volatile__("lda [%1] %2, %0\n\t"
: "=r" (val)
: "r" (vaddr | 0x200), "i" (ASI_M_FLUSH_PROBE));
if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
vaddr &= ~SRMMU_PGDIR_MASK;
vaddr >>= PAGE_SHIFT;
......@@ -221,9 +232,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr)
}
/* Probe segment. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (val) :
"r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
__asm__ __volatile__("lda [%1] %2, %0\n\t"
: "=r" (val)
: "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
vaddr &= ~SRMMU_PMD_MASK;
vaddr >>= PAGE_SHIFT;
......@@ -231,9 +242,9 @@ extern __inline__ unsigned long viking_hwprobe(unsigned long vaddr)
}
/* Probe page. */
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (val) :
"r" (vaddr), "i" (ASI_M_FLUSH_PROBE));
__asm__ __volatile__("lda [%1] %2, %0\n\t"
: "=r" (val)
: "r" (vaddr), "i" (ASI_M_FLUSH_PROBE));
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