Re: Few questions about porting Linux to SMP86xx boards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 3 Feb 2015, Kevin Cernekee wrote:

> >>>  With the introduction of revision 2 of the MIPS architecture the CP0
> >>> EBase register was added and consequently there is no longer a guarantee
> >>> that exception vectors reside at the base of KSEG1.  Using the value read
> >>> from CP0.EBase to determine a usable address might therefore be a better
> >>> idea, although the current revision of the MIPS architecture specification
> >>> that includes segmentation control makes it a bit complicated.  Using a
> >>> dummy page mapped uncached instead might work the best.
> >>
> >> Would something like this work, assuming __fast_iob() doesn't get
> >> called before mem_init()?
> >>
> >> CKSEG1ADDR((void *)empty_zero_page)
> >>
> >> It is currently a GPL export, so maybe that would need to change to
> >> allow non-GPL drivers to use iob().  But that's still easier than
> >> allocating another dummy page.

 You only need a mapping, not a separate page.  Maybe you can use `vmap' 
to alias a page from the kernel text -- no memory wasted then.

 And the point of segmentation is KSEG1 may not be uncached anymore, it 
may not be unmapped even.  So a virtual mapping is really the proper and 
only solution.  And this situation is another reason to avoid using 
CKSEG1ADDR and friends where possible.

 But this is more of a heads-up from me rather than a request for 
implementation as we don't support segmentation at this point.

> So there are two paths forward:
> 
> 1) Make SMP86xx behave like other currently-supported CPUs, i.e. use
> the remap registers to configure the chip so that uncached reads from
> PA 0 do something sensible.  This sounds like the easiest fix.
> 
> 2) Agree to support memory configurations where PA 0 doesn't map to
> RAM, changing __fast_iob (and maybe other code) accordingly.

 I suspect the latter is bound to happen sooner or later anyway.  However 
we handle setting CP0.EBase ourselves and we can use it to our advantage.  
So knowing that our CP0.EBase points to somewhere within KSEG0 we can make 
an example r2 `__fast_iob' implementation look like:

#define CKSEG1EBASE	((read_c0_ebase() | CKSEG1 | 0xfff) - 0xfff)

#define __fast_iob()				\
	__asm__ __volatile__(			\
		".set	push\n\t"		\
		".set	noreorder\n\t"		\
		"lw	$0,%a0\n\t"		\
		"nop\n\t"			\
		".set	pop"			\
		: /* no output */		\
		: "p" (CKSEG1EBASE)		\
		: "memory")

which at 6 instructions produced is I think the best you can get without 
using an auxiliary variable rather than CP0.EBase and then handcoding the 
whole address calculation in assembly or using indirection.

  Maciej





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux