diff --git a/go.mod b/go.mod index bf5424b..396bf95 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,15 @@ require ( github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/bubbletea v0.24.2 github.com/charmbracelet/lipgloss v0.9.1 + github.com/gookit/color v1.5.4 github.com/klauspost/cpuid/v2 v2.2.5 + github.com/nexidian/gocliselect v1.0.0 ) require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/buger/goterm v1.0.3 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -24,8 +27,10 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect + github.com/pkg/term v1.1.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/sahilm/fuzzy v0.1.0 // indirect + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect golang.org/x/sync v0.4.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect diff --git a/go.sum b/go.sum index 091f54e..c556381 100644 --- a/go.sum +++ b/go.sum @@ -1,118 +1,71 @@ -github.com/HikariKnight/ls-iommu v0.0.0-20230407115706-e1ca65712f56 h1:OPbMP7OR9UsdTCcy9JLg2sUdijT7H9u1Lx+QgZhIeFI= -github.com/HikariKnight/ls-iommu v0.0.0-20230407115706-e1ca65712f56/go.mod h1:1uNtCpUQNhh8GGCg+WqgRNTJf7jYDHvoGVvUJCKlEuE= -github.com/HikariKnight/ls-iommu v0.0.0-20230509103425-e96e4c465dba h1:TiEwkGL03+q6Hbw6RJBXtte4Ub5WjSwxbKr2L/GMcpQ= -github.com/HikariKnight/ls-iommu v0.0.0-20230509103425-e96e4c465dba/go.mod h1:5D+qLb7C9eJirH1oPgvf3XJYLlTVc/PZ9IoKa2ED4QA= github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5 h1:IEH+I+phCvL0fBzQKoWQxK147ZrsqPhLjzx1dETBT9Y= github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5/go.mod h1:+yX6+uXNeERvwFtP/gH/dOW/MA+K10Wi6asYcRtDXd8= github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc= github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= -github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/buger/goterm v1.0.3 h1:7V/HeAQHrzPk/U4BvyH2g9u+xbUW9nr4yRPyG59W4fM= +github.com/buger/goterm v1.0.3/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= -github.com/charmbracelet/bubbles v0.15.0 h1:c5vZ3woHV5W2b8YZI1q7v4ZNQaPetfHuoHzx+56Z6TI= -github.com/charmbracelet/bubbles v0.15.0/go.mod h1:Y7gSFbBzlMpUDR/XM9MhZI374Q+1p1kluf1uLl8iK74= github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= -github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU= -github.com/charmbracelet/bubbletea v0.23.2 h1:vuUJ9HJ7b/COy4I30e8xDVQ+VRDUEFykIjryPfgsdps= -github.com/charmbracelet/bubbletea v0.23.2/go.mod h1:FaP3WUivcTM0xOKNmhciz60M6I+weYLF76mr1JyI7sM= github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= -github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= -github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= -github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= -github.com/charmbracelet/lipgloss v0.8.0 h1:IS00fk4XAHcf8uZKc3eHeMUTCxUH6NkaTrdyCQk84RU= -github.com/charmbracelet/lipgloss v0.8.0/go.mod h1:p4eYUZZJ/0oXTuCQKFF8mqyKCz0ja6y+7DniDDw5KKU= github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= -github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= -github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= -github.com/muesli/termenv v0.14.0/go.mod h1:kG/pF1E7fh949Xhe156crRUrHNyK221IuGO7Ez60Uc8= -github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= -github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/nexidian/gocliselect v1.0.0 h1:BTxqUqqhwc/O3jJrPuvpF359FjQag7EYgwdEF9cYY+w= +github.com/nexidian/gocliselect v1.0.0/go.mod h1:xyHtRO0Au/S+4tsEooDEj5+VZtkk+RU6RRs7q4o5TmI= +github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= +github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/lsiommu/lsiommu.go b/internal/lsiommu/lsiommu.go new file mode 100644 index 0000000..0ea18df --- /dev/null +++ b/internal/lsiommu/lsiommu.go @@ -0,0 +1,71 @@ +package lsiommu + +import ( + "bufio" + "bytes" + "fmt" + "io" + "os" + "os/exec" + "regexp" + "strings" + + "github.com/HikariKnight/quickpassthrough/internal/logger" + "github.com/klauspost/cpuid/v2" +) + +func GetIOMMU(args ...string) []string { + var stdout, stderr bytes.Buffer + // Write to logger + logger.Printf("Executing: utils/ls-iommu %s", strings.Join(args, " ")) + + // Configure the ls-iommu command + cmd := exec.Command("utils/ls-iommu", args...) + cmd.Stderr = &stderr + cmd.Stdout = &stdout + + // Execute the command + err := cmd.Run() + + // Generate the correct iommu string for the system + var iommu_args string + cpuinfo := cpuid.CPU + // Write the argument based on which cpu the user got + switch cpuinfo.VendorString { + case "AuthenticAMD": + iommu_args = "iommu=pt amd_iommu=on" + case "GenuineIntel": + iommu_args = "iommu=pt intel_iommu=on" + } + + // If ls-iommu returns an error then IOMMU is disabled + if err != nil { + fmt.Printf( + "IOMMU disabled in either UEFI/BIOS or in bootloader, or run inside container!\n"+ + "For your bootloader, make sure you have added the kernel arguments:\n"+ + "%s\n", + iommu_args, + ) + os.Exit(1) + } + + // Read the output + var items []string + output, _ := io.ReadAll(&stdout) + + // Write to logger + logger.Printf("ls-iommu query returned\n%s", string(output)) + + // Make regex to shorten vendor names + shortenVendor := regexp.MustCompile(` Corporation:|Advanced Micro Devices, Inc\. \[(AMD)\/ATI\]:`) + + // Parse the output line by line + scanner := bufio.NewScanner(strings.NewReader(string(output))) + for scanner.Scan() { + // Write the objects into the list + items = append(items, shortenVendor.ReplaceAllString(scanner.Text(), "${1}")) + } + + // Return our list of items + return items +} diff --git a/internal/pages/01_welcome.go b/internal/pages/01_welcome.go new file mode 100644 index 0000000..f00f978 --- /dev/null +++ b/internal/pages/01_welcome.go @@ -0,0 +1,39 @@ +package pages + +import ( + "github.com/HikariKnight/quickpassthrough/pkg/command" + "github.com/HikariKnight/quickpassthrough/pkg/menu" + "github.com/gookit/color" +) + +// Welcome page +func Welcome() { + // Clear screen + command.Clear() + + // Write title + color.Bold.Println("Welcome to Quickpassthrough!") + + // Write welcome message + color.Println( + " This script is meant to make it easier to setup GPU passthrough for\n", + "Qemu based systems. WITH DIFFERENT 2 GPUS ON THE HOST SYSTEM\n", + "However due to the complexity of GPU passthrough\n", + "This script assumes you know how to do (or have done) the following.\n\n", + "* You have already enabled IOMMU, VT-d, SVM and/or AMD-v\n inside your UEFI/BIOS advanced settings.\n", + "* Know how to edit your bootloader\n", + "* Have a bootloader timeout of at least 3 seconds to access the menu\n", + "* Enable & Configure kernel modules\n", + "* Have a backup/snapshot of your system in case the script causes your\n system to be unbootable\n\n", + "By continuing you accept that I am not liable if your system\n", + "becomes unbootable, as you will be asked to verify the files generated\n", + ) + + // Make user accept responsibility + choice := menu.YesNo("Are you sure you want to continue?") + + // If yes, go to next page + if choice == "y" { + SelectGPU() + } +} diff --git a/internal/pages/02_select_gpu.go b/internal/pages/02_select_gpu.go new file mode 100644 index 0000000..5b05661 --- /dev/null +++ b/internal/pages/02_select_gpu.go @@ -0,0 +1,72 @@ +package pages + +import ( + "fmt" + + lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu" + "github.com/HikariKnight/quickpassthrough/pkg/command" + "github.com/HikariKnight/quickpassthrough/pkg/menu" + "github.com/gookit/color" +) + +func SelectGPU() { + // Clear the screen + command.Clear() + + // Get the users GPUs + gpus := lsiommu.GetIOMMU("-g", "-F", "vendor:,prod_name,optional_revision:,device_id") + + // Generate a list of choices based on the GPUs and get the users selection + choice := menu.GenIOMMUMenu("Select a GPU to view the IOMMU groups of", gpus) + + // View the selected GPU + ViewGPU(choice) +} + +func ViewGPU(id string, ext ...int) { + // Clear the screen + command.Clear() + + // Set mode to relative + mode := "-r" + + // Set mode to relative extended + if len(ext) > 0 { + mode = "-rr" + } + + // Get the IOMMU listings for GPUs + group := lsiommu.GetIOMMU("-g", mode, "-i", id, "-F", "vendor:,prod_name,optional_revision:,device_id") + + // Write a title + color.Bold.Println("This list should only show devices related to your GPU") + + // Print all the gpus + for _, v := range group { + fmt.Println(v) + } + + // Add a new line for tidyness + fmt.Println("") + + // Make an empty string + var choice string + + // 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?") + } else { + choice = menu.YesNoEXT("Use this GPU (and related devices) for passthrough?") + } + + // Parse the choice + switch choice { + case "ext": + // Run an extended relative search + ViewGPU(id, 1) + + case "n": + // Go back to selecting a gpu + SelectGPU() + } +} diff --git a/internal/ui_main.go b/internal/ui_main.go index 05410e7..d1eb4d8 100644 --- a/internal/ui_main.go +++ b/internal/ui_main.go @@ -7,6 +7,7 @@ import ( "os" "github.com/HikariKnight/ls-iommu/pkg/errorcheck" + "github.com/HikariKnight/quickpassthrough/internal/pages" tea "github.com/charmbracelet/bubbletea" ) @@ -18,11 +19,13 @@ func Tui() { errorcheck.ErrorCheck(err, "Error creating log file") defer logfile.Close() + pages.Welcome() + // Make a blank model to keep our state in - m := NewModel() + /*m := NewModel() // Start the program with the model p := tea.NewProgram(m, tea.WithAltScreen()) _, err = p.Run() - errorcheck.ErrorCheck(err, "Failed to initialize UI") + errorcheck.ErrorCheck(err, "Failed to initialize UI")*/ } diff --git a/pkg/command/command.go b/pkg/command/command.go index 0d033d4..9c4a0e4 100644 --- a/pkg/command/command.go +++ b/pkg/command/command.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "io" + "os" "os/exec" "time" @@ -88,3 +89,10 @@ func Elevate(password string) { err = cmd.Wait() errorcheck.ErrorCheck(err, "\nError, password given was wrong") } + +// Function to just clear the terminal +func Clear() { + c := exec.Command("clear") + c.Stdout = os.Stdout + c.Run() +} diff --git a/pkg/menu/genmenu.go b/pkg/menu/genmenu.go new file mode 100644 index 0000000..52f03ce --- /dev/null +++ b/pkg/menu/genmenu.go @@ -0,0 +1,34 @@ +package menu + +import ( + "regexp" + + "github.com/gookit/color" + "github.com/nexidian/gocliselect" +) + +func GenIOMMUMenu(msg string, choices []string) string { + // Make a regex to get the iommu group + iommu_group_regex := regexp.MustCompile(`(\d{1,3})`) + + // Make the menu + menu := gocliselect.NewMenu(msg) + + // For each choice passed + for _, choice := range choices { + // Get the iommu group + iommuGroup := iommu_group_regex.FindString(choice) + + // Add the choice with shortened vendor name and the iommu group as the return value + menu.AddItem(choice, iommuGroup) + } + + // Add a go back option + menu.AddItem(color.Bold.Sprint("Go Back"), "back") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +} diff --git a/pkg/menu/next.go b/pkg/menu/next.go new file mode 100644 index 0000000..e867188 --- /dev/null +++ b/pkg/menu/next.go @@ -0,0 +1,17 @@ +package menu + +import "github.com/nexidian/gocliselect" + +// Make a Next menu +func Next(msg string) string { + // Make the menu + menu := gocliselect.NewMenu(msg) + menu.AddItem("Next", "next") + menu.AddItem("Go Back", "back") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +} diff --git a/pkg/menu/yesno.go b/pkg/menu/yesno.go new file mode 100644 index 0000000..a9df169 --- /dev/null +++ b/pkg/menu/yesno.go @@ -0,0 +1,31 @@ +package menu + +import "github.com/nexidian/gocliselect" + +// Make a YesNo menu +func YesNo(msg string) string { + // Make the menu + menu := gocliselect.NewMenu(msg) + menu.AddItem("Yes", "y") + menu.AddItem("No", "n") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +} + +func YesNoEXT(msg string) string { + // Make the menu + menu := gocliselect.NewMenu(msg) + menu.AddItem("Yes", "y") + menu.AddItem("No", "n") + menu.AddItem("ADVANCED: View with extended related search by vendor ID, results will be inaccurate", "ext") + + // Display the menu + choice := menu.Display() + + // Return the value selected + return choice +}