All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <christoffer.dall@linaro.org>
To: Andrew Jones <drjones@redhat.com>
Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org
Subject: Re: [PATCH 6/9] Introduce a simple iomap structure
Date: Sat, 28 Dec 2013 22:30:54 -0800	[thread overview]
Message-ID: <20131229063054.GE13601@cbox> (raw)
In-Reply-To: <1386175377-23086-7-git-send-email-drjones@redhat.com>

On Wed, Dec 04, 2013 at 05:42:54PM +0100, Andrew Jones wrote:
> 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 <drjones@redhat.com>
> 
> ---
> 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/<ARCH>:	architecture dependent services for the tests
>  ./<ARCH>:	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];

I would name the field compatible to be more in-line with the
DT-representation, but OK.

it looks from the above like the array must be null terminated?

how about #define IOMAP_MAX_COMPATS 5
and then turn your loop above into:

for (i = 0; i < IOMAP_MAX_COMPATS; i++, m++) {
	if (!m->compats[i])
		break;
	if (strcmp(m->compats[i], compat) == 0)
		return m;
}

> +	u32 nr;
> +	u32 addrs[64];

why are we limiting ourselves to a 32 bit physical address space?

> +};
> +
> +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 ".
> +		"<dts-file|-> <addr-type> [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 <<EOF;
> +/*
> + * Generated file. See gen-devtree-iomaps.pl
> + */
> +#include "iomaps.h"
> +EOF
> +print "\nconst struct iomap iomaps[] = {\n";
> +foreach my $type (keys %iomaps) {
> +
> +	my $compats = $iomaps{$type}{compats};
> +	my $addrs = $iomaps{$type}{addrs};
> +
> +	my $nr_compats = $#{ $compats } + 1;
> +	if ($nr_compats > $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;

This script doesn't work on either of the Ubuntu distros I run.  The
reasons are that the dumpfdt tool is not processing the multi-compatible
strings output from the dtb correctly and the fdtget utility included
does not yet have the -l option to list subnodes.

I spent a fair amount of time trying to fix this, changing dumpfdt to
'dtc -I dtb -O dts', and I tried it on the newest Ubuntu distro, tried
compiling fdtget from the kernel sources etc. and failed miserably.

I think at the very least we need to check the tools available on the
build machine as part of the configure script or test it a little
broader.

Thanks,
-- 
Christoffer

  reply	other threads:[~2013-12-29  6:30 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-04 16:42 [PATCH 0/9 v2] kvm-unit-tests/arm: initial drop Andrew Jones
2013-12-04 16:42 ` [PATCH 1/9] remove unused files Andrew Jones
2013-12-04 16:42 ` [PATCH 2/9] makefile and run_tests tweaks Andrew Jones
2013-12-29  6:30   ` Christoffer Dall
2014-01-02 14:30     ` Andrew Jones
2013-12-04 16:42 ` [PATCH 3/9] clean root dir of all x86-ness Andrew Jones
2013-12-29  6:30   ` Christoffer Dall
2014-01-02 15:00     ` Andrew Jones
2014-01-02 17:16       ` Christoffer Dall
2013-12-04 16:42 ` [PATCH 4/9] move x86's simple heap management to common code Andrew Jones
2013-12-29  6:30   ` Christoffer Dall
2014-01-02 15:17     ` Andrew Jones
2014-01-02 17:17       ` Christoffer Dall
2013-12-04 16:42 ` [PATCH 5/9] Introduce libio to common code for io read/write Andrew Jones
2013-12-29  6:30   ` Christoffer Dall
2014-01-02 15:47     ` Andrew Jones
2014-01-02 17:19       ` Christoffer Dall
2014-01-02 18:38         ` Andrew Jones
2013-12-04 16:42 ` [PATCH 6/9] Introduce a simple iomap structure Andrew Jones
2013-12-29  6:30   ` Christoffer Dall [this message]
2014-01-02 16:04     ` Andrew Jones
2014-01-02 17:23       ` Christoffer Dall
2014-01-02 18:40         ` Andrew Jones
2014-01-02 21:05           ` Christoffer Dall
2014-01-02 17:32       ` Peter Maydell
2013-12-04 16:42 ` [PATCH 7/9] Add halt() and some error codes Andrew Jones
2013-12-29  6:31   ` Christoffer Dall
2013-12-04 16:42 ` [PATCH 8/9] Introduce virtio-testdev Andrew Jones
2013-12-29  6:31   ` Christoffer Dall
2014-01-02 16:16     ` Andrew Jones
2014-01-02 17:27       ` Christoffer Dall
2014-01-02 18:41         ` Andrew Jones
2013-12-04 16:42 ` [PATCH 9/9] arm: initial drop Andrew Jones
2013-12-29  6:31   ` Christoffer Dall
2013-12-29  9:18     ` Peter Maydell
2014-01-02 16:54     ` Andrew Jones
2014-01-02 17:40       ` Peter Maydell
2014-01-02 18:09         ` Christoffer Dall
2014-01-02 18:44           ` Andrew Jones
2014-01-02 17:44       ` Christoffer Dall
2014-01-02 18:50         ` Andrew Jones
2014-01-02 19:17           ` Christoffer Dall
2014-01-03 17:52             ` Andrew Jones
2014-01-03 17:55               ` Christoffer Dall

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=20131229063054.GE13601@cbox \
    --to=christoffer.dall@linaro.org \
    --cc=drjones@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    /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.