On Sat, Nov 05, 2011 at 02:21:16PM -0700, Kevin Cernekee wrote: > +static inline unsigned long bmips_read_zscm_reg(unsigned int offset) > +{ > + unsigned long ret; > + > + cache_op(Index_Load_Tag_S, ZSCM_REG_BASE + offset); > + > + __asm__ __volatile__( > + ".set push\n" > + ".set noreorder\n" > + "sync\n" > + "ssnop\n" > + "ssnop\n" > + "ssnop\n" > + "ssnop\n" > + "ssnop\n" > + "ssnop\n" > + "ssnop\n" > + "mfc0 %0, $28, 3\n" > + "ssnop\n" > + ".set pop\n" > + : "=&r" (ret) : : "memory"); Is it critical that the C compiler or assembler can't reorder anything to in between the cache_op and the inline asm statement? If so, I'd recommend to put the cache instruction into the asm as well. > +static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data) > +{ > + __write_32bit_c0_register($28, 3, data); > + back_to_back_c0_hazard(); > + cache_op(Index_Store_Tag_S, ZSCM_REG_BASE + offset); > + back_to_back_c0_hazard(); back_to_back_c0_hazard() is meant as the hazard barrier between a write followed immediately by a read from the same cp0 register: mtc0 $reg1, $12 mfc0 $reg2, $12 On various MIPS processors this instruction sequence would result in undefined operation such as the mfc0 instruction reading the value of $12 before the mtc0 or even next week's lucky lottery numbers.. I think we don't really have a type of hazard barrier defined in hazard.h and this seems a rather special purpose use so I suggest you just open code whatever needs to be done. Ralf