aboutsummaryrefslogtreecommitdiff
path: root/scripts/disk_image
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/disk_image')
-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 ))