Trust uboot's device list only if it does not look suspicious.
[AROS.git] / test / kernel / allocator.c
blob1c40affa17b0e7cb9e5dac3816a9c18deda86773
1 /*
2 * WARNING!!!
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.
7 */
9 /*
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>
23 #include <stdio.h>
25 /* Include private kernel.resource stuff, for DumpState() */
26 struct KernelBase;
27 #include "../../rom/kernel/mm_linear.h"
29 #define PAGES_NUM 14
31 volatile static ULONG trap;
33 static void TrapHandler(ULONG code, void *ctx)
35 trap = code;
38 static void TestRead(UBYTE *location)
40 #ifdef NO_ACCESS_TESTS
41 printf("Access tests disabled\n");
42 #else
44 volatile UBYTE val;
46 /* Reset trap indication */
47 trap = -1;
49 printf("Test read from 0x%p... ", location);
50 val = *location;
53 * We can't printf() from trap handler. Instead we just
54 * remember trap code and check it later here.
56 if (trap == -1)
57 printf("Success, value is 0x%02X\n", val);
58 else
59 printf("Hit trap 0x%08X\n", trap);
61 #endif
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;
71 IPTR p;
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]) ? "#" : ".");
78 printf("\n");
81 int main(void)
83 #if defined(KrnStatMemory)
85 APTR KernelBase;
86 struct Task *me;
87 ULONG page;
88 struct MemHeader *TestArea;
89 ULONG TestLength;
90 struct MemChunk *mc;
91 APTR region1, region2, region3, region4;
93 KernelBase = OpenResource("kernel.resource");
94 if (!KernelBase)
96 printf("Failed to open kernel.resource!\n");
97 return 1;
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");
104 return 1;
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);
111 if (!TestArea)
113 printf("Failed to allocate test region!\n");
114 return 1;
117 /* Install trap handler */
118 me = FindTask(NULL);
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;
133 mc->mc_Next = NULL;
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"
141 " mc_Next is 0x%p\n"
142 " mc_Bytes is %lu\n",
143 mc->mc_Next, mc->mc_Bytes);
144 goto exit;
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.
154 Forbid();
155 Enqueue(&SysBase->MemList, &TestArea->mh_Node);
156 Permit();
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);
161 DumpState(TestArea);
163 printf("Freeing region1...\n");
164 KrnFreePages(region1, 2 * page);
165 printf("Done!\n");
166 DumpState(TestArea);
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);
171 DumpState(TestArea);
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);
176 DumpState(TestArea);
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);
181 if (region3)
183 printf("WARNING!!! This should have been NULL!\n");
184 KrnFreePages(region3, page);
187 printf("Freeing region1...\n");
188 KrnFreePages(region1, 3 * page);
189 printf("Done!\n");
190 DumpState(TestArea);
192 printf("Freeing region2...\n");
193 KrnFreePages(region2, 4 * page);
194 printf("Done!\n");
195 DumpState(TestArea);
197 printf("Allocating region1 (one read-write page)...\n");
198 region1 = KrnAllocPages(NULL, page, MEMF_FAST);
199 printf("region1 at 0x%p\n", region1);
200 DumpState(TestArea);
202 printf("Freeing region1...\n");
203 KrnFreePages(region1, page);
204 printf("Done!\n");
205 DumpState(TestArea);
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);
212 DumpState(TestArea);
214 printf("Allocating region2 (3 pages)...\n");
215 region2 = KrnAllocPages(NULL, 3 * page, MEMF_FAST);
216 printf("region2 at 0x%p\n", region2);
217 DumpState(TestArea);
219 printf("Allocating region 3 (1 page)...\n");
220 region3 = KrnAllocPages(NULL, page, MEMF_FAST);
221 printf("Region at 0x%p\n", region3);
222 DumpState(TestArea);
224 printf("Allocating region 4 (2 pages)...\n");
225 region4 = KrnAllocPages(NULL, 2 * page, MEMF_FAST);
226 printf("region4 at 0x%p\n", region1);
227 DumpState(TestArea);
229 printf("Freeing region1...\n");
230 KrnFreePages(region1, 2 * page);
231 printf("Done!\n");
232 DumpState(TestArea);
234 printf("Freeing region3...\n");
235 KrnFreePages(region3, page);
236 printf("Done!\n");
237 DumpState(TestArea);
239 printf("Allocating region 3 (1 page) again...\n");
240 region3 = KrnAllocPages(NULL, page, MEMF_FAST);
241 printf("Region at 0x%p\n", region3);
242 DumpState(TestArea);
244 printf("Freeing region2...\n");
245 KrnFreePages(region2, 3 * page);
246 printf("Done!\n");
247 DumpState(TestArea);
249 printf("Freeing region3...\n");
250 KrnFreePages(region3, page);
251 printf("Done!\n");
252 DumpState(TestArea);
254 printf("Freeing region4...\n");
255 KrnFreePages(region4, 2 * page);
256 printf("Done!\n");
257 DumpState(TestArea);
259 exit:
260 if (TestArea->mh_Node.ln_Succ)
262 Forbid();
263 Remove(&TestArea->mh_Node);
264 Permit();
266 FreeMem(TestArea, TestLength);
268 #else
269 printf("The test can't be built for this kernel.resource implementation\n");
270 #endif
272 return 0;