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 */
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"
33 #define PCI_VENDOR_TAG "Vendor"
34 #define PCI_DEVICE_TAG "Device"
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"
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
);
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 */
99 if (doc
== NULL
) ReadXMLFile(moduleName
);
101 maxReg
= MAX_REG
- GetSrvRegNum(); /* how many reg descr we can have */
103 xmlNode
*n
= moduleElement
->children
;
106 if (n
->type
== XML_ELEMENT_NODE
&& strcasecmp((char*)n
->name
,REGISTER_TAG
) == 0)
109 char *p
= (char*)xmlGetProp(n
,(xmlChar
*)"name");
112 snprintf(defs
[idx
].name
,NAME_LEN
,"%s",p
);
115 xmlNode
*b
= n
->children
;
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
];
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);
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);
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);
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
);
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
);
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
);
169 idx
++; /* increase register counter */
175 if (idx
>= maxReg
) { /* check if within range */
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 */
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
;
212 if (n
->type
== XML_ELEMENT_NODE
&& strcasecmp((char*)n
->name
,BLOCK_TAG
) == 0)
215 defs
[idx
].blockID
= -1;
216 char *p
= (char*)xmlGetProp(n
,(xmlChar
*)"id");
219 defs
[idx
].blockID
= (short)atoi(p
);
222 xmlNode
*b
= n
->children
;
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);
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);
240 idx
++; /* increase block counter */
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 */
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
;
273 if (n
->type
== XML_ELEMENT_NODE
&& strcasecmp((char*)n
->name
,PCI_TAG
) == 0)
275 xmlNode
*b
= n
->children
;
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);
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);
292 pciInfo
->vendorId
= ASSERT_MSB(pciInfo
->vendorId
);
293 pciInfo
->deviceId
= ASSERT_MSB(pciInfo
->deviceId
);
294 return DRIVER_GEN_OK
;
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
)
314 if (doc
== NULL
) ReadXMLFile(moduleName
);
315 xmlNode
*n
= moduleElement
->children
;
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
;
325 if (strcasecmp((char*)b
->name
,VME_ADDRESS_TAG
) == 0)
328 VmeAddrInfo_t
*addr
= &vmeInfo
->addr1
;
329 if (addrSpace
== 2) addr
= &vmeInfo
->addr2
;
330 char *p
= (char*)xmlGetProp(b
,(xmlChar
*)"base");
333 addr
->baseAddr
= strtoul(p
,NULL
,0);
336 xmlNode
*a
= b
->children
;
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
;
351 fprintf(stderr
, "Unsupported AM (%s) detected for addr%d. Check xml file!\n",
353 return DRIVER_GEN_BAD
;
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);
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);
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);
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);
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);
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);
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);
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);
410 if (verboseMode
) /* verbose driverGen */
411 PrintOutVmeInfo(vmeInfo
);
412 return DRIVER_GEN_OK
;
416 return DRIVER_GEN_BAD
;
420 * @brief Printout VME configuration info.
422 * @param vmeInfo -- data to print
426 static void PrintOutVmeInfo(VmeInfo_t
* vmeInfo
)
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
,
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
,
443 printf("Interrupt vector increment => %ld\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",
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",
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
)
477 * this initialize the library and check potential ABI mismatches
478 * between the version it was compiled for and the actual shared
483 /*parse the file and get the DOM */
484 sprintf(fileName
,"%s.xml",moduleName
);
485 doc
= xmlReadFile(fileName
, NULL
, 0);
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)
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
)
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.
543 int dgxml_cerndb_info2xml(char *ifn
)
545 xmlDocPtr doc
= NULL
; /* document pointer */
546 xmlNodePtr root_node
, module
, space
, block
, reg
; /* node pointers */
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) */
557 dit
= read_info_file(ifn
);
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);
585 asprintf(&c
, "%p", (void*) dit
->addr1
.baseAddr
);
586 xmlNewProp(module
, BAD_CAST PROP_BA
, BAD_CAST 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
);
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
);
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
);
609 /* int vector increment (only if defined) */
610 asprintf(&c
, "%d", dit
->iVectorInc
);
611 xmlNewProp(module
, BAD_CAST PROP_IVEC_INCR
, BAD_CAST c
);
615 /* pass through all address spaces */
616 for (ma
= 0; ma
< DBMAM
; ma
++) {
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
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
);
635 asprintf(&c
, "%#x", aip
[ma
].addrModif
);
636 xmlNewProp(space
, BAD_CAST PROP_AM
, BAD_CAST c
);
639 asprintf(&c
, "%d", aip
[ma
].dpSize
);
640 xmlNewProp(space
, BAD_CAST PROP_DPS
, BAD_CAST c
);
643 asprintf(&c
, "%#x", aip
[ma
].range
);
644 xmlNewProp(space
, BAD_CAST PROP_RANGE
, BAD_CAST c
);
647 offst
= aip
[ma
].baseAddr
- aip
[0].baseAddr
;
649 asprintf(&c
, "%p", (void*) offst
);
651 asprintf(&c
, "0x%x", offst
);
652 xmlNewProp(space
, BAD_CAST PROP_OFFSET
, BAD_CAST 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 */
662 block
= xmlNewChild(space
, NULL
, BAD_CAST
666 asprintf(&c
, "%d", dit
->blkDesc
[ba
].block
);
667 xmlNewProp(block
, BAD_CAST PROP_NAME
, BAD_CAST c
);
670 /* offset from the Address Space, to which it belongs */
671 offst
= dit
->blkDesc
[ba
].offset
;
673 asprintf(&c
, "%p", (void*) offst
);
675 asprintf(&c
, "0x%x", offst
);
676 xmlNewProp(block
, BAD_CAST PROP_OFFSET
, BAD_CAST 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
686 reg
= xmlNewChild(block
, NULL
, BAD_CAST
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
;
695 asprintf(&c
, "%p", (void*) offst
);
697 asprintf(&c
, "0x%x", offst
);
698 xmlNewProp(reg
, BAD_CAST PROP_OFFSET
,
704 dit
->regDesc
[ra
].regDepth
);
705 xmlNewProp(reg
, BAD_CAST PROP_DEPTH
,
709 /* reg access mode */
710 regar
= dit
->regDesc
[ra
].regar
;
715 if (regar
& (1 << 0))
718 if (regar
& (1 << 1))
721 if (regar
& (1 << 2)) {
726 if (dit
->chrindex
== ra
)
729 xmlNewProp(reg
, BAD_CAST PROP_MODE
,
735 dit
->regDesc
[ra
].regSize
);
736 xmlNewProp(reg
, BAD_CAST PROP_SIZE
,
740 /* access timeloop */
741 if (!dit
->regDesc
[ra
].regtl
)
744 asprintf(&c
, "%d", dit
->regDesc
[ra
].regtl
);
745 xmlNewProp(reg
, BAD_CAST PROP_TLOOP
,
751 /* save it to the file */
753 xmlSaveFormatFileEnc(ifn
, doc
, "UTF-8", 1);
762 void dgxml_info2xml(void)
764 void dgxml_xml2info(void)