On Mon, 13 Oct 2008, Ralf Baechle wrote:
> > +static void __cpuinit build_bcm1250_m3_war(u32 **p, struct uasm_reloc **r)
> > +{
> > + uasm_i_dmfc0(p, K0, C0_BADVADDR);
> > + uasm_i_dmfc0(p, K1, C0_ENTRYHI);
> > + uasm_i_xor(p, K0, K0, K1);
> > + uasm_i_dsll(p, K1, K0, 24);
> > + uasm_i_dsrl32(p, K1, K1, (24 + PAGE_SHIFT + 1) - 32);
> > + uasm_i_dsrl32(p, K0, K0, 30);
> > + uasm_i_or(p, K0, K0, K1);
> > + uasm_il_bnez(p, r, K0, label_leave);
>
> The workaround is beginning to be relativly expensive. We're investing 8
> instructions extra only to verify that the content of c0_entryhi is
> correct. I haven't tried yet but me seems by avoiding the use of c0_context
> entirely relying only on badvaddr we may be able to get away cheaper.
Well, this is broken silicon, so we could well declare it unsupported.
Workarounds should be as cheap maintenance-wise as possible. The run-time
hit is secondary. Owing to how these bit fields are laid out I don't
think we can get anywhere below the present instruction count with the
current approach.
In this case using BadVAddr might be possible, but it'd have to be masked
as appropriate and possibly additionally transformed in some way and we
are short on registers (k0 and k1 only), so that may be tough and prove no
cheaper. Feel free to try though. At least with the synthesiser we can
keep code for all the other good hardware intact.
However as not all BCM1250 hardware suffers from this problem we should
be more finegrained wrt choosing at the run time whether the workaround
should be enabled or not in the first place and I'll see if I can find
some time to address this. It's been on my todo list for a while now, so
perhaps it's time to tick it off.
> Btw, adding linux-mips to the cc list. This really should be public.
Of course -- I haven't noticed the list was omitted. :(
Maciej