driver-gen/xml-lib: Search for version header files in the correct dir
[driver-gen.git] / xml-access.c
blob204fea6afb8816cd4c34500c4e27e56d9fd1005a
1 /**
2 * @file xmlAccess.c
4 * @brief xml file access to get hw module description is here.
6 * @author Copyright (C) 2009 - 2010 GSI. Braeuning, Harald
7 * @author Copyright (C) 2010 CERN. Georgievskiy Yury <ygeorgie@gmail.com>
9 * @date Created on 14/12/2009
11 #define _GNU_SOURCE /* asprintf rocks */
13 #include <stdio.h>
14 #include <libxml/parser.h>
15 #include <libxml/tree.h>
16 #include "driverGen.h"
17 #include "utilities.h"
19 #define ROOT_TAG "DriverGen"
20 #define MODULE_TAG "Module"
21 #define BLOCK_TAG "Block"
22 #define BLOCK_BASE_TAG "Base"
23 #define BLOCK_OFFSET_TAG "Offset"
24 #define REGISTER_TAG "Register"
25 #define REGISTER_BLOCK_TAG "Block"
26 #define REGISTER_OFFSET_TAG "Offset"
27 #define REGISTER_DEPTH_TAG "Depth"
28 #define REGISTER_MODE_TAG "Mode"
29 #define REGISTER_SIZE_TAG "Size"
30 #define REGISTER_TIMELOOP_TAG "TimeLoop"
31 #define REGISTER_COMMENT_TAG "Comment"
32 #define PCI_TAG "PCI"
33 #define PCI_VENDOR_TAG "Vendor"
34 #define PCI_DEVICE_TAG "Device"
35 #define VME_TAG "VME"
36 #define VME_ADDRESS_TAG "Address"
37 #define VME_ADDRESS_RANGE_TAG "Range"
38 #define VME_ADDRESS_INCREMENT_TAG "Increment"
39 #define VME_ADDRESS_AM_TAG "AM"
40 #define VME_ADDRESS_SIZE_TAG "Size"
41 #define VME_TYPE_TAG "Type"
42 #define VME_CHANNELS_TAG "Channels"
43 #define VME_IRQ_TAG "Irq"
44 #define VME_IRQVECTOR_TAG "IrqVector"
45 #define VME_IRQVECTORINC_TAG "IrqVectorInc"
49 #define NODE_ROOT "DriverGen"
50 #define NODE_MODULE "module"
51 #define NODE_VME "vme_space"
52 #define NODE_BLK "block"
53 #define NODE_REG "register"
55 #define PROP_NAME "name"
56 #define PROP_BA "base"
57 #define PROP_ADDR_INCR "addrinc"
58 #define PROP_AM "am"
59 #define PROP_RANGE "range"
60 #define PROP_DPS "dps"
61 #define PROP_OFFSET "offset"
62 #define PROP_DEPTH "depth"
63 #define PROP_MODE "mode"
64 #define PROP_SIZE "size"
65 #define PROP_TLOOP "timeloop"
66 #define PROP_COMMENT "comment"
67 #define PROP_ILEVEL "ilevel"
68 #define PROP_IVEC "ivec"
69 #define PROP_IVEC_INCR "ivecinc"
71 static xmlDoc *doc = NULL;
72 static xmlNode *rootElement = NULL;
73 static xmlNode *moduleElement = NULL;
75 static void PrintOutVmeInfo(VmeInfo_t *);
76 static void ReadXMLFile(char *moduleName);
78 /**
79 * @brief Get register description from the DataBase.
81 * @param moduleName -- DataBase Module Name
82 * @param defs -- register description to put
83 * @param blks -- block description
84 * @param numBlks -- number of blocks
85 * @param prog -- program name
87 * Registers are prepared for the further use. If MAX allowed register amount
88 * reached - printout error message and exits.
90 * @return number of registers, defined in the DB.
92 int XMLGetRegisterConfig(char *moduleName, RegisterDef_t *defs,
93 BlockDef_t *blks, int numBlks, char *prog)
95 int idx = 0; /* register counter */
96 int maxReg; /* */
97 int cntr; /* */
99 if (doc == NULL) ReadXMLFile(moduleName);
101 maxReg = MAX_REG - GetSrvRegNum(); /* how many reg descr we can have */
103 xmlNode *n = moduleElement->children;
104 while (n != NULL)
106 if (n->type == XML_ELEMENT_NODE && strcasecmp((char*)n->name,REGISTER_TAG) == 0)
108 if (idx < maxReg) {
109 char *p = (char*)xmlGetProp(n,(xmlChar*)"name");
110 if (p != NULL)
112 snprintf(defs[idx].name,NAME_LEN,"%s",p);
113 xmlFree(p);
115 xmlNode *b = n->children;
116 while (b != NULL)
118 if (strcasecmp((char*)b->name,REGISTER_BLOCK_TAG) == 0)
120 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
121 short blockno = (short)strtoul(str,NULL,0);
122 for (cntr = 0; cntr < numBlks; cntr++) {
123 if (blks[cntr].blockID == blockno) {
124 defs[idx].blockP = &blks[cntr];
125 break;
128 xmlFree(str);
130 else if (strcasecmp((char*)b->name,REGISTER_TIMELOOP_TAG) == 0)
132 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
133 defs[idx].timeLoop = strtoul(str,NULL,0);
134 xmlFree(str);
136 else if (strcasecmp((char*)b->name,REGISTER_OFFSET_TAG) == 0)
138 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
139 defs[idx].offset = strtoul(str,NULL,0);
140 xmlFree(str);
142 else if (strcasecmp((char*)b->name,REGISTER_DEPTH_TAG) == 0)
144 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
145 defs[idx].depth = strtoul(str,NULL,0);
146 xmlFree(str);
148 else if (strcasecmp((char*)b->name,REGISTER_SIZE_TAG) == 0)
150 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
151 snprintf(defs[idx].size, SIZE_LEN, "%s", str);
152 xmlFree(str);
154 else if (strcasecmp((char*)b->name,REGISTER_MODE_TAG) == 0)
156 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
157 snprintf(defs[idx].mode, MODE_LEN, "%s", str);
158 xmlFree(str);
160 else if (strcasecmp((char*)b->name,REGISTER_COMMENT_TAG) == 0)
162 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
163 snprintf(defs[idx].comment, COMMENT_LEN, "%s", str);
164 xmlFree(str);
166 b = b->next;
169 idx++; /* increase register counter */
171 n = n->next;
175 if (idx >= maxReg) { /* check if within range */
176 fprintf(stderr,
177 "%sFATAL%s %s Module %s has too many registers.\n",
178 RED_CLR, END_CLR, ERROR_MSG, moduleName);
179 fprintf(stderr, "\t'%s' supports MAX %d registers (including"
180 " service registers).\n\tYour module has %d register"
181 " definitions (plus %d service registers)\n\t'MAX_REG'"
182 " should be changed.\n\tPlease report this problem to"
183 " the DriverGen support!\n",
184 prog, MAX_REG, idx, GetSrvRegNum());
185 exit(EXIT_FAILURE); /* 1 */
188 defs[idx-1].last = 1; /* mark last register */
189 return idx;
193 * @brief Get block configuration from the DataBase.
195 * @param moduleName -- DataBase Module Name
196 * @param defs -- results will go here
197 * @param prog -- program name
199 * prepare results for the further use. If MAX allowed block amount
200 * reached - printout error message and exits.
202 * @return number of defined blocks
204 int XMLGetBlockConfig(char *moduleName, BlockDef_t * defs, char *prog)
206 int idx = 0; /* block counter */
208 if (doc == NULL) ReadXMLFile(moduleName);
209 xmlNode *n = moduleElement->children;
210 while (n != NULL)
212 if (n->type == XML_ELEMENT_NODE && strcasecmp((char*)n->name,BLOCK_TAG) == 0)
214 if (idx < MAX_BLK) {
215 defs[idx].blockID = -1;
216 char *p = (char*)xmlGetProp(n,(xmlChar*)"id");
217 if (p != NULL)
219 defs[idx].blockID = (short)atoi(p);
220 xmlFree(p);
222 xmlNode *b = n->children;
223 while (b != NULL)
225 if (strcasecmp((char*)b->name,BLOCK_BASE_TAG) == 0)
227 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
228 defs[idx].blkBaseAddr = (short)strtoul(str,NULL,0);
229 xmlFree(str);
231 else if (strcasecmp((char*)b->name,BLOCK_OFFSET_TAG) == 0)
233 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
234 defs[idx].offset = strtoul(str,NULL,0);
235 xmlFree(str);
237 b = b->next;
240 idx++; /* increase block counter */
242 n = n->next;
245 if (idx >= MAX_BLK) { /* check if within range */
246 fprintf(stderr, "%sFATAL%s %s Module %s has too many blocks.\n",
247 RED_CLR, END_CLR, ERROR_MSG, moduleName);
248 fprintf(stderr, "\t'%s' supports MAX %d blocks.\n\tYour module"
249 " has %d block definitions\n\t'MAX_BLK' should be"
250 " changed.\n\tPlease report this problem to the"
251 " DriverGen support!\n", prog, MAX_BLK, idx);
252 exit(EXIT_FAILURE); /* 1 */
255 return idx;
259 * @brief Get PCI board information from the database.
261 * @param moduleName -- DataBase Module Name
262 * @param pciInfo -- results will go here
264 * @return DRIVER_GEN_OK - if PCI board info is obtained.
265 * @return DRIVER_GEN_BAD - othervise.
267 rstat XMLGetPciInfo(char *moduleName, PciInfo_t * pciInfo)
269 if (doc == NULL) ReadXMLFile(moduleName);
270 xmlNode *n = moduleElement->children;
271 while (n != NULL)
273 if (n->type == XML_ELEMENT_NODE && strcasecmp((char*)n->name,PCI_TAG) == 0)
275 xmlNode *b = n->children;
276 while (b != NULL)
278 if (strcasecmp((char*)b->name,PCI_VENDOR_TAG) == 0)
280 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
281 pciInfo->vendorId = strtoul(str,NULL,0);
282 xmlFree(str);
284 else if (strcasecmp((char*)b->name,PCI_DEVICE_TAG) == 0)
286 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
287 pciInfo->deviceId = strtoul(str,NULL,0);
288 xmlFree(str);
290 b = b->next;
292 pciInfo->vendorId = ASSERT_MSB(pciInfo->vendorId);
293 pciInfo->deviceId = ASSERT_MSB(pciInfo->deviceId);
294 return DRIVER_GEN_OK;
296 n = n->next;
298 return DRIVER_GEN_BAD;
302 * @brief Get VME board information from the database.
304 * @param moduleName -- DataBase Module Name
305 * @param vmeInfo -- results will go here
307 * @return DRIVER_GEN_OK - if VME board info is obtained.
308 * @return DRIVER_GEN_BAD - othervise.
310 rstat XMLGetVmeInfo(char *moduleName, VmeInfo_t *vmeInfo)
312 int addrSpace = 0;
314 if (doc == NULL) ReadXMLFile(moduleName);
315 xmlNode *n = moduleElement->children;
316 while (n != NULL)
318 if (n->type == XML_ELEMENT_NODE && strcasecmp((char*)n->name,VME_TAG) == 0)
320 vmeInfo->addr1.baseAddr = NO_ADDRESS;
321 vmeInfo->addr2.baseAddr = NO_ADDRESS;
322 xmlNode *b = n->children;
323 while (b != NULL)
325 if (strcasecmp((char*)b->name,VME_ADDRESS_TAG) == 0)
327 addrSpace++;
328 VmeAddrInfo_t *addr = &vmeInfo->addr1;
329 if (addrSpace == 2) addr = &vmeInfo->addr2;
330 char *p = (char*)xmlGetProp(b,(xmlChar*)"base");
331 if (p != NULL)
333 addr->baseAddr = strtoul(p,NULL,0);
334 xmlFree(p);
336 xmlNode *a = b->children;
337 while (a != NULL)
339 if (strcasecmp((char*)a->name,VME_ADDRESS_AM_TAG) == 0)
341 char *str = (char*)xmlNodeListGetString(doc,a->children,1);
342 if (strcasecmp(str, "SH") == 0)
343 addr->addressModifier = DG_AM_SH;
344 else if (strcasecmp(str,"ST") == 0)
345 addr->addressModifier = DG_AM_ST;
346 else if (strcasecmp(str,"EX") == 0)
347 addr->addressModifier = DG_AM_EX;
348 else if (strcasecmp(str,"CR") == 0)
349 addr->addressModifier = DG_AM_CR;
350 else {
351 fprintf(stderr, "Unsupported AM (%s) detected for addr%d. Check xml file!\n",
352 str,addrSpace);
353 return DRIVER_GEN_BAD;
355 xmlFree(str);
357 else if (strcasecmp((char*)a->name,VME_ADDRESS_INCREMENT_TAG) == 0)
359 char *str = (char*)xmlNodeListGetString(doc,a->children,1);
360 addr->increment = strtol(str,NULL,0);
361 xmlFree(str);
363 else if (strcasecmp((char*)a->name,VME_ADDRESS_RANGE_TAG) == 0)
365 char *str = (char*)xmlNodeListGetString(doc,a->children,1);
366 addr->range = strtoul(str,NULL,0);
367 xmlFree(str);
369 else if (strcasecmp((char*)a->name,VME_ADDRESS_SIZE_TAG) == 0)
371 char *str = (char*)xmlNodeListGetString(doc,a->children,1);
372 addr->dpSize = strtol(str,NULL,0);
373 xmlFree(str);
375 a = a->next;
378 else if (strcasecmp((char*)b->name,VME_CHANNELS_TAG) == 0)
380 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
381 vmeInfo->chCntr = strtol(str,NULL,0);
382 xmlFree(str);
384 else if (strcasecmp((char*)b->name,VME_TYPE_TAG) == 0)
386 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
387 vmeInfo->mtn = strtol(str,NULL,0);
388 xmlFree(str);
390 else if (strcasecmp((char*)b->name,VME_IRQ_TAG) == 0)
392 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
393 vmeInfo->irq = strtol(str,NULL,0);
394 xmlFree(str);
396 else if (strcasecmp((char*)b->name,VME_IRQVECTOR_TAG) == 0)
398 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
399 vmeInfo->vector = strtol(str,NULL,0);
400 xmlFree(str);
402 else if (strcasecmp((char*)b->name,VME_IRQVECTORINC_TAG) == 0)
404 char *str = (char*)xmlNodeListGetString(doc,b->children,1);
405 vmeInfo->vectorInc = strtol(str,NULL,0);
406 xmlFree(str);
408 b = b->next;
410 if (verboseMode) /* verbose driverGen */
411 PrintOutVmeInfo(vmeInfo);
412 return DRIVER_GEN_OK;
414 n = n->next;
416 return DRIVER_GEN_BAD;
420 * @brief Printout VME configuration info.
422 * @param vmeInfo -- data to print
424 * @return void
426 static void PrintOutVmeInfo(VmeInfo_t * vmeInfo)
428 int cntr;
429 VmeAddrInfo_t *ptr;
431 /* general info */
432 printf("General information\n");
433 printf("-------------------\n");
434 printf("Module type number => %d\n", vmeInfo->mtn);
435 printf("Number of data channels => %s\n",
436 (vmeInfo->chCntr == -1) ? "NOT_DEFINED" : itoa(vmeInfo->chCntr,
437 10));
438 printf("Interrupt processing hardware level => %s\n",
439 (vmeInfo->irq == -1) ? "NOT_DEFINED" : itoa(vmeInfo->irq, 10));
440 printf("Interrupt vector => %s\n",
441 (vmeInfo->vector == -1) ? "NOT_DEFINED" : itoa(vmeInfo->vector,
442 10));
443 printf("Interrupt vector increment => %ld\n",
444 vmeInfo->vectorInc);
445 printf("\n");
447 /* address space specific information */
448 printf("Address space information\n");
449 printf("-------------------------\n");
450 ptr = &(vmeInfo->addr1);
451 for (cntr = 0; cntr < 2; cntr++, ptr++) {
452 if (ptr->baseAddr == NO_ADDRESS) {
453 printf("\nAddress space 'Addr%d' not defined.\n",
454 cntr + 1);
455 continue;
456 } else {
457 printf("Address space 'Addr%d' info:\n", cntr + 1);
458 printf("\tBase address => 0x%lx\n", ptr->baseAddr);
459 printf("\tAddress range => 0x%x\n", ptr->range);
460 printf("\tAddress increment => 0x%lx\n",
461 ptr->increment);
462 printf("\tDataport size => %ld\n", ptr->dpSize);
463 printf("\tAddress modifier => %s\n",
464 (ptr->addressModifier == DG_AM_SH) ? "SH - short" :
465 (ptr->addressModifier == DG_AM_ST) ? "ST - standard" :
466 (ptr->addressModifier == DG_AM_EX) ? "EX - extended" :
467 "CR - configuration");
472 static void ReadXMLFile(char *moduleName)
474 char fileName[512];
477 * this initialize the library and check potential ABI mismatches
478 * between the version it was compiled for and the actual shared
479 * library used.
481 LIBXML_TEST_VERSION
483 /*parse the file and get the DOM */
484 sprintf(fileName,"%s.xml",moduleName);
485 doc = xmlReadFile(fileName, NULL, 0);
487 if (doc == NULL) {
488 fprintf(stderr,
489 "%sFATAL%s %s Could not parse file: %s.\n",
490 RED_CLR, END_CLR, ERROR_MSG, fileName);
491 exit(EXIT_FAILURE); /* 1 */
494 /*Get the root element node */
495 rootElement = xmlDocGetRootElement(doc);
496 if (strcasecmp((char*)rootElement->name,ROOT_TAG) != 0)
498 fprintf(stderr,
499 "%sFATAL%s %s Illegal DriverGen xml file: %s.\n",
500 RED_CLR, END_CLR, ERROR_MSG, fileName);
501 exit(EXIT_FAILURE); /* 1 */
503 moduleElement = rootElement->children;
504 while (moduleElement != NULL)
506 if (moduleElement->type == XML_ELEMENT_NODE && strcasecmp((char*)moduleElement->name,MODULE_TAG) == 0)
508 xmlChar *p = xmlGetProp(moduleElement,(xmlChar*)"name");
509 if (p != NULL && strcmp((char*)p,moduleName) == 0) break;
511 moduleElement = moduleElement->next;
513 if (moduleElement == NULL)
515 fprintf(stderr,
516 "%sFATAL%s %s No valid module entry found for: %s.\n",
517 RED_CLR, END_CLR, ERROR_MSG, moduleName);
518 exit(EXIT_FAILURE); /* 1 */
523 * @brief Converts CERN-specific DB info table into xml module description
525 * @param ifn -- .info file to convert to .xml
527 * CERN Data Base has a form with a predefined module description layout.
528 * Info file generated from it has a fixed format of DevInfo_t type.
529 * Number of max allowed address spaces is fixed (2).
530 * Number of blocks and registers is not allocated dynamically and fixed
531 * in DevInfo_t structure.
532 * This information is stored in the file and read by the driver
533 * during installation.
535 * New driver installation schema -- is to pass the user-space address
536 * where device info table is located. Driver will get info table from the user
537 * space instead of a file during installation.
538 * This apporach is much more flexible, as it allows to have variable amount of
539 * address spaces, registers and blocks.
541 * @return
543 int dgxml_cerndb_info2xml(char *ifn)
545 xmlDocPtr doc = NULL; /* document pointer */
546 xmlNodePtr root_node, module, space, block, reg; /* node pointers */
547 DevInfo_t *dit;
548 AddrInfo_t *aip;
549 int ma, ba, ra; /* module/block/register amount */
550 int offst; /* address space offset from the module base address */
551 int regar; /* register access rights (rwec) */
552 char *c;
554 if (!ifn)
555 ifn = get_info_fn();
557 dit = read_info_file(ifn);
559 if (!dit)
560 return -1;
562 aip = &dit->addr1; /* initialize address info pointer */
564 doc = xmlNewDoc(BAD_CAST "1.0");
565 root_node = xmlNewNode(NULL, BAD_CAST NODE_ROOT);
566 xmlDocSetRootElement(doc, root_node);
568 /* set general module description */
569 module = xmlNewChild(root_node, NULL, BAD_CAST NODE_MODULE, NULL);
570 xmlNewProp(module, BAD_CAST PROP_NAME, BAD_CAST TranslationGetModName());
573 ----------------------------- N.B. -----------------------------------
574 Base Address can actually be set to zero by the user in the DB.
575 But as it is set to NO_ADDRESS by DBGetVmeInfo() in case if base
576 address is 0 -- rall it back to actual value.
578 It is done in such a way, because if no BaseAddress is provided in the
579 dataBase by the user -- it is set to zero by dbrt library.
580 ----------------------------------------------------------------------
582 if (dit->addr1.baseAddr == NO_ADDRESS)
583 asprintf(&c, "0x%x", 0);
584 else
585 asprintf(&c, "%p", (void*) dit->addr1.baseAddr);
586 xmlNewProp(module, BAD_CAST PROP_BA, BAD_CAST c);
587 free(c);
589 /* module base address increment. Next module base address will
590 be (base_address + increment) */
591 asprintf(&c, "%#x", dit->addr1.increment);
592 xmlNewProp(module, BAD_CAST PROP_ADDR_INCR, BAD_CAST c);
593 free(c);
595 /* interrupt level, vector and vector increment */
596 if (dit->iLevel != -1) {
597 /* int level (only if defined) */
598 asprintf(&c, "%d", dit->iLevel);
599 xmlNewProp(module, BAD_CAST PROP_ILEVEL, BAD_CAST c);
600 free(c);
603 if (dit->iVector != -1) {
604 /* int vector (only if defined) */
605 asprintf(&c, "%d", dit->iVector);
606 xmlNewProp(module, BAD_CAST PROP_IVEC, BAD_CAST c);
607 free(c);
609 /* int vector increment (only if defined) */
610 asprintf(&c, "%d", dit->iVectorInc);
611 xmlNewProp(module, BAD_CAST PROP_IVEC_INCR, BAD_CAST c);
612 free(c);
615 /* pass through all address spaces */
616 for (ma = 0; ma < DBMAM; ma++) {
617 if (!aip[ma].dpSize)
618 continue; /* not defined */
620 if (aip[ma].baseAddr == NO_ADDRESS)
621 /* BA can actually be 0.
622 But as it is set to NO_ADDRESS by DBGetVmeInfo()
623 in case if base address is 0 -- rall it back to
624 actual value.
625 NOTE, that if no BaseAddress is provided in the
626 dataBase -- it is set to zero by dbrt library */
627 aip[ma].baseAddr = 0;
629 space = xmlNewChild(module, NULL, BAD_CAST NODE_VME, NULL);
631 asprintf(&c, "%d", ma);
632 xmlNewProp(space, BAD_CAST PROP_NAME, BAD_CAST c);
633 free(c);
635 asprintf(&c, "%#x", aip[ma].addrModif);
636 xmlNewProp(space, BAD_CAST PROP_AM, BAD_CAST c);
637 free(c);
639 asprintf(&c, "%d", aip[ma].dpSize);
640 xmlNewProp(space, BAD_CAST PROP_DPS, BAD_CAST c);
641 free(c);
643 asprintf(&c, "%#x", aip[ma].range);
644 xmlNewProp(space, BAD_CAST PROP_RANGE, BAD_CAST c);
645 free(c);
647 offst = aip[ma].baseAddr - aip[0].baseAddr;
648 if (offst)
649 asprintf(&c, "%p", (void*) offst);
650 else
651 asprintf(&c, "0x%x", offst);
652 xmlNewProp(space, BAD_CAST PROP_OFFSET, BAD_CAST c);
653 free(c);
655 /* pass through all the blocks */
656 for (ba = 0; ba < dit->blkAmount; ba++) {
657 if (dit->blkDesc[ba].blkBaseAddr != ma+1)
658 /* block doesn't belong to
659 current Address Space */
660 continue;
662 block = xmlNewChild(space, NULL, BAD_CAST
663 NODE_BLK, NULL);
665 /* block ID */
666 asprintf(&c, "%d", dit->blkDesc[ba].block);
667 xmlNewProp(block, BAD_CAST PROP_NAME, BAD_CAST c);
668 free(c);
670 /* offset from the Address Space, to which it belongs */
671 offst = dit->blkDesc[ba].offset;
672 if (offst)
673 asprintf(&c, "%p", (void*) offst);
674 else
675 asprintf(&c, "0x%x", offst);
676 xmlNewProp(block, BAD_CAST PROP_OFFSET, BAD_CAST c);
677 free(c);
679 /* pass through all the registers */
680 for (ra = 0; ra < dit->regAmount; ra++) {
681 if (dit->regDesc[ra].bid != ba)
682 /* register doesn't belong
683 to current block */
684 continue;
686 reg = xmlNewChild(block, NULL, BAD_CAST
687 NODE_REG, NULL);
689 xmlNewProp(reg, BAD_CAST PROP_NAME,
690 BAD_CAST dit->regDesc[ra].regName);
692 /* offset from the Block, to which it belongs */
693 offst = dit->regDesc[ra].regOffset;
694 if (offst)
695 asprintf(&c, "%p", (void*) offst);
696 else
697 asprintf(&c, "0x%x", offst);
698 xmlNewProp(reg, BAD_CAST PROP_OFFSET,
699 BAD_CAST c);
700 free(c);
702 /* register depth */
703 asprintf(&c, "0x%x",
704 dit->regDesc[ra].regDepth);
705 xmlNewProp(reg, BAD_CAST PROP_DEPTH,
706 BAD_CAST c);
707 free(c);
709 /* reg access mode */
710 regar = dit->regDesc[ra].regar;
712 int i = 0;
713 char am[4];
715 if (regar & (1 << 0))
716 am[i++] = 'w';
718 if (regar & (1 << 1))
719 am[i++] = 'r';
721 if (regar & (1 << 2)) {
722 i = 0;
723 am[i++] = 'e';
726 if (dit->chrindex == ra)
727 am[i++] = 'c';
728 am[i] = 0;
729 xmlNewProp(reg, BAD_CAST PROP_MODE,
730 BAD_CAST am);
733 /* register size */
734 asprintf(&c, "%d",
735 dit->regDesc[ra].regSize);
736 xmlNewProp(reg, BAD_CAST PROP_SIZE,
737 BAD_CAST c);
738 free(c);
740 /* access timeloop */
741 if (!dit->regDesc[ra].regtl)
742 continue;
744 asprintf(&c, "%d", dit->regDesc[ra].regtl);
745 xmlNewProp(reg, BAD_CAST PROP_TLOOP,
746 BAD_CAST c);
751 /* save it to the file */
752 ifn = get_xml_fn();
753 xmlSaveFormatFileEnc(ifn, doc, "UTF-8", 1);
755 xmlFreeDoc(doc);
756 xmlCleanupParser();
758 free(dit);
759 return 0;
762 void dgxml_info2xml(void)
764 void dgxml_xml2info(void)