summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--models/ipecamera/camera.xml923
-rwxr-xr-xmodels/ipecamera/registers_and_banks.xsd242
-rw-r--r--pcilib/pci.c6
-rw-r--r--pcilib/xml.c1172
-rw-r--r--pcilib/xml.h90
6 files changed, 1527 insertions, 908 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fbbc383..d090433 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,7 @@ endif (NOT DISABLE_PCITOOL)
pkg_check_modules(XMLLIB libxml-2.0 REQUIRED)
check_include_files(stdatomic.h HAVE_STDATOMIC_H)
-add_definitions("-fPIC --std=c99 -Wall -O2 -gdwarf-2 -g3 -fno-omit-frame-pointer")
+add_definitions("-fPIC --std=c99 -Wall -O2 -gdwarf-2 -g3 -fno-omit-frame-pointer -g")
#add_definitions("-fPIC --std=c99 -Wall -O2")
include(cmake/version.cmake)
diff --git a/models/ipecamera/camera.xml b/models/ipecamera/camera.xml
new file mode 100644
index 0000000..0188267
--- /dev/null
+++ b/models/ipecamera/camera.xml
@@ -0,0 +1,923 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <banks>
+ <bank>
+ <bank_description>
+ <adress>bank 0</adress>
+ <bar>0</bar>
+ <size>128</size>
+ <protocol>default</protocol>
+ <read_adress>0x9010</read_adress>
+ <write_adress>0x9000</write_adress>
+ <word_size>8</word_size>
+ <endianess>little</endianess>
+ <format>%lu</format>
+ <name>cmosis</name>
+ <description>CMOSIS CMV2000 Registers</description>
+ </bank_description>
+ <registers>
+ <register>
+ <adress>1</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>1088</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines</name>
+ <description>test</description>
+ </register>
+ <register>
+ <adress>3</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start1</name>
+ </register>
+ <register>
+ <adress>5</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start2</name>
+ </register>
+ <register>
+ <adress>7</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start3</name>
+ </register>
+ <register>
+ <adress>9</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start4</name>
+ </register>
+ <register>
+ <adress>11</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start5</name>
+ </register>
+ <register>
+ <adress>13</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start6</name>
+ </register>
+ <register>
+ <adress>15</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start7</name>
+ </register>
+ <register>
+ <adress>17</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_start8</name>
+ </register>
+ <register>
+ <adress>19</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines1</name>
+ </register>
+ <register>
+ <adress>21</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines2</name>
+ </register>
+ <register>
+ <adress>23</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines3</name>
+ </register>
+ <register>
+ <adress>25</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines4</name>
+ </register>
+ <register>
+ <adress>27</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines5</name>
+ </register>
+ <register>
+ <adress>29</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines6</name>
+ </register>
+ <register>
+ <adress>31</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines7</name>
+ </register>
+ <register>
+ <adress>33</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_lines8</name>
+ </register>
+ <register>
+ <adress>35</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_sub_s</name>
+ </register>
+ <register>
+ <adress>37</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_sub_a</name>
+ </register>
+ <register>
+ <adress>39</adress>
+ <offset>0</offset>
+ <size>1</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_color</name>
+ </register>
+ <register>
+ <adress>40</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_image_flipping</name>
+ </register>
+ <register>
+ <adress>41</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_flags</name>
+ </register>
+ <register>
+ <adress>42</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1088</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_time</name>
+ <views>
+ <view>formuu3</view>
+ <view>enumm3</view>
+ </views>
+ </register>
+ <register>
+ <adress>45</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1088</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_step</name>
+ </register>
+ <register>
+ <adress>48</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_kp1</name>
+ </register>
+ <register>
+ <adress>51</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_kp2</name>
+ </register>
+ <register>
+ <adress>54</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_nr_slopes</name>
+ </register>
+ <register>
+ <adress>55</adress>
+ <offset>0</offset>
+ <size>8</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_seq</name>
+ </register>
+ <register>
+ <adress>56</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1088</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_time2</name>
+ </register>
+ <register>
+ <adress>59</adress>
+ <offset>0</offset>
+ <size>24</size>
+ <default>1088</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_step2</name>
+ </register>
+ <register>
+ <adress>68</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_nr_slopes2</name>
+ </register>
+ <register>
+ <adress>69</adress>
+ <offset>0</offset>
+ <size>8</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_exp_seq2</name>
+ </register>
+ <register>
+ <adress>70</adress>
+ <offset>0</offset>
+ <size>16</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_number_frames</name>
+ </register>
+ <register>
+ <adress>72</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_output_mode</name>
+ </register>
+ <register>
+ <adress>78</adress>
+ <offset>0</offset>
+ <size>12</size>
+ <default>85</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_training_pattern</name>
+ </register>
+ <register>
+ <adress>80</adress>
+ <offset>0</offset>
+ <size>18</size>
+ <default>0x3FFFF</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_channel_en</name>
+ </register>
+ <register>
+ <adress>82</adress>
+ <offset>0</offset>
+ <size>3</size>
+ <default>7</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_special_82</name>
+ </register>
+ <register>
+ <adress>89</adress>
+ <offset>0</offset>
+ <size>8</size>
+ <default>96</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_vlow2</name>
+ </register>
+ <register>
+ <adress>90</adress>
+ <offset>0</offset>
+ <size>8</size>
+ <default>96</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_vlow3</name>
+ </register>
+ <register>
+ <adress>100</adress>
+ <offset>0</offset>
+ <size>14</size>
+ <default>16260</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_offset</name>
+ </register>
+ <register>
+ <adress>102</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_pga</name>
+ </register>
+ <register>
+ <adress>103</adress>
+ <offset>0</offset>
+ <size>8</size>
+ <default>32</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_adc_gain</name>
+ </register>
+ <register>
+ <adress>111</adress>
+ <offset>0</offset>
+ <size>1</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_bit_mode</name>
+ </register>
+ <register>
+ <adress>112</adress>
+ <offset>0</offset>
+ <size>2</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_adc_resolution</name>
+ </register>
+ <register>
+ <adress>115</adress>
+ <offset>0</offset>
+ <size>1</size>
+ <default>1</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>cmosis_special_115</name>
+ </register>
+ </registers>
+ </bank>
+ <bank>
+ <bank_description>
+ <adress>bank 1</adress>
+ <bar>0</bar>
+ <size>0x0200</size>
+ <protocol>default</protocol>
+ <read_adress>0x9000</read_adress>
+ <write_adress>0x9000</write_adress>
+ <word_size>32</word_size>
+ <endianess>little</endianess>
+ <format>0x%lx</format>
+ <name>fpga</name>
+ <description>IPECamera Registers</description>
+ </bank_description>
+ <registers>
+ <register>
+ <adress>0x00</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>spi_conf_input</name>
+ </register>
+ <register>
+ <adress>0x10</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>spi_conf_output</name>
+ </register>
+ <register>
+ <adress>0x20</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>spi_clk_speed</name>
+ </register>
+ <register>
+ <adress>0x30</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>firmware_info</name>
+ <registers_bits>
+ <register_bits>
+ <offset>0</offset>
+ <size>8</size>
+ <mode>R</mode>
+ <name>firmware_version</name>
+ </register_bits>
+ <register_bits>
+ <offset>8</offset>
+ <size>1</size>
+ <mode>R</mode>
+ <name>firmware_bitmode</name>
+ </register_bits>
+ <register_bits>
+ <offset>12</offset>
+ <size>2</size>
+ <mode>R</mode>
+ <name>adc_resolution</name>
+ </register_bits>
+ <register_bits>
+ <offset>16</offset>
+ <size>2</size>
+ <mode>R</mode>
+ <name>output_mode</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0x40</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>control</name>
+ <registers_bits>
+ <register_bits>
+ <offset>31</offset>
+ <size>1</size>
+ <mode>R</mode>
+ <name>freq</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0x50</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>status</name>
+ </register>
+ <register>
+ <adress>0x54</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>status2</name>
+ </register>
+ <register>
+ <adress>0x58</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>status3</name>
+ </register>
+ <register>
+ <adress>0x5c</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>fr_status</name>
+ </register>
+ <register>
+ <adress>0x70</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>start_address</name>
+ </register>
+ <register>
+ <adress>0x74</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>end_address</name>
+ </register>
+ <register>
+ <adress>0x78</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>rd_address</name>
+ </register>
+ <register>
+ <adress>0xa0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>fr_param1</name>
+ <registers_bits>
+ <register_bits>
+ <offset>0</offset>
+ <size>10</size>
+ <mode>RW</mode>
+ <name>fr_skip_lines</name>
+ </register_bits>
+ <register_bits>
+ <offset>10</offset>
+ <size>11</size>
+ <mode>RW</mode>
+ <name>fr_num_lines</name>
+ </register_bits>
+ <register_bits>
+ <offset>21</offset>
+ <size>11</size>
+ <mode>RW</mode>
+ <name>fr_start_address</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0xb0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>all bits</rwmask>
+ <mode>RW</mode>
+ <name>fr_param2</name>
+ <registers_bits>
+ <register_bits>
+ <offset>0</offset>
+ <size>11</size>
+ <mode>RW</mode>
+ <name>fr_threshold_start_line</name>
+ </register_bits>
+ <register_bits>
+ <offset>16</offset>
+ <size>10</size>
+ <mode>RW</mode>
+ <name>fr_area_lines</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0xc0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>skiped_lines</name>
+ </register>
+ <register>
+ <adress>0xd0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>all bits</rwmask>
+ <mode>RW</mode>
+ <name>fr_thresholds</name>
+ </register>
+ <register>
+ <adress>0xd0</adress>
+ <offset>0</offset>
+ <size>10</size>
+ <default>0</default>
+ <rwmask>all bits</rwmask>
+ <mode>RW</mode>
+ <name>fr_pixel_thr</name>
+ </register>
+ <register>
+ <adress>0xd0</adress>
+ <offset>10</offset>
+ <size>11</size>
+ <default>0</default>
+ <rwmask>all bits</rwmask>
+ <mode>RW</mode>
+ <name>fr_num_pixel_thr</name>
+ </register>
+ <register>
+ <adress>0xd0</adress>
+ <offset>21</offset>
+ <size>11</size>
+ <default>0</default>
+ <rwmask>all bits</rwmask>
+ <mode>RW</mode>
+ <name>fr_num_lines_thr</name>
+ </register>
+ <register>
+ <adress>0x100</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>rawdata_pkt_addr</name>
+ </register>
+ <register>
+ <adress>0x110</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>temperature_info</name>
+ <registers_bits>
+ <register_bits>
+ <offset>0</offset>
+ <size>16</size>
+ <mode>R</mode>
+ <name>sensor_temperature</name>
+ <views>
+ <view>formuu1</view>
+ <view>formuu2</view>
+ <view>enumm2</view>
+ </views>
+ </register_bits>
+ <register_bits>
+ <offset>16</offset>
+ <size>3</size>
+ <mode>R</mode>
+ <name>sensor_temperature_alarms</name>
+ </register_bits>
+ <register_bits>
+ <offset>19</offset>
+ <size>10</size>
+ <mode>RW</mode>
+ <name>fpga_temperature</name>
+ <views>
+ <view>formuu1</view>
+ <view>enumm1</view>
+ </views>
+ </register_bits>
+ <register_bits>
+ <offset>29</offset>
+ <size>3</size>
+ <mode>R</mode>
+ <name>fpga_temperature_alarms</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0x120</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>num_lines</name>
+ </register>
+ <register>
+ <adress>0x130</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>start_line</name>
+ </register>
+ <register>
+ <adress>0x140</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>exp_time</name>
+ </register>
+ <register>
+ <adress>0x150</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>motor</name>
+ <registers_bits>
+ <register_bits>
+ <offset>0</offset>
+ <size>5</size>
+ <mode>RW</mode>
+ <name>motor_phi</name>
+ </register_bits>
+ <register_bits>
+ <offset>5</offset>
+ <size>5</size>
+ <mode>RW</mode>
+ <name>motor_z</name>
+ </register_bits>
+ <register_bits>
+ <offset>10</offset>
+ <size>5</size>
+ <mode>RW</mode>
+ <name>motor_y</name>
+ </register_bits>
+ <register_bits>
+ <offset>15</offset>
+ <size>5</size>
+ <mode>RW</mode>
+ <name>motor_x</name>
+ </register_bits>
+ <register_bits>
+ <offset>20</offset>
+ <size>8</size>
+ <mode>R</mode>
+ <name>adc_gain</name>
+ </register_bits>
+ </registers_bits>
+ </register>
+ <register>
+ <adress>0x160</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>write_status</name>
+ </register>
+ <register>
+ <adress>0x170</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>num_triggers</name>
+ </register>
+ <register>
+ <adress>0x180</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0x280</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>trigger_period</name>
+ <views>
+ <view>enumm2</view>
+ </views>
+ </register>
+ <register>
+ <adress>0x190</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>temperature_sample_period</name>
+ </register>
+ <register>
+ <adress>0x1a0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0x64</default>
+ <rwmask>0</rwmask>
+ <mode>RW</mode>
+ <name>ddr_max_frames</name>
+ </register>
+ <register>
+ <adress>0x1b0</adress>
+ <offset>0</offset>
+ <size>32</size>
+ <default>0</default>
+ <rwmask>0</rwmask>
+ <mode>R</mode>
+ <name>ddr_num_frames</name>
+ </register>
+ </registers>
+ </bank>
+ <bank>
+ <bank_description>
+ <adress>DMA bank</adress>
+ <bar>0</bar>
+ <size>0x0200</size>
+ <protocol>default</protocol>
+ <read_adress>0x0</read_adress>
+ <write_adress>0x0</write_adress>
+ <word_size>32</word_size>
+ <endianess>little</endianess>
+ <format>0x%lx</format>
+ <name>dma</name>
+ <description>DMA Registers</description>
+ </bank_description>
+ </bank>
+ </banks>
+ <views>
+ <view type="formula">
+ <name>formuu1</name>
+ <unit>C</unit>
+ <read_from_register>(503975./1024000)*@reg - 27315./100</read_from_register>
+ <write_to_register>(@value + 27315./100)*(102400./503975)</write_to_register>
+<description>formula to get real fpga temperature from the fpga_temperature register in decimal</description>
+ </view>
+ <view type="enum">
+ <name>enumm1</name>
+ <enum value="0x100" min="0x2" max="0x300">high</enum>
+ <enum value="0x010">low</enum>
+ <description>enum towards temperatures register</description>
+ </view>
+ <view type="formula">
+ <name>formuu2</name>
+ <unit>C</unit>
+ <read_from_register>((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000))</read_from_register>
+ <write_to_register>4*@value + 1200 if @freq==0 else (10./3)*@value + 1000</write_to_register>
+ <description>formula to get real sensor temperature from the sensor_temperature register in decimal</description>
+ </view>
+ <view type="enum">
+ <name>enumm2</name>
+ <enum value="0x120">high</enum>
+ <enum value="0x010" min="0x00" max="0x020">low</enum>
+ <description>enum towards sensor_temperature register</description>
+ </view>
+ <view type="formula">
+ <name>formuu3</name>
+ <unit>us</unit>
+ <read_from_register>(@reg+(43./100))*129./(40*1000000)if @freq==0 else (@reg+(43./100))*129./(48*1000000)</read_from_register>
+ <write_to_register>@value/129.*(40*1000000) - 43./100 if @freq==0 else @value/129.*(48*1000000) - 43./100</write_to_register>
+ <description>formula to get real exposure time from the cmosis_exp_time register in decimal</description>
+ </view>
+ <view type="enum">
+ <name>enumm3</name>
+ <enum value="0x000">short</enum>
+ <enum value="0x010">mid</enum>
+ <enum value="0x100" min="0x0F0">long</enum>
+ <description>enum towards cmosis_exp_register register</description>
+ </view>
+ </views>
+</model>
diff --git a/models/ipecamera/registers_and_banks.xsd b/models/ipecamera/registers_and_banks.xsd
new file mode 100755
index 0000000..10d49b7
--- /dev/null
+++ b/models/ipecamera/registers_and_banks.xsd
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:element name="model">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="banks" type="banks_type"/>
+ <xsd:element name="views" type="views_type" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:key name="Registerkey">
+ <xsd:selector xpath="views/view/name"/>
+ <xsd:field xpath="."/>
+ </xsd:key>
+ <xsd:keyref refer="Registerkey" name="RegisterkeyRef">
+ <xsd:selector xpath="banks/bank/registers/register/views/view"/>
+ <xsd:field xpath="."/>
+ </xsd:keyref>
+ <xsd:key name="Registerbitskey">
+ <xsd:selector xpath="views/view/name"/>
+ <xsd:field xpath="."/>
+ </xsd:key>
+ <xsd:keyref refer="Registerbitskey" name="RegisterbitskeyRef">
+ <xsd:selector xpath="banks/bank/registers/register/registers_bits/register_bits/views/view"/>
+ <xsd:field xpath="."/>
+ </xsd:keyref>
+ </xsd:element>
+
+
+ <xsd:complexType name="views_type">
+ <xsd:sequence>
+ <xsd:element name="view" type="view_type" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="banks_type">
+ <xsd:sequence>
+ <xsd:element name="bank" type="banktype" minOccurs="1" maxOccurs="12"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="banktype">
+ <xsd:sequence>
+ <xsd:element name="bank_description" type="bank_description_t"/>
+ <xsd:element name="registers" type="registerstype" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="bank_description_t">
+ <xsd:sequence>
+ <xsd:element name="adress" type="bank_adress_type"/>
+ <xsd:element name="bar" type="bar_type"/>
+ <xsd:element name="size" type="hexa_and_integer64_t"/>
+ <xsd:element name="protocol" type="xsd:string"/>
+ <xsd:element name="read_adress" type="hex64_t"/>
+ <xsd:element name="write_adress" type="hex64_t"/>
+ <xsd:element name="word_size" type="uint8_t"/>
+ <xsd:element name="endianess" type="endianess_type"/>
+ <xsd:element name="format" type="xsd:string"/>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="registerstype">
+ <xsd:sequence>
+ <xsd:element name="register" type="register_type" minOccurs="0" maxOccurs="256"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="register_type">
+ <xsd:sequence>
+ <xsd:element name="adress" type="hexa_and_integer32_t"/>
+ <xsd:element name="offset" type="uint8_t"/>
+ <xsd:element name="size" type="uint8_t"/>
+ <xsd:element name="default" type="hexa_and_integer32_t"/>
+ <xsd:element name="rwmask" type="rwmask_type"/>
+ <xsd:element name="mode" type="pcilib_register_mode_t"/>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="views" type="reg_to_views_type" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="registers_bits" type="registers_bits_type" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="value_min" type="hexa_and_integer32_t" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="value_max" type="hexa_and_integer32_t" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="registers_bits_type">
+ <xsd:sequence>
+ <xsd:element name="register_bits" type="register_bits_type" minOccurs="1" maxOccurs="32"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="reg_to_views_type">
+ <xsd:sequence>
+ <xsd:element name="view" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="register_bits_type">
+ <xsd:sequence>
+ <xsd:element name="offset" type="uint8_t"/>
+ <xsd:element name="size" type="uint8_t"/>
+ <xsd:element name="mode" type="pcilib_register_mode_t"/>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="views" type="reg_to_views_type" minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+
+ </xsd:complexType>
+
+ <xsd:simpleType name="uint8_t">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="0"/>
+ <xsd:maxInclusive value="255"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="size_t">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="0"/>
+ <xsd:maxInclusive value="18446744073709551615"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="uintptr_t">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="0"/>
+ <xsd:maxInclusive value="18446744073709551615"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="uint32_t">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="0"/>
+ <xsd:maxInclusive value="4294967295"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="pcilib_register_mode_t">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="R"/>
+ <xsd:enumeration value="W"/>
+ <xsd:enumeration value="RW"/>
+ <xsd:enumeration value="W1C"/>
+ <xsd:enumeration value="RW1C"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="bank_adress_type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="bank 0"/>
+ <xsd:enumeration value="bank 1"/>
+ <xsd:enumeration value="bank 2"/>
+ <xsd:enumeration value="bank 3"/>
+ <xsd:enumeration value="DMA bank"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="endianess_type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="little"/>
+ <xsd:enumeration value="big"/>
+ <xsd:enumeration value="host"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="bar_type">
+ <xsd:restriction base="xsd:integer">
+ <xsd:enumeration value="0"/>
+ <xsd:enumeration value="1"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="space_adress_type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="write adress"/>
+ <xsd:enumeration value="read adress"/>
+ <xsd:enumeration value="space adress"/>
+ <xsd:enumeration value="0"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="rwmask_type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="all bits"/>
+ <xsd:enumeration value="0"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="hexa_and_integer32_t">
+ <xsd:union memberTypes="uint32_t hex32_t"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="hex32_t">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="0x([a-fA-F0-9]){0,8}"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="hexa_and_integer64_t">
+ <xsd:union memberTypes="size_t hex64_t"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="hex64_t">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="0x([a-fA-F0-9]){0,16}"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="view_type">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:ID"/>
+ <xsd:element name="unit" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="read_from_register" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="write_to_register" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="enum" type="enum_t" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="description" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute name="type" type="viewtype_type" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="enum_t">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="value" type="hexa_and_integer64_t" use="required"/>
+ <xsd:attribute name="min" type="hexa_and_integer64_t"/>
+ <xsd:attribute name="max" type="hexa_and_integer64_t"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:simpleType name="viewtype_type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="enum"/>
+ <xsd:enumeration value="formula"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/pcilib/pci.c b/pcilib/pci.c
index 03b2623..8a0ee29 100644
--- a/pcilib/pci.c
+++ b/pcilib/pci.c
@@ -109,8 +109,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
size_t i;
pcilib_t *ctx = malloc(sizeof(pcilib_t));
- xmlDocPtr* docs=NULL;
-
if (!model)
model = getenv("PCILIB_MODEL");
@@ -174,9 +172,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) {
if (!ctx->model)
ctx->model = strdup(model?model:"pci");
- pcilib_init_xml(docs);
- pcilib_xml_initialize_banks(ctx,docs);
- pcilib_xml_initialize_registers(ctx,docs);
+ pcilib_init_xml(ctx);
ctx->model_info.registers = ctx->registers;
ctx->model_info.banks = ctx->banks;
diff --git a/pcilib/xml.c b/pcilib/xml.c
index ad76dcc..d4c84be 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -17,20 +17,20 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
-//#include <Python.h>
#include "pci.h"
#include "bank.h"
#include "register.h"
#include <libxml/xmlschemastypes.h>
-//#define VIEW_OK
-//#define UNIT_OK
-/**
- * pcilib_xml_getdoc
+#include <dirent.h>
+#include <errno.h>
+
+/** pcilib_xml_getdoc
* this function takes a string and will create an abtract syntax tree from the xml file represented by the string
* @param[in] filename the the name of the xml file containing registers and banks
*/
-xmlDocPtr pcilib_xml_getdoc(char* filename){
+static xmlDocPtr
+pcilib_xml_getdoc(char* filename){
xmlDocPtr doc;
doc=xmlParseFile(filename); /**<the creation of the AST from a libxml2 funtion*/
@@ -43,22 +43,20 @@ xmlDocPtr pcilib_xml_getdoc(char* filename){
}
/** pcilib_xml_getsetproperty
- *
* this function takes a context from an AST and an XPath expression, to produce an object containing the nodes corresponding to the xpath expression
* @param[in] doc the AST of the xml file
* @param[in] xpath the xpath expression that will be evaluated
*/
-xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath){
+static xmlXPathObjectPtr
+pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath){
xmlXPathObjectPtr result;
result=xmlXPathEvalExpression(xpath, doc); /**<the creation of the resulting object*/
if(result==NULL){
-// pcilib_warning(" warning : the path is empty: %s",xpath);
return NULL;
}
if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
xmlXPathFreeObject(result);
-// pcilib_warning("warning : no results found for: %s",xpath);
return NULL;
}
@@ -69,7 +67,8 @@ xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpa
* this function create a context in an AST (ie initialize XPAth for the AST).
* @param[in] doc the AST of the xml file.
*/
-xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){
+static xmlXPathContextPtr
+pcilib_xml_getcontext(xmlDocPtr doc){
xmlXPathContextPtr context;
context= xmlXPathNewContext(doc); /**<the creation of the context using a libxml2's function */
if(context==NULL){
@@ -81,16 +80,19 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){
/** validation
- *
- * function to validate the xml file against the xsd, so that it does not require extern software
+ * function to validate the xml file against the xsd
+ * @param[in] xml_filename path to the xml file
+ * @param[in] xsd_filename path to the xsd file
*/
-void validation(char* xml_filename, char* xsd_filename)
+static int
+validation(char* xml_filename, char* xsd_filename)
{
xmlDocPtr doc;
xmlSchemaPtr schema = NULL;
xmlSchemaParserCtxtPtr ctxt;
int ret=1;
+/** we first parse the xsd file for AST with validation*/
ctxt = xmlSchemaNewParserCtxt(xsd_filename);
schema = xmlSchemaParse(ctxt);
xmlSchemaFreeParserCtxt(ctxt);
@@ -115,338 +117,160 @@ if(schema != NULL)
xmlSchemaFree(schema);
xmlSchemaCleanupTypes();
-if(ret!=0) pcilib_error("xml file \"%s\" does not validate against the schema",xml_filename);
+if(ret!=0) pcilib_warning("\nxml file \"%s\" does not validate against the schema, its register won't be used",xml_filename);
+ return ret;
}
-void pcilib_init_xml(xmlDocPtr* docs){
- char *path,*command,*command_xsd, *line, *line_xsd;
- FILE *in, *in2;
- int i=1;
-
- path=malloc(sizeof(char*));
- command=malloc(sizeof(char*));
- command_xsd=malloc(sizeof(char*));
- line=malloc(sizeof(char*));
- line_xsd=malloc(sizeof(char*));
- docs=malloc(sizeof(xmlDocPtr));
-
- path=getenv("PCILIB_MODEL_DIR");
- if((strcmp(path,"(null)"))==0) pcilib_error("can't find environment variable for xml files");
- sprintf(command,"find %s -name *.xml -print",path);
- sprintf(command_xsd,"find %s -name *.xsd -print",path);
-
- if(!(in=popen(command,"r"))) pcilib_error("fail popen xml");
- if(!((in2=popen(command_xsd,"r")))) pcilib_error("fail popen xsd");
-
- while(fgets(line_xsd,sizeof(line_xsd),in2)!=NULL) {
- if((strstr(line_xsd,"units"))!=NULL) break;
- }
- if(line_xsd==NULL) pcilib_error("no xsd file found");
-
-while((fgets(line,sizeof(line),in))!=NULL) {
- validation(line,line_xsd);
- docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr));
- docs[i-1]=pcilib_xml_getdoc(line);
- i++;
- }
-
- docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr));
- docs[i]=NULL;
- free(path);
- free(command);
- free(command_xsd);
- free(line);
- free(line_xsd);
- free(in);
- free(in2);
- fclose(in);
- fclose(in2);
-}
-
-/** pcilib_xml_create_register.
- * this function create a register structure from the results of xml parsing.
- * @param[out] myregister the register we want to create
- * @param[in] adress the adress of the future register
- * @param[in] offset the offset of the future register
- * @param[in] size the size of the future register
- * @param[in] defvalue the defaut value of the future register
- * @param[in] rwmask the rwmask of the future register
- * @param[in] mode the mode of the future register
- * @param[in] type the type of the future register
- * @param[in] bank the bank of the future register
- * @param[in] name the name of the future register
- * @param[in] description the description of the future register
- */
-void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlChar* adress, xmlChar *offset, xmlChar *size, xmlChar *defvalue, xmlChar *rwmask, xmlChar *mode, xmlChar *type, xmlChar *bank, xmlChar *name, xmlChar *description){
-
- char* ptr;
-
- /* we recreate here each sub property of the register structure given the results of xml parsing
- note :the use of strtol permits to get as well hexadecimal and decimal values
- */
-
- myregister->addr=(pcilib_register_addr_t)strtol((char*)adress,&ptr,0);
- myregister->offset=(pcilib_register_size_t)strtol((char*)offset,&ptr,0);
- myregister->bits=(pcilib_register_size_t)strtol((char*)size,&ptr,0);
- myregister->defvalue=(pcilib_register_value_t)strtol((char*)defvalue,&ptr,0);
-
- if(strcmp((char*)rwmask,"all bits")==0){
- myregister->rwmask=PCILIB_REGISTER_ALL_BITS;
- }else if(strcmp((char*)rwmask,"0")==0){
- myregister->rwmask=0;
- }else{
- myregister->rwmask=(pcilib_register_value_t)strtol((char*)rwmask,&ptr,0);
- }
-
- if(strcmp((char*)mode,"R")==0){
- myregister->mode=PCILIB_REGISTER_R;
- }else if(strcmp((char*)mode,"W")==0){
- myregister->mode=PCILIB_REGISTER_W;
- }else if(strcmp((char*)mode,"RW")==0){
- myregister->mode=PCILIB_REGISTER_RW;
- }else if(strcmp((char*)mode,"W")==0){
- myregister->mode=PCILIB_REGISTER_W;
- }else if(strcmp((char*)mode,"RW1C")==0){
- myregister->mode=PCILIB_REGISTER_RW1C;
- }else if(strcmp((char*)mode,"W1C")==0){
- myregister->mode=PCILIB_REGISTER_W1C;
- }
-
- if(strcmp((char*)type,"standard")==0){
- myregister->type=PCILIB_REGISTER_STANDARD;
- }else if(strcmp((char*)type,"bits")==0){
- myregister->type=PCILIB_REGISTER_BITS;
- }else if(strcmp((char*)type,"fifo")==0){
- myregister->type=PCILIB_REGISTER_FIFO;
- }
-
- if(strcmp((char*)bank,"bank 0")==0){
- myregister->bank=PCILIB_REGISTER_BANK0;
- }else if(strcmp((char*)bank,"bank 1")==0){
- myregister->bank=PCILIB_REGISTER_BANK1;
- }else if(strcmp((char*)bank,"bank 2")==0){
- myregister->bank=PCILIB_REGISTER_BANK2;
- }else if(strcmp((char*)bank,"bank 3")==0){
- myregister->bank=PCILIB_REGISTER_BANK3;
- }else if(strcmp((char*)bank,"DMA bank")==0){
- myregister->bank=PCILIB_REGISTER_BANK_DMA;
- }else if (strcmp((char*)bank,"dynamic bank")==0){
- myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC;
- }else{
- myregister->bank=PCILIB_REGISTER_BANK_INVALID;
- }
-
- myregister->name=(char*)name;
- myregister->description=(char*)description;
-}
-
-/** pcilib_xml_getnumberbanks
- *
- * get the number of banks nodes in the AST, used to have some malloc in pci
- * @param[in] doc the Xpath context of the xml file.
- * @return the number of banks.
- */
-int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){
- xmlNodeSetPtr nodesetadress=NULL;
- xmlXPathObjectPtr temp;
- temp=pcilib_xml_getsetproperty(doc,BANK_ADDR_PATH); /**< we first get a structure containing all the banks nodes*/
- if(temp!=NULL) nodesetadress=temp->nodesetval;
- else pcilib_error("no bank in the xml file");
- return nodesetadress->nodeNr; /**< we then return the number of said nodes */
-}
/** pcilib_xml_create_bank
*
- * this function create a bank structure from the results of xml parsing
+ * this function create a bank structure from a xml bank node
* @param[out] mybank the created bank.
- * @param[in] adress the adress of the bank that will be created.
- * @param[in] bar the bar of the bank that will be created.
- * @param[in] size the size of the bank that will be created.
- * @param[in] protocol the protocol of the bank that will be created.
- * @param[in] read_addr the read adress for protocol of the bank that will be created.
- * @param[in] write_addr the write adress for the protocol of the bank that will be created.
- * @param[in] access the word size of the bank that will be created.
- * @param[in] endianess the endianess of the bank that will be created.
- * @param[in] format the format of the bank that will be created.
- * @param[in] name the name of the bank that will be created.
- * @param[in] description the description of the bank that will be created.
+ * @param[in] my node the xml node used to create the bank
+ * @param[in] doc the AST of the xml file, used for used lixbml functions
*/
-void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description){
+static void
+pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc){
- char* ptr;
+ char* ptr;
+ xmlNodePtr cur;
+ xmlChar *value;
- /** we recreate each sub property of banks' structure given the results of xml parsing
- note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/
+ cur=mynode->children; /** we place ourselves in the childrens of the bank node*/
- if (strcmp((char*)adress,"bank 0")==0){
- mybank->addr=PCILIB_REGISTER_BANK0;
- }else if (strcmp((char*)adress,"bank 1")==0){
- mybank->addr=PCILIB_REGISTER_BANK1;
- }else if (strcmp((char*)adress,"bank 2")==0){
- mybank->addr=PCILIB_REGISTER_BANK2;
- }else if (strcmp((char*)adress,"bank 3")==0){
- mybank->addr=PCILIB_REGISTER_BANK3;
- }else if (strcmp((char*)adress,"DMA bank")==0){
- mybank->addr=PCILIB_REGISTER_BANK_DMA;
- }else if (strcmp((char*)adress,"DMAconf bank")==0){
- mybank->addr=PCILIB_REGISTER_BANK_DMACONF;
- }else if (strcmp((char*)adress,"dynamic bank")==0){
- mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC;
- }else{
- mybank->addr=PCILIB_REGISTER_BANK_INVALID;
- }
-
- if(strcmp((char*)bar,"0")==0){
- mybank->bar=PCILIB_BAR0;
- }else if(strcmp((char*)bar,"1")==0){
- mybank->bar=PCILIB_BAR1;
- }else if(strcmp((char*)bar,"no_bar")==0){
- mybank->bar=PCILIB_BAR_NOBAR;
- }else{
- mybank->bar=PCILIB_BAR_INVALID;
- }
-
- mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0);
- mybank->size=(size_t)strtol((char*)size,&ptr,0);
-
- if(strcmp((char*)protocol,"default")==0){
- mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT;
- }else if(strcmp((char*)protocol,"0")==0){
- mybank->protocol=PCILIB_REGISTER_PROTOCOL0;
- }else if(strcmp((char*)protocol,"dma")==0){
- mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA;
- }else if(strcmp((char*)protocol,"dynamic")==0){
- mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC;
- }else if (strcmp((char*)protocol,"software")==0){
- mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE;
- }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID;
-
- mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0);
- mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0);
- mybank->access=(uint8_t)strtol((char*)access,&ptr,0);
-
- if(strcmp((char*)endianess,"little")==0){
- mybank->endianess=PCILIB_LITTLE_ENDIAN;
- }else if(strcmp((char*)endianess,"big")==0){
- mybank->endianess=PCILIB_BIG_ENDIAN;
- }else if(strcmp((char*)endianess,"host")==0){
- mybank->endianess=PCILIB_HOST_ENDIAN;
- }
- mybank->format=(char*)format;
- mybank->raw_endianess=mybank->endianess;
+ /** we iterate through all children, representing bank properties, to fill the structure*/
+ while(cur!=NULL){
+ /** we get each time the name of the node, corresponding to one property, and the value of the node*/
+ value=xmlNodeListGetString(doc,cur->children,1);
+
+ if(strcmp((char*)cur->name,"adress")==0){
+ if (strcmp((char*)value,"bank 0")==0){
+ mybank->addr=PCILIB_REGISTER_BANK0;
+ }else if (strcmp((char*)value,"bank 1")==0){
+ mybank->addr=PCILIB_REGISTER_BANK1;
+ }else if (strcmp((char*)value,"bank 2")==0){
+ mybank->addr=PCILIB_REGISTER_BANK2;
+ }else if (strcmp((char*)value,"bank 3")==0){
+ mybank->addr=PCILIB_REGISTER_BANK3;
+ }else if (strcmp((char*)value,"DMA bank")==0){
+ mybank->addr=PCILIB_REGISTER_BANK_DMA;
+ }else if (strcmp((char*)value,"DMAconf bank")==0){
+ mybank->addr=PCILIB_REGISTER_BANK_DMACONF;
+ }else if (strcmp((char*)value,"dynamic bank")==0){
+ mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC;
+ }else{
+ mybank->addr=PCILIB_REGISTER_BANK_INVALID;
+ }
+
+ }else if(strcmp((char*)cur->name,"bar")==0){
+ if(strcmp((char*)value,"0")==0){
+ mybank->bar=PCILIB_BAR0;
+ }else if(strcmp((char*)value,"1")==0){
+ mybank->bar=PCILIB_BAR1;
+ }else if(strcmp((char*)value,"no_bar")==0){
+ mybank->bar=PCILIB_BAR_NOBAR;
+ }else{
+ mybank->bar=PCILIB_BAR_INVALID;
+ }
+ mybank->bar=(pcilib_bar_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"size")==0){
+ mybank->size=(size_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"protocol")==0){
+ if(strcmp((char*)value,"default")==0){
+ mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT;
+ }else if(strcmp((char*)value,"0")==0){
+ mybank->protocol=PCILIB_REGISTER_PROTOCOL0;
+ }else if(strcmp((char*)value,"dma")==0){
+ mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA;
+ }else if(strcmp((char*)value,"dynamic")==0){
+ mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC;
+ }else if (strcmp((char*)value,"software")==0){
+ mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE;
+ }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID;
+
+ }else if(strcmp((char*)cur->name,"read_adress")==0){
+ mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0);
- mybank->name=(char*)name;
- mybank->description=(char*)description;
-}
+ }else if(strcmp((char*)cur->name,"write_adress")==0){
+ mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"word_size")==0){
+ mybank->access=(uint8_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"endianess")==0){
+ if(strcmp((char*)value,"little")==0){
+ mybank->endianess=PCILIB_LITTLE_ENDIAN;
+ }else if(strcmp((char*)value,"big")==0){
+ mybank->endianess=PCILIB_BIG_ENDIAN;
+ }else if(strcmp((char*)value,"host")==0){
+ mybank->endianess=PCILIB_HOST_ENDIAN;
+ }
+ mybank->raw_endianess=mybank->endianess;
+
+ }else if(strcmp((char*)cur->name,"format")==0){
+ mybank->format=(char*)value;
+
+ }else if(strcmp((char*)cur->name,"name")==0){
+ mybank->name=(char*)value;
+
+ }else if(strcmp((char*)cur->name,"description")==0){
+ mybank->description=(char*)value;
+ }
+
+ cur=cur->next;
+ }
+}
+
+
/** pcilib_xml_initialize_banks
*
* function to create the structures to store the banks from the AST
- * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node).
+ * @see pcilib_xml_create_bank(
* @param[in] doc the AST of the xml file.
- * @param[in,out] mybanks the structure containing the banks.
+ * @param[in] pci the pcilib_t running, which will be filled
*/
-void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* docs){
+static void
+pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){
pcilib_register_bank_description_t mybank;
- xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL;
- xmlChar *adress=NULL,*bar=NULL,*size=NULL,*protocol=NULL,*read_addr=NULL,*write_addr=NULL,*access=NULL,*endianess=NULL,*format=NULL,*name=NULL,*description=NULL;
+ xmlNodeSetPtr nodesetadress=NULL;
xmlNodePtr mynode;
- int number_banks;
pcilib_register_bank_description_t* banks;
xmlXPathContextPtr context;
- int i,p;
- xmlXPathObjectPtr temp;
- mynode=malloc(sizeof(xmlNode));
- p=0;
- while(docs[p]!=NULL){
- context=pcilib_xml_getcontext(docs[p]);
- number_banks=pcilib_xml_getnumberbanks(context);
- if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t));
- else return;
+ int i;
- /** we first get the nodes corresponding to the properties we want*/
-/* -----> certainly not necessary if we validate xml each time*/
- temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH);
- if(temp!=NULL) nodesetadress=temp->nodesetval;
- else pcilib_error("there is no adress for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_BAR_PATH);
- if(temp!=NULL) nodesetbar=temp->nodesetval;
- else pcilib_error("there is no bar for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_SIZE_PATH);
- if(temp!=NULL) nodesetsize=temp->nodesetval;
- else pcilib_error("there is no size for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_PROTOCOL_PATH);
- if(temp!=NULL) nodesetprotocol= temp->nodesetval;
- else pcilib_error("there is no protocol for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_READ_ADDR_PATH);
- if(temp!=NULL) nodesetread_addr=temp->nodesetval;
- else pcilib_error("there is no read_adress for banks in the xml");
+ mynode=malloc(sizeof(xmlNode));
+ context=pcilib_xml_getcontext(doc);
- temp=pcilib_xml_getsetproperty(context,BANK_WRITE_ADDR_PATH);
- if(temp!=NULL)nodesetwrite_addr=temp->nodesetval;
- else pcilib_error("there is no write_adress for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_ACCESS_PATH);
- if(temp!=NULL)nodesetaccess=temp->nodesetval;
- else pcilib_error("there is no access for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_ENDIANESS_PATH);
- if(temp!=NULL) nodesetendianess=temp->nodesetval;
- else pcilib_error("there is no endianess for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_FORMAT_PATH);
- if(temp!=NULL) nodesetformat=temp->nodesetval;
- else pcilib_error("there is no format for banks in the xml");
-
- temp=pcilib_xml_getsetproperty(context,BANK_NAME_PATH);
- if(temp!=NULL)nodesetname=temp->nodesetval;
- else pcilib_error("there is no name for banks in the xml");
+ /** we get the bank nodes using xpath expression*/
+ nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval;
+ if(nodesetadress->nodeNr>0) banks=calloc((nodesetadress->nodeNr),sizeof(pcilib_register_bank_description_t));
+ else return;
- temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH);
- if(temp!=NULL)nodesetdescription=temp->nodesetval;
-
pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr));
- if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct");
-
- for(i=0;i<nodesetadress->nodeNr;i++){
- /** we then get each node from the structures above*/
- adress=xmlNodeListGetString(docs[p],nodesetadress->nodeTab[i]->xmlChildrenNode, 1);
- bar=xmlNodeListGetString(docs[p],nodesetbar->nodeTab[i]->xmlChildrenNode, 1);
- size=xmlNodeListGetString(docs[p],nodesetsize->nodeTab[i]->xmlChildrenNode, 1);
- protocol=xmlNodeListGetString(docs[p],nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1);
- read_addr=xmlNodeListGetString(docs[p],nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1);
- write_addr=xmlNodeListGetString(docs[p],nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1);
- access=xmlNodeListGetString(docs[p],nodesetaccess->nodeTab[i]->xmlChildrenNode, 1);
- endianess=xmlNodeListGetString(docs[p],nodesetendianess->nodeTab[i]->xmlChildrenNode, 1);
- format=xmlNodeListGetString(docs[p],nodesetformat->nodeTab[i]->xmlChildrenNode, 1);
- name=xmlNodeListGetString(docs[p],nodesetname->nodeTab[i]->xmlChildrenNode, 1);
- description=xmlNodeListGetString(docs[p],nodesetdescription->nodeTab[i]->xmlChildrenNode, 1);
-
- mynode=nodesetadress->nodeTab[i]->parent;
-
- /** the following function will create the given structure for banks*/
- pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description);
- banks[i]=mybank;
- pci->banks_xml_nodes[i]=mynode;
+ if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct");
+ /** for each of the bank nodes, we create the associated structure*/
+ for(i=0;i<nodesetadress->nodeNr;i++){
+ mynode=nodesetadress->nodeTab[i];
+ pcilib_xml_create_bank(&mybank,mynode,doc);
+ banks[i]=mybank;
+ pci->banks_xml_nodes[i]=mynode;
}
-
- pcilib_add_register_banks(pci,number_banks,banks);
- p++;
- }
+ /** we push our banks structures in the pcilib environnement*/
+ pcilib_add_register_banks(pci,nodesetadress->nodeNr,banks);
}
/*
- * next 3 functions are for the implementation of a merge sort algorithm
+ * next 2 functions are for the implementation of a merge sort algorithm, because we need a stable algorithm
*/
-void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){
+static void
+pcilib_xml_topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){
int i0,i1,j;
i0= start;
i1=middle;
@@ -463,58 +287,154 @@ void topdownmerge(pcilib_register_description_t *A, int start, int middle, int e
}
}
-void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){
- int k;
- for (k=start; k<end;k++) A[k]=B[k];
-}
-
-void topdownsplitmerge(pcilib_register_description_t *A, int start, int end, pcilib_register_description_t *B){
+static void
+pcilib_xml_topdownsplitmerge(pcilib_register_description_t *A, int start, int end, pcilib_register_description_t *B){
int middle;
if(end-start <2)
return;
middle =(end+start)/2;
- topdownsplitmerge(A,start, middle,B);
- topdownsplitmerge(A,middle,end,B);
- topdownmerge(A,start,middle,end,B);
- copyarray(B,start,end,A);
+ pcilib_xml_topdownsplitmerge(A,start, middle,B);
+ pcilib_xml_topdownsplitmerge(A,middle,end,B);
+ pcilib_xml_topdownmerge(A,start,middle,end,B);
+ memcpy(&A[start],&B[start],(end-start)*sizeof(pcilib_register_description_t));
}
/** pcilib_xml_arrange_registers
- *
- * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which consider the adding of registers in order of adress
+ * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which don't consider the adding of registers in order of adress
* @param[in,out] registers the list of registers in : not ranged out: ranged.
* @param[in] size the number of registers.
*/
void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){
pcilib_register_description_t* temp;
temp=malloc(size*sizeof(pcilib_register_description_t));
- topdownsplitmerge(registers,0,size,temp);
+ pcilib_xml_topdownsplitmerge(registers,0,size,temp);
free(temp);
}
-/** pcilib_xml_getnumberregisters
- *
- * get the number of registers in the xml document, for further mallocs
- * @param[in] doc the xpath context of the xml file.
- * @return the numbers of registers in xml file.
+/** pcilib_xml_create_register.
+ * this function create a register structure from a xml register node.
+ * @param[out] myregister the register we want to create
+ * @param[in] type the type of the future register, because this property can't be parsed
+ * @param[in] doc the AST of the xml file, required for some ibxml2 sub-fonctions
+ * @param[in] mynode the xml node to create register from
*/
-int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){
- xmlNodeSetPtr nodesetadress=NULL,nodesetsuboffset=NULL;
- xmlXPathObjectPtr temp,temp2;
- temp=pcilib_xml_getsetproperty(doc,ADRESS_PATH); /**<we get the structure with all standards registers here*/
- if(temp!=NULL) nodesetadress=temp->nodesetval; /**<we get the structure with all standards registers here*/
- else {
- pcilib_error("no registers found in the xml file");
- return 0;
+void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type){
+
+ char* ptr;
+ xmlNodePtr cur;
+ xmlChar *value;
+ xmlChar *bank;
+
+ /**we get the children of the register xml nodes, that contains the properties for it*/
+ cur=mynode->children;
+
+ while(cur!=NULL){
+ value=xmlNodeListGetString(doc,cur->children,1);
+ /* we iterate throug each children to get the associated property
+ note :the use of strtol permits to get as well hexadecimal and decimal values
+ */
+ if(strcmp((char*)cur->name,"adress")==0){
+ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"offset")==0){
+ myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"size")==0){
+ myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"default")==0){
+ myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"rwmask")==0){
+ if(strcmp((char*)value,"all bits")==0){
+ myregister->rwmask=PCILIB_REGISTER_ALL_BITS;
+ }else if(strcmp((char*)value,"0")==0){
+ myregister->rwmask=0;
+ }else{
+ myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+ }
+
+ }else if(strcmp((char*)cur->name,"mode")==0){
+ if(strcmp((char*)value,"R")==0){
+ myregister->mode=PCILIB_REGISTER_R;
+ }else if(strcmp((char*)value,"W")==0){
+ myregister->mode=PCILIB_REGISTER_W;
+ }else if(strcmp((char*)value,"RW")==0){
+ myregister->mode=PCILIB_REGISTER_RW;
+ }else if(strcmp((char*)value,"W")==0){
+ myregister->mode=PCILIB_REGISTER_W;
+ }else if(strcmp((char*)value,"RW1C")==0){
+ myregister->mode=PCILIB_REGISTER_RW1C;
+ }else if(strcmp((char*)value,"W1C")==0){
+ myregister->mode=PCILIB_REGISTER_W1C;
+ }
+
+ }else if(strcmp((char*)cur->name,"name")==0){
+ myregister->name=(char*)value;
+
+ }else if(strcmp((char*)cur->name,"value_min")==0){
+ /* not implemented yet*/ // myregister->value_min=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"value_max")==0){
+ /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+
+ }else if(strcmp((char*)cur->name,"description")==0){
+ myregister->description=(char*)value;
}
+
+ cur=cur->next;
+ }
- temp2=pcilib_xml_getsetproperty(doc,SUB_OFFSET_PATH);/**< we get the structure with all bits registers here */
- if(temp2!=NULL) nodesetsuboffset=temp2->nodesetval;/**< we get the structure with all bits registers here */
- else nodesetsuboffset->nodeNr=0;
- return nodesetadress->nodeNr + nodesetsuboffset->nodeNr; /**<we sum the number of nodes in the first structure to the number of nodes in the second one*/
-}
+ /** we then get properties that can not be parsed as the previous ones*/
+ if(strcmp((char*)type,"standard")==0){
+ myregister->type=PCILIB_REGISTER_STANDARD;
+ bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**<we get the bank adress node*/
+
+ }else if(strcmp((char*)type,"bits")==0){
+ myregister->type=PCILIB_REGISTER_BITS;
+ bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**<we get the bank adress node*/
+
+ /* we then get the properties from the parent standard regsiter, and that are not present for the bit register*/
+ cur=mynode->parent->parent->children; /**<get the parent standard register*/
+ while(cur!=NULL){
+ value=xmlNodeListGetString(doc,cur->children,1);
+ if(strcmp((char*)cur->name,"adress")==0){
+ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0);
+ }else if(strcmp((char*)cur->name,"default")==0){
+ myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+ }else if(strcmp((char*)cur->name,"rwmask")==0){
+ if(strcmp((char*)value,"all bits")==0){
+ myregister->rwmask=PCILIB_REGISTER_ALL_BITS;
+ }else if(strcmp((char*)value,"0")==0){
+ myregister->rwmask=0;
+ }else{
+ myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
+ }
+ }
+ cur=cur->next;
+ }
+
+ }else if(strcmp((char*)type,"fifo")==0){
+ /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO;
+ }
+ if(strcmp((char*)bank,"bank 0")==0){
+ myregister->bank=PCILIB_REGISTER_BANK0;
+ }else if(strcmp((char*)bank,"bank 1")==0){
+ myregister->bank=PCILIB_REGISTER_BANK1;
+ }else if(strcmp((char*)bank,"bank 2")==0){
+ myregister->bank=PCILIB_REGISTER_BANK2;
+ }else if(strcmp((char*)bank,"bank 3")==0){
+ myregister->bank=PCILIB_REGISTER_BANK3;
+ }else if(strcmp((char*)bank,"DMA bank")==0){
+ myregister->bank=PCILIB_REGISTER_BANK_DMA;
+ }else if (strcmp((char*)bank,"dynamic bank")==0){
+ myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC;
+ }else{
+ myregister->bank=PCILIB_REGISTER_BANK_INVALID;
+ }
+}
/** pcilib_xml_initialize_registers
*
@@ -522,508 +442,128 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){
*
* variables who need change if xml structure change : bank,description, sub_description, sub_adress, sub_bank, sub_rwmask (we consider it to be equal to the standard register), sub_defvalue(same to standard register normally)
* @param[in] doc the xpath context of the xml file.
- * @param[in,out] registers in: initialized list out: the list of the created registers.
+ * @param[in] pci the pcilib_t struct running, that will get filled
*/
-void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr* docs){
+void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){
- xmlNodeSetPtr nodesetadress=NULL,nodesetoffset=NULL,nodesetdefvalue=NULL,nodesetrwmask=NULL,nodesetsize=NULL,nodesetmode=NULL,nodesetname=NULL;
- xmlChar *adress=NULL,*offset=NULL,*defvalue=NULL,*rwmask=NULL,*size=NULL,*mode=NULL,*name=NULL,*bank=NULL,*type=NULL,*description=NULL;
+ xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL;
+ xmlChar *type=NULL;
xmlNodePtr mynode;
- xmlNodePtr tempnode;
xmlXPathContextPtr context;
-int number_registers, count=0;
+ int number_registers;
pcilib_register_description_t *registers=NULL;
-
-while(docs[count]!=NULL){
- context=pcilib_xml_getcontext(docs[count]);
- number_registers=pcilib_xml_getnumberregisters(context);
- if(number_registers) registers=calloc(number_registers,sizeof(pcilib_register_description_t));
- else return;
-
- xmlXPathObjectPtr temp;
-
- /** get the sructures containing each property of standard regsiter */
-/* -----> certainly not necessary if we validate xml each time*/
-
- temp=pcilib_xml_getsetproperty(context,ADRESS_PATH);
- if(temp!=NULL)nodesetadress=temp->nodesetval;
- else pcilib_error("no adress for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,OFFSET_PATH);
- if(temp!=NULL)nodesetoffset=temp->nodesetval;
- else pcilib_error("no offset for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,DEFVALUE_PATH);
- if(temp!=NULL)nodesetdefvalue=temp->nodesetval;
- else pcilib_error("no defvalue for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,RWMASK_PATH);
- if(temp!=NULL)nodesetrwmask=temp->nodesetval;
- else pcilib_error("no rwmask for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,SIZE_PATH);
- if(temp!=NULL)nodesetsize=temp->nodesetval;
- else pcilib_error("no size for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,MODE_PATH);
- if(temp!=NULL)nodesetmode=temp->nodesetval;
- else pcilib_error("no mode for registers found in xml");
-
- temp=pcilib_xml_getsetproperty(context,NAME_PATH);
- if(temp!=NULL)nodesetname=temp->nodesetval;
- else pcilib_error("no name for registers found in xml");
-
- xmlNodeSetPtr nodesetsuboffset=NULL,nodesetsubsize=NULL,nodesetsubmode=NULL,nodesetsubname=NULL;
- xmlChar *subadress=NULL,*suboffset=NULL,*subdefvalue=NULL,*subrwmask=NULL,*subsize=NULL,*submode=NULL,*subname=NULL,*subbank=NULL,*subtype=NULL,*subdescription=NULL;
-
- /**get the structures containing each property of bits registers */
- temp=pcilib_xml_getsetproperty(context,SUB_OFFSET_PATH);
- if(temp!=NULL)nodesetsuboffset=temp->nodesetval;
- else pcilib_error("no offset for registers bits found in xml");
-
- temp=pcilib_xml_getsetproperty(context,SUB_SIZE_PATH);
- if(temp!=NULL)nodesetsubsize=temp->nodesetval;
- else pcilib_error("no size for registers bits found in xml");
-
- temp=pcilib_xml_getsetproperty(context,SUB_MODE_PATH);
- if(temp!=NULL)nodesetsubmode=temp->nodesetval;
- else pcilib_error("no mode for registers bits found in xml");
-
- temp=pcilib_xml_getsetproperty(context,SUB_NAME_PATH);
- if(temp!=NULL)nodesetsubname=temp->nodesetval;
- else pcilib_error("no name for registers bits found in xml");
-
-
pcilib_register_description_t myregister;
-
int i,j;
+
+ context=pcilib_xml_getcontext(doc);
+
+ /** we first get the nodes of standard and bits registers*/
+ nodesetadress=pcilib_xml_getsetproperty(context,REGISTERS_PATH)->nodesetval;
+ nodesetsubadress=pcilib_xml_getsetproperty(context,BITS_REGISTERS_PATH)->nodesetval;
+ if(nodesetadress->nodeNr>0)registers=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(pcilib_register_description_t));
+ else return;
- pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsuboffset->nodeNr,sizeof(xmlNodePtr));
+ pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(xmlNodePtr));
if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct");
+ /** we then iterate through standard registers nodes to create registers structures*/
for(i=0;i<nodesetadress->nodeNr;i++){
- /** get each sub property of each standard registers*/
- adress=xmlNodeListGetString(docs[count],nodesetadress->nodeTab[i]->xmlChildrenNode, 1);
- tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent));
- if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1);
- else pcilib_error("the xml file is malformed");
- offset=xmlNodeListGetString(docs[count],nodesetoffset->nodeTab[i]->xmlChildrenNode, 1);
- size=xmlNodeListGetString(docs[count],nodesetsize->nodeTab[i]->xmlChildrenNode, 1);
- defvalue=xmlNodeListGetString(docs[count],nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1);
- rwmask=xmlNodeListGetString(docs[count],nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1);
- mode=xmlNodeListGetString(docs[count],nodesetmode->nodeTab[i]->xmlChildrenNode, 1);
- name=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->xmlChildrenNode, 1);
type=(xmlChar*)"standard";
- if(nodesetname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetname->nodeTab[i]->next->next->name,"description")==0){
- description=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1);
- }else{
- description=(xmlChar*)"";
- }
- mynode=nodesetadress->nodeTab[i]->parent;
- /**creation of a register with the given previous properties*/
- pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description);
+ mynode=nodesetadress->nodeTab[i];
+ pcilib_xml_create_register(&myregister,mynode,doc,type);
registers[i]=myregister;
pci->registers_xml_nodes[i]=mynode;
}
j=i;
-
- for(i=0;i<nodesetsuboffset->nodeNr;i++){
- /** we get there each subproperty of each bits register*/
- tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent);
- if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1);
- else pcilib_error("xml file is malformed");
- tempnode= xmlFirstElementChild(xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent->parent->parent));
- if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1);
- else pcilib_error("xml file is malformed");
- suboffset=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1);
- subsize=xmlNodeListGetString(docs[count],nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1);
- tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent)->next->next->next->next->next->next;
- if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1);
- else pcilib_error("xml file is malformed");
- subrwmask=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1);
- submode=xmlNodeListGetString(docs[count],nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1);
- subname=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->xmlChildrenNode, 1);
- subtype=(xmlChar*)"bits";
- if(nodesetsubname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetsubname->nodeTab[i]->next->next->name,"sub_description")==0){
- subdescription=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1);
- }else{
- subdescription=(xmlChar*)"";
- }
- mynode=nodesetsuboffset->nodeTab[i]->parent;
- /** creation of a bits register given the previous properties*/
- pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription);
+ /** we then iterate through bits registers nodes to create registers structures*/
+ for(i=0;i<nodesetsubadress->nodeNr;i++){
+ type=(xmlChar*)"bits";
+ mynode=nodesetsubadress->nodeTab[i];
+ pcilib_xml_create_register(&myregister,mynode,doc,type);
registers[i+j]=myregister;
pci->registers_xml_nodes[i+j]=mynode;
}
-
- pcilib_xml_arrange_registers(registers,number_registers);
- pcilib_add_registers(pci,number_registers,registers);
- count++;
- }
-}
-
-#ifdef VIEW_OK
-/* pcilib_xml_getnumberformulaviews
- *
- * function to get the number of views of type formula, for further malloc
- */
-int pcilib_xml_getnumberformulaviews(xmlXPathContextPtr doc){
- int j;
- xmlNodeSetPtr nodeviewsset=NULL;
- nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_FORMULA_PATH)->nodesetval;
- j=nodeviewsset->nodeNr;
- return j;
+ /**we arrange the register for them to be well placed for pci-l*/
+ pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr);
+ /**we fille the pcilib_t struct*/
+ pcilib_add_registers(pci,number_registers,registers);
}
-/* pcilib_xml_getnumberenumviews
- *
- * function to get the number of views of type enum, for further malloc
- */
-int pcilib_xml_getnumberenumviews(xmlXPathContextPtr doc){
- int j;
- xmlNodeSetPtr nodeviewsset=NULL;
- nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_ENUM_PATH)->nodesetval;
- j=nodeviewsset->nodeNr;
- return j;
-
-
-}
-/* pcilib_xml_initialize_viewsformula
- *
- * function to create the structures to store the views of type formula from the xml
- *
- * values that need to be changed when xml file change: name, formula,
+/** pcilib_init_xml
+ * this function will initialize the registers and banks from the xml files
+ * @param[in,out] ctx the pciilib_t running that gets filled with structures
*/
-void pcilib_xml_initialize_viewsformula(xmlDocPtr doc, pcilib_view_formula_ptr_t* myviewsformula){
- xmlNodeSetPtr viewsetformula, viewformula, viewreverseformula, viewunit, viewformulaname, nodesetviewregister,nodesetviewregisterbit,nodesetregister,nodesetsubregister;
- xmlChar *formula, *name,*reverseformula,*registername,*bankname,*unit;
- int i,j,registernumber,viewnumber,k,l,externregisternumber,enregistrement,u;
-
- char *substr;
-
- xmlXPathContextPtr context;
- context=pcilib_xml_getcontext(doc);
-
- viewsetformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_PATH)->nodesetval;
- viewformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_FORMULA_PATH)->nodesetval;
- viewreverseformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_REVERSE_FORMULA_PATH)->nodesetval;
- viewunit=pcilib_xml_getsetproperty(context,VIEW_FORMULA_UNIT_PATH)->nodesetval;
- viewformulaname=pcilib_xml_getsetproperty(context,VIEW_FORMULA_NAME_PATH)->nodesetval;
-
+int pcilib_init_xml(pcilib_t* ctx){
+ char *path,*pwd, **line, *line_xsd=NULL;
+ int i=1,k;
+ xmlDocPtr* docs;
+ DIR* rep=NULL;
+ struct dirent* file=NULL;
+ int err;
-viewnumber=0;
-
+ path=malloc(sizeof(char*));
+ line=malloc(sizeof(char*));
+ line[0]=NULL;
+
+ /** we first get the env variable corresponding to the place of the xml files*/
+ path=getenv("PCILIB_MODEL_DIR");
+ if(path==NULL){
+ pcilib_warning("can't find environment variable for xml files");
+ return 1;
+ }
- nodesetviewregisterbit=pcilib_xml_getsetproperty(context,VIEW_BITS_REGISTER)->nodesetval;
- nodesetviewregister=pcilib_xml_getsetproperty(context,VIEW_STANDARD_REGISTER)->nodesetval;
- nodesetregister=pcilib_xml_getsetproperty(context,NAME_PATH)->nodesetval;
- nodesetsubregister=pcilib_xml_getsetproperty(context,SUB_NAME_PATH)->nodesetval;
-
- myviewsformula->viewsformula=calloc(myviewsformula->size,sizeof(pcilib_view_formula_t));
- for(i=0;i<viewsetformula->nodeNr;i++){
- registernumber=0;
- name=xmlNodeListGetString(doc,viewformulaname->nodeTab[i]->xmlChildrenNode,1);
- formula=xmlNodeListGetString(doc,viewformula->nodeTab[i]->xmlChildrenNode,1);
- reverseformula=xmlNodeListGetString(doc,viewreverseformula->nodeTab[i]->xmlChildrenNode,1);
- unit=xmlNodeListGetString(doc,viewunit->nodeTab[i]->xmlChildrenNode,1);
-
- xmlXPathObjectPtr temp,temp2;
-
- char* path;
- path=malloc(sizeof(char*));
- sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name);
- temp=pcilib_xml_getsetproperty(context,(xmlChar*)path);
- if(temp!=NULL) nodesetviewregister= temp->nodesetval;
-
- char* path2;
- path2=malloc(sizeof(char*));
- sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name);
- temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2);
- if(temp2!=NULL) nodesetviewregisterbit= temp2->nodesetval;
-
- j=0;
- if(temp!=NULL) j+=nodesetviewregister->nodeNr;
- if(temp2!=NULL) j+=nodesetviewregisterbit->nodeNr;
-
- myviewsformula->viewsformula[viewnumber].depending_registers=calloc((j),sizeof(pcilib_register_for_read_t));
- myviewsformula->viewsformula[viewnumber].number_depending_registers=j;
- registernumber=0;
- if (temp!=NULL){
- for(j=0; j<nodesetviewregister->nodeNr;j++){
- myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregister->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
- bankname=xmlNodeListGetString(doc,xmlFirstElementChild(nodesetviewregister->nodeTab[j]->parent->parent->parent->parent)->last->prev->prev->prev->xmlChildrenNode,1);
- myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname;
- registernumber++;
- }
- }
-
- if(temp2!=NULL){
- for(j=0; j<nodesetviewregisterbit->nodeNr;j++){
- myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregisterbit->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
- bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetviewregisterbit->nodeTab[j]->parent->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
- myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname;
- registernumber++;
- }
- }
-
- myviewsformula->viewsformula[viewnumber].name=(char*) name;
- myviewsformula->viewsformula[viewnumber].formula=(char*) formula;
- myviewsformula->viewsformula[viewnumber].reverseformula=(char*) reverseformula;
- myviewsformula->viewsformula[viewnumber].unit=(char*) unit;
-
- /* we then get the extern registers for the formula, which names are directly put in the formula*/
- externregisternumber=0;
- k=0;
- u=0;
- myviewsformula->viewsformula[viewnumber].extern_registers=calloc(1,sizeof(pcilib_register_for_read_t));
- myviewsformula->viewsformula[viewnumber].number_extern_registers=0;
-
- /* we first get the name of a register put in the formula, by getting indexes of start and end for this name*/
- for(j=0;j<strlen((char*)formula);j++){
- if(formula[j]=='@'){
- k=j+1;
- while((formula[k]!=' ' && formula[k]!=')' && formula[k]!='/' && formula[k]!='+' && formula[k]!='-' && formula[k]!='*' && formula[k]!='=') && (k<strlen((char*)formula))){
- k++;
- }
- enregistrement=1;
- substr=str_sub((char*)formula,j+1,k-1);
- /* we verify the register is not the depending register*/
- if(strcmp("reg",substr)!=0){
-
- /* we then get recursively each standard register and test if it's the extern register or not*/
- for(l=0;l<nodesetregister->nodeNr;l++){
- registername=xmlNodeListGetString(doc,nodesetregister->nodeTab[l]->xmlChildrenNode,1);
- if(strcmp((char*)registername,substr)==0){
- bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetregister->nodeTab[l]->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
- /*before registering the extern register, as it matches, we tast if the said register was already registered or not*/
- for(u=0;u<externregisternumber;u++){
- if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){
- enregistrement=0;
- }
- }
- if(enregistrement==1){
- myviewsformula->viewsformula[viewnumber].number_extern_registers++;
- myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t));
- myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername;
- myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname;
- enregistrement=0;
- externregisternumber++;
- }
- break;
- }
- }
- if(enregistrement==1){
- /* we get recursively each bits register and test if it's the extern register of the formula or not*/
- for(l=0;l<nodesetsubregister->nodeNr;l++){
- registername=xmlNodeListGetString(doc,nodesetsubregister->nodeTab[l]->xmlChildrenNode, 1);
- if(strcmp((char*)registername,substr)==0){
- bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetsubregister->nodeTab[l]->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1);
- /* check to test if the register has already been registered or not*/
- for(u=0;u<externregisternumber;u++){
- if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){
- enregistrement=0;
- break;
- }
- }
- if(enregistrement==1){
- myviewsformula->viewsformula[viewnumber].number_extern_registers++;
- myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t));
- myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername;
- myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname;
- externregisternumber++;
- enregistrement=0;
- }
- break;
- }
- }
- }
- }
- }
- }
- viewnumber++;
- }
-
- free(path);
- free(path2);
-}
-
-/* pcilib_xml_initialize_viewsenum
- *
- * function to create the structures to store the views of type enum from the xml
- *
- * values that need to be changed when xml file change: current,
-*
- */
-void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myviewsenum){
- xmlNodeSetPtr viewsetenum,viewsetregister3, viewsetregister4;
- xmlChar *name;
- int i,k,viewnumber,j,registernumber;
-
- xmlXPathContextPtr context;
- context=pcilib_xml_getcontext(doc);
-
- xmlXPathObjectPtr temp,temp2;
-
- xmlNodePtr current;
- viewsetenum=pcilib_xml_getsetproperty(context,VIEW_ENUM_PATH)->nodesetval;
- xmlAttr *attr2,*attr3;
- viewnumber=0;
- int enumnumber=0;
-
- myviewsenum->viewsenum=calloc(myviewsenum->size,sizeof(pcilib_view_enum_t));
- for(i=0;i<viewsetenum->nodeNr;i++){
- enumnumber=0;
- k=0;
- registernumber=0;
- name=xmlNodeListGetString(doc,xmlFirstElementChild(viewsetenum->nodeTab[i])->xmlChildrenNode,1);
- myviewsenum->viewsenum[viewnumber].name=(char*)name;
- myviewsenum->viewsenum[viewnumber].registerenum=calloc(1,sizeof(char*));
- myviewsenum->viewsenum[viewnumber].number_registerenum=0;
- registernumber=0;
-
- char* path;
- path=malloc(sizeof(char*));
- sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name);
- temp=pcilib_xml_getsetproperty(context,(xmlChar*)path);
- if(temp!=NULL) viewsetregister3= temp->nodesetval;
-
- char* path2;
- path2=malloc(sizeof(char*));
- sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name);
- temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2);
- if(temp2!=NULL) viewsetregister4= temp2->nodesetval;
-
- j=0;
- if(temp!=NULL) j+=viewsetregister3->nodeNr;
- if(temp2!=NULL) j+=viewsetregister4->nodeNr;
- myviewsenum->viewsenum[viewnumber].registerenum=malloc(j*sizeof(char*));
- myviewsenum->viewsenum[viewnumber].number_registerenum=j;
- if(temp!=NULL){
- for(j=0; j<viewsetregister3->nodeNr;j++){
- myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister3->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
- registernumber++;
- }
- }
- if(temp2!=NULL){
- for(j=0; j<viewsetregister4->nodeNr;j++){
- myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister4->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1);
- registernumber++;
- }
- }
-
-
- current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next->next->next;
- while(current!=viewsetenum->nodeTab[i]->last->prev){
- k++;
- current=current->next->next;
- }
-
- myviewsenum->viewsenum[viewnumber].myenums=calloc((k+1),sizeof(pcilib_enum_t));
- myviewsenum->viewsenum[viewnumber].number_enums=k+1;
-
- /* we get here each enum for a said view except the last one*/
- current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next;
- while(current!=viewsetenum->nodeTab[i]->last->prev->prev->prev){
- attr2 = current->properties;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1);
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content;
- attr2=attr2->next;
- /* and we take the properties that are given about range*/
- if(attr2!=NULL){
- if(strcmp((char*)attr2->name,"min")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content;
- attr3=attr2->next;
- if(attr3 !=NULL){
- if(strcmp((char*)attr3->name,"max")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content;
- }else pcilib_error("problem in xml file at enum");
-
- }else{
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- }
-
- }else if(strcmp((char*)attr2->name,"max")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content;
- }else pcilib_error("problem in xml file at enum");
- }else{
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- }
- enumnumber++;
- current=current->next->next;
- }
- /* get the last enum and the given properties */
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1);
- attr2 = current->properties;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content;
- attr2=attr2->next;
- if(attr2!=NULL){
- if(strcmp((char*)attr2->name,"min")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content;
- attr3=attr2->next;
- if(attr3 !=NULL){
- if(strcmp((char*)attr3->name,"max")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content;
- }else pcilib_error("problem in xml file at enum");
- }else{
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- }
-
- }else if(strcmp((char*)attr2->name,"max")==0){
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content;
- }else pcilib_error("problem in xml file at enum");
- }else{
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value;
- }
-
- viewnumber++;
-
- }
-
- free(path);
- free(path2);
-}
-#endif
+ /** we then open the directory corresponding to the ctx model*/
+ pwd=malloc((strlen(path)+strlen(ctx->model))*sizeof(char));
+ sprintf(pwd,"%s%s/",path,ctx->model);
+ if((rep=opendir(pwd))==NULL){
+ pcilib_warning("could not open the directory for xml files: error %i\n",errno);
+ return 1;
+ }
-#ifdef UNIT_OK
+ /** we iterate through the files of the directory, to get the xml files and the xsd file*/
+ while((file=readdir(rep))!=NULL){
+ if(strstr(file->d_name,".xml")!=NULL){
+ line=realloc(line,i*sizeof(char*));
+ line[i-1]=malloc((strlen(file->d_name)+strlen(pwd)+1)*sizeof(char));
+ sprintf(line[i-1],"%s%s",pwd,file->d_name); /**< here i wanted to use realpath() function, but it was not working correctly*/
+ i++;
+ }
+ if(strstr(file->d_name,".xsd")!=NULL){
+ line_xsd=malloc((strlen(file->d_name)+strlen(pwd))*sizeof(char));
+ sprintf(line_xsd,"%s%s",pwd,file->d_name);
+ }
+ }
-void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){
+ if(line_xsd==NULL){
+ pcilib_warning("no xsd file found");
+ return 1;
+ }
- xmlNodeSetPtr nodesetbaseunit=NULL, nodesettransformunit=NULL;
- xmlXPathContextptr context;
- context=pcilib_xml_getcontext(doc);
- xmlXPathObjectPtr temp;
- int i,j;
- char *path;
+ if(line[0]==NULL){
+ pcilib_warning("no xml file found");
+ return 1;
+ }
+
+ /** for each xml file, we validate it, and get the registers and the banks*/
+ docs=malloc((i-1)*sizeof(xmlDocPtr));
+ for(k=0;k<i-1;k++){
+ err=validation(line[k],line_xsd);
+ if(err==0){
+ docs[k]=pcilib_xml_getdoc(line[k]);
+ pcilib_xml_initialize_banks(ctx,docs[k]);
+ pcilib_xml_initialize_registers(ctx,docs[k]);
+ }
+ }
+
+ // free(path);
+ free(pwd);
+ free(line);
+ free(line_xsd);
+ free(docs);
+ return 0;
+}
- temp=pcilib_xml_getsetproperty(context, BASE_UNIT_PATH);
- if(temp!=NULL) nodesetbaseunit=temp->nodesetval;
- else pcilib_error("the unit xml file is wrong");
-
- unitsptr->list_unit=malloc(nodesetbaseunit->nodeNr*sizeof(pcilib_unit_t));
- unitsptr->size=nodesetbaseunit->nodeNr;
-
- for(i=0; i< nodesetbaseunit->NodeNr; i++){
- unitsptr->list_unit[i].name=nodesetbaseunit->nodeTab[i]->properties->children->content;
- path=malloc(sizeof(char*));
- sprintf(path, TRANSFORM_UNIT_PATH, unitsptr->list_unit[i].name);
- temp=pcilib_xml_getsetproperty(context, path);
- if(temp!=NULL){
- unitsptr->list_unit[i].size_trans_units=temp->nodeNr;
- unitsptr->list_unit[i].other_units=malloc(temp->nodeNr*sizeof(pcilib_transform_unit_t));
- for(j=0;j<temp->nodeNr;j++){
- unitsptr->list_unit[i].other_units[j].name=temp->nodeTab[j]->properties->children->content;
- unitsptr->list_unit[i].other_units[j].transform_formula=(char*)xmlNodeListGetString(doc,temp->nodeTab[j]->xmlChildrenNode,1);
- }
- }
- }
- free(path);
-}
-#endif
diff --git a/pcilib/xml.h b/pcilib/xml.h
index 00d2374..1ef8ee5 100644
--- a/pcilib/xml.h
+++ b/pcilib/xml.h
@@ -12,98 +12,16 @@
#ifndef _XML_
#define _XML_
-//#include <stdlib.h>
-//#include <stdio.h>
-//#include <string.h>
-//#include <assert.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
#include "pcilib.h"
-#include "register.h"
-#include "model.h"
-#include "bank.h"
-#include "pci.h"
-//#include <Python.h>
#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /**<all standard registers nodes.*/
-
-#define ADRESS_PATH ((xmlChar*)"/model/banks/bank/registers/register/adress") /**<adress path for standard registers.*/
-#define OFFSET_PATH ((xmlChar*)"/model/banks/bank/registers/register/offset") /**<offset path for standard registers.*/
-#define SIZE_PATH ((xmlChar*)"/model/banks/bank/registers/register/size") /**<size path for standard registers.*/
-#define DEFVALUE_PATH ((xmlChar*)"/model/banks/bank/registers/register/default") /**<defvalue path for standard registers.*/
-#define RWMASK_PATH ((xmlChar*)"/model/banks/bank/registers/register/rwmask") /**<rwmask path for standard registers.*/
-#define MODE_PATH ((xmlChar*)"/model/banks/bank/registers/register/mode") /**<mode path for standard registers.*/
-#define NAME_PATH ((xmlChar*)"/model/banks/bank/registers/register/name") /**<name path for standard registers.*/
-#define DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/registers/register/description") /**<description. not used, is searched recursively as it may not appearing in xml. */
-
-#define SUB_OFFSET_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/offset") /**<offset path for bits registers.*/
-#define SUB_SIZE_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/size") /**<size path for bits registers.*/
-#define SUB_RWMASK_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/sub_rwmask") /**<rwmask path for bits registers. not used, as the value is meant to be the same as the standard register this register depends on.*/
-#define SUB_MODE_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/mode") /**<size path for bits registers.*/
-#define SUB_NAME_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/name") /**<name path for bits registers.*/
-#define SUB_DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/adress") /**<description path for bits registers. not used, is searched recursively as it may not appear in the xml.*/
-
-#define VIEW_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]") /**< the complete node path for views of type formula.*/
-#define VIEW_FORMULA_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/read_from_register") /**< path to formula in direction read_from_register for views of type formula.*/
-#define VIEW_FORMULA_REVERSE_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/write_to_register") /**< path to formula in direction write_to_register for views of type formula.*/
-#define VIEW_FORMULA_UNIT_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/unit") /**< path to the base unit of the view of type formula. */
-#define VIEW_FORMULA_NAME_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/name") /**<path to the name of the view of type formula.*/
-
-#define VIEW_ENUM_PATH ((xmlChar*)"/model/views/view[@type=\"enum\"]") /**< the complete node path for views of type enum.*/
-
-#define VIEW_BITS_REGISTER ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/views/view") /**< @warning not used normally.*/
-#define VIEW_STANDARD_REGISTER ((xmlChar*)"/model/banks/bank/registers/register/views/view") /**< @warning not used too.*/
-#define VIEW_STANDARD_REGISTER_PLUS ((char*)"/model/banks/bank/registers/register/views/view[.=\"%s\"]") /**< path to the standard registers that depend on the given view.*/
-#define VIEW_BITS_REGISTER_PLUS ((char*)"/model/banks/bank/registers/register/registers_bits/register_bits/views/view[.=\"%s\"]") /**< path to the bits registers that depend on the given view.*/
-
+#define BITS_REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits") /**<all bits registers nodes.*/
#define BANKS_PATH ((xmlChar*)"/model/banks/bank/bank_description") /**< path to complete nodes of banks.*/
-#define BANK_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/adress") /**<path to adress of banks.*/
-#define BANK_BAR_PATH ((xmlChar*)"/model/banks/bank/bank_description/bar") /**<path to bar of banks.*/
-#define BANK_SIZE_PATH ((xmlChar*)"/model/banks/bank/bank_description/size") /**<path to size of banks.*/
-#define BANK_PROTOCOL_PATH ((xmlChar*)"/model/banks/bank/bank_description/protocol") /**< path to protocol of banks.*/
-#define BANK_READ_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/read_adress") /**<path to read_addr of banks.*/
-#define BANK_WRITE_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/write_adress") /**<path to write_addr of banks.*/
-#define BANK_RAW_ENDIANESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/raw_endianess") /**<path to raw_endianess of banks.*/
-#define BANK_ACCESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/word_size") /**<path to word_size of banks.*/
-#define BANK_ENDIANESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/endianess") /**<path to endianess of banks.*/
-#define BANK_FORMAT_PATH ((xmlChar*)"/model/banks/bank/bank_description/format") /**<path to format of banks.*/
-#define BANK_NAME_PATH ((xmlChar*)"/model/banks/bank/bank_description/name") /**< path to name of banks.*/
-#define BANK_DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/bank_description/description") /**<path to description of banks.*/
-
-
-/**
- * this path get the units in the units xml file
- */
-#define BASE_UNIT_PATH ((char*)"/units/unit")
-
-/**
- * this path permits to get the possible units one given unit can be converted into in the xml.
- */
-#define TRANSFORM_UNIT_PATH ((char*)"/units/unit[@name=\"%s\"]/convert_unit")
-
-/**
- * this function create the list of registers structures, that are manipulated during execution, from the xml file.
- * @param[in] doc the xpath context of the xml file.
- * @param[out] registers out: the list of the created registers.
- */
-void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr* doc);
-
-/**
- * this functions initialize the structures containing banks, for use in the rest of execution, from the xml file.
- * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node).
- * @param[in] doc the AST of the xml file.
- * @param[in,out] mybanks the structure containing the banks.
- */
-void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* doc);
/**
- * this function gets the xml files and validates them, before returning pre-AST of them to initialize functions
- *@param[out] docs the list of pre-AST of xml files parsed
+ * this function gets the xml files and validates them, before filling the pcilib_t struct with the registers and banks of those files
+ *@param[in,out] pci the pcilib_t struct running that gets filled with banks and registers
*/
-void pcilib_init_xml(xmlDocPtr* docs);
+int pcilib_init_xml(pcilib_t* pci);
#endif /*_XML_*/