Browse Source

Support XML configuration of device models

Suren A. Chilingaryan 8 years ago
parent
commit
eec7e74d2e
12 changed files with 261 additions and 27 deletions
  1. 7 0
      misc/ipedevices.xml
  2. 1 1
      pci
  3. 14 12
      pcilib/pci.c
  4. 185 11
      pcilib/xml.c
  5. 10 0
      pcilib/xml.h
  6. 8 0
      pcitool.spec.in
  7. 1 1
      run
  8. 5 0
      xml/CMakeLists.txt
  9. 24 0
      xml/devices.xsd
  10. 4 0
      xml/devices/testdevice.xml
  11. 1 1
      xml/test/camera.xml
  12. 1 1
      xml/test/dma.xml

+ 7 - 0
misc/ipedevices.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<devices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <device vendor="10ee" device="0" model="ipecamera"/>
+  <device vendor="10ee" device="1" model="ipecamera"/>
+  <device vendor="10ee" device="2" model="ipedma"/>
+  <device vendor="10ee" device="3" model="ipedma"/>
+</devices>

+ 1 - 1
pci

@@ -2,4 +2,4 @@
 
 APP_PATH=`dirname $0`
 
-PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $APP_PATH/pcitool/pci $*
+PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_MODEL_DIR="$APP_PATH/xml" PCILIB_DATA_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $APP_PATH/pcitool/pci $*

+ 14 - 12
pcilib/pci.c

@@ -86,13 +86,6 @@ static int pcilib_detect_model(pcilib_t *ctx, const char *model) {
 	    pcilib_add_register_ranges(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, model_info->ranges);
     }
 
