All of lore.kernel.org
 help / color / mirror / Atom feed
* (no subject)
@ 1999-02-13 17:50 Benjamin Herrenschmidt
  1999-02-14  0:12 ` David Edelsohn
  1999-02-15  9:58 ` your mail Gabriel Paubert
  0 siblings, 2 replies; 6+ messages in thread
From: Benjamin Herrenschmidt @ 1999-02-13 17:50 UTC (permalink / raw)
  To: Paul Mackerras, Cort Dougan, linuxppc-dev


Hi !

I would like your point of view about the following:

The kernel entry code starts playing with BATs as soon as it is entered.
Isn't that dangerous ? I mean, you must have enough luck for this BAT not
to be used at this specific time, or not overlapping another BAT setup by
MacOS (overlapping BATs causes undefined behaviour according to the PPC
manual) ?

I have made a test bootx that I'll upload to
ftp.linuxppc.org/developement/users/benh later today (the archive will
probably be called BootX_phys_test.sit). This version of BootX doesn't
jump directly to the kernel but goes to a small piece of PPC asm that
will cause the kernel to be entered with MMU (and interrupts) disabled. I
beleive this should get rid of potential problems with TLB misses during
boot too. Of course, all addresses passed to the kernel are turned into
physical addresses (frame buffer, stack, boot_infos).

This version works on my desktop G3, I didn't have time to test it on
other machines yet.
The bootstrap code is simple (it's entered with the same parameters as
the kernel, but with physical addresses and with the kernel physical
entry in r6) :

    /* switch interrupts off */
    mfmsr   r0;
    ori     r31,r31,MSR_EE;
    andc    r0,r0,r31;
    sync;
    mtmsr   r0;
    sync;

    /* put kernel entry (phys) in ssr0 */
    mtspr   SSR0, r6;

    /* Setup ssr1 (kernel entry MSR) */
    ori     r31,r31,(MSR_IR|MSR_DR);
    andc    r0,r0,r31;
    mtspr   SSR1, r0;

    /* Branch to the kernel */
    rfi;

Note: I wrote this little piece of asm with CodeWarrior. Since I would
like to make a C boostrap that takes place between this and the kernel, I
still need to figure out how to build code for this with egcs. If I could
find the correct MakeFile options to get an output like prom.c
(PC-relative branches, datas accessed thru a RELOC macro), I think it
would be just fine. A better approach would be to store datas relative to
a register that I can setup before entering the boostrap, but that means
parsing enough of the ELF to extract the offset of the datas. I would
appreciate if someone could give me some tips about what is usually done
in those cases or some pointers to infos/samples.


-- 
           E-Mail: <mailto:bh40@calva.net>
BenH.      Web   : <http://calvaweb.calvacom.fr/bh40/>





