From patchwork Wed Dec 4 16:42:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 3283681 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7CD3C9F37C for ; Wed, 4 Dec 2013 16:43:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 257DF20265 for ; Wed, 4 Dec 2013 16:43:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1644F204EB for ; Wed, 4 Dec 2013 16:43:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932930Ab3LDQnd (ORCPT ); Wed, 4 Dec 2013 11:43:33 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47675 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932925Ab3LDQn3 (ORCPT ); Wed, 4 Dec 2013 11:43:29 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rB4GhCbE021613 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 4 Dec 2013 11:43:13 -0500 Received: from hawk.usersys.redhat.com.com (dhcp-1-158.brq.redhat.com [10.34.1.158]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id rB4Gh3G0015485; Wed, 4 Dec 2013 11:43:11 -0500 From: Andrew Jones To: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Subject: [PATCH 6/9] Introduce a simple iomap structure Date: Wed, 4 Dec 2013 17:42:54 +0100 Message-Id: <1386175377-23086-7-git-send-email-drjones@redhat.com> In-Reply-To: <1386175377-23086-1-git-send-email-drjones@redhat.com> References: <1386175377-23086-1-git-send-email-drjones@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a simple structure and search function to the common code that can be used for looking up a set of addresses by type. The user must supply the iomaps[] table, e.g. struct iomap iomaps[] = { { .type = "virtio_mmio", .nr = 4, .addrs = { 0x2000000, 0x2000200, 0x2000400, 0x2000600, }, }, { .type = NULL, }, }; Also add a script scripts/gen-devtree-iomaps.pl that can generate the iomaps table from an fdt, e.g. fdtdump dtb | scripts/gen-devtree-iomaps.pl - virtio_mmio Signed-off-by: Andrew Jones --- v2: - switch to kernel coding style - rework fdt parsing to enable extraction of properties. Extract the 'compatible' property. - add iomaps_find_compatible() to allow searching for iomaps by its 'compatible' property. --- README | 1 + lib/iomaps.c | 31 +++++++++++++ lib/iomaps.h | 14 ++++++ scripts/gen-devtree-iomaps.pl | 105 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 lib/iomaps.c create mode 100644 lib/iomaps.h create mode 100755 scripts/gen-devtree-iomaps.pl diff --git a/README b/README index 0174679c05021..f834c61dc6112 100644 --- a/README +++ b/README @@ -20,6 +20,7 @@ Directory structure: .: Makefile and config files for the tests ./config: config files for the tests ./docs: documentation files +./scripts: misc helper scripts ./lib: general services for the tests ./lib/: architecture dependent services for the tests ./: the sources of the tests and the created objects/images diff --git a/lib/iomaps.c b/lib/iomaps.c new file mode 100644 index 0000000000000..f2263b79dce96 --- /dev/null +++ b/lib/iomaps.c @@ -0,0 +1,31 @@ +#include "libcflat.h" +#include "iomaps.h" + +extern const struct iomap iomaps[]; + +const struct iomap *iomaps_find_type(const char *type) +{ + const struct iomap *m = &iomaps[0]; + + while (m->type) { + if (strcmp(m->type, type) == 0) + return m; + ++m; + } + return NULL; +} + +const struct iomap *iomaps_find_compatible(const char *compat) +{ + const struct iomap *m = &iomaps[0]; + const char *c; + int i; + + while (m->type) { + for (i = 0, c = m->compats[0]; c != NULL; c = m->compats[++i]) + if (strcmp(c, compat) == 0) + return m; + ++m; + } + return NULL; +} diff --git a/lib/iomaps.h b/lib/iomaps.h new file mode 100644 index 0000000000000..76a1aa4720337 --- /dev/null +++ b/lib/iomaps.h @@ -0,0 +1,14 @@ +#ifndef _IOMAPS_H_ +#define _IOMAPS_H_ +#include "libcflat.h" + +struct iomap { + const char *type; + const char *compats[5]; + u32 nr; + u32 addrs[64]; +}; + +const struct iomap *iomaps_find_type(const char *type); +const struct iomap *iomaps_find_compatible(const char *compat); +#endif diff --git a/scripts/gen-devtree-iomaps.pl b/scripts/gen-devtree-iomaps.pl new file mode 100755 index 0000000000000..b48e85e48ab34 --- /dev/null +++ b/scripts/gen-devtree-iomaps.pl @@ -0,0 +1,105 @@ +#!/usr/bin/perl -w +use strict; +use File::Temp qw/:POSIX/; + +my $dts = shift @ARGV; +my @types = @ARGV; +my $max_nr_addrs = 64; +my $max_nr_compats = 4; + +if (!defined $dts || $#types < 0) { + print STDERR "Usage: gen-devtree-iomaps ". + " [addr-types...]\n"; + exit 1; +} + +my $dtb = tmpnam(); +system "dtc -I dts -O dtb $dts -o $dtb"; + +my $g = join '|', map { $_ . '@' } @types; +my @devs = grep { /$g/ } `fdtget -l $dtb / 2>/dev/null`; + +my %iomaps; +foreach my $dev (@devs) { + + chomp($dev); + my ($type, $addr) = split /@/, $dev; + + if (!exists $iomaps{$type}) { + + my $compatible = `fdtget $dtb /$dev compatible 2>/dev/null`; + chomp($compatible); + my @compats = split ' ', $compatible; + + $iomaps{$type}{compats} = \@compats; + $iomaps{$type}{addrs} = [$addr]; + } else { + push @{ $iomaps{$type}{addrs} }, $addr; + } +} +unlink $dtb; + +print < $max_nr_compats) { + print STDERR "$type has $nr_compats compats, but iomaps can ". + "only support up to $max_nr_compats.\n"; + splice @{ $compats }, $max_nr_compats; + } + + @{ $addrs } = sort @{ $addrs }; + + my $nr = $#{ $addrs } + 1; + if ($nr > $max_nr_addrs) { + print STDERR "$type has $nr addrs, but iomaps can ". + "only support up to $max_nr_addrs.\n"; + $nr = $max_nr_addrs; + splice @{ $addrs }, $nr; + } + + @{ $addrs } = map { $_ = sprintf '0x%.8x', hex($_) } @{ $addrs }; + + print "{\n"; + print "\t.type = \"$type\",\n"; + + print "\t.compats = {"; + foreach my $compat (@{ $compats }) { + print " \"$compat\","; + } + print " NULL, },\n"; + + print "\t.nr = $nr,\n"; + print "\t.addrs = {"; + if ($nr < 5) { + print ' '; + print join ', ', @{ $addrs }; + print ", },\n"; + } else { + print "\n"; + for (my $i = 0; $i < $nr; $i += 5) { + print "\t\t"; + my $j = $i; + while ($j < $i + 4 && $j < $nr - 1) { + print $addrs->[$j] . ", "; + ++$j; + } + print $addrs->[$j] . ",\n"; + } + print "\t},\n"; + } + print "},\n"; +} +print "{\n\t.type = NULL,\n},\n"; +print "};\n"; +exit 0;