All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alan Tull <delicious.quinoa@gmail.com>
To: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Cc: Moritz Fischer <moritz.fischer@ettus.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-fpga@vger.kernel.org
Subject: Re: [RFC 7/8] fpga-region: add sysfs interface
Date: Wed, 15 Feb 2017 16:49:58 -0600	[thread overview]
Message-ID: <CANk1AXQiCy6ySx_LVs9Oi6BT_T-hQPWX_ckakQ-UTE9PKh-7PA@mail.gmail.com> (raw)
In-Reply-To: <20170215194918.GA5531@obsidianresearch.com>

On Wed, Feb 15, 2017 at 1:49 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> On Wed, Feb 15, 2017 at 12:23:28PM -0600, Alan Tull wrote:
>> > This is usually the sort of stuff I'd punt to userspace, but since the
>> > kernel is doing request_firmware it is hard to see how that is an
>> > option in this case...
>>
>> I like how extensible (and readable!) this is.  It wouldn't take much
>> kernel code to add this.  I'd like to see the python script.
>
> Sure, attached
>
> Jason

Hi Jason,

Thanks for sharing this.

So this script takes the bitfile and its build logs as input, parses
the build logs for image information, does some manipulations on bit
order as needed, and adds the header.  So it's really doing (at least)
two things: adding header info and doing bitorder changes where needed
so that the kernel won't need to do it.

Alan

