move VMWare SVGA driver to generic location
[AROS.git] / rom / exec / romtagscanner.c
blob16af13e860443045d934f561c7c0af60c78b03aa
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 ROMTag scanner. Adapted from the original i386-native to become
6 system independent.
7 */
9 #include <exec/types.h>
10 #include <exec/lists.h>
11 #include <exec/nodes.h>
12 #include <exec/memory.h>
13 #include <exec/resident.h>
14 #include <proto/exec.h>
16 #include "exec_intern.h"
18 #define DEBUG 0
19 #include <aros/debug.h>
21 * RomTag scanner.
23 * This function scans kernel for existing Resident modules. If two modules
24 * with the same name are found, the one with higher version or priority
25 * wins.
27 * After building list of kernel modules, the KickTagPtr and KickMemPtr are
28 * checksummed. If checksum is proper and all memory pointed in KickMemPtr
29 * may be allocated, then all modules from KickTagPtr are added to RT list
31 * Afterwards the proper RomTagList is created (see InitCode() for details)
32 * and memory after list and nodes is freed.
34 * The array ranges gives a [ start, end ] pair to scan, with an entry of
35 * -1 used to break the loop.
38 struct rt_node
40 struct Node node;
41 struct Resident *module;
44 ULONG **AROS_SLIB_ENTRY(RomTagScanner,Exec)
46 struct ExecBase *SysBase,
47 UWORD *ranges[]
50 struct List rtList; /* List of modules */
51 UWORD *end;
52 UWORD *ptr; /* Start looking here */
54 struct Resident *res; /* module found */
56 int i;
57 ULONG **RomTag;
59 /* Initialize list */
60 NEWLIST(&rtList);
62 /* Look in whole kernel for resident modules */
63 while (*ranges != (UWORD *)~0)
65 ptr = *ranges++;
66 end = *ranges++;
68 kprintf("RomTagScanner: Start = %p, End = %p\n", ptr, end);
71 res = (struct Resident *)ptr;
73 /* Do we have RTC_MATCHWORD and rt_MatchTag*/
74 if ( res->rt_MatchWord == RTC_MATCHWORD
75 && res->rt_MatchTag == res
78 /* Yes, it is Resident module */
79 struct rt_node *node;
81 /* Check if there is module with such name already */
82 node = (struct rt_node*)FindName(&rtList, res->rt_Name);
83 if (node)
86 Rules for replacing modules:
87 1. Higher version always wins.
88 2. If the versions are equal, then lower priority
89 looses.
93 node->module->rt_Version < res->rt_Version
96 node->module->rt_Version == res->rt_Version
97 && node->node.ln_Pri <= res->rt_Pri
101 node->node.ln_Pri = res->rt_Pri;
102 node->module = res;
104 /* Have to re-add the node at it's new position. */
105 Remove((struct Node *)node);
106 Enqueue(&rtList, (struct Node *)node);
109 else
111 /* New module. Allocate some memory for it */
112 node = (struct rt_node *)
113 AllocMem(sizeof(struct rt_node),MEMF_PUBLIC|MEMF_CLEAR);
115 if (node)
117 node->node.ln_Name = res->rt_Name;
118 node->node.ln_Pri = res->rt_Pri;
119 node->module = res;
121 Enqueue(&rtList,(struct Node*)node);
125 /* Get address of EndOfResident from RomTag but only when
126 * it's higher then present one - this avoids strange locks
127 * when not all modules have Resident structure in .text
128 * section */
129 ptr = ((ULONG)res->rt_EndSkip > (ULONG)ptr)
130 ? (UWORD *)res->rt_EndSkip - 2
131 : ptr;
133 if ((ULONG)ptr & 0x01)
134 ptr = (UWORD *)((ULONG)ptr+1);
137 /* Get next address... */
138 ptr++;
139 } while (ptr < (UWORD*)end);
143 * By now we have valid (and sorted) list of kernel resident modules.
145 * Now, we will have to analyze used-defined RomTags (via KickTagPtr and
146 * KickMemPtr)
148 #warning TODO: Implement external modules!
151 * Everything is done now. Allocate buffer for normal RomTag and convert
152 * list to RomTag
155 ListLength(&rtList,i); /* Get length of the list */
157 RomTag = AllocMem((i+1)*4,MEMF_PUBLIC | MEMF_CLEAR);
159 kprintf("Resident modules (addr: pri version name):\n");
160 if (RomTag)
162 int j;
163 struct rt_node *n;
165 for (j=0; j<i; j++)
167 n = (struct rt_node *)RemHead(&rtList);
168 kprintf("+ 0x%08.8lx: %3d %3d \"%s\"\n",
169 n->module,
170 n->node.ln_Pri,
171 n->module->rt_Version,
172 n->node.ln_Name);
173 RomTag[j] = (ULONG*)n->module;
175 FreeMem(n, sizeof(struct rt_node));
177 RomTag[i] = 0;
179 return RomTag;