English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   Killing caches: fool-proof method? (https://eab.abime.net/showthread.php?t=96233)

Keir 08 February 2019 08:56

Killing caches: fool-proof method?
 
Hi,

Does anyone have a nice blob of code for disabling caches across all 680x0? Let's assume this is just before or after taking over the system, ExecBase still available. I'm aware there's a little dance of poking control registers that may not all exist so need to be tested for, or the resulting exceptions handled.

Alternatively (or as well): would CacheControl(bits=0,mask=-1) be suitable system-friendly approach? I haven't actually yet found an example of someone calling this to disable all caches, but I guess I haven't foraged *that* hard. ;)

Cheers!

hooverphonique 08 February 2019 11:35

If you have LVOCacheControl available, it should be fine. Beware that you need Exec V37+ for it to be present.

ross 08 February 2019 12:26

000~060, all KS

Code:

start
        move.w        #$4000,$dff09a
        movea.l        $4.w,a6
        lea        super(pc),a5
        jsr        _LVOSupervisor(a6)
        move.w        #$c000,$dff09a
        rts

super
        moveq        #0,d0
        lea        trap(pc),a5
        lea        $10.w,a1
        lea        $2c.w,a2
        movea.l        (a1),a3
        movea.l        (a2),a4
        move.l        a5,(a1)
        move.l        a5,(a2)
        dc.l        $4e7b0801        ;movec d0,vbr
        dc.l        $f4784e71        ;cpusha dc
        dc.l        $4e7b0002        ;movec d0,cacr
        dc.l        $4e7b0808        ;movec d0,pcr
        move.l        a3,(a1)
        move.l        a4,(a2)
        rte
trap        addq.l        #4,2(sp)
        rte


Keir 08 February 2019 13:50

Quote:

Originally Posted by ross (Post 1303326)
000~060, all KS

That's the blob I need. Awesome, thanks!

jotd 08 February 2019 22:08

I remember CPUSHA BC (branch cache? 68060?)

mark_k 08 February 2019 22:44

ross's example code sets VBR to 0 in the supervisor routine but doesn't restore it afterwards. May not be a problem if you're killing the system/OS anyway though.

ross 08 February 2019 22:53

Quote:

Originally Posted by jotd (Post 1303429)
I remember CPUSHA BC (branch cache? 68060?)

Hi jotd, see this message http://eab.abime.net/showpost.php?p=...5&postcount=15
CPUSHA pushes and possibly invalidates selected cache lines (IC=instruction, DC=data, BC=both).
BC works, but if you disable all caches (CACR=0) then a DC suffice.
For the 060 i've disabled also the Superscalar Dispatch (ESS bit in PCR register).

ross 08 February 2019 23:00

Quote:

Originally Posted by mark_k (Post 1303442)
ross's example code sets VBR to 0 in the supervisor routine but doesn't restore it afterwards. May not be a problem if you're killing the system/OS anyway though.

Yes, i've used it in a non-return ambient.
You can simply add:

Code:

        move.l        a5,(a2)
        ...
        moveq        #0,d1
        movec        vbr,d1

        ...
        dc.l        $4e7b0801        ;movec d0,vbr

Also the cache and special registers can be saved in the same way.

EDIT: well, the moveq #0,d1 actually only serves if you plan to use the previous base and you are on a 000
not much if the next instruction is movec d0,vbr, so one of the two can be removed ;)

jotd 08 February 2019 23:25

I like the way your code does NOT test CPU family explicitly. Nice.

Keir 09 February 2019 10:54

Quote:

Originally Posted by mark_k (Post 1303442)
ross's example code sets VBR to 0 in the supervisor routine but doesn't restore it afterwards. May not be a problem if you're killing the system/OS anyway though.

Is it a problem even if you don't kill the system? Obviously it's a bit rude, but I assume the vectors at 0x0 are actually the originals, never change after boot, and the ones pointed at by the VBR are copies?

Zeroing VBR in this routine is quite nice if you're eventually killing the system: in some cases whatever you end up jumping into might well not consider non-zero VBR itself.

Secondly I wondered whether touching INTENA is necessary -- is it just because touching exception vectors is frowned on? I suppose it might stop AV or debug software going nuts.

Keir 21 June 2020 12:50

Interesting update on this: I found the CPUSHA instruction can hang on some (specifically, Apollo) 68020 and 68030 accelerators. I didn't track down the root cause -- sometimes it hangs, while in other places it might appear to execute (without the expected F-Line exception). The CPUSHA will cause a bus cycle on 020/030, so perhaps the Apollo glue mucks up the handling.

I fixed this by gating execution of CPUSHA on a 'safer' 040+ instruction (MOVEC ITT0,D1) which does not depend on external decode logic.

Thomas Richter 21 June 2020 13:01

Quote:

Originally Posted by Keir (Post 1409156)
Interesting update on this: I found the CPUSHA instruction can hang on some (specifically, Apollo) 68020 and 68030 accelerators.

I would not know how that might be possible, given that neither the 68020 nor the 68030 has a CPUSH instruction. Actually, they do not have the need for one in first place. The 68020 has only an I-cache, and the 68030 has a D-cache on top, but it is write-through.

