fix paths.
[AROS.git] / arch / m68k-amiga / c / mmudump.c
blobb18a2d37803baf9ffa458c2c32eadddc3767f514
2 /*
3 * Copyright (C) 2012, The AROS Development Team. All rights reserved.
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
6 */
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>
14 #include <dos/dos.h>
15 #include <stdio.h>
17 #define PROTO_KERNEL_H /* Don't pick up AROS kernel hooks */
19 #define MMU030 1
20 #define MMU040 2
21 #define MMU060 3
23 #define LEVELA_SIZE 7
24 #define LEVELB_SIZE 7
25 #define LEVELC_SIZE 6
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)
40 struct mmu68040
42 ULONG *srp;
43 ULONG *urp;
44 ULONG itt0, itt1;
45 ULONG dtt0, dtt1;
46 ULONG tc;
47 ULONG pcr;
49 struct mmu68030
51 ULONG crp[2];
52 ULONG tt0;
53 ULONG tt1;
54 ULONG tc;
57 static UBYTE mmutype;
58 struct mmu68040 m68040s;
59 struct mmu68030 m68030s;
60 struct DosLibrary *DOSBase;
62 static ULONG getdesc(ULONG *root, ULONG addr)
64 ULONG desc;
66 desc = LEVELA(root, addr);
67 if (ISINVALID(desc))
68 return desc;
69 desc = LEVELB(desc, addr);
70 if (ISINVALID(desc))
71 return desc;
72 desc = LEVELC(desc, addr);
73 return desc;
76 static void get68040(void)
78 asm volatile (
79 ".chip 68040\n"
80 "lea m68040s,%%a0\n"
81 "movec %%srp,%%a1\n"
82 "move.l %%a1,(%%a0)+\n"
83 "movec %%urp,%%a1\n"
84 "move.l %%a1,(%%a0)+\n"
85 "movec %%itt0,%%a1\n"
86 "move.l %%a1,(%%a0)+\n"
87 "movec %%itt1,%%a1\n"
88 "move.l %%a1,(%%a0)+\n"
89 "movec %%dtt0,%%a1\n"
90 "move.l %%a1,(%%a0)+\n"
91 "movec %%dtt1,%%a1\n"
92 "move.l %%a1,(%%a0)+\n"
93 "movec %%tc,%%a1\n"
94 "move.l %%a1,(%%a0)+\n"
95 "rte\n"
96 : : : "a0", "a1");
99 static void get68060(void)
101 asm volatile (
102 ".chip 68060\n"
103 "lea m68040s,%%a0\n"
104 "movec %%pcr,%%a1\n"
105 "move.l %%a1,7*4(%%a0)\n"
106 "rte\n"
107 : : : "a0", "a1");
110 static void get68030(void)
112 #if 0
113 asm volatile (
114 ".chip 68030\n"
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"
120 "rte\n"
121 : : : "a0");
122 #endif
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 " : "- ");
131 if (cm == 0)
132 Printf("WT");
133 else if (cm == 1)
134 Printf("CB");
135 else if (cm == 2)
136 Printf("IP");
137 else
138 Printf("II");
141 // Ugnore M and U
142 #define IGNOREMASK (0x10 | 0x08)
144 static void dump_mmu(ULONG *root)
146 ULONG i;
147 ULONG startaddr;
148 ULONG odesc;
149 ULONG totalpages;
150 ULONG pagemask = (1 << PAGE_SIZE) - 1;
152 totalpages = 1 << (32 - PAGE_SIZE);
153 startaddr = 0;
154 odesc = getdesc(root, startaddr);
155 for (i = 0; i <= totalpages; i++) {
156 ULONG addr = i << PAGE_SIZE;
157 ULONG desc = 0;
158 if (i < totalpages)
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);
169 } else {
170 dump_descriptor (odesc);
171 Printf(" %08lx", odesc & ~pagemask);
173 } else {
174 Printf(" %08lx", odesc & ~pagemask);
176 } else {
177 Printf(" INV");
179 Printf("\n");
180 startaddr = addr;
181 odesc = desc;
186 __startup static AROS_PROCH(startup, argstr, argsize, SysBase)
188 AROS_PROCFUNC_INIT
190 DOSBase = (APTR)OpenLibrary("dos.library", 0);
192 if (Output() == BNULL)
193 goto end;
195 if (!(SysBase->AttnFlags & AFF_68030)) {
196 Printf("68030 or better required\n");
197 goto end;
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");
215 else
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);
223 } else {
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);
229 end:
230 CloseLibrary((APTR)DOSBase);
231 return 0;
233 AROS_PROCFUNC_EXIT