2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Additional ExecBase manipulation code
9 #include <exec/lists.h>
10 #include <exec/memory.h>
11 #include <exec/resident.h>
12 #include <exec/execbase.h>
14 #include <proto/exec.h>
16 #include "exec_intern.h"
18 static void reloclist(struct List
*l
)
22 if (l
->lh_Head
->ln_Succ
== NULL
) {
28 n
->ln_Pred
= (struct Node
*)&l
->lh_Head
;
31 n
->ln_Succ
= (struct Node
*)&l
->lh_Tail
;
34 /* Move execbase to better location, used by m68k-amiga port to move exec from
35 * chip or slow ram to real fast ram if autoconfig detected any real fast boards
36 * RTF_SINGLETASK run level.
37 * Note that oldSysBase is NOT location where to copy from but location of SysBase
38 * before reset (from where to copy reset proof pointers)
40 struct ExecBase
*PrepareExecBaseMove(struct ExecBase
*oldSysBase
)
42 ULONG totalsize
, i
, oldIntFlags
;
43 struct ExecBase
*oldsb
= SysBase
, *newsb
;
45 APTR ColdCapture
= NULL
, CoolCapture
= NULL
, WarmCapture
= NULL
;
46 APTR KickMemPtr
= NULL
, KickTagPtr
= NULL
, KickCheckSum
= NULL
;
49 ColdCapture
= oldSysBase
->ColdCapture
;
50 CoolCapture
= oldSysBase
->CoolCapture
;
51 WarmCapture
= oldSysBase
->WarmCapture
;
52 KickMemPtr
= oldSysBase
->KickMemPtr
;
53 KickTagPtr
= oldSysBase
->KickTagPtr
;
54 KickCheckSum
= oldSysBase
->KickCheckSum
;
57 Remove((struct Node
*)oldsb
);
59 totalsize
= oldsb
->LibNode
.lib_NegSize
+ oldsb
->LibNode
.lib_PosSize
;
61 /* A little discussion on why MEMF_KICK is used.
63 * MEMF_CHIP is the 'core' memory on an Amiga, at address 0.
64 * Always there, but super slow.
65 * MEMF_LOCAL is all of MEMF_CHIP, plus any non-AutoConfig expansion
66 * (ie A500/600 Ranger at 0xc00000, A3000 and A4000 motherboard RAMs)
67 * MEMF_KICK is all of MEMF_LOCAL, plus any AutoConfig expansions
68 * (ie Zorro II and Zorro III memory cards)
69 * MEMF_FAST *may* include other memories, which could be set up
70 * by the SysBase->KickTags list, or CLI utilities
72 * arch/m68k-amiga/exec/boot.c has been specially prepared to handle
73 * MEMF_LOCAL or MEMF_KICK SysBase, so MEMF_KICK is the fastest
76 newsb
= (struct ExecBase
*)((UBYTE
*)AllocMem(totalsize
, MEMF_KICK
) + oldsb
->LibNode
.lib_NegSize
);
77 CopyMem((UBYTE
*)oldsb
- oldsb
->LibNode
.lib_NegSize
, (UBYTE
*)newsb
- oldsb
->LibNode
.lib_NegSize
, totalsize
);
79 reloclist(&newsb
->LibList
);
80 AddTail(&newsb
->LibList
, (struct Node
*)newsb
);
82 reloclist(&newsb
->MemList
);
83 reloclist(&newsb
->ResourceList
);
84 reloclist(&newsb
->DeviceList
);
85 reloclist(&newsb
->IntrList
);
86 reloclist(&newsb
->PortList
);
87 reloclist(&newsb
->TaskReady
);
88 reloclist(&newsb
->TaskWait
);
89 reloclist(&newsb
->SemaphoreList
);
90 reloclist((struct List
*)&newsb
->ex_MemHandlers
);
91 reloclist(&newsb
->TaskReady
);
92 for (i
= 0; i
< 5; i
++) {
93 reloclist(&newsb
->SoftInts
[i
].sh_List
);
95 reloclist(&PrivExecBase(newsb
)->ResetHandlers
);
96 reloclist((struct List
*)&PrivExecBase(newsb
)->AllocMemList
);
97 reloclist((struct List
*)&PrivExecBase(newsb
)->TaskStorageSlots
);
98 reloclist((struct List
*)&PrivExecBase(newsb
)->AllocatorCtxList
);
100 InitSemaphore(&PrivExecBase(newsb
)->MemListSem
);
101 InitSemaphore(&PrivExecBase(newsb
)->LowMemSem
);
105 /* We need to temporarily disable MungWall, because
106 * it wasn't on when we were allocated.
108 oldIntFlags
= PrivExecBase(oldsb
)->IntFlags
;
109 PrivExecBase(SysBase
)->IntFlags
&= ~EXECF_MungWall
;
110 FreeMem((UBYTE
*)oldsb
- oldsb
->LibNode
.lib_NegSize
, totalsize
);
111 PrivExecBase(SysBase
)->IntFlags
= oldIntFlags
;
114 SysBase
->ColdCapture
= ColdCapture
;
115 SysBase
->CoolCapture
= CoolCapture
;
116 SysBase
->WarmCapture
= WarmCapture
;
117 SysBase
->KickMemPtr
= KickMemPtr
;
118 SysBase
->KickTagPtr
= KickTagPtr
;
119 SysBase
->KickCheckSum
= KickCheckSum
;