Keir 21 June 2020 16:28

Quote:

Originally Posted by Thomas Richter (Post 1409157)
I would not know how that might be possible, given that neither the 68020 nor the 68030 has a CPUSH instruction. Actually, they do not have the need for one in first place. The 68020 has only an I-cache, and the 68030 has a D-cache on top, but it is write-through.

CPUSHA opcode is F4xx so will cause a coprocessor bus cycle for CpID=2. If the external logic doesn't handle this correctly who knows what happens? And how much software really does this instruction on 020/030, for board testing to have picked up on it? It is a theory, but absolutely it's that instruction that causes problems on an Apollo 1230 and a 1220.

Thomas Richter 21 June 2020 17:04

Ah, so that's what you are saying. Indeed, one should *not* attempt to run CPUSHA on these processors at all since the instruction is unsupported on them. To clear the cache, use CacheClearU() in exec, which is processor-independent.

Toni Wilen 21 June 2020 17:52

Properly designed hardware should reject CPU co-processor IDs that don't exist by activating bus error signal when CPU attempts to access non-existing co-pro which CPU internally converts to normal F-line exception. This is documented in official 020/030 documentation.

Unfortunately some 020/030 boards fail to do it.

Keir 21 June 2020 18:09

Quote:

Originally Posted by Toni Wilen (Post 1409194)
Properly designed hardware should reject CPU co-processor IDs that don't exist by activating bus error signal when CPU attempts to access non-existing co-pro which CPU internally converts to normal F-line exception. This is documented in official 020/030 documentation.

Unfortunately some 020/030 boards fail to do it.

Thanks for confirming. So a canonical 'disable caches on any cpu' code blob really should work around this.

By the way, tangentially related: I have had reported that 'PMOVE TC' (to disable MMU on 68851/68030) would give an unexpected exception on a Furia 68020 card (Coprocessor Protocol Violation, which was a new one on me). I figure that since 68851 is external, 68020 must do bus cycles for that instruction too and is also subject to vagaries of external logic. So I am making that instruction 68030-only: I assume that since 030 doesn't support external PMMU, the PMOVE to disable MMU must be safe even on 68EC030 which does not 'support' MMU? No bus cycles there?

Thomas Richter 21 June 2020 19:33

Quote:

Originally Posted by Keir (Post 1409195)
Thanks for confirming. So a canonical 'disable caches on any cpu' code blob really should work around this.

Yes, except that this canonical code blob already exists as part of exec CacheControl().


Quote:

Originally Posted by Keir (Post 1409195)

By the way, tangentially related: I have had reported that 'PMOVE TC' (to disable MMU on 68851/68030) would give an unexpected exception on a Furia 68020 card (Coprocessor Protocol Violation, which was a new one on me).

Only if there is no 68851 is on board, which is not so unusual. Actually, it is quite common.


Quote:

Originally Posted by Keir (Post 1409195)

I assume that since 030 doesn't support external PMMU, the PMOVE to disable MMU must be safe even on 68EC030 which does not 'support' MMU? No bus cycles there?

I afraid this is not so simple. It may or may not cause an exception, may just work, or may have more or less desasterous side effects. To my experience, mot sold 68030 which failed an MMU test as 68EC030, and there is to my very knowledge no reliable way to tell a 68EC030 apart from a 68030. A 68EC030 is just a 68030 with a failing MMU.

AmigaHope 27 June 2020 02:57

Quote:

Originally Posted by ross (Post 1303444)
For the 060 i've disabled also the Superscalar Dispatch (ESS bit in PCR register).


Why would you want to do this? Just as a means of slowing down the CPU even more? AFAIK having superscalar on doesn't cause any compatibility problems with anything. Only possibility I can think of is if you're doing some weird externally-modified code that changes an opcode for the very next instruction fetch somehow.

ross 27 June 2020 12:06

Quote:

Originally Posted by AmigaHope (Post 1410160)
Why would you want to do this? Just as a means of slowing down the CPU even more? AFAIK having superscalar on doesn't cause any compatibility problems with anything. Only possibility I can think of is if you're doing some weird externally-modified code that changes an opcode for the very next instruction fetch somehow.

Yes, it is precisely for the reasons you have explained.

--

So the code blob need to be modified, I had no idea that the CPUSHA in some accelerator can hang the machine..
How to fast recognize 020/030 CPUs (w/o SO)?

meynaf 27 June 2020 12:47

Quote:

Originally Posted by ross (Post 1410181)
How to fast recognize 020/030 CPUs (w/o SO)?

You mean without OS ?

Not sure it's what you want, but here are a few tricks :
- set some 040+ bit in cacr - if it reads back as 0, then 020-030
- try to access caar register - if not illegal, then 020-030
- trace a trap instruction - if you get to the trap vector instead of trace, then 040+
- try some cpsave opcode (e.g. $FF10) in user mode - if privilege violation instead of line-F, then 020-030

Note that it's possible emulators get caught and won't behave properly :p


All times are GMT +2. The time now is 10:34.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.08737 seconds with 11 queries