>
> #!/usr/bin/env python
> # COPYRIGHT (c) 2016 Obsidian Research Corporation.
> # Permission is hereby granted, free of charge, to any person obtaining a copy
> # of this software and associated documentation files (the "Software"), to deal
> # in the Software without restriction, including without limitation the rights
> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> # copies of the Software, and to permit persons to whom the Software is
> # furnished to do so, subject to the following conditions:
>
> # The above copyright notice and this permission notice shall be included in
> # all copies or substantial portions of the Software.
>
> # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> # THE SOFTWARE.
>
> import subprocess,re,string,os,stat,mmap,sys,base64;
> import argparse
> import time;
>
> def timeRFC1123():
>     # Python doesn't have this as a built in
>     return subprocess.check_output(["date","-u",'+%a, %02d %b %Y %T GMT']).strip();
>
> def getTOT():
>     """Return the top of tree commit hash from git"""
>     try:
>         HEAD = subprocess.check_output(["git","rev-parse","--verify","HEAD"]).strip();
>     except subprocess.CalledProcessError:
>         return "??? %s"%(os.getcwd());
>
>     dirty = subprocess.check_output(["git","diff","--stat"]).strip();
>     if dirty:
>         return "%s-dirty"%(HEAD);
>     return HEAD;
>
> def parseISEPar(f,fmts):
>     """Read Xilinx ISE par log files to get relevant design information"""
>     f = string.join(f.readlines());
>     g = re.search('"([^"]+)" is an NCD, version [0-9.]+, device (\S+), package (\S+), speed -(\d+)',f).groups();
>     fmts.update({"Design": g[0],
>                  "Device": g[1],
>                  "Package": g[2],
>                  "Speed": g[3]});
>     fmts["PAR-Ver"] = re.search("(Release \S+ par \S+(?: \(\S+\))?)\n",f).groups()[0]
>     fmts["Speed-File"] = re.search('Device speed data version:\s+"([^"]+)"',f).groups()[0];
>
> def parseVivadoTwr(f,fmts):
>     """Read Vivado 'report_timing' log files to get relevant design information"""
>     f = string.join(f.readlines(1024));
>     g = re.search('Design\s+:\s+(\S+)',f).groups();
>     fmts["Design"] = g[0];
>
>     g = re.search('Speed File\s+:\s+-(\d+)\s+(.+)',f);
>     if g is not None:
>         g = g.groups();
>         fmts["Speed"] = g[0];
>         fmts["Speed-File"] = g[1];
>         g = re.search('Device\s+:\s+(\S+)-(\S+)',f).groups();
>         fmts["Device"] = g[0];
>         fmts["Package"] = g[1];
>     else:
>         g = re.search('Part\s+:\s+Device=(\S+)\s+Package=(\S+)\s+Speed=-(\d+)\s+\((.+)\)',f).groups();
>         fmts.update({"Device": g[0],
>                      "Package": g[1],
>                      "Speed": g[2],
>                      "Speed-File": g[3]});
>
>     g = re.search('Version\s+:\s+(.+)',f).groups();
>     fmts["Xilinx-Ver"] = g[0];
>
> def parseSrr(f,fmts):
>     """Read Synplify log files to get relevent design information"""
>     l = f.readline().strip();
>     fmts["Synplify-Ver"] = re.match("#Build: Synplify (.*)",l).groups()[0];
>
> def find_start(bitm):
>     """Locate the start of the actual bitsream in a Xilinx .bit file.  Xilinx
>        tools drop an Impact header in front of the sync word. The FPGA ignores
>        everything prior to the sync word."""
>     for I in range(len(bitm)):
>         if (bitm[I] == '\xaa' and bitm[I+1] == '\x99' and
>             bitm[I+2] == '\x55' and bitm[I+3] == '\x66'):
>             return I;
>     return 0;
>
> def align_bitstream(fmts,alignment=8):
>     """Adjust the header content so that the bitstream starts aligned. This is
>     so we can mmap this file with the header and still DMA from it."""
>     while True:
>         hdr = ("YYBIT/1.0\n" +
>                "\n".join("%s: %s"%(k,v) for k,v in sorted(fmts.iteritems())) +
>                "\n\n");
>         if len(hdr) % alignment == 0:
>             return hdr;
>         fmts["Pad"] = "x"*(alignment - ((len(hdr) + 6) % alignment));
>
> def makeHeader(out,args):
>     fmts = {
>         "Builder": os.getenv("USERNAME",os.getenv("USER","???")),
>         "Date": timeRFC1123(),
>         "GIT-TOT": getTOT(),
>         "Bit-Order": args.order,
>     };
>     for fn in args.logs:
>         with open(fn) as F:
>             if fn.endswith(".par"):
>                 parseISEPar(F,fmts);
>             if fn.endswith(".srr"):
>                 parseSrr(F,fmts);
>             if fn.endswith(".twr"):
>                 parseVivadoTwr(F,fmts);
>             if fn.endswith(".tsr"):
>                 parseVivadoTwr(F,fmts);
>
>     with open(args.bit) as bitf:
>         bitlen = os.fstat(bitf.fileno())[stat.ST_SIZE];
>
>         bitm = mmap.mmap(bitf.fileno(),bitlen,access=mmap.ACCESS_COPY);
>         start = 0;
>
>         # This is the format for our bit bang schemes. The pin labeled D0 is
>         # taken from bit 7.
>         if args.order == "reversed":
>             for i in range(0,bitlen):
>                 v = ord(bitm[i]);
>                 bitm[i] = chr(((v & (1<<0)) << 7) |
>                               ((v & (1<<1)) << 5) |
>                               ((v & (1<<2)) << 3) |
>                               ((v & (1<<3)) << 1) |
>                               ((v & (1<<4)) >> 1) |
>                               ((v & (1<<5)) >> 3) |
>                               ((v & (1<<6)) >> 5) |
>                               ((v & (1<<7)) >> 7));
>
>         # This is the format DMA to devcfg on the Zynq wants, impact header
>         # stripped, sync word in little endian and aligned.
>         if args.order == "byte-reversed":
>             start = find_start(bitm);
>             for i in range(start,bitlen//4*4,4):
>                 bitm[i],bitm[i+1],bitm[i+2],bitm[i+3] = bitm[i+3],bitm[i+2],bitm[i+1],bitm[i];
>
>         if start != 0:
>             fmts["Impact-Header"] = base64.b64encode(bitm[:start]);
>
>         fmts["Content-Length"] = bitlen - start;
>         out.write(align_bitstream(fmts));
>
>         out.write(bitm[start:]);
>
> parser = argparse.ArgumentParser(description="Format a Xilinx .bit file into a ybf with the necessary headers")
> parser.add_argument("--ybf",required=True,
>                     help="Output filename");
> parser.add_argument("--bit",required=True,
>                     help="Input bit filename");
> parser.add_argument("--archive",
>                     help="Optional directory to place a timestamped hardlink");
> parser.add_argument("--deps",
>                     help="File to write makefile dependencies list to");
> parser.add_argument("--order",default="reversed",
>                     help="Byte or bit order to use for the raw data");
> parser.add_argument('logs',nargs="+",
>                     help="Log files to pull meta data out of")
> args = parser.parse_args();
>
> with open(args.ybf,"wt") as F:
>     makeHeader(F,args);
>
> if args.archive:
>     os.link(args.ybf,os.path.join(args.archive,"%s-%s"%(os.path.basename(args.ybf),int(time.time()))));

  reply	other threads:[~2017-02-15 22:50 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-15 16:14 FPGA Region enhancements and fixes Alan Tull
2017-02-15 16:14 ` [RFC 1/8] fpga-mgr: add a single function for fpga loading methods Alan Tull
2017-02-16  0:36   ` matthew.gerlach
2017-02-15 16:14 ` [RFC 2/8] fpga-region: support more than one overlay per FPGA region Alan Tull
2017-02-16 16:50   ` matthew.gerlach
2017-02-16 17:35     ` Alan Tull
2017-02-15 16:14 ` [RFC 3/8] fpga-bridge: add non-dt support Alan Tull
2017-02-15 16:14 ` [RFC 4/8] doc: fpga-mgr: separate getting/locking FPGA manager Alan Tull
2017-02-17 17:14   ` Li, Yi
2017-02-17 21:55     ` Alan Tull
2017-02-17 17:52   ` Moritz Fischer
2017-02-17 22:02     ` Alan Tull
2017-02-15 16:14 ` [RFC 5/8] " Alan Tull
2017-02-15 16:14 ` [RFC 6/8] fpga-region: separate out common code to allow non-dt support Alan Tull
2017-02-15 16:14 ` [RFC 7/8] fpga-region: add sysfs interface Alan Tull
2017-02-15 17:21   ` Jason Gunthorpe
2017-02-15 17:46     ` Alan Tull
2017-02-15 17:55       ` Moritz Fischer
2017-02-15 18:06       ` Jason Gunthorpe
2017-02-15 18:23         ` Alan Tull
2017-02-15 18:31           ` Moritz Fischer
2017-02-15 19:49           ` Jason Gunthorpe
2017-02-15 22:49             ` Alan Tull [this message]
2017-02-15 23:07               ` Jason Gunthorpe
2017-02-15 20:07           ` matthew.gerlach
2017-02-15 20:37             ` Jason Gunthorpe
2017-02-15 20:54               ` Moritz Fischer
2017-02-15 21:15                 ` Jason Gunthorpe
2017-02-15 21:36                   ` Moritz Fischer
2017-02-15 22:42                     ` Alan Tull
2017-02-16  0:16                       ` Moritz Fischer
2017-02-16 17:47                         ` Alan Tull
2017-02-16 17:56                           ` Jason Gunthorpe
2017-02-16 18:11                             ` Moritz Fischer
2017-02-17 22:28                 ` Yves Vandervennet
2017-02-18  2:30                   ` Moritz Fischer
2017-02-18 12:45                     ` Nadathur, Sundar
2017-02-18 20:10                       ` Alan Tull
2017-02-18 20:45                         ` Moritz Fischer
2017-02-19 15:00                           ` Alan Tull
2017-02-19 23:16                             ` Alan Tull
2017-02-20 23:49                               ` Moritz Fischer
2017-02-21 18:33                                 ` Alan Tull
2017-02-22  3:13                                   ` Nadathur, Sundar
2017-02-22  3:49                                     ` Moritz Fischer
2017-02-22  5:12                                       ` Jason Gunthorpe
2017-02-22  5:38                                         ` Moritz Fischer
2017-02-22  5:46                                           ` Nadathur, Sundar
2017-02-22  6:05                                             ` Moritz Fischer
2017-02-22 16:44                                               ` Jason Gunthorpe
2017-02-22 17:50                                                 ` Moritz Fischer
2017-02-22 17:54                                                   ` Jason Gunthorpe
2017-02-22 17:57                                                     ` Moritz Fischer
2017-02-22 16:33                                           ` Alan Tull
2017-02-22 16:44                                             ` Moritz Fischer
2017-02-22 16:52                                               ` Alan Tull
2017-02-27 20:09                                   ` Alan Tull
2017-02-27 22:49                                     ` Moritz Fischer
2017-02-28  0:04                                       ` matthew.gerlach
2017-02-15 21:20         ` Anatolij Gustschin
2017-02-15 16:14 ` [RFC 8/8] doc: fpga: add sysfs document for fpga region Alan Tull
2017-02-28 17:35 ` FPGA Region enhancements and fixes Alan Tull
2017-02-28 22:03   ` Alan Tull

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CANk1AXQiCy6ySx_LVs9Oi6BT_T-hQPWX_ckakQ-UTE9PKh-7PA@mail.gmail.com \
    --to=delicious.quinoa@gmail.com \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=linux-fpga@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=moritz.fischer@ettus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.