From 82fec3ab5877a46c3ac8e316f5eccfd83e0c95bc Mon Sep 17 00:00:00 2001 From: HikariKnight <2557889+HikariKnight@users.noreply.github.com> Date: Thu, 2 Nov 2023 16:45:50 +0100 Subject: [PATCH] refactor and start adding actual functionality --- internal/configs/config_vbios_dumper.go | 2 +- internal/configs/config_vfio_video.go | 2 +- internal/configs/configs.go | 4 ++ internal/pages/01_welcome.go | 3 +- internal/pages/02_select_gpu.go | 58 ++++++++++++++++++++----- internal/pages/03_vbios_extract.go | 25 +++++++---- internal/pages/04_disable_video.go | 22 +++++++--- internal/pages/05_select_usbctrl.go | 14 +++--- internal/pages/06_finalize.go | 5 +++ pkg/menu/manual.go | 27 ++++++++++++ pkg/menu/yesno.go | 29 +++++++++++++ 11 files changed, 158 insertions(+), 33 deletions(-) create mode 100644 internal/pages/06_finalize.go create mode 100644 pkg/menu/manual.go diff --git a/internal/configs/config_vbios_dumper.go b/internal/configs/config_vbios_dumper.go index afc4260..e8bc92c 100644 --- a/internal/configs/config_vbios_dumper.go +++ b/internal/configs/config_vbios_dumper.go @@ -63,7 +63,7 @@ func GenerateVBIOSDumper(vbios_path string) { errorcheck.ErrorCheck(err, "Could not change permissions of \"utils/dump_vbios.sh\"") // Write to logger - logger.Printf("Writing utils/dump_vbios.sh") + logger.Printf("Writing utils/dump_vbios.sh\n") // Write the script scriptfile.WriteString(vbios_script) diff --git a/internal/configs/config_vfio_video.go b/internal/configs/config_vfio_video.go index a438cba..63230b1 100644 --- a/internal/configs/config_vfio_video.go +++ b/internal/configs/config_vfio_video.go @@ -17,7 +17,7 @@ func DisableVFIOVideo(i int) { config := GetConfig() // Write to logger - logger.Printf("Adding vfio_pci.disable_vga=%v to %s", i, config.Path.CMDLINE) + logger.Printf("Adding vfio_pci.disable_vga=%v to %s\n", i, config.Path.CMDLINE) // Get the current kernel arguments we have generated kernel_args := fileio.ReadFile(config.Path.CMDLINE) diff --git a/internal/configs/configs.go b/internal/configs/configs.go index f2ed38d..0ff868f 100644 --- a/internal/configs/configs.go +++ b/internal/configs/configs.go @@ -28,6 +28,8 @@ type Config struct { Bootloader string Cpuvendor string Path *Path + Gpu_Group string + Gpu_IDs []string } // Gets the path to all the config files @@ -52,6 +54,8 @@ func GetConfig() *Config { Bootloader: "unknown", Cpuvendor: cpuid.CPU.VendorString, Path: GetConfigPaths(), + Gpu_Group: "", + Gpu_IDs: []string{}, } // Detect the bootloader we are using diff --git a/internal/pages/01_welcome.go b/internal/pages/01_welcome.go index d57d7d2..6bcb8d1 100644 --- a/internal/pages/01_welcome.go +++ b/internal/pages/01_welcome.go @@ -39,7 +39,8 @@ func Welcome() { // If yes, go to next page if choice == "y" { configs.InitConfigs() - SelectGPU() + config := configs.GetConfig() + SelectGPU(config) } else { fmt.Println("") os.Exit(0) diff --git a/internal/pages/02_select_gpu.go b/internal/pages/02_select_gpu.go index 4a1b8ed..99ca090 100644 --- a/internal/pages/02_select_gpu.go +++ b/internal/pages/02_select_gpu.go @@ -4,13 +4,16 @@ import ( "fmt" "os" + "github.com/HikariKnight/ls-iommu/pkg/errorcheck" + "github.com/HikariKnight/quickpassthrough/internal/configs" lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu" "github.com/HikariKnight/quickpassthrough/pkg/command" + "github.com/HikariKnight/quickpassthrough/pkg/fileio" "github.com/HikariKnight/quickpassthrough/pkg/menu" "github.com/gookit/color" ) -func SelectGPU() { +func SelectGPU(config *configs.Config) { // Clear the screen command.Clear() @@ -29,11 +32,12 @@ func SelectGPU() { fmt.Println("") os.Exit(0) default: - viewGPU(choice) + config.Gpu_Group = choice + viewGPU(config) } } -func viewGPU(id string, ext ...int) { +func viewGPU(config *configs.Config, ext ...int) { // Clear the screen command.Clear() @@ -46,10 +50,10 @@ func viewGPU(id string, ext ...int) { } // Get the IOMMU listings for GPUs - group := lsiommu.GetIOMMU("-g", mode, "-i", id, "-F", "vendor:,prod_name,optional_revision:,device_id") + group := lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "-F", "vendor:,prod_name,optional_revision:,device_id") // Write a title - color.Bold.Println("This list should only show devices related to your GPU") + color.Bold.Println("This list should only show devices related to your GPU (usually 1 video, 1 audio device)") // Print all the gpus for _, v := range group { @@ -64,7 +68,7 @@ func viewGPU(id string, ext ...int) { // Change choices depending on if we have done an extended search or not if len(ext) > 0 { - choice = menu.YesNo("Use this GPU (any extra devices listed may or may not be linked to it) for passthrough?") + choice = menu.YesNoManual("Use this GPU (any extra devices listed may or may not be linked to it) for passthrough?") } else { choice = menu.YesNoEXT("Use this GPU (and related devices) for passthrough?") } @@ -78,15 +82,47 @@ func viewGPU(id string, ext ...int) { case "ext": // Run an extended relative search - viewGPU(id, 1) + viewGPU(config, 1) case "n": // Go back to selecting a gpu - SelectGPU() + SelectGPU(config) case "y": - // Go to the select a usb controller - //selectUSB() - genVBIOS_dumper(id) + // Get the device ids for the selected gpu using ls-iommu + config.Gpu_IDs = lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "--id") + + // If the kernel_args file already exists + if fileio.FileExist(config.Path.CMDLINE) { + // Delete it as we will have to make a new one anyway + err := os.Remove(config.Path.CMDLINE) + errorcheck.ErrorCheck(err, fmt.Sprintf("Could not remove %s", config.Path.CMDLINE)) + } + + // Write initial kernel_arg file + configs.Set_Cmdline(config.Gpu_IDs) + + // Go to the vbios dumper page + genVBIOS_dumper(config) + + case "manual": + config.Gpu_IDs = menu.ManualInput( + "Please manually enter the vendorID:deviceID for every device to use except PCI Express Switches\n"+ + "NOTE: All devices sharing the same IOMMU group will still get pulled into the VM!", + "xxxx:yyyy,xxxx:yyyy,xxxx:yyyy", + ) + + // If the kernel_args file already exists + if fileio.FileExist(config.Path.CMDLINE) { + // Delete it as we will have to make a new one anyway + err := os.Remove(config.Path.CMDLINE) + errorcheck.ErrorCheck(err, fmt.Sprintf("Could not remove %s", config.Path.CMDLINE)) + } + + // Write initial kernel_arg file + configs.Set_Cmdline(config.Gpu_IDs) + + // Go to the vbios dumper page + genVBIOS_dumper(config) } } diff --git a/internal/pages/03_vbios_extract.go b/internal/pages/03_vbios_extract.go index 0e5a3ba..76c653a 100644 --- a/internal/pages/03_vbios_extract.go +++ b/internal/pages/03_vbios_extract.go @@ -6,11 +6,13 @@ import ( "path/filepath" "strings" + "github.com/HikariKnight/quickpassthrough/internal/configs" + lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu" "github.com/HikariKnight/quickpassthrough/pkg/command" "github.com/HikariKnight/quickpassthrough/pkg/menu" ) -func genVBIOS_dumper(id string) { +func genVBIOS_dumper(config *configs.Config) { // Clear the scren command.Clear() @@ -23,8 +25,9 @@ func genVBIOS_dumper(id string) { scriptdir, _ = os.Getwd() } - // Get the vbios path - //vbios_path := lsiommu.GetIOMMU("-g", "-i", id, "--rom")[0] + // Get the vbios path and generate the vbios dumping script + vbios_path := lsiommu.GetIOMMU("-g", "-i", config.Gpu_Group, "--rom")[0] + configs.GenerateVBIOSDumper(vbios_path) // Tell users about the VBIOS dumper script fmt.Print( @@ -38,13 +41,17 @@ func genVBIOS_dumper(id string) { ) // Get the OK press - choice := menu.Ok("Make sure you run the script with the display-manager stopped using ssh or tty!") + choice := menu.OkBack("Make sure you run the script with the display-manager stopped using ssh or tty!") - // If OK is pressed - if choice == "next" { - disableVideo() - selectUSB() - } else { + // Parse choice + switch choice { + case "next": + disableVideo(config) + + case "back": + SelectGPU(config) + + case "": fmt.Println("") os.Exit(0) } diff --git a/internal/pages/04_disable_video.go b/internal/pages/04_disable_video.go index 23ae8fe..36aba95 100644 --- a/internal/pages/04_disable_video.go +++ b/internal/pages/04_disable_video.go @@ -2,13 +2,14 @@ package pages import ( "fmt" + "os" "github.com/HikariKnight/quickpassthrough/internal/configs" "github.com/HikariKnight/quickpassthrough/pkg/command" "github.com/HikariKnight/quickpassthrough/pkg/menu" ) -func disableVideo() { +func disableVideo(config *configs.Config) { // Clear the screen command.Clear() @@ -22,14 +23,25 @@ func disableVideo() { ) // Make the yesno menu - choice := menu.YesNo("Do you want to force disable video output in linux on this card?") + choice := menu.YesNoBack("Do you want to force disable video output in linux on this card?") - if choice == "Yes" { + switch choice { + case "y": // Add disable VFIO video to the config configs.DisableVFIOVideo(1) - } else { + selectUSB(config) + + case "n": // Do not disable VFIO Video configs.DisableVFIOVideo(0) - } + selectUSB(config) + case "back": + genVBIOS_dumper(config) + + case "": + // If ESC is pressed + fmt.Println("") + os.Exit(0) + } } diff --git a/internal/pages/05_select_usbctrl.go b/internal/pages/05_select_usbctrl.go index 01995ea..bc9a004 100644 --- a/internal/pages/05_select_usbctrl.go +++ b/internal/pages/05_select_usbctrl.go @@ -4,13 +4,14 @@ import ( "fmt" "os" + "github.com/HikariKnight/quickpassthrough/internal/configs" lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu" "github.com/HikariKnight/quickpassthrough/pkg/command" "github.com/HikariKnight/quickpassthrough/pkg/menu" "github.com/gookit/color" ) -func selectUSB() { +func selectUSB(config *configs.Config) { // Clear the screen command.Clear() @@ -23,18 +24,20 @@ func selectUSB() { // Parse the choice switch choice { case "back": - SelectGPU() + disableVideo(config) + case "": // If ESC is pressed fmt.Println("") os.Exit(0) + default: // View the selected GPU - viewUSB(choice) + viewUSB(choice, config) } } -func viewUSB(id string, ext ...int) { +func viewUSB(id string, config *configs.Config, ext ...int) { // Clear the screen command.Clear() @@ -76,9 +79,10 @@ func viewUSB(id string, ext ...int) { // If ESC is pressed fmt.Println("") os.Exit(0) + case "n": // Go back to selecting a gpu - selectUSB() + selectUSB(config) case "y": // Go to the select a usb controller diff --git a/internal/pages/06_finalize.go b/internal/pages/06_finalize.go new file mode 100644 index 0000000..7389da0 --- /dev/null +++ b/internal/pages/06_finalize.go @@ -0,0 +1,5 @@ +package pages + +func finalize() { + +} diff --git a/pkg/menu/manual.go b/pkg/menu/manual.go new file mode 100644 index 0000000..5e0b06c --- /dev/null +++ b/pkg/menu/manual.go @@ -0,0 +1,27 @@ +package menu + +import ( + "fmt" + "strings" + + "github.com/HikariKnight/ls-iommu/pkg/errorcheck" + "github.com/gookit/color" +) + +func ManualInput(msg string, format string) []string { + // Print the title + color.Bold.Println(msg) + + // Tell user the format to use + color.Bold.Printf("The format is %s\n", format) + + // Get the user input + var input string + _, err := fmt.Scan(&input) + errorcheck.ErrorCheck(err) + + input_list := strings.Split(input, ",") + + // Return the input + return input_list +} diff --git a/pkg/menu/yesno.go b/pkg/menu/yesno.go index 03008ce..292bbe8 100644 --- a/pkg/menu/yesno.go +++ b/pkg/menu/yesno.go @@ -16,6 +16,20 @@ func YesNo(msg string) string { return choice } +func YesNoBack(msg string) string { + // Make the menu + menu := gocliselect.NewMenu(msg) + menu.AddItem("Yes", "y") + menu.AddItem("No", "n") + menu.AddItem("Go Back", "back") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +} + func YesNoEXT(msg string) string { // Make the menu menu := gocliselect.NewMenu(msg) @@ -29,3 +43,18 @@ func YesNoEXT(msg string) string { // Return the value selected return choice } + +// Make a YesNo menu +func YesNoManual(msg string) string { + // Make the menu + menu := gocliselect.NewMenu(msg) + menu.AddItem("Yes", "y") + menu.AddItem("No", "n") + menu.AddItem("Manual Entry", "manual") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +}