diff options
author | zilio nicolas <nicolas.zilio@kit.edu> | 2015-09-04 12:52:07 +0200 |
---|---|---|
committer | zilio nicolas <nicolas.zilio@kit.edu> | 2015-09-04 12:52:07 +0200 |
commit | 57149189cb4e15ed38ee34d44450390955e56697 (patch) | |
tree | ba3e589b23b9295ca6fdc5b7e7f02037f47999c1 | |
parent | a1e8741ac0d77ab721a413a283127352d80fb944 (diff) | |
download | pcitool-57149189cb4e15ed38ee34d44450390955e56697.tar.gz pcitool-57149189cb4e15ed38ee34d44450390955e56697.tar.bz2 pcitool-57149189cb4e15ed38ee34d44450390955e56697.tar.xz pcitool-57149189cb4e15ed38ee34d44450390955e56697.zip |
almost finished regarding suren remarks
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | models/ipecamera/camera.xml | 923 | ||||
-rwxr-xr-x | models/ipecamera/registers_and_banks.xsd | 242 | ||||
-rw-r--r-- | pcilib/pci.c | 6 | ||||
-rw-r--r-- | pcilib/xml.c | 1172 | ||||
-rw-r--r-- | pcilib/xml.h | 90 |
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_*/ |