-    // Load XML registers
-
-    // Check for all installed models
-    // memcpy(&ctx->model_info, model, sizeof(pcilib_model_description_t));
-    // how we reconcile the banks from event model and dma description? The banks specified in the DMA description should override corresponding banks of events...
-
-
     if (!model_info) {
 	if ((model)&&(strcasecmp(model, "pci"))/*&&(no xml)*/)
 	    return PCILIB_ERROR_NOTFOUND;
@@ -108,6 +101,7 @@ static int pcilib_detect_model(pcilib_t *ctx, const char *model) {
 pcilib_t *pcilib_open(const char *device, const char *model) {
     int err, xmlerr;
     pcilib_t *ctx = malloc(sizeof(pcilib_t));
+    const pcilib_board_info_t *board_info;
     const pcilib_driver_version_t *drv_version;
 	
     if (!model)
@@ -138,6 +132,17 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
 	    return ctx;
 	}
 
+	board_info = pcilib_get_board_info(ctx);
+	if (!board_info) {
+	    pcilib_error("Failed to enumerate PCI device");
+	    pcilib_close(ctx);
+	    return NULL;
+	}
+
+	    // Check if model is specified in the XML configuration
+	if (!model)
+	    model = pcilib_detect_xml_model(ctx, board_info->vendor_id, board_info->device_id);
+
 	err = pcilib_init_locking(ctx);
 	if (err) {
 	    pcilib_error("Error (%i) initializing locking subsystem", err);
@@ -151,6 +156,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
 	    pcilib_free_py(ctx);
 	}
 
+
 	ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE;
 	ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE;
 	ctx->alloc_units = PCILIB_DEFAULT_UNIT_SPACE;
@@ -179,11 +185,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
 
 	err = pcilib_detect_model(ctx, model);
 	if ((err)&&(err != PCILIB_ERROR_NOTFOUND)) {
-	    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
-	    if (board_info)
-	        pcilib_error("Error (%i) configuring model %s (%x:%x)", err, (model?model:""), board_info->vendor_id, board_info->device_id);
-	    else
-	        pcilib_error("Error (%i) configuring model %s", err, (model?model:""));
+	    pcilib_error("Error (%i) configuring model %s (%x:%x)", err, (model?model:""), board_info->vendor_id, board_info->device_id);
 	    pcilib_close(ctx);
 	    return NULL;
 	}

+ 185 - 11
pcilib/xml.c

@@ -49,12 +49,11 @@
 #define REGISTERS_PATH ((xmlChar*)"./register")		 			/**< all standard registers nodes */
 #define BIT_REGISTERS_PATH ((xmlChar*)"./field") 				/**< all bits registers nodes */
 #define REGISTER_VIEWS_PATH ((xmlChar*)"./view") 				/**< supported register & field views */
-#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform")		/**< path to complete nodes of views */
+#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform")			/**< path to complete nodes of views */
 #define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum")	 			/**< path to complete nodes of views */
 #define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") 				/**< all elements in the enum */
 #define UNITS_PATH ((xmlChar*)"/model/unit")	 				/**< path to complete nodes of units */
-#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") 			/**< all transforms of the unit */
-
+#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform")				/**< all transforms of the unit */
 
 
 static const char *pcilib_xml_bank_default_format = "0x%lx";
@@ -892,7 +891,7 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon
     return 0;
 }
 
-static int pcilib_xml_load_xsd_file(pcilib_t *ctx, char *xsd_filename, xmlSchemaPtr *schema, xmlSchemaValidCtxtPtr *validator) {
+static int pcilib_xml_load_xsd_file(pcilib_t *ctx, const char *xsd_filename, xmlSchemaPtr *schema, xmlSchemaValidCtxtPtr *validator) {
     int err;
 
     xmlSchemaParserCtxtPtr ctxt;
@@ -923,6 +922,7 @@ static int pcilib_xml_load_xsd_file(pcilib_t *ctx, char *xsd_filename, xmlSchema
     *validator  = xmlSchemaNewValidCtxt(*schema);
     if (!*validator) {
         xmlErrorPtr xmlerr = xmlGetLastError();
+	xmlSchemaFree(*schema); *schema = NULL;
         if (xmlerr) pcilib_error("xmlSchemaNewValidCtxt reported error %d - %s", xmlerr->code, xmlerr->message);
         else pcilib_error("Failed to create a validation context");
         return PCILIB_ERROR_FAILED;
@@ -931,6 +931,8 @@ static int pcilib_xml_load_xsd_file(pcilib_t *ctx, char *xsd_filename, xmlSchema
     err = xmlSchemaSetValidOptions(*validator, XML_SCHEMA_VAL_VC_I_CREATE);
     if (err) {
         xmlErrorPtr xmlerr = xmlGetLastError();
+	xmlSchemaFreeValidCtxt(*validator); *validator = NULL;
+	xmlSchemaFree(*schema); *schema = NULL;
         if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message);
         else pcilib_error("Failed to configure the validation context to populate default attributes");
         return PCILIB_ERROR_FAILED;
@@ -939,8 +941,87 @@ static int pcilib_xml_load_xsd_file(pcilib_t *ctx, char *xsd_filename, xmlSchema
     return 0;
 }
 
+/*
+static xmlDocPtr pcilib_xml_load_xml_file(pcilib_t *ctx, const char *xsd_filename, const char *xml_filename) {
+    int err;
+    xmlDocPtr doc;
+    xmlSchemaPtr schema;
+    xmlSchemaValidCtxtPtr validator;
+    xmlParserCtxtPtr parser;
+
+    err = pcilib_xml_load_xsd_file(ctx, xsd_filename, &schema, &validator);
+    if (err) {
+	pcilib_error("Error (%i) parsing the devices schema (%s)", err, xsd_filename);
+	return NULL;
+    }
 
-static int pcilib_xml_load_xsd(pcilib_t *ctx, char *model_dir) {
+    parser = xmlNewParserCtxt();
+    if (!parser) {
+        xmlErrorPtr xmlerr = xmlGetLastError();
+	xmlSchemaFree(schema);
+	xmlSchemaFreeValidCtxt(validator);
+        if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
+        else pcilib_error("Failed to create an XML parser context");
+        return NULL;
+    }
+
+    doc = xmlCtxtReadFile(parser, xml_filename, NULL, 0);
+    if (!doc) {
+        xmlErrorPtr xmlerr = xmlGetLastError();
+	xmlFreeParserCtxt(parser);
+	xmlSchemaFree(schema);
+	xmlSchemaFreeValidCtxt(validator);
+	if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
+        else pcilib_error("Error parsing %s", xml_filename);
+	return NULL;
+    }
+    
+    err = xmlSchemaValidateDoc(validator, doc);
+    if (err) {
+        xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
+	xmlFreeDoc(doc);
+	xmlFreeParserCtxt(parser);
+	xmlSchemaFree(schema);
+	xmlSchemaFreeValidCtxt(validator);
+        if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", xml_filename, xmlerr->code, xmlerr->message);
+        else pcilib_error("Error validating %s", xml_filename);
+        return NULL;
+    }
+
+    xmlFreeParserCtxt(parser);
+    xmlSchemaFree(schema);
+    xmlSchemaFreeValidCtxt(validator);
+
+    return doc;
+}
+*/
+
+static xmlXPathObjectPtr pcilib_xml_eval_xpath_expression(pcilib_t *ctx, xmlDocPtr doc, const xmlChar *query) {
+    xmlXPathContextPtr xpath;
+    xmlXPathObjectPtr nodes;
+
+    xpath = xmlXPathNewContext(doc);
+    if (!xpath) {
+        xmlErrorPtr xmlerr = xmlGetLastError();
+        if (xmlerr) pcilib_error("xmlXpathNewContext reported error %d - %s", xmlerr->code, xmlerr->message);
+        else pcilib_error("Error creating XPath context");
+        return NULL;
+    }
+
+    nodes = xmlXPathEvalExpression(query, xpath);
+    if (!nodes) {
+        xmlErrorPtr xmlerr = xmlGetLastError();
+	xmlXPathFreeContext(xpath);
+        if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", query, xmlerr->code, xmlerr->message);
+        else pcilib_error("Failed to parse XPath expression %s", query);
+        return NULL;
+    }
+
+    xmlXPathFreeContext(xpath);
+    return nodes;
+}
+
+static int pcilib_xml_load_xsd(pcilib_t *ctx, const char *model_dir) {
     int err;
 
     struct stat st;
@@ -969,7 +1050,7 @@ static int pcilib_xml_load_xsd(pcilib_t *ctx, char *model_dir) {
 
 
 
-static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, const char *path, const char *name) {
+static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, xmlParserCtxtPtr parser, xmlSchemaValidCtxtPtr validator, const char *path, const char *name) {
     int err;
     char *full_name;
     xmlDocPtr doc;
@@ -982,17 +1063,17 @@ static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, const char *path, const cha
 
     sprintf(full_name, "%s/%s", path, name);
 
-    doc = xmlCtxtReadFile(ctx->xml.parser, full_name, NULL, 0);
+    doc = xmlCtxtReadFile(parser, full_name, NULL, 0);
     if (!doc) {
-        xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
+        xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
         if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
         else pcilib_error("Error parsing %s", full_name);
         return NULL;
     }
 
-    err = xmlSchemaValidateDoc(ctx->xml.parts_validator, doc);
+    err = xmlSchemaValidateDoc(validator, doc);
     if (err) {
-        xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser);
+        xmlErrorPtr xmlerr = xmlCtxtGetLastError(parser);
         xmlFreeDoc(doc);
         if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message);
         else pcilib_error("Error validating %s", full_name);
@@ -1002,6 +1083,11 @@ static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, const char *path, const cha
     return doc;
 }
 
+static xmlDocPtr pcilib_xml_load_model_file(pcilib_t *ctx, const char *path, const char *name) {
+    return pcilib_xml_load_file(ctx, ctx->xml.parser, ctx->xml.parts_validator, path, name);
+}
+
+
 static int pcilib_process_xml_internal(pcilib_t *ctx, const char *model, const char *location) {
     int err;
 
@@ -1039,7 +1125,7 @@ static int pcilib_process_xml_internal(pcilib_t *ctx, const char *model, const c
         if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
         if (file->d_type != DT_REG) continue;
 
-        newdoc = pcilib_xml_load_file(ctx, model_path, file->d_name);
+        newdoc = pcilib_xml_load_model_file(ctx, model_path, file->d_name);
         if (!newdoc) {
             pcilib_error("Error processing XML file %s", file->d_name);
             continue;
@@ -1190,3 +1276,91 @@ void pcilib_free_xml(pcilib_t *ctx) {
         xmlMemoryDump();
     */
 }
+
+
+char *pcilib_detect_xml_model(pcilib_t *ctx, unsigned int vendor_id, unsigned int device_id) {
+    int err;
+    char *model = NULL;
+    xmlSchemaPtr schema;  				/**< Pointer to the parsed xsd schema */
+    xmlSchemaValidCtxtPtr validator;       		/**< Pointer to the XML validation context */
+    xmlParserCtxtPtr parser;				/**< Pointer to the XML parser context */
+
+    DIR *rep;
+    struct dirent *file = NULL;
+    struct stat st;
+    const char *data_dir;
+    char *xsd_path, *xml_path;
+
+    xmlXPathObjectPtr nodes;
+    xmlChar xpath_query[64];
+
+    xmlStrPrintf(xpath_query, sizeof(xpath_query), (xmlChar*)"/devices/device[@vendor=%x and @device=%x]/@model", vendor_id, device_id);
+
+    data_dir = getenv("PCILIB_DATA_DIR");
+    if (!data_dir) data_dir = PCILIB_DATA_DIR;
+
+    xsd_path = (char*)alloca(strlen(data_dir) + 32);
+    xml_path = (char*)alloca(strlen(data_dir) + 32);
+    if ((!xsd_path)||(!xml_path)) {
+	pcilib_error("Error allocating stack memory");
+	return NULL;
+    }
+
+    sprintf(xsd_path, "%s/devices.xsd", data_dir);
+    sprintf(xml_path, "%s/devices", data_dir);
+    if (stat(xsd_path, &st)||stat(xml_path, &st)) {
+        pcilib_info("No XML devices are defined, missing devices schema or list");
+        return NULL;
+    }
+
+    parser = xmlNewParserCtxt();
+    if (!parser) {
+        xmlErrorPtr xmlerr = xmlGetLastError();
+        if (xmlerr) pcilib_error("xmlNewParserCtxt reported error %d (%s)", xmlerr->code, xmlerr->message);
+        else pcilib_error("Failed to create an XML parser context");
+        return NULL;
+    }
+
+    err = pcilib_xml_load_xsd_file(ctx, xsd_path, &schema, &validator);
+    if (err) {
+	xmlFreeParserCtxt(parser);
+	pcilib_error("Error (%i) parsing the device schema (%s)", err, xsd_path);
+	return NULL;
+    }
+
+    rep = opendir(xml_path);
+    if (!rep) goto cleanup;
+
+    while ((model == NULL)&&((file = readdir(rep)) != NULL)) {
+	xmlDocPtr doc;
+        
+        size_t len = strlen(file->d_name);
+        if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue;
+        if (file->d_type != DT_REG) continue;
+
+	doc = pcilib_xml_load_file(ctx, parser, validator, xml_path, file->d_name);
+	if (!doc) continue;
+
+	nodes = pcilib_xml_eval_xpath_expression(ctx, doc, xpath_query);
+	if (!nodes) {
+	    xmlFreeDoc(doc);
+	    continue;
+	}
+
+	if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) {
+	    xmlNodePtr node = nodes->nodesetval->nodeTab[0];
+	    model = strdup((char*)node->children->content);
+	}
+
+	xmlXPathFreeObject(nodes);
+	xmlFreeDoc(doc);
+    }
+    closedir(rep);
+
+cleanup:    
+    xmlSchemaFree(schema);
+    xmlSchemaFreeValidCtxt(validator);
+    xmlFreeParserCtxt(parser);
+
+    return model;
+}

+ 10 - 0
pcilib/xml.h

@@ -40,6 +40,16 @@ struct pcilib_xml_s {
 extern "C" {
 #endif
 
+/**
+ * Resolves device model from vendor and device ids using XML configuration
+ * The association of vendor/device id pairs with model are provided devices.xml under PCILIB_MODEL_DIR
+ * @param[in,out] ctx 	- pcilib context
+ * @param[in] vendor_id	- the vendor id
+ * @param[in] device_id	- the device id
+ * @return 		- the name of model or NULL on an error and unknown device. It is caller responsibility to free returned string.
+ */
+char *pcilib_detect_xml_model(pcilib_t *ctx, unsigned int vendor_id, unsigned int device_id);
+
 /** Initializes XML stack and loads a default set of XML files. 
  * The default location for XML files is /usr/local/share/pcilib/models/@b{model}.
  * This can be altered using CMake PCILIB_MODEL_DIR variable while building or using 

+ 8 - 0
pcitool.spec.in

@@ -143,6 +143,10 @@ cp -r driver $RPM_BUILD_ROOT/usr/src/%{modname}-%{version}/
 
 # Sample model
 cp -r xml/test $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/
+cp -r xml/devices $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/
+
+# Default configuration
+install -m 644 misc/ipedevices.xml $RPM_BUILD_ROOT/%{_datadir}/pcilib${PCILIB_ABI_VERSION}/devices/
 
 # Servers
 mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
@@ -200,8 +204,11 @@ exit 0
 %doc docs/HARDWARE
 %dir %{_libdir}/pcilib${PCILIB_ABI_VERSION}/
 %dir %{_datadir}/pcilib${PCILIB_ABI_VERSION}/
+%dir %{_datadir}/pcilib${PCILIB_ABI_VERSION}/devices/
 %dir %{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/*.xsd
 %{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/*.xsd
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/devices/ipedevices.xml
 %{_libdir}/libpcilib.so.*
 
 %files -n libpcilib-devel
@@ -216,6 +223,7 @@ exit 0
 %files -n pcilib-test
 %defattr(-, root, root)  
 %{_datadir}/pcilib${PCILIB_ABI_VERSION}/models/test
+%{_datadir}/pcilib${PCILIB_ABI_VERSION}/devices/testdevice.xml
 
 %files -n pcilib-dkms
 %defattr(-, root, root)  

+ 1 - 1
run

@@ -2,4 +2,4 @@
 
 APP_PATH=`dirname $0`
 
-PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_SCRIPTS_DIR="$APP_PATH/pyserver/scripts" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $*
+PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_SCRIPTS_DIR="$APP_PATH/pyserver/scripts" PCILIB_MODEL_DIR="$APP_PATH/xml" PCILIB_DATA_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $*

+ 5 - 0
xml/CMakeLists.txt

@@ -1,3 +1,8 @@
+
+install(FILES devices.xsd
+    DESTINATION ${PCILIB_DATA_DIR}
+)
+
 install(FILES model.xsd references.xsd types.xsd
     DESTINATION ${PCILIB_MODEL_DIR}
 )

+ 24 - 0
xml/devices.xsd

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:include schemaLocation="types.xsd"/>
+
+  <xsd:simpleType name="hex16_t">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="([a-fA-F0-9]){1,4}"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="device_t">
+    <xsd:attribute name="vendor" type="hex16_t" />
+    <xsd:attribute name="device" type="hex16_t" />
+    <xsd:attribute name="model" type="xsd:string" />
+  </xsd:complexType>
+
+  <xsd:element name="devices">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element name="device" type="device_t" minOccurs="0" maxOccurs="unbounded" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>

+ 4 - 0
xml/devices/testdevice.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<devices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <device vendor="0000" device="0" model="test"/>
+</devices>

+ 1 - 1
xml/test/camera.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x9000" write_address="0x9000" word_size="32" endianess="little" format="0x%lx" name="fpga" description="IPECamera Registers">
+  <bank size="0x0200" protocol="software_registers" read_address="0x9000" write_address="0x9000" word_size="32" endianess="little" format="0x%lx" name="fpga" description="IPECamera Registers">
     <register address="0x00" offset="0" size="32" default="0" rwmask="0" mode="RW" name="spi_conf_input"/>
     <register address="0x10" offset="0" size="32" default="0" rwmask="0" mode="R" name="spi_conf_output"/>
     <register address="0x20" offset="0" size="32" default="0" rwmask="0" mode="RW" name="spi_clk_speed"/>

+ 1 - 1
xml/test/dma.xml

@@ -1,4 +1,4 @@
 <?xml version="1.0"?>
 <model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x0" write_address="0x0" word_size="32" endianess="little" format="0x%lx" name="dma" description="DMA Registers"/>
+  <bank size="0x0200" protocol="software_registers" read_address="0x0" write_address="0x0" word_size="32" endianess="little" format="0x%lx" name="dma" description="DMA Registers"/>
 </model>