aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAyan Kumar Halder2021-12-24 15:08:25 +0000
committerStefano Stabellini2022-01-04 17:31:26 -0800
commit1993749a7d38b825e9ec74b0da20041cd7e41c67 (patch)
treed3eb3d296dda8d660fc92eeacd60735650068005
parentb098f3d5d627ad40c000fa100f8a72d011dba15e (diff)
Update the generated domU.cfg
domU.cfg has been updated with the following propereties:- 1. iomem - This corresponds to the "xen,reg" property. It obtains mfn, num_pages and gfn. 2. dtdev - This corresponds to the "xen,path" property. This is set only if "xen,force-assign-without-iommu" is not present. 3. irqs - This corresponds to the "interrupts" property. One needs to add 32 to the interrupt value. This is due to initial 32 interrupts being reserved by GIC for special purposes. The corresponding properties are obtained from partial dtb. Signed-off-by: Ayan Kumar Halder <ayankuma@xilinx.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
-rwxr-xr-xscripts/disk_image297
1 files changed, 297 insertions, 0 deletions
diff --git a/scripts/disk_image b/scripts/disk_image
index 69b037f..afd21f9 100755
--- a/scripts/disk_image
+++ b/scripts/disk_image
@@ -68,6 +68,295 @@ function add_rootfs()
fi
}
+function get_interrupts()
+{
+ local xen_intr_txt="$1"
+ local num_fields
+ local intr_num
+ local intr_str
+ local val
+ local i
+
+ while IFS= read -r val
+ do
+ #Remove the prefix "interrupts = <"
+ val=${val#*"interrupts = <"}
+
+ #Remove the suffix ">;" from each line
+ val=${val%>;*}
+
+ num_fields=`echo $val | awk '{print NF}'`
+
+ #We expect the following format
+ #interrupts = <0x00 irq_no flags 0x00 irq_no flags 0x00 irq_no flags ..>;
+ if test $((num_fields % 3)) -ne 0
+ then
+ return 1
+ fi
+
+ #Position of the first interrupt no
+ i=2
+ while test $i -lt $num_fields
+ do
+ intr_num=`echo $val | awk -v i="$i" '{print $i}'`
+
+ #The next irq_no will be after 3 places
+ i=$((i+3))
+
+ intr_num=$((intr_num + 32))
+
+ if test "$intr_str"
+ then
+ intr_str="$intr_str,"
+ fi
+ intr_str="$intr_str"$intr_num
+ done
+
+ done < "$xen_intr_txt"
+
+ if test "$intr_str"
+ then
+ echo "$intr_str"
+ fi
+}
+
+function contains()
+{
+ local item="$1"
+ local list="$2"
+ local each
+
+ for each in $list
+ do
+ if test "$each" = "$item"
+ then
+ echo "yes"
+ fi
+ done
+}
+
+function check_if_force_assign_iommu()
+{
+ local xen_path="$1"
+ local dtb="$2"
+ local node="$3"
+ local path
+ local subnode
+ local subnode_cnt
+ local props
+ local xen_path_present
+ local assign_present
+
+ subnode_cnt=$(fdtget -l "$dtb" "$node" | wc -l)
+
+ props=$(fdtget -p "$dtb" "$node")
+ xen_path_present=$(contains "xen,path" "$props")
+ assign_present=$(contains "xen,force-assign-without-iommu" "$props")
+
+ if test "$xen_path_present" = "yes" && test "$assign_present" = "yes"
+ then
+ path=$(fdtget "$dtb" "$node" "xen,path")
+ if test "$path" = "$xen_path"
+ then
+ echo "yes"
+ return 0
+ fi
+ fi
+
+ if test $subnode_cnt -gt 0
+ then
+ for subnode in `fdtget -l "$dtb" "$node"`
+ do
+ subnode="$node/$subnode"
+ check_if_force_assign_iommu "$xen_path" "$dtb" "$subnode"
+ done
+ fi
+}
+
+function get_iommu_prop()
+{
+ local xen_path_txt="$1"
+ local domU_dtb="$2"
+ local dtdev_str
+ local devpath
+ local force_assign
+
+ #Iterate through all the lines in the file
+ while IFS= read -r devpath
+ do
+ #Extract the path of the device from each line
+ #
+ #For eg, the line may be as follows
+ #xen,path = "/axi/serial@ff010000";
+ #
+ #What we want is the following substring
+ #"/axi/serial@ff010000"
+ devpath=`echo $devpath | awk '{print $3}'`
+ devpath=${devpath#*\"}
+ devpath=${devpath%\";*}
+
+ force_assign=$(check_if_force_assign_iommu "$devpath" "$domU_dtb" "/passthrough")
+
+ if test -z "$force_assign"
+ then
+ if test "$dtdev_str"
+ then
+ dtdev_str="$dtdev_str, "
+ fi
+ dtdev_str=${dtdev_str}"\""${devpath}"\""
+ fi
+
+ done < "$xen_path_txt"
+
+ if test "$dtdev_str"
+ then
+ echo "$dtdev_str"
+ fi
+}
+
+function get_iomem()
+{
+ local xen_reg_txt="$1"
+ local addr="$2"
+ local size="$3"
+ local val
+ local i
+ local num_fields
+ local iomem_str
+ local address_size_pair
+ local mfn
+ local gfn
+ local size_
+ local PAGE_SHIFT=12
+
+ #Iterate through all the lines in the file
+ #The file will look similar to the following:-
+ #
+ #xen,reg = <0x00 0xff010000 0x00 0x1000 0x00 0xff010000 0x00 0xff110000 0x00 0x1000 0x00 0xff110000 0x00 0xff120000 0x00 0x1000 0x00 0xff120000 0x00 0xff130000 0x00 0x1000 0x00 0xff130000 0x00 0xff140000 0x00 0x1000 0x00 0xff140000>;
+ #xen,reg = <0x00 0xfd0c0000 0x00 0x2000 0x00 0xfd0c0000>;
+ while IFS= read -r val
+ do
+ #Remove the prefix "xen,reg = <" from each line
+ val=${val#*"xen,reg = <"}
+
+ #Remove the suffix ">;" from each line
+ val=${val%>;*}
+
+ num_fields=`echo $val | awk '{print NF}'`
+
+ i=0
+
+ while test $i -lt $num_fields
+ do
+
+ i=$((i + addr))
+
+ #Extract the iomem physical address
+ mfn=`echo $val | awk -v i="$i" '{print $i}'`
+
+ #Calculate the page address
+ mfn=0x$(printf "%X" $(( $((mfn>>PAGE_SHIFT)) & 0xfffff)) )
+
+ i=$((i + size))
+
+ #Extract the size of the iomem address
+ size_=`echo $val | awk -v i="$i" '{print $i}'`
+
+ #Calculatde the number of pages
+ size_=$(printf "%X" $(( $((size_>>PAGE_SHIFT)) & 0xfffff)) )
+
+ i=$((i + addr))
+
+ #Extract the iomem guest address
+ gfn=`echo $val | awk -v i="$i" '{print $i}'`
+
+ #Calculate the page address
+ gfn=0x$(printf "%X" $(( $((gfn>>PAGE_SHIFT)) & 0xfffff)) )
+
+ if test "$gfn" != "$mfn"
+ then
+ address_size_pair="\"$mfn,${size_}@${gfn}\""
+ else
+ address_size_pair="\"$mfn,$size_\""
+ fi
+
+ if test "$iomem_str"
+ then
+ iomem_str="$iomem_str, $address_size_pair"
+ else
+ iomem_str=$address_size_pair
+ fi
+ done
+
+ done < "$xen_reg_txt"
+
+ if test "$iomem_str"
+ then
+ echo "$iomem_str"
+ fi
+}
+
+function update_domU_cfg()
+{
+ local domU_dtb="$1"
+ local domU_cfg_file="$2"
+ local addr=$(fdtget $domU_dtb /passthrough \#address-cells)
+ local size=$(fdtget $domU_dtb /passthrough \#size-cells)
+ local iomem_str
+ local dtdev_str
+ local intr_str
+ local tmp_dts
+ local tmp_search_results
+
+ tmp_dts=`mktemp`
+ tmp_files+=($tmp_dts)
+ dtc -I dtb -O dts -o "$tmp_dts" "$domU_dtb"
+
+ tmp_search_results=`mktemp`
+ tmp_files+=($tmp_search_results)
+
+ #Let's get all the lines containing xen,path in a file
+ grep 'xen,reg' "$tmp_dts" > "$tmp_search_results"
+
+ #From "xen,reg", one can determine the "iomem" attribute of the
+ #cfg file.
+ iomem_str="$(get_iomem $tmp_search_results $addr $size)"
+ if test -z "$iomem_str"
+ then
+ echo "Error occurred while generating the iomem property"
+ return 1
+ else
+ iomem_str="iomem = [ "$iomem_str" ]"
+ echo "${iomem_str}" >> $domU_cfg_file
+ fi
+
+ #Let's get all the lines containing xen,path in a file
+ grep 'xen,path' $tmp_dts > $tmp_search_results
+
+ #From "xen,path", one can determine the "dtdev" attribute of the
+ #cfg file. This attribute is optional.
+ dtdev_str=$(get_iommu_prop $tmp_search_results $domU_dtb)
+ if test "$dtdev_str"
+ then
+ dtdev_str="dtdev = [ "$dtdev_str" ]"
+ echo "${dtdev_str}" >> $domU_cfg_file
+ fi
+
+ #Let's get all the lines containing interrupts in a file
+ grep 'interrupts' $tmp_dts > $tmp_search_results
+
+ #From "interrupts", one can determine the "irqs" attribute of the
+ #cfg file.
+ intr_str=$(get_interrupts $tmp_search_results)
+ if test "$intr_str"
+ then
+ intr_str="irqs = [ "$intr_str" ]"
+ echo "${intr_str}" >> $domU_cfg_file
+ fi
+
+ return 0
+}
+
function generate_domU_configs()
{
local i=0
@@ -136,6 +425,14 @@ function generate_domU_configs()
add_rootfs $n
echo "disk=[\"$retval,,xvda\"]" >> $dest
fi
+
+ update_domU_cfg ${DOMU_PASSTHROUGH_DTB[$i]} $dest
+ if test $? -ne 0
+ then
+ umount $DESTDIR/part/disk$j
+ cleanup_disk_image_error
+ exit 1
+ fi
fi
n=$(( $n + 1 ))