small amendment
[AROS.git] / arch / m68k-amiga / c / SetPatch.c
blobe775ee41b844deeb4501b4a8377649d181ea5b0d
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 #include <exec/types.h>
9 #include <exec/execbase.h>
10 #include <graphics/gfxbase.h>
11 #include <proto/exec.h>
12 #include <proto/dos.h>
13 #include <proto/setpatch.h>
14 #include <proto/kernel.h>
15 #include <proto/graphics.h>
17 #define SH_GLOBAL_DOSBASE 1
18 #define SH_GLOBAL_SYSBASE 1
20 #include <aros/shcommands.h>
22 const TEXT version[] = "$VER: SetPatch AROS-m68k 41.3 (" ADATE ")\n";
24 void Enable68060SuperScalar(void);
25 asm (
26 ".text\n"
27 ".global Enable68060SuperScalar\n"
28 ".func Enable68060SuperScalar\n"
29 "Enable68060SuperScalar:\n"
30 /* enable supercalar */
31 "dc.l 0x4e7a0808\n" // movec %pcr,%d0
32 "bset #0,%d0\n"
33 "dc.l 0x4e7b0808\n" // movec %d0,%pcr
34 /* enable code&data caches, store buffer and branch cache */
35 "dc.l 0x4e7a0002\n" // movec %cacr,%d0
36 "or.l #0xa0808000,%d0\n"
37 "dc.l 0x4e7b0002\n" // movec %d0,%cacr
38 "rte\n"
39 ".endfunc\n"
42 ULONG Check68030MMU(void);
43 asm (
44 ".text\n"
45 ".chip 68030\n"
46 ".global Check68030MMU\n"
47 ".func Check68030MMU\n"
48 "Check68030MMU:\n"
49 "subq.l #4,%sp\n"
50 "pmove %tc,(%sp)\n"
51 "move.l (%sp),%d0\n"
52 "addq.l #4,%sp\n"
53 "rte\n"
54 ".endfunc\n"
57 APTR getvbr(void);
58 asm (
59 ".text\n"
60 ".chip 68010\n"
61 ".global getvbr\n"
62 ".func getvbr\n"
63 "getvbr:\n"
64 "movec %vbr,%d0\n"
65 "rte\n"
66 ".endfunc\n"
69 static void setvbr(APTR vbr)
71 asm volatile (
72 ".chip 68010\n"
73 "move.l %0,%%d0\n"
74 "movem.l %%a5/%%a6,-(%%sp)\n"
75 "move.l 4.w,%%a6\n"
76 "lea 1f(%%pc),%%a5\n"
77 "jsr -0x1e(%%a6)\n"
78 "movem.l (%%sp)+,%%a5/%%a6\n"
79 "bra.s 0f\n"
80 "1:\n"
81 "movec %%d0,%%vbr\n"
82 "rte\n"
83 "0:\n"
84 : : "m" (vbr)
88 struct mmuportnode
90 struct Node node;
91 ULONG addr;
92 ULONG len;
93 ULONG flags;
96 #define PAGE_SIZE 4096
98 static void fastvbr(BOOL quiet)
100 APTR oldvbr, newvbr;
102 if (!(SysBase->AttnFlags & AFF_68010))
103 return;
104 Disable();
105 oldvbr = (APTR)Supervisor((ULONG_FUNC)getvbr);
106 Enable();
107 if (!oldvbr) {
108 newvbr = AllocMem(4 * 256, MEMF_FAST | MEMF_CLEAR);
109 if (!newvbr)
110 return;
111 CopyMemQuick(oldvbr, newvbr, 4 * 256);
112 Disable();
113 setvbr(newvbr);
114 Enable();
115 oldvbr = newvbr;
117 if (!quiet)
118 Printf("VBR moved to Fast RAM at %p\n", oldvbr);
121 static void p5stuff(BOOL quiet)
123 APTR KernelBase;
124 UBYTE *mmuport;
125 struct mmuportnode *node;
126 struct List *list;
128 mmuport = (UBYTE*)FindPort("BOOT-MMU-Port");
129 if (!mmuport)
130 return;
131 if (!quiet)
132 Printf("Phase 5 BOOT-MMU-Port found at %p\n", mmuport);
133 KernelBase = OpenResource("kernel.resource");
134 if (!KernelBase)
135 return;
136 list = (struct List*)(mmuport + 0x26);
137 ForeachNode(list, node) {
138 ULONG addr = node->addr, end;
139 ULONG len = node->len;
140 if (!quiet)
141 Printf("- %p %08lx %08lx\n", addr, len, node->flags);
142 end = addr + len;
143 addr &= ~(PAGE_SIZE - 1);
144 end += (PAGE_SIZE - 1);
145 end &= ~(PAGE_SIZE - 1);
146 Disable();
147 KrnSetProtection((void*)addr, end - addr, MAP_Readable | MAP_Writable | MAP_Executable | MAP_CacheInhibit);
148 Enable();
153 static void mmusetup(BOOL quiet)
155 // enable 68040+ data caches and 68060 superscalar mode
156 // copyback is also enabled if MMU setup was done by rom code
157 CacheClearU();
158 Disable();
159 if (SysBase->AttnFlags & AFF_68060) {
160 Supervisor((ULONG_FUNC)Enable68060SuperScalar);
161 } else if (SysBase->AttnFlags & AFF_68040) {
162 CacheControl(CACRF_EnableD, CACRF_EnableD);
163 } else if (SysBase->AttnFlags & AFF_68030) {
164 ULONG tc = Supervisor((ULONG_FUNC)Check68030MMU);
165 if (tc & (1 << 31)) { /* Only if MMU enabled */
166 CacheControl(CACRF_EnableD | CACRF_WriteAllocate, CACRF_EnableD | CACRF_WriteAllocate);
169 Enable();
172 extern void patches(BOOL, ULONG);
174 AROS_SH6H(SetPatch, 41.4, "AROS SetPatch (m68k)",
175 AROS_SHAH(BOOL, Q=, QUIET, /S, FALSE, "Be quiet"),
176 AROS_SHAH(BOOL, NOCA=, NOCACHE, /S, FALSE, "Don't install cache patches"),
177 AROS_SHAH(BOOL, NOCO=,NOCOPYMEM, /S, FALSE, "Don't install CopyMem patches"),
178 AROS_SHAH(BOOL, NOV=, NOVBRMOVE, /S, FALSE, "Don't move the VBR to MEMF_FAST"),
179 AROS_SHAH(BOOL, NOAGA=, NOAGA, /S, FALSE, "Don't enable AGA modes"),
180 AROS_SHAH(BOOL, DMMU=, DEBUGMMU, /S, FALSE, "MMU protect first page"))
182 AROS_SHCOMMAND_INIT
184 struct Library *SetPatchBase;
185 struct GfxBase *GfxBase;
187 /* NOTE: This is currently a 'am I running on AROS' test, but
188 * we should use SetPatch/AddPatch() one day
190 if ((SetPatchBase = OpenLibrary("setpatch.library", 41))) {
191 BOOL justinstalled680x0 = FALSE;
192 BOOL installed680x0 = FALSE;
193 BOOL x68040 = FALSE, x68060 = FALSE;
195 GfxBase = (struct GfxBase*)OpenLibrary("graphics.library", 0);
196 if (SysBase->AttnFlags & (AFF_68040 | AFF_68060)) {
197 BOOL ox68040 = FALSE, ox68060 = FALSE;
199 Forbid();
200 if (FindName(&SysBase->LibList, "68040.library"))
201 ox68040 = TRUE;
202 if (FindName(&SysBase->LibList, "68060.library"))
203 ox68060 = TRUE;
204 Permit();
205 CloseLibrary(OpenLibrary("680x0.library", 0));
206 Forbid();
207 if (FindName(&SysBase->LibList, "68040.library"))
208 x68040 = TRUE;
209 if (FindName(&SysBase->LibList, "68060.library"))
210 x68060 = TRUE;
211 Permit();
213 if ((!ox68040 && !ox68060) && (x68040 || x68060))
214 justinstalled680x0 = TRUE;
215 if (x68040 || x68060)
216 installed680x0 = TRUE;
219 if (!SHArg(NOVBRMOVE))
220 fastvbr(SHArg(QUIET));
222 if (justinstalled680x0)
223 patches(SHArg(QUIET), SHArg(NOCOPYMEM) ? 0 : 1);
225 if (!SHArg(NOCACHE)) {
226 if (justinstalled680x0)
227 p5stuff(SHArg(QUIET));
228 mmusetup(SHArg(QUIET));
229 } else {
230 CacheControl(0, CACRF_EnableD | CACRF_CopyBack | CACRF_DBE);
233 if (!SHArg(NOAGA))
234 SetChipRev(SETCHIPREV_BEST);
236 if (SHArg(DEBUGMMU)) {
237 /* Mark first page invalid, special handler only accepts ExecBase reads */
238 void *KernelBase = OpenResource("kernel.resource");
239 if (KernelBase) {
240 KrnSetProtection(0, PAGE_SIZE, 0);
244 if (SHArg(QUIET) == FALSE) {
245 ULONG flags;
246 if (installed680x0) {
247 Printf("%ld Support Code Loaded\n", x68060 ? 68060 : 68040);
248 } else if (SysBase->AttnFlags & (AFF_68040 | AFF_68060)) {
249 Printf("WARNING: %ld CPU without LIBS:680x0.library.\n", (SysBase->AttnFlags & AFF_68060) ? 68060 : 68040);
251 flags = CacheControl(0, 0);
252 if (flags & CACRF_EnableD)
253 Printf("Data Cache Enabled\n");
254 if (flags & CACRF_CopyBack)
255 Printf("CopyBack Enabled\n");
256 if ((GfxBase->ChipRevBits0 & SETCHIPREV_AA) == SETCHIPREV_AA)
257 Printf("Enabled Advanced Graphics Modes\n");
259 CloseLibrary(GfxBase);
260 CloseLibrary(SetPatchBase);
262 return (SetPatchBase != NULL) ? RETURN_OK : RETURN_FAIL;
264 AROS_SHCOMMAND_EXIT