3 * Copyright (C) 2012, The AROS Development Team. All rights reserved.
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
8 /* Outputs current MMU table setup. AOS compatible. */
10 #include <exec/types.h>
11 #include <exec/execbase.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
17 #define PROTO_KERNEL_H /* Don't pick up AROS kernel hooks */
26 #define PAGE_SIZE 12 // = 1 << 12 = 4096
28 /* Macros that hopefully make MMU magic a bit easier to understand.. */
30 #define LEVELA_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE ))) & ((1 << LEVELA_SIZE) - 1))
31 #define LEVELB_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE + LEVELB_SIZE ))) & ((1 << LEVELB_SIZE) - 1))
32 #define LEVELC_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE + LEVELB_SIZE + LEVELC_SIZE))) & ((1 << LEVELC_SIZE) - 1))
34 #define LEVELA(root, x) (root[LEVELA_VAL(x)])
35 #define LEVELB(a, x) (((ULONG*)(((ULONG)a) & ~((1 << (LEVELB_SIZE + 2)) - 1)))[LEVELB_VAL(x)])
36 #define LEVELC(b, x) (((ULONG*)(((ULONG)b) & ~((1 << (LEVELC_SIZE + 2)) - 1)))[LEVELC_VAL(x)])
38 #define ISINVALID(x) ((((ULONG)x) & 3) == 0)
58 struct mmu68040 m68040s
;
59 struct mmu68030 m68030s
;
60 struct DosLibrary
*DOSBase
;
62 static ULONG
getdesc(ULONG
*root
, ULONG addr
)
66 desc
= LEVELA(root
, addr
);
69 desc
= LEVELB(desc
, addr
);
72 desc
= LEVELC(desc
, addr
);
76 static void get68040(void)
82 "move.l %%a1,(%%a0)+\n"
84 "move.l %%a1,(%%a0)+\n"
86 "move.l %%a1,(%%a0)+\n"
88 "move.l %%a1,(%%a0)+\n"
90 "move.l %%a1,(%%a0)+\n"
92 "move.l %%a1,(%%a0)+\n"
94 "move.l %%a1,(%%a0)+\n"
99 static void get68060(void)
105 "move.l %%a1,7*4(%%a0)\n"
110 static void get68030(void)
115 "move.l #m68030,%%a0\n"
116 "pmove %%crp,(%%a0)\n"
117 "pmove %%tt0,8(%%a0)\n"
118 "pmove %%tt1,12(%%a0)\n"
119 "pmove %%tc,16(%a0)\n"
125 static void dump_descriptor(ULONG desc
)
127 UBYTE cm
= (desc
& (0x040 | 0x020)) >> 5;
128 Printf ((desc
& 0x400) ? " G" : " -");
129 Printf ((desc
& 0x080) ? "S" : "-");
130 Printf ((desc
& 0x004) ? "W " : "- ");
142 #define IGNOREMASK (0x10 | 0x08)
144 static void dump_mmu(ULONG
*root
)
150 ULONG pagemask
= (1 << PAGE_SIZE
) - 1;
152 totalpages
= 1 << (32 - PAGE_SIZE
);
154 odesc
= getdesc(root
, startaddr
);
155 for (i
= 0; i
<= totalpages
; i
++) {
156 ULONG addr
= i
<< PAGE_SIZE
;
159 desc
= getdesc(root
, addr
);
160 if ((desc
& (pagemask
& ~IGNOREMASK
)) != (odesc
& (pagemask
& ~IGNOREMASK
)) || i
== totalpages
) {
161 Printf("%08lx - %08lx: %08lx", startaddr
, addr
- 1, odesc
);
162 if (!ISINVALID(odesc
)) {
163 if (mmutype
>= MMU040
) {
164 if ((odesc
& 3) == 2) {
165 ULONG idesc
= *((ULONG
*)(odesc
& ~3));
166 Printf(" -> %08lx", idesc
);
167 dump_descriptor (idesc
);
168 Printf(" %08lx", idesc
& ~pagemask
);
170 dump_descriptor (odesc
);
171 Printf(" %08lx", odesc
& ~pagemask
);
174 Printf(" %08lx", odesc
& ~pagemask
);
186 __startup
static AROS_PROCH(startup
, argstr
, argsize
, SysBase
)
190 DOSBase
= (APTR
)OpenLibrary("dos.library", 0);
192 if (Output() == BNULL
)
195 if (!(SysBase
->AttnFlags
& AFF_68030
)) {
196 Printf("68030 or better required\n");
199 mmutype
= (SysBase
->AttnFlags
& AFF_68040
) ? MMU040
: MMU030
;
200 Supervisor((ULONG_FUNC
)(mmutype
== MMU030
? get68030
: get68040
));
202 if (mmutype
>= MMU040
) {
203 Printf("SRP: %08lx URP: %08lx\n", m68040s
.srp
, m68040s
.urp
);
204 Printf("ITT0: %08lx ITT1: %08lx\n", m68040s
.itt0
, m68040s
.itt1
);
205 Printf("DTT0: %08lx DTT1: %08lx\n", m68040s
.dtt0
, m68040s
.dtt1
);
206 Printf("TC : %08lx\n", m68040s
.tc
);
207 if (SysBase
->AttnFlags
& AFF_68060
) {
208 Supervisor((ULONG_FUNC
)get68060
);
209 Printf("PCR : %08lx\n", m68040s
.pcr
);
212 if ((m68040s
.tc
& 0xc000) == 0x8000) {
213 if (m68040s
.srp
!= m68040s
.urp
)
214 Printf("SRP dump:\n");
216 Printf("MMU dump:\n");
217 dump_mmu(m68040s
.srp
);
218 if (m68040s
.srp
!= m68040s
.urp
) {
219 Printf("URP dump:\n");
220 dump_mmu(m68040s
.urp
);
224 Printf("CRP: %08lx %08lx\n", m68030s
.crp
[0], m68030s
.crp
[1]);
225 Printf("TT0: %08lx TT1: %08lx\n", m68030s
.tt0
, m68030s
.tt1
);
226 Printf("TC : %08lx\n", m68030s
.tc
);
230 CloseLibrary((APTR
)DOSBase
);