1 #include "DeviceSettings.h"
9 # define WIN32_LEAN_AND_MEAN
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
19 #include <libxml/debugXML.h>
21 #define SETTINGS_DIR "./devices/"
24 const char separatorChar
= '\\';
26 const char separatorChar
= '/';
31 void DeviceSettings::listAll() {
33 std::string filter
= SETTINGS_DIR
;
34 if( filter
[filter
.length() - 1] != separatorChar
)
35 filter
+= File::separatorChar
;
39 long h
= _findfirst(filter
.c_str(), &fileinfo
);
42 if( (strcmp(fileinfo
.name
,".") != 0) &&
43 (strcmp(fileinfo
.name
,"..") != 0) ) {
44 std::cout
<< fileinfo
.name
<< std::endl
;
47 if( _findnext(h
,&fileinfo
) != 0 )
53 DIR *dir
= opendir(SETTINGS_DIR
);
58 while ( (dp
= readdir(dir
)) != 0) {
59 if ( (strcmp(dp
->d_name
, ".") != 0)&&(strcmp(dp
->d_name
, "..")!= 0)) {
60 std::cout
<< dp
->d_name
<< std::endl
;
69 XmlHandle(const char *filename
) {
71 * this initialize the library and check potential ABI mismatches
72 * between the version it was compiled for and the actual shared
77 int flags
= XML_PARSE_DTDATTR
| /* default DTD attributes */
78 XML_PARSE_NOENT
| /* substitute entities */
79 XML_PARSE_DTDVALID
; /* validate with the DTD */
81 /*parse the file and get the DOM */
82 doc
= xmlReadFile(filename
, NULL
, flags
);
85 throw ParseException( util::format("Unable to open %s") % filename
);
89 /*free the document */
93 * Cleanup function for the XML library.
98 operator xmlDocPtr() {
106 char *getAttribute(xmlNode
*node
, const char *name
, bool required
= false) {
107 char *result
= reinterpret_cast<char*>(xmlGetNoNsProp(
108 node
, reinterpret_cast<const xmlChar
*>(name
)));
109 if( required
&& (result
== 0) )
110 throw ParseException(
111 util::format("Expected an attribute %s on node %s") % name
% node
->name
);
116 int getIntAttribute(xmlNode
*node
, const char *name
, int base
= 10, bool required
= false) {
117 xmlChar
*result
= xmlGetNoNsProp(node
,
118 reinterpret_cast<const xmlChar
*>(name
));
122 ret
= strtoul( reinterpret_cast<char*>(result
), 0, base
);
124 } else if( required
) {
125 throw ParseException(
126 util::format("Expected an attribute %s on node %s") % name
% node
->name
);
132 int getIntAttributeDef(xmlNode
*node
, const char *name
, int def
= 0, int base
= 10) {
133 xmlChar
*result
= xmlGetNoNsProp(node
,
134 reinterpret_cast<const xmlChar
*>(name
));
138 ret
= strtoul( reinterpret_cast<char*>(result
), 0, base
);
147 void freeAttribute(char *attr
) {
148 xmlFree( reinterpret_cast<xmlChar
*>(attr
) );
151 bool compare(const xmlChar
*a
, const char *b
) {
152 return strcmp( reinterpret_cast<const char*>(a
), b
) == 0;
155 HardwareSettings::HardwareSettings(XmlHandle
& doc
, _xmlNode
*node
)
156 : doc(doc
), node(node
) {
158 reg
= node
->children
;
159 while( (reg
!= 0) && (reg
->type
!= XML_ELEMENT_NODE
) )
163 int HardwareSettings::intAttribute(const char *name
, int base
/*= 10*/) const {
164 return getIntAttribute(node
, name
, base
, true);
167 int HardwareSettings::intAttributeDef(const char *name
,
168 int def
/*=0*/, int base
/*= 10*/) const {
169 return getIntAttributeDef(node
, name
, def
, base
);
172 std::string
HardwareSettings::strAttribute(const char *name
) const {
173 char *s
= getAttribute(node
, name
, true);
179 bool HardwareSettings::getBinding(std::string
& name
, std::string
& binding
) {
183 name
= reinterpret_cast<const char*>( reg
->name
);
186 // Get binding registers
187 xmlChar
*txt
= xmlNodeListGetString(doc
, reg
->children
, 1);
188 binding
= reinterpret_cast<const char*>( txt
);
193 } while( (reg
!= 0) && (reg
->type
!= XML_ELEMENT_NODE
) );
197 void DeviceSettings::parseMemory(Device
*dev
, xmlNode
*memory
) {
198 unsigned int ioSpaceSize
= 0;
199 unsigned int flashSize
= 0;
200 unsigned int sramSize
= 0;
201 unsigned int pcSize
= 2;
202 unsigned int stackMask
= 0xffff;
204 for(xmlNode
*node
= memory
->children
; node
!= 0; node
= node
->next
) {
205 if( node
->type
== XML_ELEMENT_NODE
) {
206 if( compare(node
->name
, "stack") ) {
207 stackMask
= getIntAttribute(node
, "mask", 16, true);
210 unsigned int *size
= 0;
211 if( compare(node
->name
, "flash") )
213 if( compare(node
->name
, "sram") )
215 if( compare(node
->name
, "pc") )
217 if( compare(node
->name
, "iospace") )
221 *size
= getIntAttribute(node
, "size", 10, true);
226 std::cout
<< "ioSpaceSize = " << ioSpaceSize
<< std::endl
;
227 std::cout
<< "flashSize = " << flashSize
<< std::endl
;
228 std::cout
<< "sramSize = " << sramSize
<< std::endl
;
229 std::cout
<< "pcSize = " << pcSize
<< std::endl
;
230 std::cout
<< "stackMask = " << stackMask
<< std::endl
;
233 dev
->buildCore(ioSpaceSize
, sramSize
, flashSize
, stackMask
, pcSize
);
236 void DeviceSettings::parseRegisters(Device
*dev
, xmlNode
*registers
) {
237 for(xmlNode
*node
= registers
->children
; node
!= 0; node
= node
->next
) {
238 if( node
->type
== XML_ELEMENT_NODE
) {
239 char *n
= getAttribute(node
, "name", true);
240 unsigned int address
= getIntAttribute(node
, "address", 16, true);
241 unsigned char initial
= getIntAttributeDef(node
, "initial", 0, 16);
242 dev
->addIOReg(address
, std::string(n
), initial
);
244 std::cout
<< "Adding register "<< n
245 << " at address "<< address
246 << ", initial value = "
247 << std::hex
<< (int)initial
<< std::dec
256 void DeviceSettings::parseInterrupts(Device
*dev
, xmlNode
*interrupts
) {
257 for(xmlNode
*node
= interrupts
->children
; node
!= 0; node
= node
->next
) {
258 if( node
->type
== XML_ELEMENT_NODE
) {
259 unsigned int vector
= getIntAttribute(node
, "vector", 10, true);
260 unsigned int address
= getIntAttribute(node
, "address", 16, true);
261 char *name
= getAttribute(node
, "name", true);
263 dev
->addInterrupt(vector
, address
, name
);
265 std::cout
<< "Adding interrupt "<< vector
266 << " at address "<< std::hex
<< address
<< std::dec
267 << ", name = " << name
276 void DeviceSettings::parseHardware(Device
*dev
, XmlHandle
& doc
, xmlNode
*hardware
) {
277 for(xmlNode
*node
= hardware
->children
; node
!= 0; node
= node
->next
) {
278 if( node
->type
== XML_ELEMENT_NODE
) {
279 const char *hwname
= reinterpret_cast<const char*>( node
->name
);
280 HardwareSettings
hws( doc
, node
);
281 dev
->buildHardware( hwname
, hws
);
286 void DeviceSettings::load(Device
*dev
, const char *devicename
) {
287 std::string
filename( SETTINGS_DIR
);
288 filename
+= devicename
;
290 XmlHandle
doc(filename
.c_str() );
292 //xmlDebugDumpDocument(stdout, doc);
294 /*Get the root element node */
295 xmlNode
*root
= xmlDocGetRootElement(doc
);
296 for(xmlNode
*node
= root
->children
; node
!= 0; node
= node
->next
) {
297 if( node
->type
== XML_ELEMENT_NODE
) {
298 if( compare(node
->name
, "memory") )
299 parseMemory(dev
, node
);
301 if( compare(node
->name
, "ioregisters") )
302 parseRegisters(dev
, node
);
304 if( compare(node
->name
, "interrupts") )
305 parseInterrupts(dev
, node
);
307 if( compare(node
->name
, "hardware") )
308 parseHardware(dev
, doc
, node
);