@@ -34,17 +34,18 @@ const (
3434
3535func main () {
3636 var err error
37- var bitstream string
38- var device string
39- var dryRun bool
37+ var bitstream , device string
38+ var dryRun , force , quiet bool
4039 flag .StringVar (& bitstream , "b" , "" , "Path to bitstream file (GBS or AOCX)" )
4140 flag .StringVar (& device , "d" , "" , "Path to device node (FME or Port)" )
4241 flag .BoolVar (& dryRun , "dry-run" , false , "Don't write/program, just validate and log" )
42+ flag .BoolVar (& force , "force" , false , "Force overwrite operation for installing bitstreams" )
43+ flag .BoolVar (& quiet , "q" , false , "Quiet mode. Only errors will be reported" )
4344
4445 flag .Parse ()
4546
4647 if flag .NArg () < 1 {
47- log .Fatal ("Please provide command: info, fpgainfo, fmeinfo, portinfo, install , pr" )
48+ log .Fatal ("Please provide command: info, fpgainfo, install, list, fmeinfo, portinfo, list-fme, list-port , pr" )
4849 }
4950
5051 cmd := flag .Arg (0 )
@@ -53,25 +54,27 @@ func main() {
5354 log .Fatalf ("Invalid arguments: %+v" , err )
5455 }
5556
56- // fmt.Printf("Cmd: %q\nBitstream: %q\nDevice: %q\n", cmd, bitstream, device)
5757 switch cmd {
5858 case "info" :
59- err = printBitstreamInfo (bitstream )
59+ err = printBitstreamInfo (bitstream , quiet )
6060 case "pr" :
61- err = doPR (device , bitstream , dryRun )
61+ err = doPR (device , bitstream , dryRun , quiet )
6262 case "fpgainfo" :
63- err = fpgaInfo (device )
63+ err = fpgaInfo (device , quiet )
6464 case "fmeinfo" :
65- err = fmeInfo (device )
65+ err = fmeInfo (device , quiet )
6666 case "portinfo" :
67- err = portInfo (device )
67+ err = portInfo (device , quiet )
6868 case "install" :
69- err = installBitstream (bitstream , dryRun )
70- case "magic" :
71- err = magic (device )
69+ err = installBitstream (bitstream , dryRun , force , quiet )
70+ case "list" :
71+ err = listDevices (true , true , quiet )
72+ case "list-fme" :
73+ err = listDevices (true , false , quiet )
74+ case "list-port" :
75+ err = listDevices (false , true , quiet )
7276 default :
7377 err = errors .Errorf ("unknown command %+v" , flag .Args ())
74-
7578 }
7679 if err != nil {
7780 log .Fatalf ("%+v" , err )
@@ -85,7 +88,7 @@ func validateFlags(cmd, bitstream, device string) error {
8588 if bitstream == "" {
8689 return errors .Errorf ("bitstream filename is missing" )
8790 }
88- case "fpgainfo" , "fmeinfo" , "portinfo" , "magic" :
91+ case "fpgainfo" , "fmeinfo" , "portinfo" :
8992 // device must not be empty
9093 if device == "" {
9194 return errors .Errorf ("FPGA device name is missing" )
@@ -102,13 +105,7 @@ func validateFlags(cmd, bitstream, device string) error {
102105 return nil
103106}
104107
105- // WIP testing command
106- func magic (dev string ) (err error ) {
107- fmt .Println (fpga .ListFpgaDevices ())
108- return
109- }
110-
111- func installBitstream (fname string , dryRun bool ) (err error ) {
108+ func installBitstream (fname string , dryRun , force , quiet bool ) (err error ) {
112109 info , err := bitstream .Open (fname )
113110 if err != nil {
114111 return
@@ -117,10 +114,12 @@ func installBitstream(fname string, dryRun bool) (err error) {
117114
118115 installPath := info .InstallPath (fpgaBitStreamDirectory )
119116
120- fmt .Printf ("Installing bitstream %q as %q\n " , fname , installPath )
121- if dryRun {
122- fmt .Println ("Dry-run: no copying performed" )
123- return
117+ if ! quiet {
118+ fmt .Printf ("Installing bitstream %q as %q\n " , fname , installPath )
119+ if dryRun {
120+ fmt .Println ("Dry-run: no copying performed" )
121+ return
122+ }
124123 }
125124 err = os .MkdirAll (filepath .Dir (installPath ), 0755 )
126125 if err != nil {
@@ -131,26 +130,23 @@ func installBitstream(fname string, dryRun bool) (err error) {
131130 return errors .Wrap (err , "can't open bitstream file" )
132131 }
133132 defer src .Close ()
134- dst , err := os .OpenFile (installPath , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , 0644 )
133+ flags := os .O_WRONLY | os .O_CREATE | os .O_TRUNC
134+ if ! force {
135+ flags = flags | os .O_EXCL
136+ }
137+ dst , err := os .OpenFile (installPath , flags , 0644 )
135138 if err != nil {
139+ if os .IsExist (err ) {
140+ return fmt .Errorf ("Destination file %q already exist. Use --force to overwrite it" , installPath )
141+ }
136142 return errors .Wrap (err , "can't create destination file" )
137143 }
138144 defer dst .Close ()
139145 _ , err = io .Copy (dst , src )
140146 return
141147}
142148
143- func fpgaInfo (fname string ) error {
144- switch {
145- case fpga .IsFpgaFME (fname ):
146- return fmeInfo (fname )
147- case fpga .IsFpgaPort (fname ):
148- return portInfo (fname )
149- }
150- return errors .Errorf ("unknown FPGA device file %s" , fname )
151- }
152-
153- func printBitstreamInfo (fname string ) (err error ) {
149+ func printBitstreamInfo (fname string , quiet bool ) (err error ) {
154150 info , err := bitstream .Open (fname )
155151 if err != nil {
156152 return
@@ -162,7 +158,7 @@ func printBitstreamInfo(fname string) (err error) {
162158 fmt .Printf ("Unique UUID : %q\n " , info .UniqueUUID ())
163159 fmt .Printf ("Installation Path : %q\n " , info .InstallPath (fpgaBitStreamDirectory ))
164160 extra := info .ExtraMetadata ()
165- if len (extra ) > 0 {
161+ if len (extra ) > 0 && ! quiet {
166162 fmt .Println ("Extra:" )
167163 for k , v := range extra {
168164 fmt .Printf ("\t %s : %q\n " , k , v )
@@ -171,84 +167,168 @@ func printBitstreamInfo(fname string) (err error) {
171167 return
172168}
173169
174- func fmeInfo (fname string ) error {
170+ func fpgaInfo (fname string , quiet bool ) error {
171+ switch {
172+ case fpga .IsFpgaFME (fname ):
173+ return fmeInfo (fname , quiet )
174+ case fpga .IsFpgaPort (fname ):
175+ return portInfo (fname , quiet )
176+ }
177+ return errors .Errorf ("unknown FPGA device file %s" , fname )
178+ }
179+
180+ func fmeInfo (fname string , quiet bool ) error {
175181 var f fpga.FpgaFME
176182 var err error
177183 f , err = fpga .NewFpgaFME (fname )
178184 if err != nil {
179185 return err
180186 }
181187 defer f .Close ()
182- fmt . Print ( "API:" )
183- fmt . Println ( f . GetAPIVersion ())
184- fmt . Print ( "CheckExtension:" )
185- fmt . Println ( f . CheckExtension ())
186-
187- fmt .Println ( "GetDevPath: " , f .GetDevPath ())
188- fmt .Println ( "GetSysFsPath: " , f .GetSysFsPath ())
189- fmt .Println ( "GetName: " , f .GetName ())
188+ return printFpgaFME ( f , quiet )
189+ }
190+
191+ func printFpgaFME ( f fpga. FpgaFME , quiet bool ) ( err error ) {
192+ fmt . Println ( "//****** FME ******//" )
193+ fmt .Printf ( "Name : %s \n " , f .GetName ())
194+ fmt .Printf ( "Device Node : %s \n " , f .GetDevPath ())
195+ fmt .Printf ( "SysFS Path : %s \n " , f .GetSysFsPath ())
190196 pci , err := f .GetPCIDevice ()
191- fmt .Printf ("GetPCIDevice: %+v %+v\n " , pci , err )
192- fmt .Println ("GetInterfaceUUID: " , f .GetInterfaceUUID ())
193- fmt .Println ("GetPortNums: " , f .GetPortsNum ())
194- return nil
197+ if err != nil {
198+ return
199+ }
200+ printPCIeInfo (pci , quiet )
201+ fmt .Printf ("Interface UUID : %s\n " , f .GetInterfaceUUID ())
202+ if ! quiet {
203+ if apiVer , err := f .GetAPIVersion (); err == nil {
204+ fmt .Printf ("Kernet API Version : %d\n " , apiVer )
205+ }
206+ fmt .Printf ("Ports Num : %d\n " , f .GetPortsNum ())
207+ if id , err := f .GetSocketID (); err == nil {
208+ fmt .Printf ("Socket Id : %d\n " , id )
209+ }
210+ fmt .Printf ("Bitstream Id : %s\n " , f .GetBitstreamID ())
211+ fmt .Printf ("Bitstream Metadata : %s\n " , f .GetBitstreamMetadata ())
212+ }
213+
214+ return
195215}
196216
197- func portInfo (fname string ) error {
217+ func portInfo (fname string , quiet bool ) error {
198218 var f fpga.FpgaPort
199219 var err error
200220 f , err = fpga .NewFpgaPort (fname )
201221 if err != nil {
202222 return err
203223 }
204224 defer f .Close ()
205- fmt .Print ("API:" )
206- fmt .Println (f .GetAPIVersion ())
207- fmt .Print ("CheckExtension:" )
208- fmt .Println (f .CheckExtension ())
209- fmt .Print ("Reset:" )
210- fmt .Println (f .PortReset ())
211- fmt .Print ("PortGetInfo:" )
212- fmt .Println (f .PortGetInfo ())
213- pi , err := f .PortGetInfo ()
214- if err == nil {
215- for idx := 0 ; uint32 (idx ) < pi .Regions ; idx ++ {
216- fmt .Printf ("PortGetRegionInfo %d\n " , idx )
217- fmt .Println (f .PortGetRegionInfo (uint32 (idx )))
218- }
219- }
220-
221- fmt .Println ("GetDevPath: " , f .GetDevPath ())
222- fmt .Println ("GetSysFsPath: " , f .GetSysFsPath ())
223- fmt .Println ("GetName: " , f .GetName ())
225+ return printFpgaPort (f , quiet )
226+ }
227+
228+ func printFpgaPort (f fpga.FpgaPort , quiet bool ) (err error ) {
229+ fmt .Println ("//****** PORT ******//" )
230+ fmt .Printf ("Name : %s\n " , f .GetName ())
231+ fmt .Printf ("Device Node : %s\n " , f .GetDevPath ())
232+ fmt .Printf ("SysFS Path : %s\n " , f .GetSysFsPath ())
224233 pci , err := f .GetPCIDevice ()
225- fmt .Printf ("GetPCIDevice: %+v %+v\n " , pci , err )
226- id , err := f .GetPortID ()
227- fmt .Printf ("GetPort: %+v %+v\n " , id , err )
228- fmt .Println ("GetAcceleratorTypeUUID: " , f .GetAcceleratorTypeUUID ())
229- fmt .Println ("GetInterfaceUUID: " , f .GetInterfaceUUID ())
234+ if err != nil {
235+ return
236+ }
237+ printPCIeInfo (pci , quiet )
230238 fme , err := f .GetFME ()
231- fmt .Printf ("GetFME: %+v %+v\n " , fme , err )
232-
233- return nil
239+ if err != nil {
240+ return
241+ }
242+ fmt .Printf ("FME Name : %s\n " , fme .GetName ())
243+ num , err := f .GetPortID ()
244+ if err != nil {
245+ return
246+ }
247+ fmt .Printf ("Port Id : %d\n " , num )
248+ fmt .Printf ("Interface UUID : %s\n " , f .GetInterfaceUUID ())
249+ fmt .Printf ("Accelerator UUID : %s\n " , f .GetAcceleratorTypeUUID ())
250+ if ! quiet {
251+ if apiVer , err := f .GetAPIVersion (); err == nil {
252+ fmt .Printf ("Kernet API Version : %d\n " , apiVer )
253+ pi , err := f .PortGetInfo ()
254+ if err == nil {
255+ fmt .Printf ("Port Regions : %d\n " , pi .Regions )
256+ for idx := 0 ; uint32 (idx ) < pi .Regions ; idx ++ {
257+ if ri , err := f .PortGetRegionInfo (uint32 (idx )); err == nil {
258+ fmt .Printf ("Port Region (Index/Size/Offset) : %d / %d / %d\n " , ri .Index , ri .Size , ri .Offset )
259+ }
260+ }
261+ }
262+ }
263+ }
264+ return
234265}
235266
236- func doPR (dev , bs string , dryRun bool ) error {
267+ func printPCIeInfo (pci * fpga.PCIDevice , quiet bool ) {
268+ fmt .Printf ("PCIe s:b:d:f : %s\n " , pci .BDF )
269+ if pci .PhysFn != nil && ! quiet {
270+ fmt .Printf ("Physical Function PCIe s:b:d:f : %s\n " , pci .PhysFn .BDF )
271+ }
272+ fmt .Printf ("Device Id : %s:%s\n " , pci .Vendor , pci .Device )
273+ if ! quiet {
274+ fmt .Printf ("Device Class : %s\n " , pci .Class )
275+ fmt .Printf ("Local CPUs : %s\n " , pci .CPUs )
276+ fmt .Printf ("NUMA : %s\n " , pci .NUMA )
277+ if pci .VFs != "" {
278+ fmt .Printf ("SR-IOV Virtual Functions : %s\n " , pci .VFs )
279+ }
280+ if pci .TotalVFs != "" {
281+ fmt .Printf ("SR-IOV maximum Virtual Functions : %s\n " , pci .TotalVFs )
282+ }
283+ }
284+ return
285+ }
237286
238- f , err := fpga .NewFpgaPort (dev )
287+ func doPR (dev , fname string , dryRun , quiet bool ) (err error ) {
288+ fp , err := fpga .NewFpgaPort (dev )
239289 if err != nil {
240- return err
290+ return
241291 }
242- defer f .Close ()
243- m , err := bitstream .Open (bs )
292+ defer fp .Close ()
293+ bs , err := bitstream .Open (fname )
244294 if err != nil {
245- return err
295+ return
296+ }
297+ defer bs .Close ()
298+
299+ if ! quiet {
300+ fmt .Printf ("Before: Interface ID: %q AFU ID: %q\n " , fp .GetInterfaceUUID (), fp .GetAcceleratorTypeUUID ())
301+ fmt .Printf ("Programming %q to port %q: " , fname , dev )
302+ }
303+ err = fp .PR (bs , dryRun )
304+ if ! quiet {
305+ if err != nil {
306+ fmt .Println ("FAILED" )
307+ } else {
308+ fmt .Println ("OK" )
309+ }
310+ fmt .Printf ("After : Interface ID: %q AFU ID: %q\n " , fp .GetInterfaceUUID (), fp .GetAcceleratorTypeUUID ())
246311 }
247- defer m .Close ()
312+ return
313+ }
248314
249- fmt .Printf ("Before programming I %q A %q\n " , f .GetInterfaceUUID (), f .GetAcceleratorTypeUUID ())
250- fmt .Printf ("Trying to program %s to port %s: " , bs , dev )
251- fmt .Println (f .PR (m , dryRun ))
252- fmt .Printf ("After programming I %q A %q\n " , f .GetInterfaceUUID (), f .GetAcceleratorTypeUUID ())
315+ func listDevices (listFMEs , listPorts , quiet bool ) error {
316+ fmes , ports := fpga .ListFpgaDevices ()
317+ if listFMEs {
318+ if ! quiet {
319+ fmt .Printf ("Detected FPGA FMEs: %d\n " , len (fmes ))
320+ }
321+ for _ , v := range fmes {
322+ fmt .Println (v )
323+ }
324+ }
325+ if listPorts {
326+ if ! quiet {
327+ fmt .Printf ("Detected FPGA Ports: %d\n " , len (ports ))
328+ }
329+ for _ , v := range ports {
330+ fmt .Println (v )
331+ }
332+ }
253333 return nil
254334}
0 commit comments