2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
8 * This test relies on some particular internal functioning of kernel memory allocator!
9 * You'll have to change the code if you change something in kernel!
11 * Note also that this test requires working exec trap handling.
15 * We will not perform access tests because when we exit from trap handler,
16 * execution continues from the same location (re-triggering the trap again).
17 * Fixing this requires adjusting PC register in the context, which is not
18 * portable accross various CPUs and additionally will not currently work
19 * on all ports. We don't want to overcomplicate things so much.
21 #define NO_ACCESS_TESTS
23 #include <aros/kernel.h>
24 #include <exec/execbase.h>
25 #include <proto/exec.h>
26 #include <proto/kernel.h>
30 #if defined(__AROSPLATFORM_SMP__)
31 #include <aros/types/spinlock_s.h>
32 #include <proto/execlock.h>
33 #include <resources/execlock.h>
36 /* Include private kernel.resource stuff, for DumpState() */
38 #include "../../rom/kernel/mm_linear.h"
42 volatile static ULONG trap
;
44 static void TrapHandler(ULONG code
, void *ctx
)
49 static void TestRead(UBYTE
*location
)
51 #ifdef NO_ACCESS_TESTS
52 printf("Access tests disabled\n");
57 /* Reset trap indication */
60 printf("Test read from 0x%p... ", location
);
64 * We can't printf() from trap handler. Instead we just
65 * remember trap code and check it later here.
68 printf("Success, value is 0x%02X\n", val
);
70 printf("Hit trap 0x%08X\n", trap
);
76 * Print status of all pages in the specified MemHeader.
77 * '#' means allocated page, '.' means free page
79 static void DumpState(struct MemHeader
*mh
)
81 struct BlockHeader
*head
= (struct BlockHeader
*)mh
->mh_First
;
84 printf("Page map (%u total):\n", (unsigned)head
->size
);
86 for (p
= 0; p
< head
->size
; p
++)
87 printf(P_STATUS(head
->map
[p
]) ? "#" : ".");
94 #if defined(KrnStatMemory)
96 #if defined(__AROSPLATFORM_SMP__)
97 void *ExecLockBase
= OpenResource("execlock.resource");
102 struct MemHeader
*TestArea
;
105 APTR region1
, region2
, region3
, region4
;
107 KernelBase
= OpenResource("kernel.resource");
110 printf("Failed to open kernel.resource!\n");
114 if (!KrnStatMemory(0, KMS_PageSize
, &page
, TAG_DONE
))
116 printf("MMU support is not implemented for this system!\n"
117 "kernel.resource memory allocator will not work!\n");
120 printf("System page size: %u (0x%08X)\n", (unsigned)page
, (unsigned)page
);
122 TestLength
= PAGES_NUM
* page
;
123 TestArea
= AllocMem(TestLength
, MEMF_ANY
);
124 printf("Allocated test region (%u bytes) at 0x%p\n", (unsigned)TestLength
, TestArea
);
127 printf("Failed to allocate test region!\n");
131 /* Install trap handler */
133 me
->tc_TrapCode
= TrapHandler
;
135 /* Compose a MemHeader */
136 TestArea
->mh_Node
.ln_Succ
= NULL
;
137 TestArea
->mh_Node
.ln_Type
= NT_MEMORY
;
138 TestArea
->mh_Node
.ln_Name
= "Kernel allocator test area";
139 TestArea
->mh_Node
.ln_Pri
= 127; /* This MemHeader must be the first in the list, otherwise KrnFreePages() will find a wrong one */
140 TestArea
->mh_Attributes
= MEMF_FAST
;
141 TestArea
->mh_Lower
= TestArea
;
142 TestArea
->mh_Upper
= TestArea
->mh_Lower
+ TestLength
- 1;
143 TestArea
->mh_First
= TestArea
->mh_Lower
+ MEMHEADER_TOTAL
;
144 TestArea
->mh_Free
= TestLength
- MEMHEADER_TOTAL
;
146 mc
= TestArea
->mh_First
;
148 mc
->mc_Bytes
= TestArea
->mh_Free
;
150 /* Give up the area to kernel allocator */
151 KrnInitMemory(TestArea
);
152 if (mc
->mc_Next
|| mc
->mc_Bytes
)
154 printf("KrnInitMemory() failed:\n"
156 " mc_Bytes is %lu\n",
157 mc
->mc_Next
, mc
->mc_Bytes
);
161 printf("Testing initial no-access protection...\n");
162 TestRead((UBYTE
*)TestArea
+ page
);
165 * Insert the area into system list.
166 * We do it manually because in future AddMemList() will call KrnInitMemory() itself.
168 #if defined(__AROSPLATFORM_SMP__)
170 ObtainSystemLock(&SysBase
->MemList
, SPINLOCK_MODE_WRITE
, LOCKF_FORBID
);
176 Enqueue(&SysBase
->MemList
, &TestArea
->mh_Node
);
177 #if defined(__AROSPLATFORM_SMP__)
179 ReleaseSystemLock(&SysBase
->MemList
, LOCKF_FORBID
);
186 printf("Allocating region1 (two read-write pages)...\n");
187 region1
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
188 printf("region1 at 0x%p\n", region1
);
191 printf("Freeing region1...\n");
192 KrnFreePages(region1
, 2 * page
);
196 printf("Allocating region1 (3 read-only pages)...\n");
197 region1
= KrnAllocPages(NULL
, 3 * page
, MEMF_FAST
);
198 printf("region1 at 0x%p\n", region1
);
201 printf("Allocating region2 (4 write-only ;-) pages)...\n");
202 region2
= KrnAllocPages(NULL
, 4 * page
, MEMF_FAST
);
203 printf("region2 at 0x%p\n", region2
);
206 printf("Attempting to allocate page with wrong flags...\n");
207 region3
= KrnAllocPages(NULL
, page
, MEMF_CHIP
|MEMF_FAST
);
208 printf("Region at 0x%p\n", region3
);
211 printf("WARNING!!! This should have been NULL!\n");
212 KrnFreePages(region3
, page
);
215 printf("Freeing region1...\n");
216 KrnFreePages(region1
, 3 * page
);
220 printf("Freeing region2...\n");
221 KrnFreePages(region2
, 4 * page
);
225 printf("Allocating region1 (one read-write page)...\n");
226 region1
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
227 printf("region1 at 0x%p\n", region1
);
230 printf("Freeing region1...\n");
231 KrnFreePages(region1
, page
);
235 printf("Now we'll try to fragment the memory\n");
237 printf("Allocating region1 (2 pages)...\n");
238 region1
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
239 printf("region1 at 0x%p\n", region1
);
242 printf("Allocating region2 (3 pages)...\n");
243 region2
= KrnAllocPages(NULL
, 3 * page
, MEMF_FAST
);
244 printf("region2 at 0x%p\n", region2
);
247 printf("Allocating region 3 (1 page)...\n");
248 region3
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
249 printf("Region at 0x%p\n", region3
);
252 printf("Allocating region 4 (2 pages)...\n");
253 region4
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
254 printf("region4 at 0x%p\n", region1
);
257 printf("Freeing region1...\n");
258 KrnFreePages(region1
, 2 * page
);
262 printf("Freeing region3...\n");
263 KrnFreePages(region3
, page
);
267 printf("Allocating region 3 (1 page) again...\n");
268 region3
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
269 printf("Region at 0x%p\n", region3
);
272 printf("Freeing region2...\n");
273 KrnFreePages(region2
, 3 * page
);
277 printf("Freeing region3...\n");
278 KrnFreePages(region3
, page
);
282 printf("Freeing region4...\n");
283 KrnFreePages(region4
, 2 * page
);
288 if (TestArea
->mh_Node
.ln_Succ
)
291 Remove(&TestArea
->mh_Node
);
294 FreeMem(TestArea
, TestLength
);
297 printf("The test can't be built for this kernel.resource implementation\n");