* dcbz works on 862 everywhere!
@ 2003-03-24 10:19 Joakim Tjernlund
2003-03-24 11:01 ` Joakim Tjernlund
` (2 more replies)
0 siblings, 3 replies; 51+ messages in thread
From: Joakim Tjernlund @ 2003-03-24 10:19 UTC (permalink / raw)
To: Linuxppc-Embedded@Lists. Linuxppc. Org; +Cc: strauman
Hi list
I have been researching why I can't use dcbz and friends on 8xx CPU.
Till Strauman found out long ago that the dcxx instuctions did not update
the DAR register and that was the key I needed.
After a lot of testing/reading I found a 2 instruction workaround
that lets me use dcbz in copy_tofrom_user().
I can also used dcbz in a user space app without problems. I even
removed the TLB change bit hack by Tom Rini and everything works.
By copying the MD_EPN register to the DAR register in the DTLB Miss handler
just before MD_RPN is written everything just works. The only explanation that
makes sense to me is that the MD_RPN has a undocumented dependency to the DAR
register, the 20 msb of MD_EPN and DAR needs to be the same before MD_RPN is written.
Does this make any sense to anyone?
I can prepare a patch if somebody is interested to try it on their 8xx CPU.
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 51+ messages in thread* RE: dcbz works on 862 everywhere! 2003-03-24 10:19 dcbz works on 862 everywhere! Joakim Tjernlund @ 2003-03-24 11:01 ` Joakim Tjernlund 2003-03-24 12:25 ` Joakim Tjernlund 2003-03-24 20:15 ` Tom Rini 2 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 11:01 UTC (permalink / raw) To: joakim.tjernlund, Linuxppc-Embedded@Lists. Linuxppc. Org; +Cc: strauman > Does this make any sense to anyone? > I can prepare a patch if somebody is interested to try it on their 8xx CPU. > > Jocke I forgot: Why is the Guarded flag set in DTLB Miss handler for the pte? Won't performance degrade? Jocke PS. Here is the patch if anyone wants to test. Please report your results. Don't forget to enable dcbz in arch/ppc/kernel/misc.S and arch/ppc/lib/string.S for 8xx. Index: arch/ppc/kernel/head_8xx.S =================================================================== RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/kernel/head_8xx.S,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 head_8xx.S --- arch/ppc/kernel/head_8xx.S 1 Nov 2002 13:44:02 -0000 1.1.1.1 +++ arch/ppc/kernel/head_8xx.S 24 Mar 2003 10:46:22 -0000 @@ -407,6 +407,13 @@ rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */ beq 2f /* If zero, don't try to find a pte */ + /* For some reason the 20 msb of MD_EPN and DAR must be the same when + * MD_RPN is written. The dcxx instructions don't set DAR when they + * cause a DTLB Miss so copy them from MD_EPN. + */ + mfspr r20, MD_EPN + mtspr DAR, r20 + /* We have a pte table, so load fetch the pte from the table. */ tophys(r21, r21) @@ -463,7 +470,18 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from EPN to DAR since the dcxx instuctions fails + * update the DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 + + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-24 10:19 dcbz works on 862 everywhere! Joakim Tjernlund 2003-03-24 11:01 ` Joakim Tjernlund @ 2003-03-24 12:25 ` Joakim Tjernlund 2003-03-24 14:20 ` Joakim Tjernlund 2003-03-24 20:15 ` Tom Rini 2 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 12:25 UTC (permalink / raw) To: Linuxppc-Embedded@Lists. Linuxppc. Org; +Cc: strauman > Hi list > > I have been researching why I can't use dcbz and friends on 8xx CPU. > Till Strauman found out long ago that the dcxx instuctions did not update > the DAR register and that was the key I needed. > > After a lot of testing/reading I found a 2 instruction workaround > that lets me use dcbz in copy_tofrom_user(). > I can also used dcbz in a user space app without problems. I even > removed the TLB change bit hack by Tom Rini and everything works. > > By copying the MD_EPN register to the DAR register in the DTLB Miss handler > just before MD_RPN is written everything just works. The only explanation that > makes sense to me is that the MD_RPN has a undocumented dependency to the DAR > register, the 20 msb of MD_EPN and DAR needs to be the same before MD_RPN is written. hmm, this is not quite correct. I can copy MD_EPN to DAR after the write to MD_RPN and it still works. Seems like DAR must be correct when rfi is executed. I wonder why? Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-24 12:25 ` Joakim Tjernlund @ 2003-03-24 14:20 ` Joakim Tjernlund 2003-03-24 17:09 ` Till Straumann 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 14:20 UTC (permalink / raw) To: Linuxppc-Embedded@Lists. Linuxppc. Org; +Cc: strauman > > Hi list > > > > I have been researching why I can't use dcbz and friends on 8xx CPU. > > Till Strauman found out long ago that the dcxx instuctions did not update > > the DAR register and that was the key I needed. > > > > After a lot of testing/reading I found a 2 instruction workaround > > that lets me use dcbz in copy_tofrom_user(). > > I can also used dcbz in a user space app without problems. I even > > removed the TLB change bit hack by Tom Rini and everything works. > > > > By copying the MD_EPN register to the DAR register in the DTLB Miss handler > > just before MD_RPN is written everything just works. The only explanation that > > makes sense to me is that the MD_RPN has a undocumented dependency to the DAR > > register, the 20 msb of MD_EPN and DAR needs to be the same before MD_RPN is written. > > hmm, this is not quite correct. I can copy MD_EPN to DAR after the write to MD_RPN > and it still works. Seems like DAR must be correct when rfi is executed. I wonder > why? hmm, can it be that when you return from the DTLB Miss, you sometimes get an DTLB error immediately and that DTLB Error "inherits" the DAR from the DTLB Miss? I removed the "copy DAR to MD_EPN" part in the DTLB Error handler and my systems runs fine. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 14:20 ` Joakim Tjernlund @ 2003-03-24 17:09 ` Till Straumann 2003-03-24 17:42 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Till Straumann @ 2003-03-24 17:09 UTC (permalink / raw) To: joakim.tjernlund; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org Joakim Tjernlund wrote: >>>Hi list >>> -- snip -- >>> I even >>>removed the TLB change bit hack by Tom Rini and everything works. >>> -- snip -- > >I removed the "copy DAR to MD_EPN" part in the DTLB Error handler and my systems >runs fine. > How exactly do you know that "everything works fine" ??? Please note that a) you may have bug-free hardware. b) you may have a valid TLB entry at the time 'dcbz' is executed. c) you may end up with a bogus mapping but not notice it. You really should first confirm that your hardware suffers from the bug by running a _simple_ test program in a _simple_ environment (NOT linux). Then, you should confirm that your workaround solution is correct by testing it in the same simple environment. Just because you are able to use 'dcbz' on linux repeatedly without crashing does'nt prove that your hardware is buggy but linux handles it correctly. -- Till PS: please CC me on any replies; I'm not subscribed to this list > > Jocke > ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-24 17:09 ` Till Straumann @ 2003-03-24 17:42 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 17:42 UTC (permalink / raw) To: Till Straumann; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org > Joakim Tjernlund wrote: > > >>>Hi list > >>> > -- snip -- > > >>> I even > >>>removed the TLB change bit hack by Tom Rini and everything works. > >>> > -- snip -- > > > > >I removed the "copy DAR to MD_EPN" part in the DTLB Error handler and my systems > >runs fine. > > > > How exactly do you know that "everything works fine" ??? > > Please note that > > a) you may have bug-free hardware. > b) you may have a valid TLB entry at the time 'dcbz' is executed. > c) you may end up with a bogus mapping but not notice it. Every time I tried to use dcbz on user space it failed HARD directly. Whenever I tried to "undo" any hacks that were there to compensate for buggy dcxx instructions, the kernel would not boot. Now I can boot and run my app and even run a user space app which clears memory with dcbz. I can remove HWWRITE bit setting on kernel space address and remove the copying of DAR to MD_EPN in the DTLB Error handler. I think I am on to something here, don't you? > > You really should first confirm that your hardware suffers from the bug by > running a _simple_ test program in a _simple_ environment (NOT linux). I don't have a simple environment. I have ppcboot on my board which doesn't use the MMU at all. > > Then, you should confirm that your workaround solution is correct by > testing it in the same simple environment. > > Just because you are able to use 'dcbz' on linux repeatedly without > crashing does'nt prove that your hardware is buggy but linux handles > it correctly. Yes, I know that and that's why I write to this list to seek input from others that know more than I do and have a simple test environment(hint, hint :-) > > -- Till > > PS: please CC me on any replies; I'm not subscribed to this list > > > > > Jocke > > Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 10:19 dcbz works on 862 everywhere! Joakim Tjernlund 2003-03-24 11:01 ` Joakim Tjernlund 2003-03-24 12:25 ` Joakim Tjernlund @ 2003-03-24 20:15 ` Tom Rini 2003-03-24 20:57 ` Joakim Tjernlund 2003-03-24 22:44 ` Joakim Tjernlund 2 siblings, 2 replies; 51+ messages in thread From: Tom Rini @ 2003-03-24 20:15 UTC (permalink / raw) To: Joakim Tjernlund; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org, strauman On Mon, Mar 24, 2003 at 11:19:29AM +0100, Joakim Tjernlund wrote: > > Hi list > > I have been researching why I can't use dcbz and friends on 8xx CPU. > Till Strauman found out long ago that the dcxx instuctions did not update > the DAR register and that was the key I needed. > > After a lot of testing/reading I found a 2 instruction workaround > that lets me use dcbz in copy_tofrom_user(). > I can also used dcbz in a user space app without problems. I even > removed the TLB change bit hack by Tom Rini and everything works. > > By copying the MD_EPN register to the DAR register in the DTLB Miss handler > just before MD_RPN is written everything just works. The only explanation that > makes sense to me is that the MD_RPN has a undocumented dependency to the DAR > register, the 20 msb of MD_EPN and DAR needs to be the same before MD_RPN is written. > > Does this make any sense to anyone? > I can prepare a patch if somebody is interested to try it on their 8xx CPU. Can you post a patch which does everything (remove the TLB change bit, etc)? Thanks. -- Tom Rini http://gate.crashing.org/~trini/ ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 20:15 ` Tom Rini @ 2003-03-24 20:57 ` Joakim Tjernlund 2003-03-24 21:07 ` Tom Rini 2003-03-24 21:42 ` Dan Malek 2003-03-24 22:44 ` Joakim Tjernlund 1 sibling, 2 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 20:57 UTC (permalink / raw) To: Tom Rini; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Can you post a patch which does everything (remove the TLB change bit, > etc)? Thanks. Sure, but I don't want to restore the old TLB change bit. I removed it as a test only to see if my system could take it. The kernel will do a lot DTLB errors if it is restored. I will removed the Guarded flag though since I don't see why it's there. Speak up now if you want to have it left. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 20:57 ` Joakim Tjernlund @ 2003-03-24 21:07 ` Tom Rini 2003-03-24 21:54 ` Joakim Tjernlund 2003-03-24 21:42 ` Dan Malek 1 sibling, 1 reply; 51+ messages in thread From: Tom Rini @ 2003-03-24 21:07 UTC (permalink / raw) To: Joakim Tjernlund; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org, strauman On Mon, Mar 24, 2003 at 09:57:43PM +0100, Joakim Tjernlund wrote: > > Can you post a patch which does everything (remove the TLB change bit, > > etc)? Thanks. > > Sure, but I don't want to restore the old TLB change bit. I removed it as a test only to see if > my system could take it. The kernel will do a lot DTLB errors if it is restored. > > I will removed the Guarded flag though since I don't see why it's there. Speak up > now if you want to have it left. Well, if I understand what you think you've got working correctly, what you've got replaces the current workaround for a similar (related?) issue. -- Tom Rini http://gate.crashing.org/~trini/ ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 21:07 ` Tom Rini @ 2003-03-24 21:54 ` Joakim Tjernlund 2003-03-24 22:59 ` Dan Malek 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 21:54 UTC (permalink / raw) To: Tom Rini; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > On Mon, Mar 24, 2003 at 09:57:43PM +0100, Joakim Tjernlund wrote: > > > Can you post a patch which does everything (remove the TLB change bit, > > > etc)? Thanks. > > > > Sure, but I don't want to restore the old TLB change bit. I removed it as a test only to see if > > my system could take it. The kernel will do a lot DTLB errors if it is restored. > > > > I will removed the Guarded flag though since I don't see why it's there. Speak up > > now if you want to have it left. > > Well, if I understand what you think you've got working correctly, what > you've got replaces the current workaround for a similar (related?) > issue. I think it makes the "copy DAR to MD_EPN" part in the DTLB error handler needless. Anyway it works with and without that part. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 21:54 ` Joakim Tjernlund @ 2003-03-24 22:59 ` Dan Malek 2003-03-25 0:33 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-24 22:59 UTC (permalink / raw) To: Joakim Tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman Joakim Tjernlund wrote: > > I think it makes the "copy DAR to MD_EPN" part in the DTLB error handler needless. > Anyway it works with and without that part. No, you need to leave that there as well. Read the comment..... If it appears to "work" for you, what happens is you have a DTLB Error immediately following a DTLB miss (the common case lots of the time), so the MD_EPN just happens to contain the proper information. When you generate the case where a DTLB Error does not match a previous DTLB miss, you will end up tracking down the wrong PTEs. Even in this case it is likely to appear things work correctly, but they do not. There is one case with the dcbi where there is no proper operation of the code, so it was necessary to solve the problem another way. This is exactly why people are telling you to carefully generate test cases the prove an error exists 100% of the time, and that your modifications properly correct the condition 100% of the time. When you run something like Linux you get pathological cases that do not exercise all conditions with a particular configurations, or you could be generating errors that are not precisely tested as failure conditions. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 22:59 ` Dan Malek @ 2003-03-25 0:33 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-25 0:33 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Joakim Tjernlund wrote: > > > > > I think it makes the "copy DAR to MD_EPN" part in the DTLB error handler needless. > > Anyway it works with and without that part. > > No, you need to leave that there as well. Read the comment..... > > If it appears to "work" for you, what happens is you have a DTLB Error > immediately following a DTLB miss (the common case lots of the time), so > the MD_EPN just happens to contain the proper information. When you generate > the case where a DTLB Error does not match a previous DTLB miss, you will > end up tracking down the wrong PTEs. Even in this case it is likely to > appear things work correctly, but they do not. There is one case with the dcbi > where there is no proper operation of the code, so it was necessary to solve > the problem another way. What case is that(when dcbi does not work)? Give me an example so I can test and see what happens, with and without my patch. > This is exactly why people are telling you to carefully generate test cases > the prove an error exists 100% of the time, and that your modifications > properly correct the condition 100% of the time. When you run something > like Linux you get pathological cases that do not exercise all conditions > with a particular configurations, or you could be generating errors that > are not precisely tested as failure conditions. I know all that and thats why post to the list with questions, ideas and patches to try out. If you had read my mails you would had understood that too. Your yelling at me for trying isn't very helpful. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 20:57 ` Joakim Tjernlund 2003-03-24 21:07 ` Tom Rini @ 2003-03-24 21:42 ` Dan Malek 2003-03-24 21:51 ` Joakim Tjernlund 1 sibling, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-24 21:42 UTC (permalink / raw) To: Joakim Tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman Joakim Tjernlund wrote: > I will removed the Guarded flag though since I don't see why it's there. Speak up > now if you want to have it left. Everything is there for a reason, including setting the guarded flag if the PTE indicates this should be done. Since it doesn't seem to be clear from messages I've sent in the past, the guarded flag is used to ensure the proper order of operation on I/O spaces. Any ioremap will request this feature. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 21:42 ` Dan Malek @ 2003-03-24 21:51 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 21:51 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Joakim Tjernlund wrote: > > > I will removed the Guarded flag though since I don't see why it's there. Speak up > > now if you want to have it left. > > Everything is there for a reason, including setting the guarded flag if > the PTE indicates this should be done. Since it doesn't seem to be clear > from messages I've sent in the past, the guarded flag is used to ensure > the proper order of operation on I/O spaces. Any ioremap will request > this feature. I got the impression that the Guarded flag was ALWAYS set. Reading the comment again I think I missunderstood(my assembly is rusty), right? Jocke > -- Dan > ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 20:15 ` Tom Rini 2003-03-24 20:57 ` Joakim Tjernlund @ 2003-03-24 22:44 ` Joakim Tjernlund 2003-03-24 23:09 ` Dan Malek 1 sibling, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 22:44 UTC (permalink / raw) To: Tom Rini; +Cc: Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Can you post a patch which does everything (remove the TLB change bit, > etc)? Thanks. > > -- > Tom Rini OK, here it goes. I had do this blind since I am still on 2.4.20. Let me know if it does not compile. Jocke ===== arch/ppc/kernel/head_8xx.S 1.41 vs edited ===== --- 1.41/arch/ppc/kernel/head_8xx.S Thu Feb 27 20:40:15 2003 +++ edited/arch/ppc/kernel/head_8xx.S Mon Mar 24 23:31:27 2003 @@ -451,6 +451,13 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + /* The 20 msb of MD_EPN and DAR must be the same when rfi is + * executed. The dcxx instructions don't set DAR when they + * cause a DTLB Miss so copy them from MD_EPN. + */ + mfspr r20, MD_EPN + mtspr DAR, r20 + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -460,7 +467,18 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from EPN to DAR since the dcxx instuctions fails + * update the DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 + + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) @@ -504,6 +522,9 @@ andis. r21, r20, 0x0200 /* If set, indicates store op */ beq 2f +#if 0 + /* Maybe this should stay? Time will tell */ + /* The EA of a data TLB miss is automatically stored in the MD_EPN * register. The EA of a data TLB error is automatically stored in * the DAR, but not the MD_EPN register. We must copy the 20 most @@ -531,7 +552,7 @@ lwz r3, 12(r0) #endif mtspr MD_EPN, r21 - +#endif mfspr r20, M_TWB /* Get level 1 table entry address */ /* If we are faulting a kernel address, we have to use the ===== arch/ppc/kernel/misc.S 1.80 vs edited ===== --- 1.80/arch/ppc/kernel/misc.S Thu Mar 6 06:36:05 2003 +++ edited/arch/ppc/kernel/misc.S Mon Mar 24 23:33:53 2003 @@ -664,7 +664,7 @@ _GLOBAL(clear_page) li r0,4096/L1_CACHE_LINE_SIZE mtctr r0 -#ifdef CONFIG_8xx +#ifdef CONFIG_8xx_CPU6 li r4, 0 1: stw r4, 0(r3) stw r4, 4(r3) @@ -698,7 +698,7 @@ addi r4,r4,-4 li r5,4 -#ifndef CONFIG_8xx +#ifndef CONFIG_8xx_CPU6 #if MAX_COPY_PREFETCH > 1 li r0,MAX_COPY_PREFETCH li r11,4 @@ -706,7 +706,7 @@ 11: dcbt r11,r4 addi r11,r11,L1_CACHE_LINE_SIZE bdnz 11b -#else /* MAX_L1_COPY_PREFETCH == 1 */ +#elif !defined(CONFIG_8xx) /* MAX_L1_COPY_PREFETCH == 1 */ dcbt r5,r4 li r11,L1_CACHE_LINE_SIZE+4 #endif /* MAX_L1_COPY_PREFETCH */ @@ -715,8 +715,10 @@ li r0,4096/L1_CACHE_LINE_SIZE mtctr r0 1: +#ifndef CONFIG_8xx_CPU6 #ifndef CONFIG_8xx - dcbt r11,r4 + dcbt r11,r4 /* Makes 8xx slower */ +#endif dcbz r5,r3 #endif COPY_16_BYTES ===== arch/ppc/lib/string.S 1.20 vs edited ===== --- 1.20/arch/ppc/lib/string.S Thu Feb 27 20:40:16 2003 +++ edited/arch/ppc/lib/string.S Mon Mar 24 23:34:20 2003 @@ -151,7 +151,7 @@ bdnz 4b 3: mtctr r9 li r7,4 -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx_CPU6) 10: dcbz r7,r6 #else 10: stw r4, 4(r6) @@ -253,7 +253,7 @@ mtctr r0 beq 63f 53: -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx_CPU6) dcbz r11,r6 #endif COPY_16_BYTES @@ -427,7 +427,7 @@ li r11,4 beq 63f -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx_CPU6) /* Here we decide how far ahead to prefetch the source */ #if MAX_COPY_PREFETCH > 1 /* Heuristically, for large transfers we prefetch @@ -442,7 +442,7 @@ 112: dcbt r3,r4 addi r3,r3,CACHELINE_BYTES bdnz 112b -#else /* MAX_COPY_PREFETCH == 1 */ +#elif !defined(CONFIG_8xx) /* MAX_COPY_PREFETCH == 1 */ li r3,CACHELINE_BYTES + 4 dcbt r11,r4 #endif /* MAX_COPY_PREFETCH */ @@ -450,8 +450,10 @@ mtctr r0 53: +#if !defined(CONFIG_8xx_CPU6) #if !defined(CONFIG_8xx) - dcbt r3,r4 + dcbt r3,r4 /* Makes 8xx slower */ +#endif 54: dcbz r11,r6 #endif /* had to move these to keep extable in order */ @@ -461,7 +463,7 @@ .long 71b,101f .long 72b,102f .long 73b,103f -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx_CPU6) .long 54b,105f #endif .text ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 22:44 ` Joakim Tjernlund @ 2003-03-24 23:09 ` Dan Malek 2003-03-24 23:57 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-24 23:09 UTC (permalink / raw) To: Joakim Tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman Joakim Tjernlund wrote: > OK, here it goes. No, this isn't correct...... > + /* The 20 msb of MD_EPN and DAR must be the same when rfi is > + * executed. The dcxx instructions don't set DAR when they > + * cause a DTLB Miss so copy them from MD_EPN. No, don't be screwing around with these registers. > -#ifdef CONFIG_8xx > +#ifdef CONFIG_8xx_CPU6 What is this all about? The CPU6 errata is a clearly defined problem on well known silicon revisions. Don't be using it where it isn't intended. Please try again..........thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 23:09 ` Dan Malek @ 2003-03-24 23:57 ` Joakim Tjernlund 2003-03-25 0:48 ` Dan Malek 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-24 23:57 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Joakim Tjernlund wrote: > > > OK, here it goes. > > No, this isn't correct...... > > > > + /* The 20 msb of MD_EPN and DAR must be the same when rfi is > > + * executed. The dcxx instructions don't set DAR when they > > + * cause a DTLB Miss so copy them from MD_EPN. > > No, don't be screwing around with these registers. Did you read my mails? This is the key. What harm can it do? This is much less intrusive than the "copy DAR to MD_EPN" part in the TLB Error handler. > > > > > -#ifdef CONFIG_8xx > > +#ifdef CONFIG_8xx_CPU6 > > What is this all about? The CPU6 errata is a clearly defined > problem on well known silicon revisions. Don't be using it where > it isn't intended. OK, I have removed all CONFIG_8xx_CPU6 and CONFIG_8xx I restored the "copy DAR to MD_EPN" in the TLB Error hanler as well. > > Please try again..........thanks. Here it is: ===== arch/ppc/kernel/head_8xx.S 1.41 vs edited ===== --- 1.41/arch/ppc/kernel/head_8xx.S Thu Feb 27 20:40:15 2003 +++ edited/arch/ppc/kernel/head_8xx.S Tue Mar 25 00:43:39 2003 @@ -451,6 +451,13 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + /* The 20 msb of MD_EPN and DAR must be the same when rfi is + * executed. The dcxx instructions don't set DAR when they + * cause a DTLB Miss so copy them from MD_EPN. + */ + mfspr r20, MD_EPN + mtspr DAR, r20 + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -460,7 +467,18 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from EPN to DAR since the dcxx instuctions fails + * update the DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 + + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) ===== arch/ppc/kernel/misc.S 1.80 vs edited ===== --- 1.80/arch/ppc/kernel/misc.S Thu Mar 6 06:36:05 2003 +++ edited/arch/ppc/kernel/misc.S Tue Mar 25 00:41:16 2003 @@ -664,15 +664,7 @@ _GLOBAL(clear_page) li r0,4096/L1_CACHE_LINE_SIZE mtctr r0 -#ifdef CONFIG_8xx - li r4, 0 -1: stw r4, 0(r3) - stw r4, 4(r3) - stw r4, 8(r3) - stw r4, 12(r3) -#else 1: dcbz 0,r3 -#endif addi r3,r3,L1_CACHE_LINE_SIZE bdnz 1b blr @@ -698,7 +690,6 @@ addi r4,r4,-4 li r5,4 -#ifndef CONFIG_8xx #if MAX_COPY_PREFETCH > 1 li r0,MAX_COPY_PREFETCH li r11,4 @@ -706,7 +697,7 @@ 11: dcbt r11,r4 addi r11,r11,L1_CACHE_LINE_SIZE bdnz 11b -#else /* MAX_L1_COPY_PREFETCH == 1 */ +#elif !defined(CONFIG_8xx) /* MAX_L1_COPY_PREFETCH == 1 */ dcbt r5,r4 li r11,L1_CACHE_LINE_SIZE+4 #endif /* MAX_L1_COPY_PREFETCH */ @@ -716,9 +707,10 @@ mtctr r0 1: #ifndef CONFIG_8xx - dcbt r11,r4 - dcbz r5,r3 + dcbt r11,r4 /* Makes 8xx slower */ #endif + dcbz r5,r3 + COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 32 COPY_16_BYTES ===== arch/ppc/lib/string.S 1.20 vs edited ===== --- 1.20/arch/ppc/lib/string.S Thu Feb 27 20:40:16 2003 +++ edited/arch/ppc/lib/string.S Tue Mar 25 00:42:56 2003 @@ -151,14 +151,7 @@ bdnz 4b 3: mtctr r9 li r7,4 -#if !defined(CONFIG_8xx) 10: dcbz r7,r6 -#else -10: stw r4, 4(r6) - stw r4, 8(r6) - stw r4, 12(r6) - stw r4, 16(r6) -#endif addi r6,r6,CACHELINE_BYTES bdnz 10b clrlwi r5,r8,32-LG_CACHELINE_BYTES @@ -253,9 +246,8 @@ mtctr r0 beq 63f 53: -#if !defined(CONFIG_8xx) dcbz r11,r6 -#endif + COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 32 COPY_16_BYTES @@ -427,7 +419,6 @@ li r11,4 beq 63f -#if !defined(CONFIG_8xx) /* Here we decide how far ahead to prefetch the source */ #if MAX_COPY_PREFETCH > 1 /* Heuristically, for large transfers we prefetch @@ -442,7 +433,7 @@ 112: dcbt r3,r4 addi r3,r3,CACHELINE_BYTES bdnz 112b -#else /* MAX_COPY_PREFETCH == 1 */ +#elif !defined(CONFIG_8xx) /* MAX_COPY_PREFETCH == 1 */ li r3,CACHELINE_BYTES + 4 dcbt r11,r4 #endif /* MAX_COPY_PREFETCH */ @@ -451,9 +442,9 @@ mtctr r0 53: #if !defined(CONFIG_8xx) - dcbt r3,r4 -54: dcbz r11,r6 + dcbt r3,r4 /* Makes 8xx slower */ #endif +54: dcbz r11,r6 /* had to move these to keep extable in order */ .section __ex_table,"a" .align 2 @@ -461,9 +452,7 @@ .long 71b,101f .long 72b,102f .long 73b,103f -#if !defined(CONFIG_8xx) .long 54b,105f -#endif .text /* the main body of the cacheline loop */ COPY_16_BYTES_WITHEX(0) ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-24 23:57 ` Joakim Tjernlund @ 2003-03-25 0:48 ` Dan Malek 2003-03-25 1:22 ` Dan Malek 2003-03-25 1:57 ` Joakim Tjernlund 0 siblings, 2 replies; 51+ messages in thread From: Dan Malek @ 2003-03-25 0:48 UTC (permalink / raw) To: Joakim Tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman Joakim Tjernlund wrote: > Did you read my mails? I did. From this I gathered that you don't understand why some of this code is there in the first place, you removed code that would have guaranteed to cause an error if you would have run the proper test, and you can't explain why the changes you made cause the results you see. Not something that instills much confidence. All of these MMU and cache control registers have effects on one another. Writing one register can have the side effect of updating another. The DAR must have valid addresses in order to properly rfi, we know some cache operations may not set this properly, and we also know that in these cases the MD_EPN is also not set properly. The reason it "works" for you is you found the most likely case where you took a DTLB miss, followed by a DTLB Error to the same page (or at least to valid pages). If the miss/error sequence was to the same page, it will likely work correctly. If the miss/error sequence is not to the same pages, it could appear to "work" but chances are the dcbz was not executed properly and you didn't notice the side effects of that. If you happen to find the case where you generate the DTLB miss/error/error with intervening TLB exceptions for other pages (like when swapping) and the instructions involved are cache instructions (like the dcbi in the comment example), you will end up with a big mess. It's really hard to generate all of these test cases, and you can't always use Linux to do so, but eventually Linux will stumble across them. For a long time, we "solved" these problems on 8xx by not properly implementing copy-on-write pages and always marking pages dirty. It reduced the likelyhood of the problem, reduced the MMU overhead, but cost lots more in memory and processing time during forks. This still may not be a bad configuration option for selected applications. Like I said from the beginning, the 100% guaranteed working solution is to not use dcbz/dcbt on the 8xx. Anything else will eventually stumble across the error conditions. If I'm developing a product that uses Linux (or any other OS that will dynamically update the MMU and take DTLB exceptions) I won't take the risk of failure using these instructions. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-25 0:48 ` Dan Malek @ 2003-03-25 1:22 ` Dan Malek 2003-03-25 14:02 ` Joakim Tjernlund 2003-03-25 1:57 ` Joakim Tjernlund 1 sibling, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-25 1:22 UTC (permalink / raw) To: Dan Malek Cc: Joakim Tjernlund, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman After reading this I guess I need to further clarify what happens..... Dan Malek wrote: > ... The reason it "works" for you is you found the > most likely case where you took a DTLB miss, followed by a DTLB Error > to the same page... What happens in these cases (which occurs like almost all of the time), is there is "leftover" information in the control/status registers from previous exceptions that causes the fault processing to take place properly. In some error conditions, the leftover information isn't exactly correct, causing the page fault handler to look up wrong information or the dcbz/dcbt to do their thing on the wrong address. If you are not running a specific test case and precisely testing for the results of the operation, you may not notice this or at some time in the future notice erratic system behavior that is impossible to explain. The "normal" instructions have exactly one well documented failure case, in the case of DTLBError, the MD_EPN sometimes doesn't get the proper status, but we know the DAR does, so we can copy the bits we need from the DAR to the EPN to properly process the fault. The cache instructions have never been normal instructions. In some versions of silicon they won't generate a fault, some will allow cache operations to uncached spaces, some will fault but not provide the proper status in any MMU register. Sometimes they work, it all depends upon the state of the cache line and TLB. The cases most likely to fail are the ones that are the hardest to create. I've spent way too much time working on this on many versions of silicon with the assistance of people from Motorola. It isn't a trivial problem to detect, quantify and document so someone else can repeat the exercise. Through the first four major versions of 860 silicon (and countless minor versions) the wrong behavior I discussed was fixed in the next release, only to have something else unexpected appear. Since I didn't want a career in cache instruction debugging (and I had products to get to market), the solution was to simply not use these instructions. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-25 1:22 ` Dan Malek @ 2003-03-25 14:02 ` Joakim Tjernlund 2003-03-26 2:17 ` Till Straumann 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-25 14:02 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > After reading this I guess I need to further clarify what happens..... > > Dan Malek wrote: > > > ... The reason it "works" for you is you found the > > most likely case where you took a DTLB miss, followed by a DTLB Error > > to the same page... > > What happens in these cases (which occurs like almost all of the time), > is there is "leftover" information in the control/status registers from > previous exceptions that causes the fault processing to take place > properly. In some error conditions, the leftover information isn't > exactly correct, causing the page fault handler to look up wrong > information or the dcbz/dcbt to do their thing on the wrong address. > If you are not running a specific test case and precisely testing > for the results of the operation, you may not notice this or at some > time in the future notice erratic system behavior that is impossible > to explain. The "normal" instructions have exactly one well documented > failure case, in the case of DTLBError, the MD_EPN sometimes doesn't > get the proper status, but we know the DAR does, so we can copy the > bits we need from the DAR to the EPN to properly process the fault. > The cache instructions have never been normal instructions. In some > versions of silicon they won't generate a fault, some will allow cache > operations to uncached spaces, some will fault but not provide the > proper status in any MMU register. Sometimes they work, it all depends > upon the state of the cache line and TLB. The cases most likely to > fail are the ones that are the hardest to create. So maybe there still is silicon bugs which is visible in the DTLB Error handler. Is there a problem with MD_EPN in DTLB Miss context? We do know that the dcxx instructions (including those that are used by xxx_dcache_range functions) does not update the DAR register. You say that the rfi depends on DAR(I would like to know in what way, I can't find any info about that) so should we not try to make sure that DAR contains a valid address by copying the EPN from MD_EPN? I have another idea: If you get a DTLB Error direcly after DTLB Miss for the same page, DAR will NOT be updated(at least in some cases) and you "inherit" the DAR from the preceeding DTLB Miss. I have tried to verify that but I have not been able to construct a test case that will prove this. Any ideas on that one? Either way the patch makes it possible to use dcbz in user space, I can remove the "copy DAR to MD_EPN" part in the DTLB Error handler, restore the Change bit in the pte for kernel space and still have a usable system, wheras doing any one of these modifications without my patch resulted in hard lookups during boot. That suggests to me that the DTLB Miss patch does some good. Can you present a case where will be worse off with the DTLB Miss part of my patch applied? > I've spent way too much time working on this on many versions of > silicon with the assistance of people from Motorola. It isn't a trivial > problem to detect, quantify and document so someone else can repeat > the exercise. Through the first four major versions of 860 silicon > (and countless minor versions) the wrong behavior I discussed was > fixed in the next release, only to have something else unexpected appear. > Since I didn't want a career in cache instruction debugging (and I had > products to get to market), the solution was to simply not use these > instructions. I do understand your position, but please consider that the current impl. may still have bugs or can be improved upon so please don't dismiss any attempt to make the 8xx CPUs perform better under linux. Again, you don't have to enable the use of dcbz(yet :-). The DTLB Miss modification should IMHO go in regardless, unless you find a case were it does not work. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-25 14:02 ` Joakim Tjernlund @ 2003-03-26 2:17 ` Till Straumann 2003-03-26 7:57 ` Joakim Tjernlund 2003-03-26 15:18 ` Dan Malek 0 siblings, 2 replies; 51+ messages in thread From: Till Straumann @ 2003-03-26 2:17 UTC (permalink / raw) To: joakim.tjernlund Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Hi guys. I revitalized my old test environment on a mpc860t (XPC860TZP50B5 / 3J21M to be precise). I found that 'dcbz' (while failing to set DAR) indeed sets MD_EPN correctly. Hence, Jocke's fix (copy EPN[0:19]->DAR) would handle that. My older idea (fixing up MD_EPN and DAR based on the faulting instruction opcode and the involved GPR contents) should work even if we have neither a valid MD_EPN nor DAR. -- Till. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-26 2:17 ` Till Straumann @ 2003-03-26 7:57 ` Joakim Tjernlund 2003-03-26 15:18 ` Dan Malek 1 sibling, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-26 7:57 UTC (permalink / raw) To: Till Straumann Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > Hi guys. Thanks Till, you are the first one who actually tested my fix. > I revitalized my old test environment on a > mpc860t (XPC860TZP50B5 / 3J21M to be precise). hmm, B5 rev is pretty buggy. Good that it works on this silicon as well. > > I found that 'dcbz' (while failing to set DAR) > indeed sets MD_EPN correctly. Hence, Jocke's fix > (copy EPN[0:19]->DAR) would handle that. Did you try any of the other dcxx instructions as well? > My older idea (fixing up MD_EPN and DAR based > on the faulting instruction opcode and the involved > GPR contents) should work even if we have neither > a valid MD_EPN nor DAR. Yes, I tried to do that. I never got past how to convert the virtual address in SRR0 to physical so I could read the instruction and decode it. > > -- Till. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 2:17 ` Till Straumann 2003-03-26 7:57 ` Joakim Tjernlund @ 2003-03-26 15:18 ` Dan Malek 2003-03-26 17:04 ` Joakim Tjernlund ` (2 more replies) 1 sibling, 3 replies; 51+ messages in thread From: Dan Malek @ 2003-03-26 15:18 UTC (permalink / raw) To: Till Straumann Cc: joakim.tjernlund, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Till Straumann wrote: > I found that 'dcbz' (while failing to set DAR) > indeed sets MD_EPN correctly. Hence, Jocke's fix > (copy EPN[0:19]->DAR) would handle that. After sleeping for a couple of days and consuming large amounts of medicine to cure a cold, I think I understand why copying these bits around seems to "fix" problems. It's all related to the sequence of TLB miss/error exceptions that I had been describing all along. The first thing that is going to most likely happen is you will get a TLB miss to load a PTE into the TLB. It will be marked valid but not dirty (not writable). Immediately upon performing the rfi you will get a TLB Error to handle the dirty PTE update. By copying the bits from MD_EPN to the DAR in the miss handler, the Error handler will have at least a 4K boundary aligned DAR and it will execute correctly to update the dirty state. At this point, it will appear to "work" properly (even though it is likely the dcbz didn't execute) because the system will at least keep running (for a while). If you have a situation where you get a TLB Error without a matching TLB miss (very rare, but they can happen as the result of swapping, copy on write, certain other page table updates), then you are hosed. The DAR will contain some information from a previous exception, we will likely end up on a "hung" system continually taking TLB Error exceptions because we can't fix them properly. This is basically what happens without the bit copying "fix". > My older idea (fixing up MD_EPN and DAR based > on the faulting instruction opcode and the involved > GPR contents) should work even if we have neither > a valid MD_EPN nor DAR. All of the TLB exception handlers must have minimal instructions. The ones in Linux are too big already. The very little you would gain from making a dcbz/dcbt work correctly would be lost many, many, many times over in a more complex TLB exception handler. Copying bits from MD_EPN to DAR doesn't set the DAR "correctly", it only gives you the page boundary. This is going to further confuse debuggers or signal handlers if you actually have an addressing bug that is detected by one of these instructions. The only update I would like to see to TLB exception handlers is the removal of code due to streamlining of the page table organization. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-26 15:18 ` Dan Malek @ 2003-03-26 17:04 ` Joakim Tjernlund 2003-03-26 18:52 ` Dan Malek 2003-03-26 18:11 ` Till Straumann 2003-03-26 18:52 ` Till Straumann 2 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-26 17:04 UTC (permalink / raw) To: Dan Malek, Till Straumann Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > Till Straumann wrote: > > > I found that 'dcbz' (while failing to set DAR) > > indeed sets MD_EPN correctly. Hence, Jocke's fix > > (copy EPN[0:19]->DAR) would handle that. > > > After sleeping for a couple of days and consuming large > amounts of medicine to cure a cold, I think I understand > why copying these bits around seems to "fix" problems. Sleeping is also good, I wish I got some more of that too :-) > > It's all related to the sequence of TLB miss/error exceptions > that I had been describing all along. The first thing that > is going to most likely happen is you will get a TLB miss to > load a PTE into the TLB. It will be marked valid but not > dirty (not writable). Immediately upon performing the rfi > you will get a TLB Error to handle the dirty PTE update. > By copying the bits from MD_EPN to the DAR in the miss handler, > the Error handler will have at least a 4K boundary aligned DAR > and it will execute correctly to update the dirty state. Yes, that's the conclusion I came to too. > At this point, it will appear to "work" properly (even though > it is likely the dcbz didn't execute) hmm, why would not dcbz execute properly? Surely the instruction is restarted when the DTLB Miss/Error handler return? > because the system will > at least keep running (for a while). > > If you have a situation where you get a TLB Error without > a matching TLB miss (very rare, but they can happen as the > result of swapping, copy on write, certain other page table > updates), then you are hosed. The DAR will contain some information > from a previous exception, we will likely end up on a "hung" > system continually taking TLB Error exceptions because we > can't fix them properly. This is basically what happens > without the bit copying "fix". In a earlier mail you said the there was a case where the "normal" instructions would not set MD_EPN in the DTLB Error handler and that it was documented. What case is this and where can I find this documentation? What this boils down to is that you don't known what register, DAR or MD_EPN to trust in the DTLB Error handler, right? Maybe Till Straumann's suggestion to set the DAR register to a known "bad" address when leaving an exception. Then test for this bad address in the DTLB error handler to decide what register to trust? Note that the other dcxx instructions(according to Till) does not set DAR either so if a dcbi ever causes a 1) DTLB Miss followed by a DTLB Error 2) DTLB Miss taking the DataAccess path 3) DTLB Error taking the DataAccess path* 4) DTLB Error not the DataAccess path* * = I assume that these does not update DAR either, can anyone confirm this? then you are also hosed. My patch will at least fix 1 and 2. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 17:04 ` Joakim Tjernlund @ 2003-03-26 18:52 ` Dan Malek 2003-03-27 21:49 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-26 18:52 UTC (permalink / raw) To: joakim.tjernlund Cc: Till Straumann, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Joakim Tjernlund wrote: > hmm, why would not dcbz execute properly? Surely the instruction is restarted > when the DTLB Miss/Error handler return? Write a test to verify it. I know there were cases in the past when it didn't work. You would notice it when you expected to have some zero initialized spaces that weren't. > In a earlier mail you said the there was a case where the "normal" instructions > would not set MD_EPN in the DTLB Error handler and that it was documented. > What case is this and where can I find this documentation? Well, it's more of an interpretation of the documentation and discussions with Motorola engineers. > What this boils down to is that you don't known what register, DAR or MD_EPN to > trust in the DTLB Error handler, right? The registers we are discussing belong to two distinct functional areas. The Mx_xxx registers are all part of the mmu functional unit and can serve to be hardware assist to the software TLB management. The DAR, DSISR, SRRx and so on are part of the PowerPC core, set during exceptions and used by fault handlers to determine the course of action for fault repair. The latter function is PowerPC generic, the former is unique to the 8xx implementation. I do not know why DAR is sometimes not set properly during some types cache operation exceptions. In general, cache operation exceptions have been unpredictable in various ways across all of the different silicon revisions. Sometimes a dcbz to uncached space was ignored, sometimes it generated an alignment exception (which is the correct behavior), sometimes it generated tlb error exceptions, for example. In all cases except some cache instructions, the DAR is properly set for tlb error exceptions. It has to be or the system won't function properly, so there isn't any question as to whether we can trust it. For TLB miss exceptions, the Mx_xxx hardware assist registers work properly, as documented, to minimize the number of instructions needed to determine what PTE to load. The TLB miss exception has exactly one function, to as quickly as possible locate the PTE from the table hierarchy and stuff the bits into the MMU. That's it and it should really be implemented in five lines of code. The interpretation of the value of the Mx_xxx registers during TLB Error exceptions has always been under discussion. Sometimes you can read they should work like the TLB miss case, but since we aren't processing a TLB miss exception, perhaps they aren't set. Perhaps when it appears to work it is the result of residual information from a previous TLB miss, other times we know it has been set as the result of the exception. In any case, we know if we copy the bits from the DAR into the MD_EPN, we can then use the hardware assist of these registers to perform the PTE lookup just like the TLB miss function. We optimize the update of the usage and dirty indicators in the PTE right in the TLB Error exception function to more closely emulate "real" PPC processors. This way, we can use the same fault processing functions. If we didn't wish to do this, we could simply call an 8xx specific version of do_fault, in which case it doesn't matter what is in the Mx_xxx registers because we would do a software lookup using DAR. It wouldn't be as efficient and we couldn't use a common PPC function, but we wouldn't have to question the workings of the silicon in this case. So, we can always trust DAR, it's just that MD_EPN is left to your interpretation of the documentation and depends upon the implementation of the functions. > Maybe Till Straumann's suggestion to set the DAR register to a known "bad" address > when leaving an exception. Then test for this bad address in the DTLB error handler > to decide what register to trust? Not necessary. By not "correctly" tracking usage and dirty pages, as we did in the past, it caused us to never generate DTLB Error exceptions unless it was truly an access to a non-recoverable bad address or if the page was swapped out. I would just set 'used' on every instruction page and 'used + dirty' on every data page allocation. A static embedded system would just converge on this point anyway, but in more dynamic systems it cost more real memory. Of course, the 8xx has custom cache management/control functions that have always seemed to work properly. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 18:52 ` Dan Malek @ 2003-03-27 21:49 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-27 21:49 UTC (permalink / raw) To: Dan Malek Cc: Till Straumann, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > > hmm, why would not dcbz execute properly? Surely the instruction is restarted > > when the DTLB Miss/Error handler return? > > Write a test to verify it. I know there were cases in the past when > it didn't work. You would notice it when you expected to have some > zero initialized spaces that weren't. I think Till's superb analysis show that this is not a problem. > > > In a earlier mail you said the there was a case where the "normal" instructions > > would not set MD_EPN in the DTLB Error handler and that it was documented. > > What case is this and where can I find this documentation? > > Well, it's more of an interpretation of the documentation and discussions > with Motorola engineers. So this case is mere speculation and has never been proven? [SNIP] > For TLB miss exceptions, the Mx_xxx hardware assist registers work > properly, as documented, to minimize the number of instructions needed > to determine what PTE to load. The TLB miss exception has exactly > one function, to as quickly as possible locate the PTE from the table > hierarchy and stuff the bits into the MMU. That's it and it should > really be implemented in five lines of code. Five lines of code, that I would like to see :-) Seriously, why do the DTLB handlers have two tables, one for kernel space and one for the rest? Can the DataAccess path be removed in the DTLB Miss handler? [SNIP] > > Maybe Till Straumann's suggestion to set the DAR register to a known "bad" address > > when leaving an exception. Then test for this bad address in the DTLB error handler > > to decide what register to trust? > > Not necessary. > > By not "correctly" tracking usage and dirty pages, as we did in the past, > it caused us to never generate DTLB Error exceptions unless it was truly > an access to a non-recoverable bad address or if the page was swapped out. > I would just set 'used' on every instruction page and 'used + dirty' on > every data page allocation. A static embedded system would just converge on > this point anyway, but in more dynamic systems it cost more real memory. hmm, don't you loose copy-on-write by doing so? Would the suggested instruction decoding in the DLTB Error handler be too ugly for your liking? Since dcbi also causes DTLB Errors with undefined values in DAR and MD_EPN it might be a good idea. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 15:18 ` Dan Malek 2003-03-26 17:04 ` Joakim Tjernlund @ 2003-03-26 18:11 ` Till Straumann 2003-03-26 19:06 ` Dan Malek 2003-03-26 18:52 ` Till Straumann 2 siblings, 1 reply; 51+ messages in thread From: Till Straumann @ 2003-03-26 18:11 UTC (permalink / raw) To: Dan Malek Cc: joakim.tjernlund, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Dan Malek wrote: > Till Straumann wrote: > >> I found that 'dcbz' (while failing to set DAR) >> indeed sets MD_EPN correctly. Hence, Jocke's fix >> (copy EPN[0:19]->DAR) would handle that. > > > > After sleeping for a couple of days and consuming large > amounts of medicine to cure a cold, I think I understand > why copying these bits around seems to "fix" problems. > > It's all related to the sequence of TLB miss/error exceptions > that I had been describing all along. The first thing that > is going to most likely happen is you will get a TLB miss to > load a PTE into the TLB. It will be marked valid but not > dirty (not writable). Immediately upon performing the rfi > you will get a TLB Error to handle the dirty PTE update. > By copying the bits from MD_EPN to the DAR in the miss handler, > the Error handler will have at least a 4K boundary aligned DAR > and it will execute correctly to update the dirty state. At > this point, it will appear to "work" properly (even though > it is likely the dcbz didn't execute) because the system will > at least keep running (for a while). I'm not sure whether to agree with this analysis. I thought you said that TLB Error correctly set DAR? Hence you would get - TLB Miss, copy EPN to DAR (DAR is semi-correct, i.e. to a page boundary). - RFI, dcbz is restarted --- here, task switching could occur --- - TLB Error because the page was not writable (but, according to your earlier mail, DAR should be correct now). - copy DAR-> EPN, lookup PTE, replace TLB - RFI, dcbz is restarted and eventually executed. Under the premise that TLB Miss always sets EPN correctly and TLB Error always sets DAR correctly, this should work even if a task switch (or IRQ) sneaks in. > > If you have a situation where you get a TLB Error without > a matching TLB miss (very rare, but they can happen as the > result of swapping, copy on write, certain other page table > updates), then you are hosed. Again: I thought you said that TLB Error _does_ set DAR? > The DAR will contain some information > from a previous exception, we will likely end up on a "hung" > system continually taking TLB Error exceptions because we > can't fix them properly. This is basically what happens > without the bit copying "fix". > > >> My older idea (fixing up MD_EPN and DAR based >> on the faulting instruction opcode and the involved >> GPR contents) should work even if we have neither >> a valid MD_EPN nor DAR. > > > All of the TLB exception handlers must have minimal instructions. > The ones in Linux are too big already. The very little you would > gain from making a dcbz/dcbt work correctly would be lost many, > many, many times over in a more complex TLB exception handler. From a performance standpoint, perhaps (although I believe that working around the problem is more of a 'size' than execution path length increase). But you gain the huge advantage that you don't have to carefully screen any software you intend to port for cache instructions. > > Copying bits from MD_EPN to DAR doesn't set the DAR "correctly", > it only gives you the page boundary. This is going to further > confuse debuggers or signal handlers if you actually have an > addressing bug that is detected by one of these instructions. The 'fixup' workaround would provide a correct DAR, however. -- Till > > > The only update I would like to see to TLB exception handlers is > the removal of code due to streamlining of the page table organization. > > Thanks. > > > -- Dan > ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 18:11 ` Till Straumann @ 2003-03-26 19:06 ` Dan Malek 2003-03-26 22:42 ` mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions Till Straumann ` (2 more replies) 0 siblings, 3 replies; 51+ messages in thread From: Dan Malek @ 2003-03-26 19:06 UTC (permalink / raw) To: Till Straumann Cc: joakim.tjernlund, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Till Straumann wrote: > - TLB Miss, copy EPN to DAR (DAR is semi-correct, i.e. to > a page boundary). > - RFI, dcbz is restarted The EPN has never been copied to DAR. Some bits of DAR are copied to EPN so we can use the hardware assist in the TLB Error exception. > > --- here, task switching could occur --- No, it can't because the TLB Miss rfi is likely to immediately result in a TLB Error. The TLB Miss doesn't return through a path that causes a context switch. > Under the premise that TLB Miss always sets EPN correctly > and TLB Error always sets DAR correctly, this should work > even if a task switch (or IRQ) sneaks in. The current implementation relies on TLB Miss always setting EPN (and other hardware assist registers) correctly, and TLB Error relies on DAR being set correctly. Everything works fine until you get a TLB Error on a dcbz/dcbt that doesn't properly update DAR. In this case EPN isn't set correctly either. > Again: I thought you said that TLB Error _does_ set DAR? It does, except in the case of some cache instruction exceptions. > ... But you gain the huge advantage that you don't > have to carefully screen any software you intend to port for cache > instructions. The instructions that don't work properly are dcbz/dcbt. We have corrected this in the kernel and all GNU libraries long ago. There are other reasons to need a unique 8xx (and 4xx) set of libraries other than the use of these cache instructions. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-03-26 19:06 ` Dan Malek @ 2003-03-26 22:42 ` Till Straumann 2003-03-27 1:25 ` Till Straumann 2003-04-01 9:37 ` dcbz works on 862 everywhere! Joakim Tjernlund 2 siblings, 0 replies; 51+ messages in thread From: Till Straumann @ 2003-03-26 22:42 UTC (permalink / raw) To: Dan Malek, joakim.tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Here are the results of some tests I ran on my mpc860t (XPC860TZP50B5 / 3J21M). I use mpc8bug on a FADS board to load motorola's 'init860.S' example. The example was slightly modified to include (1-4 use differend EAs, of course). 1) a 1:1 TLB to DRAM, R/W access (already present in the vanilla code) 2) a TLB to map DRAM r/w, caching inhibited 3) a TLB to map DRAM r/o (behavior is the same if for a 'real RO' mapping and for a RW mapping with the 'CHANGE' bit cleared). 4) a TLB to map DRAM r/w but with the VALID bit clear. 5) a 'main' routine which executes the instructions under test through one of the aforementioned TLB mappings. Here's what I found (I generally load bogus values into MD_EPN/DAR prior to executing any of the cache instructions under test) A) All of dcbf, dcbi, dcbst, dcbz (dcbt and dcbtst should not and do not) raise a TLBMiss exception with MD_EPN set correctly but failing to set DAR (i.e. DAR is left unmodified) when trying to access an address not in any of the TLBs. B) All of dcbf, dcbi, dcbst, dcbz raise a TLBError exception when accessing mapping 4) [as they should]. Unlike regular loads/stores (non-cache instructions), DAR is NOT SET, however (i.e. left unmodified). MD_EPN is set to 0x00000000 which does NOT point to the faulting EA. C) dcbi and dcbz behave like B) when accessing through 3) [RO mapping]. Note that dcbf and dcbst are treated like 'loads' and hence do not raise a TLBError due to protection violation (in accordance with the docs). D) dcbz through a cache inhibited mapping (2)) does not generate an alignment exception but transparently clears the memory (either is allowed according to the PPC specs). Note: dcbt/dcbtst were included in all of the tests but they never raise an exception which is the correct behavior. CONCLUSION: - the only correct workaround for TLBError is the one I suggested earlier: TLBError handler has to inspect the faulting opcode and fixup DAR and MD_EPN based on the GPR values if the faulting instruction is any of dcbf, dcbi, dcbst or dcbz. Performance of this solution could be improved (eliminate opcode-check in the vast majority of the cases) by storing a 'tag' value in DAR. - the aforementioned workaround also could handle TLBMiss - although performance is more of an issue there. Alternatives are a) Jocke's workaround: copy MD_EPN -> DAR (disadvantage: DAR truncated to page boundary). b) like a) but do this only if the faulting instruction is any dcbxx (disadvantage: performance loss). c) merge significant bits of MD_EPN into DAR. Thus, only cache instructions suffer from an incorrect page offset in DAR. At the same time, it's cheap. Based on the analysis, I'd suggest to implement the 'fixup' workaround for TLBError and alternative c) for TLBMiss -- Till PS. due to unclear re-distribution terms of init860.S, I refrain from appending it to this message. Send me email for details about the test software. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-03-26 19:06 ` Dan Malek 2003-03-26 22:42 ` mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions Till Straumann @ 2003-03-27 1:25 ` Till Straumann 2003-03-27 14:01 ` Joakim Tjernlund 2003-04-03 12:50 ` Joakim Tjernlund 2003-04-01 9:37 ` dcbz works on 862 everywhere! Joakim Tjernlund 2 siblings, 2 replies; 51+ messages in thread From: Till Straumann @ 2003-03-27 1:25 UTC (permalink / raw) To: Dan Malek, joakim.tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org My earlier message was not completely correct. The TLBError exception raised by any of the cache instructions (dcbf, dcbst, dcbi, dcbz) does actually leave the EPN bits in MD_EPN unmodified, clears the reserved bits and sets CASID. Here are the (corrected) results of some tests I ran on my mpc860t (XPC860TZP50B5 / 3J21M). I use mpc8bug on a FADS board to load motorola's 'init860.S' example. The example was slightly modified to include (1-4 use differend EAs, of course). 1) a 1:1 TLB to DRAM, R/W access (already present in the vanilla code) 2) a TLB to map DRAM r/w, caching inhibited 3) a TLB to map DRAM r/o (behavior is the same if for a 'real RO' mapping and for a RW mapping with the 'CHANGE' bit cleared). 4) a TLB to map DRAM r/w but with the VALID bit clear. 5) a 'main' routine which executes the instructions under test through one of the aforementioned TLB mappings. Here's what I found (I generally load bogus values into MD_EPN/DAR prior to executing any of the cache instructions under test) A) All of dcbf, dcbi, dcbst, dcbz (dcbt and dcbtst should not and do not) raise a TLBMiss exception with MD_EPN set correctly but failing to set DAR (i.e. DAR is left unmodified) when trying to access an address not in any of the TLBs. B) All of dcbf, dcbi, dcbst, dcbz raise a TLBError exception when accessing mapping 4) [as they should]. Unlike regular loads/stores (non-cache instructions), NEITHER DAR not MD_EPN are set, however. DAR is left unmodified MD_EPN has the CASID and reserved bits set/reset but leaves the EPN bits unmodified. C) dcbi and dcbz behave like B) when accessing through 3) [RO mapping]. Note that dcbf and dcbst are treated like 'loads' and hence do not raise a TLBError due to protection violation (in accordance with the docs). D) dcbz through a cache inhibited mapping (2)) does not generate an alignment exception but transparently clears the memory (either is allowed according to the PPC specs). Note: dcbt/dcbtst were included in all of the tests but they never raise an exception which is the correct behavior. CONCLUSION: - the only correct workaround for TLBError is the one I suggested earlier: TLBError handler has to inspect the faulting opcode and fixup DAR and MD_EPN based on the GPR values if the faulting instruction is any of dcbf, dcbi, dcbst or dcbz. Performance of this solution could be improved (eliminate opcode-check in the vast majority of the cases) by storing a 'tag' value in DAR. - the aforementioned workaround also could handle TLBMiss - although performance is more of an issue there. Alternatives are a) Jocke's workaround: copy MD_EPN -> DAR (disadvantage: DAR truncated to page boundary). b) like a) but do this only if the faulting instruction is any dcbxx (disadvantage: performance loss). c) merge significant bits of MD_EPN into DAR. Thus, only cache instructions suffer from an incorrect page offset in DAR. At the same time, it's cheap. Based on the analysis, I'd suggest to implement the 'fixup' workaround for TLBError and alternative c) for TLBMiss -- Till PS. due to unclear re-distribution terms of init860.S, I refrain from appending it to this message. Send me email for details about the test software. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-03-27 1:25 ` Till Straumann @ 2003-03-27 14:01 ` Joakim Tjernlund 2003-04-03 12:50 ` Joakim Tjernlund 1 sibling, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-27 14:01 UTC (permalink / raw) To: Till Straumann, Dan Malek Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Great job Till! I have forwarded this to Motorola. Primarly I want to know if never silicon behaves the same way. > Here are the (corrected) results of some tests I ran > on my mpc860t (XPC860TZP50B5 / 3J21M). > > I use mpc8bug on a FADS board to load motorola's > 'init860.S' example. The example was slightly > modified to include (1-4 use differend EAs, of > course). > > 1) a 1:1 TLB to DRAM, R/W access (already present > in the vanilla code) > > 2) a TLB to map DRAM r/w, caching inhibited > > 3) a TLB to map DRAM r/o (behavior is the same > if for a 'real RO' mapping and for a RW > mapping with the 'CHANGE' bit cleared). > > 4) a TLB to map DRAM r/w but with the VALID > bit clear. Level1 or Level2 valid bit? Does it matter which one? > > 5) a 'main' routine which executes the > instructions under test through one > of the aforementioned TLB mappings. hmm, I wonder if the Guarded bit would change anything. > > Here's what I found (I generally load bogus > values into MD_EPN/DAR prior to executing any > of the cache instructions under test) > > A) All of dcbf, dcbi, dcbst, dcbz (dcbt and dcbtst > should not and do not) raise a TLBMiss exception > with MD_EPN set correctly but failing to set DAR > (i.e. DAR is left unmodified) when trying to > access an address not in any of the TLBs. > > B) All of dcbf, dcbi, dcbst, dcbz raise a TLBError > exception when accessing mapping 4) [as they should]. > > Unlike regular loads/stores (non-cache instructions), > NEITHER DAR not MD_EPN are set, however. DAR is left > unmodified MD_EPN has the CASID and reserved bits set/reset > but leaves the EPN bits unmodified. > > C) dcbi and dcbz behave like B) when accessing > through 3) [RO mapping]. Note that dcbf and > dcbst are treated like 'loads' and hence do > not raise a TLBError due to protection violation > (in accordance with the docs). > > D) dcbz through a cache inhibited mapping (2)) does > not generate an alignment exception but > transparently clears the memory (either is allowed > according to the PPC specs). > > Note: dcbt/dcbtst were included in all of the > tests but they never raise an exception which is > the correct behavior. > > CONCLUSION: > > - the only correct workaround for TLBError > is the one I suggested earlier: TLBError > handler has to inspect the faulting opcode > and fixup DAR and MD_EPN based on the GPR > values if the faulting instruction is any > of dcbf, dcbi, dcbst or dcbz. > Performance of this solution could be > improved (eliminate opcode-check in the > vast majority of the cases) by storing > a 'tag' value in DAR. Yes, but I can't even figure out how to read the instruction. Address translation is off so how do I figure out the real address? hmm, what does mfspr r20, M_TWB return when MD_EPN contain old EPN? The old EPN in MD_EPN or does M_TWB know real address that generated the fault? > > - the aforementioned workaround also could handle > TLBMiss - although performance is more of an issue > there. > Alternatives are > a) Jocke's workaround: copy MD_EPN -> DAR > (disadvantage: DAR truncated to page > boundary). > b) like a) but do this only if the faulting > instruction is any dcbxx (disadvantage: > performance loss). > c) merge significant bits of MD_EPN into > DAR. Thus, only cache instructions suffer > from an incorrect page offset in DAR. > At the same time, it's cheap. > > Based on the analysis, I'd suggest to implement > the 'fixup' workaround for TLBError and alternative > c) for TLBMiss The TLB Miss workaround only needs to be in the slow path(DataAccess path) and yes, it should be alternative c). ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-03-27 1:25 ` Till Straumann 2003-03-27 14:01 ` Joakim Tjernlund @ 2003-04-03 12:50 ` Joakim Tjernlund 2003-04-08 10:47 ` Joakim Tjernlund 1 sibling, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-03 12:50 UTC (permalink / raw) To: Till Straumann, Dan Malek Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > CONCLUSION: > > - the only correct workaround for TLBError > is the one I suggested earlier: TLBError > handler has to inspect the faulting opcode > and fixup DAR and MD_EPN based on the GPR > values if the faulting instruction is any > of dcbf, dcbi, dcbst or dcbz. > Performance of this solution could be > improved (eliminate opcode-check in the > vast majority of the cases) by storing > a 'tag' value in DAR. Hi again I have been hacking on dcxx address decoder. Since assembler isn't my cup of tea, I used C mixed with asm statements. The resulting assembler isn't too bad either IMHO. To load the instruction into r21 I used: mfspr r20,SRR0 andis. r21, r20, 0x8000 beq 56f tophys(r21, r20) lwz r21,0(r21) 56: This only works for kernel space addresses. I can't figure out how to get to user space as well. I can live without user space anyway. I am still thinking about the 'tag'. Since MD_EPN isn't set as well as DAR I thinking about storing a tag in MD_EPN instead. It's less intrusive. Maybe it is enough to look at the valid bit in MD_EPN? What do you think so far? Oh, this should go into the DTLB Error handler. Jocke ======================= dcxx address decoder ========================= #define RA(inst) (((inst) & 0x001F0000) >> 16) #define RA_MASK 0x001F0000 #define RB(inst) (((inst) & 0x0000F800) >> 11) #define RB_MASK 0x0000F800 /* Compile with ppc_8xx-gcc -S -O2 -mregnames dcbz.c -fcall-used-r20 -fcall-used-r21 * to see the resulting assembler */ /* Assumes dcxx instruction in reg 21 when called */ decode_dcxx_and_sum(void) { register unsigned long r21 asm("r21"); /* make it live in reg 21 */ register unsigned long r20 asm("r20"); /* make it live in reg 20 */ asm("mfctr %0\n\t" "stw %0, 16(0)":: "r" (r20)); /* save ctr reg on stack */ r20 = RB(r21) * 8; /* offset into jump table for reg RB */ asm("addi %0, %0, 100f@l":: "r" (r20)); /* add start of table */ asm("mtctr %0":: "r" (r20)); /* load ctr with jump address */ r20 = 0; /* sum starts at zero */ asm("bctr"::); /* jump into table */ /* Below is the jump table. */ asm("100:\n\t" "add %0, %0, 0\n\t" "b 99f\n\t" "add %0, %0, 1\n\t" "b 99f\n\t" "add %0, %0, 2\n\t" "b 99f\n\t" "add %0, %0, 3\n\t" "b 99f\n\t" "add %0, %0, 4\n\t" "b 99f\n\t" "add %0, %0, 5\n\t" "b 99f\n\t" "add %0, %0, 6\n\t" "b 99f\n\t" "add %0, %0, 7\n\t" "b 99f\n\t" "add %0, %0, 8\n\t" "b 99f\n\t" "add %0, %0, 9\n\t" "b 99f\n\t" "add %0, %0, 10\n\t" "b 99f\n\t" "add %0, %0, 11\n\t" "b 99f\n\t" "add %0, %0, 12\n\t" "b 99f\n\t" "99:\n\t" : : "r" (r20)); r21 = RA(r21) * 8; /* offset into jump table for reg RA */ if(r21){ /* if reg zero, don't add it */ asm("addi %0, %0, 100b@l":: "r" (r21)); /* add start of table */ asm("mtctr %0":: "r" (r21)); /* load ctr with jump address */ r21 &= ~RA_MASK; /* make sure we don't execute this mre than once */ asm("bctr":: "r" (r21)); /* jump into table */ } asm("mtdar %0": : "r" (r20)); /* save sum to DAR */ asm("lwz %0, 16(0)\n\t" "mtctr %0" :: "r" (r21)); /* restore ctr reg from stack */ } This is the resulting assembler: .file "dcbz.c" gcc2_compiled.: .section ".text" .align 2 .globl decode_dcxx_and_sum .type decode_dcxx_and_sum,@function decode_dcxx_and_sum: mfctr %r20 stw %r20, 16(0) rlwinm %r20,%r21,24,24,28 addi %r20, %r20, 100f@l mtctr %r20 li %r20,0 bctr 100: add %r20, %r20, 0 b 99f add %r20, %r20, 1 b 99f add %r20, %r20, 2 b 99f add %r20, %r20, 3 b 99f add %r20, %r20, 4 b 99f add %r20, %r20, 5 b 99f add %r20, %r20, 6 b 99f add %r20, %r20, 7 b 99f add %r20, %r20, 8 b 99f add %r20, %r20, 9 b 99f add %r20, %r20, 10 b 99f add %r20, %r20, 11 b 99f add %r20, %r20, 12 b 99f 99: rlwinm. %r21,%r21,19,24,28 bc 12,2,.L3 addi %r21, %r21, 100b@l mtctr %r21 rlwinm %r21,%r21,0,16,10 bctr .L3: mtdar %r20 lwz %r21, 16(0) mtctr %r21 blr .Lfe1: .size decode_dcxx_and_sum,.Lfe1-decode_dcxx_and_sum .ident "GCC: (GNU) 2.95.3 20010315 (release/MontaVista)" ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-03 12:50 ` Joakim Tjernlund @ 2003-04-08 10:47 ` Joakim Tjernlund 2003-04-08 16:25 ` Till Straumann ` (2 more replies) 0 siblings, 3 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-08 10:47 UTC (permalink / raw) To: Till Straumann, Dan Malek Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > > CONCLUSION: > > > > - the only correct workaround for TLBError > > is the one I suggested earlier: TLBError > > handler has to inspect the faulting opcode > > and fixup DAR and MD_EPN based on the GPR > > values if the faulting instruction is any > > of dcbf, dcbi, dcbst or dcbz. > > Performance of this solution could be > > improved (eliminate opcode-check in the > > vast majority of the cases) by storing > > a 'tag' value in DAR. > > Hi again > > I have been hacking on dcxx address decoder. Since assembler isn't my cup of tea, > I used C mixed with asm statements. The resulting assembler isn't too bad either IMHO. > > To load the instruction into r21 I used: > mfspr r20,SRR0 > andis. r21, r20, 0x8000 > beq 56f > > tophys(r21, r20) > lwz r21,0(r21) > 56: > This only works for kernel space addresses. I can't figure out how to get to user space as well. > I can live without user space anyway. > > I am still thinking about the 'tag'. Since MD_EPN isn't set as well as DAR I thinking about > storing a tag in MD_EPN instead. It's less intrusive. Maybe it is enough to look at the > valid bit in MD_EPN? > > What do you think so far? > Oh, this should go into the DTLB Error handler. Me again :-) I have completed and tested my workaround for the dcbx instructions. The workaround handles ALL dcbx instructions, ANY register combination and works both on kernel space and user space addresses. During my testing I noticed that memory allocated with consistent_alloc() or kmalloc() causes TLB Errors while vmalloc does not. If this is true(confirmation wanted) it means that the current impl. is fragile. Both dcbi and dcbz does not update DAR when a TLB error happens, instead the the previous setting of DAR is used. I also did some benchmarking using copy_page(dcbz enabled) and memcpy to memory allocated with kmalloc and/or vmalloc. copy_page is about 30% faster than memcpy even with the workaround applied. There is one concern left. I tag DAR with a "bad address" just before an exception is finished. In the TLB Error handler, check if DAR contains the "bad address" and if it does then the workaround is executed. I need find all exceptions where DAR is modified. Currently I tag DAR in STD_EXCEPTON(), DataAccess, Alignment, DataStore and DataTLBError. Have I missed any exception? I also need to find a good value for the "bad address". Currently I use 0xdead0000 and that's probably not the best value. Tagging with this value is a two instruction operation: lis r20, 0xdead mtspr DAR, r20 The test in the TLB Error handler look like this: mfspr r21, DAR lis r20, 0xdead cmpw cr0, r20, r21 beq- <workaround address> I can not see any reason NOT to add this to the BK tree(after some minor modifications mentioned above and a little cleanup). It fixes a real problem with dcbi and as a bonus you can use dcbz as well since it has the same problem that dcbi has and the fix is generic for all dcbx instructions. Dan's argument, "It's interesting to watch these hacks, but I can't justify complicating a general purpose function with more bus cycles by emulating a functional problem. By not using these instructions we have a working system that costs just a few more cycles during the memory copy/zero operations. If we had _working_ dcbz instructions, it would be a gain to use them, but from a system perspective it is going to cost more to "fix up" these than the code that already exists", is not valid. This is not only about optimization, but also about correctness of existing use of dcbi. Patch against 2.4.20 devel available on request until I have cleaned it up a little. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 10:47 ` Joakim Tjernlund @ 2003-04-08 16:25 ` Till Straumann 2003-04-08 16:42 ` Joakim Tjernlund ` (2 more replies) 2003-04-08 17:25 ` Joakim Tjernlund 2003-05-09 12:37 ` Joakim Tjernlund 2 siblings, 3 replies; 51+ messages in thread From: Till Straumann @ 2003-04-08 16:25 UTC (permalink / raw) To: joakim.tjernlund Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Joakim Tjernlund wrote: Why not tag MD_EPN with an unused CASID? -- Till ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 16:25 ` Till Straumann @ 2003-04-08 16:42 ` Joakim Tjernlund 2003-04-08 16:52 ` Joakim Tjernlund 2003-04-08 21:01 ` Dan Malek 2 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-08 16:42 UTC (permalink / raw) To: Till Straumann Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > Joakim Tjernlund wrote: > > Why not tag MD_EPN with an unused CASID? That won't work, will it? Your test report said that the CASID bits were set/reset by dcbi and dcbz? Did I missunderstand something? Also, the tagging procedure will require more than 2 instructions, I think. I tried to use the VALID bit in MD_EPN, but that does not work. One thing I noticed is that I can remove M_CASID and M_EVALID copy in the DTLB Error handler without any visible problems. Why are they needed? Jocke > > -- Till ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 16:25 ` Till Straumann 2003-04-08 16:42 ` Joakim Tjernlund @ 2003-04-08 16:52 ` Joakim Tjernlund 2003-04-08 21:01 ` Dan Malek 2 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-08 16:52 UTC (permalink / raw) To: Till Straumann Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Hi again I am wonder if it is possible to reduce the number of instructions in: mfspr r20, DAR lis r21, 0xdead cmpw cr0, r20, r21 beq- 100f Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 16:25 ` Till Straumann 2003-04-08 16:42 ` Joakim Tjernlund 2003-04-08 16:52 ` Joakim Tjernlund @ 2003-04-08 21:01 ` Dan Malek 2 siblings, 0 replies; 51+ messages in thread From: Dan Malek @ 2003-04-08 21:01 UTC (permalink / raw) To: Till Straumann Cc: joakim.tjernlund, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Till Straumann wrote: > Why not tag MD_EPN with an unused CASID? There isn't such a thing. The ASIDs are used for MMU optimizations. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 10:47 ` Joakim Tjernlund 2003-04-08 16:25 ` Till Straumann @ 2003-04-08 17:25 ` Joakim Tjernlund 2003-04-08 18:14 ` Tom Rini 2003-05-09 12:37 ` Joakim Tjernlund 2 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-08 17:25 UTC (permalink / raw) To: Till Straumann, Dan Malek Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > > Patch against 2.4.20 devel available on request until I have cleaned it up a little. > > Jocke Here is the patch, against 2.4.20 devel but I think it will apply against BK HEAD. Comments welcome :-) Jocke Index: arch/ppc/kernel/head_8xx.S =================================================================== RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/kernel/head_8xx.S,v retrieving revision 1.1 diff -u -r1.1 head_8xx.S --- arch/ppc/kernel/head_8xx.S 1 Nov 2002 13:44:02 -0000 1.1 +++ arch/ppc/kernel/head_8xx.S 8 Apr 2003 17:21:08 -0000 @@ -34,6 +34,24 @@ #include <asm/ppc_asm.h> #include "ppc_defs.h" +/* These macros are used to tag DAR with a known value so that the + * DataTLBError can recognize a buggy dcbx instruction and workaround + * the problem. + */ +#define TAG_VAL 0xdead +#define TAG_DAR_R20 \ + lis r20, TAG_VAL;\ + mtspr DAR, r20; + +/* Macro to make the code more readable. */ +#ifdef CONFIG_8xx_CPU6 + #define DO_8xx_CPU6(val, reg) \ + li reg, val; \ + stw reg, 12(r0); \ + lwz reg, 12(r0); +#else + #define DO_8xx_CPU6(val, reg) +#endif .text .globl _stext _stext: @@ -163,6 +181,7 @@ . = n; \ label: \ EXCEPTION_PROLOG; \ + TAG_DAR_R20; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(hdlr) @@ -185,6 +204,7 @@ mr r5,r20 mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -223,6 +243,7 @@ EXCEPTION_PROLOG mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 mfspr r5,DSISR stw r5,_DSISR(r21) addi r3,r1,STACK_FRAME_OVERHEAD @@ -454,6 +475,7 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + TAG_DAR_R20 mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -463,7 +485,17 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fails + * to update DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) @@ -501,10 +533,18 @@ stw r20, 0(r0) stw r21, 4(r0) + /* If DAR contains TAG_VAL implies a buggy dcbx instruction + * than did not set DAR. + */ + mfspr r20, DAR + lis r21, TAG_VAL + cmpw cr0, r20, r21 + beq- 100f /* Branch if TAG_VAL to dcbx workaround procedure */ +101: /* return from dcbx instruction bug workaround, r20 holds value of DAR */ /* First, make sure this was a store operation. */ - mfspr r20, DSISR - andis. r21, r20, 0x0200 /* If set, indicates store op */ + mfspr r21, DSISR + andis. r21, r21, 0x0200 /* If set, indicates store op */ beq 2f /* The EA of a data TLB miss is automatically stored in the MD_EPN @@ -523,7 +563,7 @@ * are initialized in mapin_ram(). This will avoid the problem, * assuming we only use the dcbi instruction on kernel addresses. */ - mfspr r20, DAR + /* DAR is in r20 already */ rlwinm r21, r20, 0, 0, 19 ori r21, r21, MD_EVALID mfspr r20, M_CASID @@ -588,6 +628,7 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + TAG_DAR_R20 mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -624,6 +665,146 @@ STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) . = 0x2000 +/* This is the workaround procedure to calculate the data EA for a buggy dcbx instruction + * by decoding the registers used by the dcbx instruction and adding them. + * DAR is set to the calculated address and r20 also holds the EA on exit. + */ +139:/* fetch instruction from userspace memory */ + DO_8xx_CPU6(0x3780, r3) + mtspr MD_EPN, r20 /* Have to use MD_EPN for walk, MI_EPN can't */ + mfspr r21, M_TWB /* Get level 1 table entry address */ + lwz r21, 0(r21) /* Get the level 1 entry */ + tophys (r21, r21) + DO_8xx_CPU6(0x3b80, r3) + mtspr MD_TWC, r21 /* Load pte table base address */ + mfspr r21, MD_TWC /* ....and get the pte address */ + lwz r21, 0(r21) /* Get the pte */ + /* concat physical page address and page offset */ + rlwinm r21, r21, 0, 0, 19 + rlwinm r20, r20, 0, 20, 31 + or r21, r20, r21 + b 140f +100:/* Entry point for dcbx workaround. */ + /* fetch instruction from memory. */ + mfspr r20,SRR0 + andis. r21, r20, 0x8000 + beq- 139b /* Branch if user space address */ + tophys (r21, r20) +140: lwz r21,0(r21) +#if DEBUG_DCBX_INSTRUCTIONS +/* Check if it really is a dcbx instruction */ + rlwinm r20,r21,0,21,30 + cmpwi cr0,r20,940 /* Is dcbi? */ + bc 12,2,142f + cmpwi cr0,r20,2028 /* Is dcbz? */ + bc 12,2,142f + cmpwi cr0,r20,492 /* Is dcbtst? */ + bc 12,2,142f + cmpwi cr0,r20,556 /* Is dcbt? */ + bc 12,2,142f + cmpwi cr0,r20,108 /* Is dcbst? */ + bc 12,2,142f + cmpwi cr0,r20,172 /* Is dcbf? */ + bc 12,2,142f + +141: b 141b /* Stop here if no dcbx instruction */ +142: /* continue, it was a dcbx instruction. */ +#endif + +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) /* restore r3 from memory */ +#endif + mfctr r20 + mtdar r20 /* save ctr reg in DAR */ + rlwinm r20, r21, 24, 24, 28 /* offset into jump table for reg RB */ + addi r20, r20, 150f@l /* add start of table */ + mtctr r20 /* load ctr with jump address */ + xor r20, r20, r20 /* sum starts at zero */ + bctr /* jump into table */ +150: + add r20, r20, r0 + b 151f + add r20, r20, r1 + b 151f + add r20, r20, r2 + b 151f + add r20, r20, r3 + b 151f + add r20, r20, r4 + b 151f + add r20, r20, r5 + b 151f + add r20, r20, r6 + b 151f + add r20, r20, r7 + b 151f + add r20, r20, r8 + b 151f + add r20, r20, r9 + b 151f + add r20, r20, r10 + b 151f + add r20, r20, r11 + b 151f + add r20, r20, r12 + b 151f + add r20, r20, r13 + b 151f + add r20, r20, r14 + b 151f + add r20, r20, r15 + b 151f + add r20, r20, r16 + b 151f + add r20, r20, r17 + b 151f + add r20, r20, r18 + b 151f + add r20, r20, r19 + b 151f + mtctr r21 /* reg 20 needs special handling */ + b 154f + mtctr r21 /* reg 21 needs special handling */ + b 153f + add r20, r20, r22 + b 151f + add r20, r20, r23 + b 151f + add r20, r20, r24 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r27 + b 151f + add r20, r20, r28 + b 151f + add r20, r20, r29 + b 151f + add r20, r20, r30 + b 151f + add r20, r20, r31 +151: + rlwinm. r21,r21,19,24,28 /* offset into jump table for reg RA */ + bc 12,2,152f /* if reg RA is zero, don't add it */ + addi r21, r21, 150b@l /* add start of table */ + mtctr r21 /* load ctr with jump address */ + rlwinm r21,r21,0,16,10 /* make sure we don't execute this more than once */ + bctr /* jump into table */ +152: + mfdar r21 + mtctr r21 /* restore ctr reg from DAR */ + mtdar r20 /* save fault EA to DAR */ + b 101b /* Go back to normal TLB handling */ + + /* special handling for r20,r21 since these are modified already */ +153: lwz r21, 4(r0) /* load r21 from memory */ + b 155f +154: mfspr r21, M_TW /* load r20 from M_TW */ +155: add r20, r20, r21 /* add it */ + mfctr r21 /* restore r21 */ + b 151b /* * This code finishes saving the registers to the exception frame ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 17:25 ` Joakim Tjernlund @ 2003-04-08 18:14 ` Tom Rini 2003-04-08 21:07 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Tom Rini @ 2003-04-08 18:14 UTC (permalink / raw) To: Joakim Tjernlund Cc: Till Straumann, Dan Malek, Linuxppc-Embedded@Lists. Linuxppc. Org On Tue, Apr 08, 2003 at 07:25:37PM +0200, Joakim Tjernlund wrote: > > > > Patch against 2.4.20 devel available on request until I have cleaned it up a little. > > > > Jocke > > Here is the patch, against 2.4.20 devel but I think it will apply > against BK HEAD. Comments welcome :-) Can you let me know if this applies cleanly to the current linux-2.4 tree (Or, 2.4.21-pre7 tarball)? If not, can you generate a patch against this? Thanks. -- Tom Rini http://gate.crashing.org/~trini/ ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 18:14 ` Tom Rini @ 2003-04-08 21:07 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-08 21:07 UTC (permalink / raw) To: Tom Rini Cc: Till Straumann, Dan Malek, Linuxppc-Embedded@Lists. Linuxppc. Org > > On Tue, Apr 08, 2003 at 07:25:37PM +0200, Joakim Tjernlund wrote: > > > > > > Patch against 2.4.20 devel available on request until I have cleaned it up a little. > > > > > > Jocke > > > > Here is the patch, against 2.4.20 devel but I think it will apply > > against BK HEAD. Comments welcome :-) > > Can you let me know if this applies cleanly to the current linux-2.4 > tree (Or, 2.4.21-pre7 tarball)? If not, can you generate a patch > against this? Thanks. > > -- > Tom Rini pulled the latest linuxppc_2_4, patched it and inspected the result. Current patch will apply with some offset and looks good. I cannot run standard 2.4 without major patching, so I can't be sure that it works. Anyhow here is a version against linuxppc_2_4: ===== arch/ppc/kernel/head_8xx.S 1.33 vs edited ===== --- 1.33/arch/ppc/kernel/head_8xx.S Thu Mar 27 10:05:55 2003 +++ edited/arch/ppc/kernel/head_8xx.S Tue Apr 8 22:49:49 2003 @@ -31,6 +31,24 @@ #include <asm/ppc_asm.h> #include "ppc_defs.h" +/* These macros are used to tag DAR with a known value so that the + * DataTLBError can recognize a buggy dcbx instruction and workaround + * the problem. + */ +#define TAG_VAL 0xdead +#define TAG_DAR_R20 \ + lis r20, TAG_VAL;\ + mtspr DAR, r20; + +/* Macro to make the code more readable. */ +#ifdef CONFIG_8xx_CPU6 + #define DO_8xx_CPU6(val, reg) \ + li reg, val; \ + stw reg, 12(r0); \ + lwz reg, 12(r0); +#else + #define DO_8xx_CPU6(val, reg) +#endif .text .globl _stext _stext: @@ -166,6 +184,7 @@ . = n; \ label: \ EXCEPTION_PROLOG; \ + TAG_DAR_R20; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(hdlr) @@ -188,6 +207,7 @@ mr r5,r20 mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -226,6 +246,7 @@ EXCEPTION_PROLOG mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 mfspr r5,DSISR stw r5,_DSISR(r21) addi r3,r1,STACK_FRAME_OVERHEAD @@ -461,6 +482,7 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + TAG_DAR_R20 mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -470,7 +492,17 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: + /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fails + * to update DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) @@ -508,10 +540,18 @@ stw r20, 0(r0) stw r21, 4(r0) + /* If DAR contains TAG_VAL implies a buggy dcbx instruction + * than did not set DAR. + */ + mfspr r20, DAR + lis r21, TAG_VAL + cmpw cr0, r20, r21 + beq- 100f /* Branch if TAG_VAL to dcbx workaround procedure */ +101: /* return from dcbx instruction bug workaround, r20 holds value of DAR */ /* First, make sure this was a store operation. */ - mfspr r20, DSISR - andis. r21, r20, 0x0200 /* If set, indicates store op */ + mfspr r21, DSISR + andis. r21, r21, 0x0200 /* If set, indicates store op */ beq 2f /* The EA of a data TLB miss is automatically stored in the MD_EPN @@ -530,7 +570,7 @@ * are initialized in mapin_ram(). This will avoid the problem, * assuming we only use the dcbi instruction on kernel addresses. */ - mfspr r20, DAR + /* DAR is in r20 already */ rlwinm r21, r20, 0, 0, 19 ori r21, r21, MD_EVALID mfspr r20, M_CASID @@ -597,6 +637,7 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ + TAG_DAR_R20 mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -633,6 +674,146 @@ STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) . = 0x2000 +/* This is the workaround procedure to calculate the data EA for a buggy dcbx instruction + * by decoding the registers used by the dcbx instruction and adding them. + * DAR is set to the calculated address and r20 also holds the EA on exit. + */ +139:/* fetch instruction from userspace memory */ + DO_8xx_CPU6(0x3780, r3) + mtspr MD_EPN, r20 /* Have to use MD_EPN for walk, MI_EPN can't */ + mfspr r21, M_TWB /* Get level 1 table entry address */ + lwz r21, 0(r21) /* Get the level 1 entry */ + tophys (r21, r21) + DO_8xx_CPU6(0x3b80, r3) + mtspr MD_TWC, r21 /* Load pte table base address */ + mfspr r21, MD_TWC /* ....and get the pte address */ + lwz r21, 0(r21) /* Get the pte */ + /* concat physical page address and page offset */ + rlwinm r21, r21, 0, 0, 19 + rlwinm r20, r20, 0, 20, 31 + or r21, r20, r21 + b 140f +100:/* Entry point for dcbx workaround. */ + /* fetch instruction from memory. */ + mfspr r20,SRR0 + andis. r21, r20, 0x8000 + beq- 139b /* Branch if user space address */ + tophys (r21, r20) +140: lwz r21,0(r21) +#if DEBUG_DCBX_INSTRUCTIONS +/* Check if it really is a dcbx instruction */ + rlwinm r20,r21,0,21,30 + cmpwi cr0,r20,940 /* Is dcbi? */ + bc 12,2,142f + cmpwi cr0,r20,2028 /* Is dcbz? */ + bc 12,2,142f + cmpwi cr0,r20,492 /* Is dcbtst? */ + bc 12,2,142f + cmpwi cr0,r20,556 /* Is dcbt? */ + bc 12,2,142f + cmpwi cr0,r20,108 /* Is dcbst? */ + bc 12,2,142f + cmpwi cr0,r20,172 /* Is dcbf? */ + bc 12,2,142f + +141: b 141b /* Stop here if no dcbx instruction */ +142: /* continue, it was a dcbx instruction. */ +#endif + +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) /* restore r3 from memory */ +#endif + mfctr r20 + mtdar r20 /* save ctr reg in DAR */ + rlwinm r20, r21, 24, 24, 28 /* offset into jump table for reg RB */ + addi r20, r20, 150f@l /* add start of table */ + mtctr r20 /* load ctr with jump address */ + xor r20, r20, r20 /* sum starts at zero */ + bctr /* jump into table */ +150: + add r20, r20, r0 + b 151f + add r20, r20, r1 + b 151f + add r20, r20, r2 + b 151f + add r20, r20, r3 + b 151f + add r20, r20, r4 + b 151f + add r20, r20, r5 + b 151f + add r20, r20, r6 + b 151f + add r20, r20, r7 + b 151f + add r20, r20, r8 + b 151f + add r20, r20, r9 + b 151f + add r20, r20, r10 + b 151f + add r20, r20, r11 + b 151f + add r20, r20, r12 + b 151f + add r20, r20, r13 + b 151f + add r20, r20, r14 + b 151f + add r20, r20, r15 + b 151f + add r20, r20, r16 + b 151f + add r20, r20, r17 + b 151f + add r20, r20, r18 + b 151f + add r20, r20, r19 + b 151f + mtctr r21 /* reg 20 needs special handling */ + b 154f + mtctr r21 /* reg 21 needs special handling */ + b 153f + add r20, r20, r22 + b 151f + add r20, r20, r23 + b 151f + add r20, r20, r24 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r27 + b 151f + add r20, r20, r28 + b 151f + add r20, r20, r29 + b 151f + add r20, r20, r30 + b 151f + add r20, r20, r31 +151: + rlwinm. r21,r21,19,24,28 /* offset into jump table for reg RA */ + bc 12,2,152f /* if reg RA is zero, don't add it */ + addi r21, r21, 150b@l /* add start of table */ + mtctr r21 /* load ctr with jump address */ + rlwinm r21,r21,0,16,10 /* make sure we don't execute this more than once */ + bctr /* jump into table */ +152: + mfdar r21 + mtctr r21 /* restore ctr reg from DAR */ + mtdar r20 /* save fault EA to DAR */ + b 101b /* Go back to normal TLB handling */ + + /* special handling for r20,r21 since these are modified already */ +153: lwz r21, 4(r0) /* load r21 from memory */ + b 155f +154: mfspr r21, M_TW /* load r20 from M_TW */ +155: add r20, r20, r21 /* add it */ + mfctr r21 /* restore r21 */ + b 151b /* * This code finishes saving the registers to the exception frame ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions. 2003-04-08 10:47 ` Joakim Tjernlund 2003-04-08 16:25 ` Till Straumann 2003-04-08 17:25 ` Joakim Tjernlund @ 2003-05-09 12:37 ` Joakim Tjernlund 2 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-05-09 12:37 UTC (permalink / raw) To: Till Straumann, Dan Malek Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > Me again :-) > > I have completed and tested my workaround for the dcbx instructions. The workaround > handles ALL dcbx instructions, ANY register combination and works both on > kernel space and user space addresses. > > I also did some benchmarking using copy_page(dcbz enabled) and memcpy to > memory allocated with kmalloc and/or vmalloc. copy_page is about 30% faster > than memcpy even with the workaround applied. Here I go again :) I have been running this patch on some 20-30 custom MPC860/862 boards in our test lab since I posted this message and it is stable. I made some changes since then: - Made it configurable, #define CONFIG_8xx_DCBxFIXED to enable it. - Tagging in the fast path in the DLBMiss handler is just one(1) instruction. - Test and branch if TAG present is two instructions in the DTLB Error handler. - Enabled the use of the dcbz instruction in copy_tofrom_user(), cacheable_memzero(), cacheable_memcpy(), clear_page() and copy_page() Feedback most welcome! Patch against linuxppc_2_4_devel follows. Jocke --- a/arch/ppc/kernel/head_8xx.S Tue Apr 29 00:45:35 2003 +++ b/arch/ppc/kernel/head_8xx.S Fri May 9 14:16:44 2003 @@ -31,6 +31,27 @@ #include <asm/ppc_asm.h> #include "ppc_defs.h" +#ifdef CONFIG_8xx_DCBxFIXED +/* These macros are used to tag DAR with a known value so that the + * DataTLBError can recognize a buggy dcbx instruction and workaround + * the problem. + */ + #define TAG_VAL 0x00f0 + #define TAG_DAR_R20 \ + li r20, TAG_VAL;\ + mtspr DAR, r20; +#else + #define TAG_DAR_R20 +#endif +/* Macro to make the code more readable. */ +#ifdef CONFIG_8xx_CPU6 + #define DO_8xx_CPU6(val, reg) \ + li reg, val; \ + stw reg, 12(r0); \ + lwz reg, 12(r0); +#else + #define DO_8xx_CPU6(val, reg) +#endif .text .globl _stext _stext: @@ -166,6 +187,7 @@ . = n; \ label: \ EXCEPTION_PROLOG; \ + TAG_DAR_R20; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(hdlr) @@ -188,6 +210,7 @@ mr r5,r20 mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -226,6 +249,7 @@ EXCEPTION_PROLOG mfspr r4,DAR stw r4,_DAR(r21) + TAG_DAR_R20 mfspr r5,DSISR stw r5,_DSISR(r21) addi r3,r1,STACK_FRAME_OVERHEAD @@ -457,6 +481,13 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ +#ifdef CONFIG_8xx_DCBxFIXED +#if TAG_VAL == 0x00f0 /* Save 1 instr. by reusing the val loaded in r21 above */ + mtspr DAR, r21 +#else + TAG_DAR_R20 +#endif +#endif mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -466,7 +497,17 @@ #endif rfi -2: mfspr r20, M_TW /* Restore registers */ +2: +#ifdef CONFIG_8xx_DCBxFIXED + /* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fails + * to update DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + mfspr r20, DAR + rlwimi r20, r21, 0, 0, 19 + mtspr DAR, r20 +#endif + mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 lwz r21, 4(r0) @@ -504,10 +545,19 @@ stw r20, 0(r0) stw r21, 4(r0) + mfspr r20, DAR +#ifdef CONFIG_8xx_DCBxFIXED + /* If DAR contains TAG_VAL implies a buggy dcbx instruction + * that did not set DAR. + */ + cmplwi cr0, r20, TAG_VAL + beq- 100f /* Branch if TAG_VAL to dcbx workaround procedure */ +101: /* return from dcbx instruction bug workaround, r20 holds value of DAR */ /* First, make sure this was a store operation. */ - mfspr r20, DSISR - andis. r21, r20, 0x0200 /* If set, indicates store op */ +#endif + mfspr r21, DSISR + andis. r21, r21, 0x0200 /* If set, indicates store op */ beq 2f /* The EA of a data TLB miss is automatically stored in the MD_EPN @@ -526,7 +576,7 @@ * are initialized in mapin_ram(). This will avoid the problem, * assuming we only use the dcbi instruction on kernel addresses. */ - mfspr r20, DAR + /* DAR is in r20 already */ rlwinm r21, r20, 0, 0, 19 ori r21, r21, MD_EVALID mfspr r20, M_CASID @@ -591,6 +641,13 @@ #endif mtspr MD_RPN, r20 /* Update TLB entry */ +#ifdef CONFIG_8xx_DCBxFIXED +#if TAG_VAL == 0x00f0 /* Save 1 instr. by reusing the val loaded in r21 above */ + mtspr DAR, r21 +#else + TAG_DAR_R20 +#endif +#endif mfspr r20, M_TW /* Restore registers */ lwz r21, 0(r0) mtcr r21 @@ -628,6 +685,149 @@ . = 0x2000 +#ifdef CONFIG_8xx_DCBxFIXED +/* This is the workaround procedure to calculate the data EA for a buggy dcbx instruction + * by decoding the registers used by the dcbx instruction and adding them. + * DAR is set to the calculated address and r20 also holds the EA on exit. + */ +139: /* fetch instruction from userspace memory */ + DO_8xx_CPU6(0x3780, r3) + mtspr MD_EPN, r20 + mfspr r21, M_TWB /* Get level 1 table entry address */ + lwz r21, 0(r21) /* Get the level 1 entry */ + tophys (r21, r21) + DO_8xx_CPU6(0x3b80, r3) + mtspr MD_TWC, r21 /* Load pte table base address */ + mfspr r21, MD_TWC /* ....and get the pte address */ + lwz r21, 0(r21) /* Get the pte */ + /* concat physical page address(r21) and page offset(r20) */ + rlwimi r21, r20, 0, 20, 31 + b 140f +100: /* Entry point for dcbx workaround. */ + /* fetch instruction from memory. */ + mfspr r20,SRR0 + andis. r21, r20, 0x8000 + beq- 139b /* Branch if user space address */ + tophys (r21, r20) +140: lwz r21,0(r21) + +/* Check if it really is a dcbx instruction */ + rlwinm r20, r21, 0, 21, 30 + cmpwi cr0, r20, 2028 /* Is dcbz? */ + beq+ 142f + cmpwi cr0, r20, 940 /* Is dcbi? */ + beq+ 142f + cmpwi cr0, r20, 556 /* Is dcbt? */ + beq+ 142f + cmpwi cr0, r20, 172 /* Is dcbf? */ + beq+ 142f +#ifdef DEBUG_DCBX_INSTRUCTIONS + cmpwi cr0, r20, 108 /* Is dcbst? Should never cause a DTLB Miss/Error */ + beq+ 142f + cmpwi cr0, r20, 492 /* Is dcbtst? Should never cause a DTLB Miss/Error */ + beq+ 142f + +141: b 141b /* Stop here if no dcbx instruction */ +#endif + mfspr r20, DAR /* r20 must hold DAR at exit */ + b 101b /* None of the above, go back to normal TLB processing */ +142: /* continue, it was a dcbx instruction. */ + +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) /* restore r3 from memory */ +#endif + mfctr r20 + mtdar r20 /* save ctr reg in DAR */ + rlwinm r20, r21, 24, 24, 28 /* offset into jump table for reg RB */ + addi r20, r20, 150f@l /* add start of table */ + mtctr r20 /* load ctr with jump address */ + xor r20, r20, r20 /* sum starts at zero */ + bctr /* jump into table */ +150: + add r20, r20, r0 + b 151f + add r20, r20, r1 + b 151f + add r20, r20, r2 + b 151f + add r20, r20, r3 + b 151f + add r20, r20, r4 + b 151f + add r20, r20, r5 + b 151f + add r20, r20, r6 + b 151f + add r20, r20, r7 + b 151f + add r20, r20, r8 + b 151f + add r20, r20, r9 + b 151f + add r20, r20, r10 + b 151f + add r20, r20, r11 + b 151f + add r20, r20, r12 + b 151f + add r20, r20, r13 + b 151f + add r20, r20, r14 + b 151f + add r20, r20, r15 + b 151f + add r20, r20, r16 + b 151f + add r20, r20, r17 + b 151f + add r20, r20, r18 + b 151f + add r20, r20, r19 + b 151f + mtctr r21 /* reg 20 needs special handling */ + b 154f + mtctr r21 /* reg 21 needs special handling */ + b 153f + add r20, r20, r22 + b 151f + add r20, r20, r23 + b 151f + add r20, r20, r24 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r25 + b 151f + add r20, r20, r27 + b 151f + add r20, r20, r28 + b 151f + add r20, r20, r29 + b 151f + add r20, r20, r30 + b 151f + add r20, r20, r31 +151: + rlwinm. r21,r21,19,24,28 /* offset into jump table for reg RA */ + beq 152f /* if reg RA is zero, don't add it */ + addi r21, r21, 150b@l /* add start of table */ + mtctr r21 /* load ctr with jump address */ + rlwinm r21,r21,0,16,10 /* make sure we don't execute this more than once */ + bctr /* jump into table */ +152: + mfdar r21 + mtctr r21 /* restore ctr reg from DAR */ + mtdar r20 /* save fault EA to DAR */ + b 101b /* Go back to normal TLB handling */ + + /* special handling for r20,r21 since these are modified already */ +153: lwz r21, 4(r0) /* load r21 from memory */ + b 155f +154: mfspr r21, M_TW /* load r20 from M_TW */ +155: add r20, r20, r21 /* add it */ + mfctr r21 /* restore r21 */ + b 151b +#endif /* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception, turning --- a/arch/ppc/lib/string.S Tue Apr 29 00:45:35 2003 +++ b/arch/ppc/lib/string.S Fri May 9 14:17:07 2003 @@ -151,7 +151,7 @@ bdnz 4b 3: mtctr r9 li r7,4 -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx) || defined(CONFIG_8xx_DCBxFIXED) 10: dcbz r7,r6 #else 10: stw r4, 4(r6) @@ -253,7 +253,7 @@ mtctr r0 beq 63f 53: -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx) || defined(CONFIG_8xx_DCBxFIXED) dcbz r11,r6 #endif COPY_16_BYTES @@ -452,6 +452,8 @@ 53: #if !defined(CONFIG_8xx) dcbt r3,r4 +#endif +#if !defined(CONFIG_8xx) || defined(CONFIG_8xx_DCBxFIXED) 54: dcbz r11,r6 #endif /* had to move these to keep extable in order */ @@ -461,7 +463,7 @@ .long 71b,101f .long 72b,102f .long 73b,103f -#if !defined(CONFIG_8xx) +#if !defined(CONFIG_8xx) || defined(CONFIG_8xx_DCBxFIXED) .long 54b,105f #endif .text --- a/arch/ppc/kernel/misc.S Tue Apr 29 00:45:35 2003 +++ b/arch/ppc/kernel/misc.S Fri May 9 14:16:23 2003 @@ -657,7 +657,7 @@ _GLOBAL(clear_page) li r0,4096/L1_CACHE_LINE_SIZE mtctr r0 -#ifdef CONFIG_8xx +#if defined(CONFIG_8xx) && !defined(CONFIG_8xx_DCBxFIXED) li r4, 0 1: stw r4, 0(r3) stw r4, 4(r3) @@ -710,6 +710,8 @@ 1: #ifndef CONFIG_8xx dcbt r11,r4 +#endif +#if !defined(CONFIG_8xx) || defined(CONFIG_8xx_DCBxFIXED) dcbz r5,r3 #endif COPY_16_BYTES ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-26 19:06 ` Dan Malek 2003-03-26 22:42 ` mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions Till Straumann 2003-03-27 1:25 ` Till Straumann @ 2003-04-01 9:37 ` Joakim Tjernlund 2003-04-04 15:09 ` Joakim Tjernlund 2 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-01 9:37 UTC (permalink / raw) To: Dan Malek, Till Straumann Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > The current implementation relies on TLB Miss always setting EPN > (and other hardware assist registers) correctly, and TLB Error > relies on DAR being set correctly. Everything works fine until > you get a TLB Error on a dcbz/dcbt that doesn't properly update DAR. > In this case EPN isn't set correctly either. I just want to point out(again) that TLB Miss caused by most of the dcxx(dcbf, dcbi, dcbst, dcbz) instructions that end up in the slow path(DataAccess) don't work with the current impl. since DAR isn't set. The code fragment below will fix that(from my earlier patch). This won't affect the fast path at all since it all of it can be in the slow path. + /* Copy 20 msb from EPN to DAR since the dcxx instructions fails + * update the DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 It is hard to end up in slow path for kernel space addresses, but it's not impossible I guess. Comments? Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-04-01 9:37 ` dcbz works on 862 everywhere! Joakim Tjernlund @ 2003-04-04 15:09 ` Joakim Tjernlund 2003-04-04 15:43 ` Dan Malek 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-04 15:09 UTC (permalink / raw) To: Dan Malek, Till Straumann Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > > The current implementation relies on TLB Miss always setting EPN > > (and other hardware assist registers) correctly, and TLB Error > > relies on DAR being set correctly. Everything works fine until > > you get a TLB Error on a dcbz/dcbt that doesn't properly update DAR. > > In this case EPN isn't set correctly either. > > I just want to point out(again) that TLB Miss caused by most of the > dcxx(dcbf, dcbi, dcbst, dcbz) instructions that end up in the slow path(DataAccess) > don't work with the current impl. since DAR isn't set. The code fragment below > will fix that(from my earlier patch). This won't affect the fast path at all > since it all of it can be in the slow path. > > + /* Copy 20 msb from EPN to DAR since the dcxx instructions fails > + * update the DAR when they cause a DTLB Miss. > + */ > + mfspr r21, MD_EPN > + rlwinm r21, r21, 0, 0, 19 > + mfspr r20, DAR > + rlwinm r20, r20, 0, 20, 31 > + or r20, r20, r21 > + mtspr DAR, r20 > > It is hard to end up in slow path for kernel space addresses, but > it's not impossible I guess. Comments? hmm, no response from the maintainer(s). You don't agree? Did another test. I tagged DAR with a bad address(0xdead0000) in the TLB Miss handler(after the mtspr MD_RPN, r20) shortly before rfi. Now the kernel won't boot. It turns out it's consistent_alloc that is doing a invalidate_dcache_range(). According to a comment, memory is allocated from the vmalloc memory space. Doing a invalidate_dcache_range() on this memory causes a DTLB error with the change bit cleared and since DAR isn't set by dcbi, linux hangs. Clearly, the DTLB exeception procedure still is buggy. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-04-04 15:09 ` Joakim Tjernlund @ 2003-04-04 15:43 ` Dan Malek 2003-04-04 16:37 ` Joakim Tjernlund 2003-04-09 14:32 ` Joakim Tjernlund 0 siblings, 2 replies; 51+ messages in thread From: Dan Malek @ 2003-04-04 15:43 UTC (permalink / raw) To: joakim.tjernlund Cc: Till Straumann, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Joakim Tjernlund wrote: > hmm, no response from the maintainer(s). You don't agree? It's interesting to watch these hacks, but I can't justify complicating a general purpose function with more bus cycles by emulating a functional problem. By not using these instructions we have a working system that costs just a few more cycles during the memory copy/zero operations. If we had _working_ dcbz instructions, it would be a gain to use them, but from a system perspective it is going to cost more to "fix up" these than the code that already exists. As I said in the past, I'm sensitive to the code in the TLB exception processing. So do something to remove code and streamline the process and I'm really interested. Do something to add more code and it's going to get placed pretty low in my pile of things to do. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-04-04 15:43 ` Dan Malek @ 2003-04-04 16:37 ` Joakim Tjernlund 2003-04-09 14:32 ` Joakim Tjernlund 1 sibling, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-04 16:37 UTC (permalink / raw) To: Dan Malek Cc: Till Straumann, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > Joakim Tjernlund wrote: > > > hmm, no response from the maintainer(s). You don't agree? > > It's interesting to watch these hacks, but I can't justify > complicating a general purpose function with more bus cycles by > emulating a functional problem. By not using these instructions > we have a working system that costs just a few more cycles during > the memory copy/zero operations. If we had _working_ dcbz > instructions, it would be a gain to use them, but from a system > perspective it is going to cost more to "fix up" these than > the code that already exists. Look a little harder. I am not talking just about dcbz, dcbi has the same problem. As it stands today, there are real bugs w.r.t dcbi. consistent_alloc() causes DTLB errors with a incorrect address in DAR. Just force DAR to an invalid address in the DTLB Miss handler before you leave it and see if you kernel boots. > As I said in the past, I'm sensitive to the code in the TLB exception > processing. So do something to remove code and streamline the process > and I'm really interested. Do something to add more code and it's > going to get placed pretty low in my pile of things to do. Yes I know, but you are not reading what am writing. For instance, the change below does not add to the fast path of the DTLB Miss handler and it fixes a real problem: > I just want to point out(again) that TLB Miss caused by most of the > dcxx(dcbf, dcbi, dcbst, dcbz) instructions that end up in the slow path(DataAccess) > don't work with the current impl. since DAR isn't set. The code fragment below > will fix that(from my earlier patch). This won't affect the fast path at all > since it all of it can be in the slow path. > > + /* Copy 20 msb from EPN to DAR since the dcxx instructions fails > + * update the DAR when they cause a DTLB Miss. > + */ > + mfspr r21, MD_EPN > + rlwinm r21, r21, 0, 0, 19 > + mfspr r20, DAR > + rlwinm r20, r20, 0, 20, 31 > + or r20, r20, r21 > + mtspr DAR, r20 Go back and think dcbi instead of dcbz. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-04-04 15:43 ` Dan Malek 2003-04-04 16:37 ` Joakim Tjernlund @ 2003-04-09 14:32 ` Joakim Tjernlund 1 sibling, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-04-09 14:32 UTC (permalink / raw) To: Dan Malek Cc: Till Straumann, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org > As I said in the past, I'm sensitive to the code in the TLB exception > processing. So do something to remove code and streamline the process > and I'm really interested. Do something to add more code and it's > going to get placed pretty low in my pile of things to do. > > Thanks. If you make swapper_pg_dir 64KB aligned, you can removed ori r21, r21, swapper_pg_dir@l instructions in DataStoreTLBMiss, DataTLBError and InstructionTLBMiss I did it with the following, ugly, hack in vmliunx.lds: swapper_pg_dir = ALIGN(0x10000); . = . + 4096; I guess there is a better way to this. Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-26 15:18 ` Dan Malek 2003-03-26 17:04 ` Joakim Tjernlund 2003-03-26 18:11 ` Till Straumann @ 2003-03-26 18:52 ` Till Straumann 2 siblings, 0 replies; 51+ messages in thread From: Till Straumann @ 2003-03-26 18:52 UTC (permalink / raw) To: joakim.tjernlund Cc: Dan Malek, Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org Jocke. There's of course a trivial test to check Dan's suspicion that it might just be a lucky sequence of TLBMiss-TLBError exceptions helping you out. Just load some bogus values (a la 0xdeadbeef) into MD_EPN and DAR shortly prior to returning from the TLBMiss exception (but after walking the tables, of course). Thereby you make sure that any 'leftover' values seen by a subsequent TLBError are invalidated. -- Till Dan Malek wrote: > Till Straumann wrote: > >> I found that 'dcbz' (while failing to set DAR) >> indeed sets MD_EPN correctly. Hence, Jocke's fix >> (copy EPN[0:19]->DAR) would handle that. > > > > After sleeping for a couple of days and consuming large > amounts of medicine to cure a cold, I think I understand > why copying these bits around seems to "fix" problems. > > It's all related to the sequence of TLB miss/error exceptions > that I had been describing all along. The first thing that > is going to most likely happen is you will get a TLB miss to > load a PTE into the TLB. It will be marked valid but not > dirty (not writable). Immediately upon performing the rfi > you will get a TLB Error to handle the dirty PTE update. > By copying the bits from MD_EPN to the DAR in the miss handler, > the Error handler will have at least a 4K boundary aligned DAR > and it will execute correctly to update the dirty state. At > this point, it will appear to "work" properly (even though > it is likely the dcbz didn't execute) because the system will > at least keep running (for a while). > > If you have a situation where you get a TLB Error without > a matching TLB miss (very rare, but they can happen as the > result of swapping, copy on write, certain other page table > updates), then you are hosed. The DAR will contain some information > from a previous exception, we will likely end up on a "hung" > system continually taking TLB Error exceptions because we > can't fix them properly. This is basically what happens > without the bit copying "fix". > > >> My older idea (fixing up MD_EPN and DAR based >> on the faulting instruction opcode and the involved >> GPR contents) should work even if we have neither >> a valid MD_EPN nor DAR. > > > All of the TLB exception handlers must have minimal instructions. > The ones in Linux are too big already. The very little you would > gain from making a dcbz/dcbt work correctly would be lost many, > many, many times over in a more complex TLB exception handler. > > Copying bits from MD_EPN to DAR doesn't set the DAR "correctly", > it only gives you the page boundary. This is going to further > confuse debuggers or signal handlers if you actually have an > addressing bug that is detected by one of these instructions. > > The only update I would like to see to TLB exception handlers is > the removal of code due to streamlining of the page table organization. > > Thanks. > > > -- Dan > ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-25 0:48 ` Dan Malek 2003-03-25 1:22 ` Dan Malek @ 2003-03-25 1:57 ` Joakim Tjernlund 2003-03-25 17:37 ` Joakim Tjernlund 1 sibling, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-25 1:57 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Joakim Tjernlund wrote: > > > > Did you read my mails? > > I did. From this I gathered that you don't understand why some > of this code is there in the first place, you removed code that No I don't understand this code fully. I don't think anybody but you understand this code since it contains undocumented workarounds. I asked the list before I removed it. Had you objected before I got to the patch I had left it alone. It was just a test. > would have guaranteed to cause an error if you would have run > the proper test, and you can't explain why the changes you made > cause the results you see. But I can explain(didn't I do that earlier?). We agree that dcxx will cause DTLB Misses without setting DAR, right?. By copying the MD_EPN to DAR before rfi, DAR will have address whose EPN is correct but with a semirandom page offset(the last bits in MD_EPN that doesn't referrer to the EPN). This must be better than just leaving dar as is, especially if rfi needs a valid addess to operate properly as you write below. The second part: + /* Copy 20 msb from EPN to DAR since the dcxx instuctions fails + * update the DAR when they cause a DTLB Miss. + */ + mfspr r21, MD_EPN + rlwinm r21, r21, 0, 0, 19 + mfspr r20, DAR + rlwinm r20, r20, 0, 20, 31 + or r20, r20, r21 + mtspr DAR, r20 Just replaces the EPN part to generate a valid address within the page. The lower bits are untouched. This is a nop if DAR already contains the right address, otherwise DAR will at least contain a valid page address. This could be move to before error test if you want play safe(the 2 instructions before rfi should be removed in this case) > Not something that instills much confidence. After the above explanation I hope that will improve somewhat. > > All of these MMU and cache control registers have effects on > one another. Writing one register can have the side effect of > updating another. The DAR must have valid addresses in order > to properly rfi, we know some cache operations may not set this > properly, and we also know that in these cases the MD_EPN is also > not set properly. If MD_EPN is not set propely in the DTLB Miss, you are lost regardless of my patch. [SNIP] > For a long time, we "solved" these problems on 8xx by not properly > implementing copy-on-write pages and always marking pages dirty. > It reduced the likelyhood of the problem, reduced the MMU overhead, > but cost lots more in memory and processing time during forks. > This still may not be a bad configuration option for selected > applications. Is it easy to patch/hard code? I would like to test the stability of my system. > Like I said from the beginning, the 100% guaranteed working solution > is to not use dcbz/dcbt on the 8xx. Anything else will eventually > stumble across the error conditions. If I'm developing a product > that uses Linux (or any other OS that will dynamically update the MMU > and take DTLB exceptions) I won't take the risk of failure using > these instructions. I still that the patch to head_8xx.S has merit on its own. It will workaround the case where DAR has an invalid value in the DTLB Miss handler. Still, it would be nice if you could give the patch a go in your lab(with recent silicon). Time to sleep for me Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-25 1:57 ` Joakim Tjernlund @ 2003-03-25 17:37 ` Joakim Tjernlund 2003-03-26 15:22 ` Dan Malek 0 siblings, 1 reply; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-25 17:37 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > > For a long time, we "solved" these problems on 8xx by not properly > > implementing copy-on-write pages and always marking pages dirty. > > It reduced the likelyhood of the problem, reduced the MMU overhead, > > but cost lots more in memory and processing time during forks. > > This still may not be a bad configuration option for selected > > applications. > > Is it easy to patch/hard code? I would like to test the stability of my system. I am still intrested in trying copy-on-write but I can't figure out how. Is it a big job? Any pointers? Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: dcbz works on 862 everywhere! 2003-03-25 17:37 ` Joakim Tjernlund @ 2003-03-26 15:22 ` Dan Malek 2003-03-26 17:09 ` Joakim Tjernlund 0 siblings, 1 reply; 51+ messages in thread From: Dan Malek @ 2003-03-26 15:22 UTC (permalink / raw) To: joakim.tjernlund Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman Joakim Tjernlund wrote: > I am still intrested in trying copy-on-write but I can't figure out > how. Is it a big job? Any pointers? The 8xx properly implements copy-on-write now. I don't remember when I updated this, maybe somewhere in the mid 2.3.xxx timeframe. All of the processor specific MM functions have to be changed, it isn't something that is likely going to be a configuration option. due to all of the common #define, macros, and page table functions. It does remove three instructions and a branch from the TLBmiss handler :-) -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: dcbz works on 862 everywhere! 2003-03-26 15:22 ` Dan Malek @ 2003-03-26 17:09 ` Joakim Tjernlund 0 siblings, 0 replies; 51+ messages in thread From: Joakim Tjernlund @ 2003-03-26 17:09 UTC (permalink / raw) To: Dan Malek; +Cc: Tom Rini, Linuxppc-Embedded@Lists. Linuxppc. Org, strauman > Joakim Tjernlund wrote: > > > I am still intrested in trying copy-on-write but I can't figure out > > how. Is it a big job? Any pointers? > > The 8xx properly implements copy-on-write now. I don't remember when > I updated this, maybe somewhere in the mid 2.3.xxx timeframe. All of > the processor specific MM functions have to be changed, it isn't > something that is likely going to be a configuration option. due to > all of the common #define, macros, and page table functions. It > does remove three instructions and a branch from the TLBmiss handler :-) Ahh, that explanins why I had such a hard time trying to find where it didn't do copy-on-write :-) Thanks Jocke ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 51+ messages in thread
end of thread, other threads:[~2003-05-09 12:37 UTC | newest] Thread overview: 51+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-03-24 10:19 dcbz works on 862 everywhere! Joakim Tjernlund 2003-03-24 11:01 ` Joakim Tjernlund 2003-03-24 12:25 ` Joakim Tjernlund 2003-03-24 14:20 ` Joakim Tjernlund 2003-03-24 17:09 ` Till Straumann 2003-03-24 17:42 ` Joakim Tjernlund 2003-03-24 20:15 ` Tom Rini 2003-03-24 20:57 ` Joakim Tjernlund 2003-03-24 21:07 ` Tom Rini 2003-03-24 21:54 ` Joakim Tjernlund 2003-03-24 22:59 ` Dan Malek 2003-03-25 0:33 ` Joakim Tjernlund 2003-03-24 21:42 ` Dan Malek 2003-03-24 21:51 ` Joakim Tjernlund 2003-03-24 22:44 ` Joakim Tjernlund 2003-03-24 23:09 ` Dan Malek 2003-03-24 23:57 ` Joakim Tjernlund 2003-03-25 0:48 ` Dan Malek 2003-03-25 1:22 ` Dan Malek 2003-03-25 14:02 ` Joakim Tjernlund 2003-03-26 2:17 ` Till Straumann 2003-03-26 7:57 ` Joakim Tjernlund 2003-03-26 15:18 ` Dan Malek 2003-03-26 17:04 ` Joakim Tjernlund 2003-03-26 18:52 ` Dan Malek 2003-03-27 21:49 ` Joakim Tjernlund 2003-03-26 18:11 ` Till Straumann 2003-03-26 19:06 ` Dan Malek 2003-03-26 22:42 ` mpc8xx DCBZ (&friends) hw bug. Tests, analysis + conclusions Till Straumann 2003-03-27 1:25 ` Till Straumann 2003-03-27 14:01 ` Joakim Tjernlund 2003-04-03 12:50 ` Joakim Tjernlund 2003-04-08 10:47 ` Joakim Tjernlund 2003-04-08 16:25 ` Till Straumann 2003-04-08 16:42 ` Joakim Tjernlund 2003-04-08 16:52 ` Joakim Tjernlund 2003-04-08 21:01 ` Dan Malek 2003-04-08 17:25 ` Joakim Tjernlund 2003-04-08 18:14 ` Tom Rini 2003-04-08 21:07 ` Joakim Tjernlund 2003-05-09 12:37 ` Joakim Tjernlund 2003-04-01 9:37 ` dcbz works on 862 everywhere! Joakim Tjernlund 2003-04-04 15:09 ` Joakim Tjernlund 2003-04-04 15:43 ` Dan Malek 2003-04-04 16:37 ` Joakim Tjernlund 2003-04-09 14:32 ` Joakim Tjernlund 2003-03-26 18:52 ` Till Straumann 2003-03-25 1:57 ` Joakim Tjernlund 2003-03-25 17:37 ` Joakim Tjernlund 2003-03-26 15:22 ` Dan Malek 2003-03-26 17:09 ` Joakim Tjernlund
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).