3 * This test relies on some particular internal functioning of kernel memory allocator!
4 * You'll have to change the code if you change something in kernel!
6 * Note also that this test requires working exec trap handling.
10 * We will not perform access tests because when we exit from trap handler,
11 * execution continues from the same location (re-triggering the trap again).
12 * Fixing this requires adjusting PC register in the context, which is not
13 * portable accross various CPUs and additionally will not currently work
14 * on all ports. We don't want to overcomplicate things so much.
16 #define NO_ACCESS_TESTS
18 #include <aros/kernel.h>
19 #include <exec/execbase.h>
20 #include <proto/exec.h>
21 #include <proto/kernel.h>
25 /* Include private kernel.resource stuff, for DumpState() */
27 #include "../../rom/kernel/mm_linear.h"
31 volatile static ULONG trap
;
33 static void TrapHandler(ULONG code
, void *ctx
)
38 static void TestRead(UBYTE
*location
)
40 #ifdef NO_ACCESS_TESTS
41 printf("Access tests disabled\n");
46 /* Reset trap indication */
49 printf("Test read from 0x%p... ", location
);
53 * We can't printf() from trap handler. Instead we just
54 * remember trap code and check it later here.
57 printf("Success, value is 0x%02X\n", val
);
59 printf("Hit trap 0x%08X\n", trap
);
65 * Print status of all pages in the specified MemHeader.
66 * '#' means allocated page, '.' means free page
68 static void DumpState(struct MemHeader
*mh
)
70 struct BlockHeader
*head
= (struct BlockHeader
*)mh
->mh_First
;
73 printf("Page map (%u total):\n", (unsigned)head
->size
);
75 for (p
= 0; p
< head
->size
; p
++)
76 printf(P_STATUS(head
->map
[p
]) ? "#" : ".");
83 #if defined(KrnStatMemory)
88 struct MemHeader
*TestArea
;
91 APTR region1
, region2
, region3
, region4
;
93 KernelBase
= OpenResource("kernel.resource");
96 printf("Failed to open kernel.resource!\n");
100 if (!KrnStatMemory(0, KMS_PageSize
, &page
, TAG_DONE
))
102 printf("MMU support is not implemented for this system!\n"
103 "kernel.resource memory allocator will not work!\n");
106 printf("System page size: %u (0x%08X)\n", (unsigned)page
, (unsigned)page
);
108 TestLength
= PAGES_NUM
* page
;
109 TestArea
= AllocMem(TestLength
, MEMF_ANY
);
110 printf("Allocated test region (%u bytes) at 0x%p\n", (unsigned)TestLength
, TestArea
);
113 printf("Failed to allocate test region!\n");
117 /* Install trap handler */
119 me
->tc_TrapCode
= TrapHandler
;
121 /* Compose a MemHeader */
122 TestArea
->mh_Node
.ln_Succ
= NULL
;
123 TestArea
->mh_Node
.ln_Type
= NT_MEMORY
;
124 TestArea
->mh_Node
.ln_Name
= "Kernel allocator test area";
125 TestArea
->mh_Node
.ln_Pri
= 127; /* This MemHeader must be the first in the list, otherwise KrnFreePages() will find a wrong one */
126 TestArea
->mh_Attributes
= MEMF_FAST
;
127 TestArea
->mh_Lower
= TestArea
;
128 TestArea
->mh_Upper
= TestArea
->mh_Lower
+ TestLength
- 1;
129 TestArea
->mh_First
= TestArea
->mh_Lower
+ MEMHEADER_TOTAL
;
130 TestArea
->mh_Free
= TestLength
- MEMHEADER_TOTAL
;
132 mc
= TestArea
->mh_First
;
134 mc
->mc_Bytes
= TestArea
->mh_Free
;
136 /* Give up the area to kernel allocator */
137 KrnInitMemory(TestArea
);
138 if (mc
->mc_Next
|| mc
->mc_Bytes
)
140 printf("KrnInitMemory() failed:\n"
142 " mc_Bytes is %lu\n",
143 mc
->mc_Next
, mc
->mc_Bytes
);
147 printf("Testing initial no-access protection...\n");
148 TestRead((UBYTE
*)TestArea
+ page
);
151 * Insert the area into system list.
152 * We do it manually because in future AddMemList() will call KrnInitMemory() itself.
155 Enqueue(&SysBase
->MemList
, &TestArea
->mh_Node
);
158 printf("Allocating region1 (two read-write pages)...\n");
159 region1
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
160 printf("region1 at 0x%p\n", region1
);
163 printf("Freeing region1...\n");
164 KrnFreePages(region1
, 2 * page
);
168 printf("Allocating region1 (3 read-only pages)...\n");
169 region1
= KrnAllocPages(NULL
, 3 * page
, MEMF_FAST
);
170 printf("region1 at 0x%p\n", region1
);
173 printf("Allocating region2 (4 write-only ;-) pages)...\n");
174 region2
= KrnAllocPages(NULL
, 4 * page
, MEMF_FAST
);
175 printf("region2 at 0x%p\n", region2
);
178 printf("Attempting to allocate page with wrong flags...\n");
179 region3
= KrnAllocPages(NULL
, page
, MEMF_CHIP
|MEMF_FAST
);
180 printf("Region at 0x%p\n", region3
);
183 printf("WARNING!!! This should have been NULL!\n");
184 KrnFreePages(region3
, page
);
187 printf("Freeing region1...\n");
188 KrnFreePages(region1
, 3 * page
);
192 printf("Freeing region2...\n");
193 KrnFreePages(region2
, 4 * page
);
197 printf("Allocating region1 (one read-write page)...\n");
198 region1
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
199 printf("region1 at 0x%p\n", region1
);
202 printf("Freeing region1...\n");
203 KrnFreePages(region1
, page
);
207 printf("Now we'll try to fragment the memory\n");
209 printf("Allocating region1 (2 pages)...\n");
210 region1
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
211 printf("region1 at 0x%p\n", region1
);
214 printf("Allocating region2 (3 pages)...\n");
215 region2
= KrnAllocPages(NULL
, 3 * page
, MEMF_FAST
);
216 printf("region2 at 0x%p\n", region2
);
219 printf("Allocating region 3 (1 page)...\n");
220 region3
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
221 printf("Region at 0x%p\n", region3
);
224 printf("Allocating region 4 (2 pages)...\n");
225 region4
= KrnAllocPages(NULL
, 2 * page
, MEMF_FAST
);
226 printf("region4 at 0x%p\n", region1
);
229 printf("Freeing region1...\n");
230 KrnFreePages(region1
, 2 * page
);
234 printf("Freeing region3...\n");
235 KrnFreePages(region3
, page
);
239 printf("Allocating region 3 (1 page) again...\n");
240 region3
= KrnAllocPages(NULL
, page
, MEMF_FAST
);
241 printf("Region at 0x%p\n", region3
);
244 printf("Freeing region2...\n");
245 KrnFreePages(region2
, 3 * page
);
249 printf("Freeing region3...\n");
250 KrnFreePages(region3
, page
);
254 printf("Freeing region4...\n");
255 KrnFreePages(region4
, 2 * page
);
260 if (TestArea
->mh_Node
.ln_Succ
)
263 Remove(&TestArea
->mh_Node
);
266 FreeMem(TestArea
, TestLength
);
269 printf("The test can't be built for this kernel.resource implementation\n");