[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* (no subject)
  1999-02-13 17:50 Benjamin Herrenschmidt
@ 1999-02-14  0:12 ` David Edelsohn
  1999-02-15  9:58 ` your mail Gabriel Paubert
  1 sibling, 0 replies; 6+ messages in thread
From: David Edelsohn @ 1999-02-14  0:12 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Paul Mackerras, Cort Dougan, linuxppc-dev


	Just to make sure, you are not asking how to create XCOFF
TOC-based code using GCC?

	If you know the physical location or can control the physical
location at which the code will be loaded, you simply can instruct the
linker to link the executable based at that location.  Otherwise, you
might need additional -fpic position independent code option.  If you need
data and cannot set the GPR specifying the GOT address yourself, you can
use the GCC SVR4 eABI PPC suppport to calculate it on entry as it does for
embedded systems.  Note that branches generated by GCC already are
position-independent displacements (not "ba" branch absolute instruction).

	Are all of those "sync" instructions necessary in your code?  You
are not touching memory.  The instructions already are serializing.  I
think that you should be able to do something like:

enable:
        mfmsr   r0
        ori     r0,r0,MSR_EE
        mtmsr   r0

disable:
        mfmsr   r0
        andi.   r0,r0,(~MSR_EE)&0xffff
        mtmsr   r0

David

[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: your mail
  1999-02-13 17:50 Benjamin Herrenschmidt
  1999-02-14  0:12 ` David Edelsohn
@ 1999-02-15  9:58 ` Gabriel Paubert
  1999-02-15 11:23   ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 6+ messages in thread
From: Gabriel Paubert @ 1999-02-15  9:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Paul Mackerras, Cort Dougan, linuxppc-dev




On Sat, 13 Feb 1999, Benjamin Herrenschmidt wrote:

> 
> Hi !
> 
> I would like your point of view about the following:
> 
> The kernel entry code starts playing with BATs as soon as it is entered.
> Isn't that dangerous ? I mean, you must have enough luck for this BAT not
> to be used at this specific time, or not overlapping another BAT setup by
> MacOS (overlapping BATs causes undefined behaviour according to the PPC
> manual) ?

One of the first steps I do in prepboot is to invalidate all the BATs and
all the TLB entries, to make sur that I start from a known state
(invalidating the BATs is a pain because it's different in 601 and
others). But then I'm quite sure I'm called with address translation
disabled, only that some FW version leave stale values in these registers. 

> I have made a test bootx that I'll upload to
> ftp.linuxppc.org/developement/users/benh later today (the archive will
> probably be called BootX_phys_test.sit). This version of BootX doesn't
> jump directly to the kernel but goes to a small piece of PPC asm that
> will cause the kernel to be entered with MMU (and interrupts) disabled. I
> beleive this should get rid of potential problems with TLB misses during
> boot too. Of course, all addresses passed to the kernel are turned into
> physical addresses (frame buffer, stack, boot_infos).

I still had problems with stale TLB entries between prepboot when the 
kernel enabled the MMU. You have to flush the TLB before starting the
kernel to be absolutely sure that there the kernel uses only translations 
it has defined (I discovered that I had added code accessing I/O 
space before the corresponding BATs were set up due to staale TLB
entries).

> This version works on my desktop G3, I didn't have time to test it on
> other machines yet.
> The bootstrap code is simple (it's entered with the same parameters as
> the kernel, but with physical addresses and with the kernel physical
> entry in r6) :
> 
>     /* switch interrupts off */
>     mfmsr   r0;
>     ori     r31,r31,MSR_EE;
>     andc    r0,r0,r31;
>     sync;
>     mtmsr   r0;
>     sync;

Wrong, what is in r31 before ? You may clear unwanted MSR bits:
	
	mfmsr	r0
	rlwinm  r0,r0,0,17,15
	mtmsr 	r0

is enough (And if you don't like using rlwinm like this, which is
guaranteed to work according to the architecture):
	
	mfmsr	r0
	ori	r0,r0,MSR_EE
	xori	r0,r0,MSR_EE
	mtmsr	r0

and you never need a sync before or after disabling interrupts. It is
different when enabling them however, because you have to make
sure that accesses to the interrupt controller have made it to the bus.  


> 
>     /* put kernel entry (phys) in ssr0 */
>     mtspr   SSR0, r6;
> 
>     /* Setup ssr1 (kernel entry MSR) */
>     ori     r31,r31,(MSR_IR|MSR_DR);
>     andc    r0,r0,r31;
>     mtspr   SSR1, r0;
> 
>     /* Branch to the kernel */
>     rfi;
> 
> Note: I wrote this little piece of asm with CodeWarrior. Since I would
> like to make a C boostrap that takes place between this and the kernel, I
> still need to figure out how to build code for this with egcs. If I could
> find the correct MakeFile options to get an output like prom.c
> (PC-relative branches, datas accessed thru a RELOC macro), I think it
> would be just fine. A better approach would be to store datas relative to
> a register that I can setup before entering the boostrap, but that means
> parsing enough of the ELF to extract the offset of the datas. I would
> appreciate if someone could give me some tips about what is usually done
> in those cases or some pointers to infos/samples.


I would recommend that you take a look at the patch files I have for
prep (only have a look at the prepboot directory): 

	ftp://vcorr1.iram.es/pub/linux-2.2/mvme2600.generic-patch-2.2.1.gz

it is even probably overkill for what you need. But the Makefile
(with -m rleocatable), the linker script (ppcboot.lds) and the
early boot (head.S) are probably good examples (and I tried to keep them
clean). 

	Gabriel.


[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: your mail
  1999-02-15  9:58 ` your mail Gabriel Paubert
@ 1999-02-15 11:23   ` Benjamin Herrenschmidt
  1999-02-15 14:18     ` Gabriel Paubert
  0 siblings, 1 reply; 6+ messages in thread
From: Benjamin Herrenschmidt @ 1999-02-15 11:23 UTC (permalink / raw)
  To: Gabriel Paubert, linuxppc-dev


On Mon, Feb 15, 1999, Gabriel Paubert <paubert@iram.es> wrote:

>One of the first steps I do in prepboot is to invalidate all the BATs and
>all the TLB entries, to make sur that I start from a known state
>(invalidating the BATs is a pain because it's different in 601 and
>others). But then I'm quite sure I'm called with address translation
>disabled, only that some FW version leave stale values in these registers. 

My bootstrap is now a two-step bootstrap too, written all in asm to avoid
relocation problems. 

>I still had problems with stale TLB entries between prepboot when the 
>kernel enabled the MMU. You have to flush the TLB before starting the
>kernel to be absolutely sure that there the kernel uses only translations 
>it has defined (I discovered that I had added code accessing I/O 
>space before the corresponding BATs were set up due to staale TLB
>entries).

Since the MMU is switched off by the boostrap, I beleive those TLB
entries won't do any harm until the kernel switches the MMU back on,
that's it ? (I just want to make sure I fully understand). So, basically,
I could add to my bootstrap a piece of code that invalidates all BATs and
flush the TLB (I'll look at your preploader code for that).

>Wrong, what is in r31 before ? You may clear unwanted MSR bits:

You are right. I already changed this to rlwinm approx. 5 minutes after
sending the previous mail ;-)
	
>	mfmsr	r0
>	rlwinm  r0,r0,0,17,15
>	mtmsr 	r0
>
>is enough (And if you don't like using rlwinm like this, which is
>guaranteed to work according to the architecture):
>	
>	mfmsr	r0
>	ori	r0,r0,MSR_EE
>	xori	r0,r0,MSR_EE
>	mtmsr	r0
>
>and you never need a sync before or after disabling interrupts. It is
>different when enabling them however, because you have to make
>sure that accesses to the interrupt controller have made it to the bus.  

Ok, so I'll finally remove this sync.

>I would recommend that you take a look at the patch files I have for
>prep (only have a look at the prepboot directory): 
>
>	ftp://vcorr1.iram.es/pub/linux-2.2/mvme2600.generic-patch-2.2.1.gz
>
>it is even probably overkill for what you need. But the Makefile
>(with -m rleocatable), the linker script (ppcboot.lds) and the
>early boot (head.S) are probably good examples (and I tried to keep them
>clean). 

Ok, thanks.


-- 
           E-Mail: <mailto:bh40@calva.net>
BenH.      Web   : <http://calvaweb.calvacom.fr/bh40/>





[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: your mail
  1999-02-15 11:23   ` Benjamin Herrenschmidt
@ 1999-02-15 14:18     ` Gabriel Paubert
  1999-02-15 17:42       ` David Edelsohn
  0 siblings, 1 reply; 6+ messages in thread
From: Gabriel Paubert @ 1999-02-15 14:18 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev




On Mon, 15 Feb 1999, Benjamin Herrenschmidt wrote:

> My bootstrap is now a two-step bootstrap too, written all in asm to avoid
> relocation problems. 

Well, -m relocate is quite powerful IMHO. And I tried to write as little
assembly as possible, as you can easily guess from the 5000 lines of
PPC assembly of the x86 emulator :-)

> Since the MMU is switched off by the boostrap, I beleive those TLB
> entries won't do any harm until the kernel switches the MMU back on,
> that's it ? (I just want to make sure I fully understand). So, basically,
> I could add to my bootstrap a piece of code that invalidates all BATs and
> flush the TLB (I'll look at your preploader code for that).

No, but I need to run the bootloader mostly with MMU on to initialize the
VGA boards by emulating the VGA ROM BIOS for 2 reasons:
- having correct memeory attributes and the caches enabled,
- emulating the 1Mb of Intel Mobo (640k RAM+128k VGA+ ROM BIOS...)

I found that if I did not invalidate the TLB before starting the kernel, I
was allowed to do strange things (specifically accessing I/O space before
it was even mapped by BATs or PTE) due to stale TLB entries.  This caused
the introduction of a few bugs in some versions of my PreP initialization
code which were extremely hard to find. I even was unlucky enough to fall
on the borderline case where adding or suppressing a single debug message
in the loader cause the critical TLB entry to be valid or invalid.

Note that my code to invalidate TLB is the hammer to kill flies method: it
is guaranteed to work for all PPC (except embedded) implementations from
the architectural handbook because I don't want to rely on any system info
(too often wrong), so I invalidate 65536 TLB entries. In a bootloader, I
obviously don't care about the couple of milliseconds it takes. 

> 
> >Wrong, what is in r31 before ? You may clear unwanted MSR bits: 
> 
> You are right. I already changed this to rlwinm approx. 5 minutes after
> sending the previous mail ;-)

Ok, better like this. Unfortunately for rlwinm and friends, gas allows you
to replace the last 2 parameters by a single value (bit mask), for
example: rlwinm r3,r4,0, 0x00ffff00, but it does not work if you have the
complementary mask (ones, zeros, ones) so you can't type rlwinm
r0,r0,0,~MSR_EE. Note that gcc/egcs would generate the code with the
rlwinm instruction. Anybody wants to tweak binutils to allow this ?

	Gabriel. 


[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: your mail
  1999-02-15 14:18     ` Gabriel Paubert
@ 1999-02-15 17:42       ` David Edelsohn
  0 siblings, 0 replies; 6+ messages in thread
From: David Edelsohn @ 1999-02-15 17:42 UTC (permalink / raw)
  To: Gabriel Paubert; +Cc: Benjamin Herrenschmidt, linuxppc-dev


>>>>> Gabriel Paubert writes:

Gabriel> Ok, better like this. Unfortunately for rlwinm and friends, gas allows you
Gabriel> to replace the last 2 parameters by a single value (bit mask), for
Gabriel> example: rlwinm r3,r4,0, 0x00ffff00, but it does not work if you have the
Gabriel> complementary mask (ones, zeros, ones) so you can't type rlwinm
Gabriel> r0,r0,0,~MSR_EE. Note that gcc/egcs would generate the code with the
Gabriel> rlwinm instruction. Anybody wants to tweak binutils to allow this ?

	I think that this already was discovered and fixed in the
development sources.  From the ChangeLog:

Wed Aug 12 14:00:38 1998  Ian Lance Taylor  <ian@cygnus.com>

        From Peter Thiemann <thiemann@informatik.uni-tuebingen.de>:
        * ppc-opc.c (insert_mbe): Handle wrapping bitmasks.
        (extract_mbe): Likewise.

David

[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~1999-02-15 17:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-13 17:50 Benjamin Herrenschmidt
1999-02-14  0:12 ` David Edelsohn
1999-02-15  9:58 ` your mail Gabriel Paubert
1999-02-15 11:23   ` Benjamin Herrenschmidt
1999-02-15 14:18     ` Gabriel Paubert
1999-02-15 17:42       ` David Edelsohn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.