Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/Documentation/driver-api/media/drivers/ccs/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 11 kB image not shown  

Quelle  mk-ccs-regs   Sprache: C

 
#!/usr/bin/perl -w
# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
# Copyright (C) 2019--2020 Intel Corporation

use Getopt::Long qw(:config no_ignore_case);
use File::Basename;

my $ccsregs = "ccs-regs.asc";
my $header;
my $regarray;
my $limitc;
my $limith;
my $kernel;
my $help;

GetOptions("ccsregs|c=s" => \$ccsregs,
    "header|e=s" => \$header,
    "regarray|r=s" => \$regarray,
    "limitc|l=s" => \$limitc,
    "limith|L=s" => \$limith,
    "kernel|k" => \$kernel,
    "help|h" => \$help) or die "can't parse options";

$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;

if (defined $help) {
 print <<EOH
$0 - Create CCS register definitions for C

usage: $0 -c ccs-regs.asc -e header -r regarray -l limit-c -L limit-header [-k]

 -c ccs register file
 -e header file name
 -r register description array file name
 -l limit and capability array file name
 -L limit and capability header file name
 -k generate files for kernel space consumption
EOH
   ;
 exit 0;
}

my $lh_hdr = ! defined $kernel
 ? '#include "ccs-os.h"' . "\n"
 : "#include <linux/bits.h>\n#include <linux/types.h>\n";
my $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
my $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';

open(my $R, "< $ccsregs") or die "can't open $ccsregs";

open(my $H, "> $header") or die "can't open $header";
my $A;
if (defined $regarray) {
 open($A, "> $regarray") or die "can't open $regarray";
}
open(my $LC, "> $limitc") or die "can't open $limitc";
open(my $LH, "> $limith") or die "can't open $limith";

my %this;

sub is_limit_reg($) {
 my $addr = hex $_[0];

 return 0 if $addr < 0x40; # weed out status registers
 return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers

 return 1;
}

my $uc_header = basename uc $header;
$uc_header =~ s/[^A-Z0-9]/_/g;

my $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
my $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
my $note = "/*\n * Generated by $0;\n * do not modify.\n */\n";

for my $fh ($A, $LC) {
 print $fh "// $license\n$copyright$note\n" if defined $fh;
}

for my $fh ($H, $LH) {
 print $fh "/* $license */\n$copyright$note\n";
}

print $H <<EOF
#ifndef __${uc_header}__
#define __${uc_header}__

EOF
  ;

print $H <<EOF
#include <linux/bits.h>

#include <media/v4l2-cci.h>

EOF
 if defined $kernel;

print $H "#define CCS_FL_BASE  " .
    (defined $kernel ? "CCI_REG_PRIVATE_SHIFT" : 16) . "\n";

my $flag = -1;
my $all_flags;

sub bit_def($) {
 my $bit = shift @_;

 if (defined $kernel) {
  return "BIT$bit" if $bit =~ /^\(.*\)$/;
  return "BIT($bit)";
 }
 return "(1U << $bit)";
}

sub flag_str($$) {
 my ($flag, $check) = @_;

 $$flag++;

 my $flag_str = !$$flag ? "CCS_FL_BASE" : "(CCS_FL_BASE + $$flag)";

 $flag_str = bit_def($flag_str);

 $$check .= " | " if defined $$check;

 $$check .= $flag_str;

 return $flag_str;
}

if (! defined $kernel) {
 print $H "#define CCS_FL_16BIT  " . flag_str(\$flag, \$all_flags) . "\n";
 print $H "#define CCS_FL_32BIT  " . flag_str(\$flag, \$all_flags) . "\n";
}

print $H "#define CCS_FL_FLOAT_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_FL_IREAL  " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_BUILD_BUG \\
 BUILD_BUG_ON(~CCI_REG_PRIVATE_MASK & ($all_flags))\n"
    if defined $kernel;

print $H <<EOF

#define CCS_R_ADDR(r)  ((r) & 0xffff)

EOF
    if ! defined $kernel;

print $A <<EOF
#include <stdint.h>
#include <stdio.h>
#include "ccs-extra.h"
#include "ccs-regs.h"

EOF
 if defined $A;

my $uc_limith = basename uc $limith;
$uc_limith =~ s/[^A-Z0-9]/_/g;

print $LH <<EOF
#ifndef __${uc_limith}__
#define __${uc_limith}__

$lh_hdr
struct ccs_limit {
 $uint32_t reg;
 $uint16_t size;
 $uint16_t flags;
 const char *name;
};

EOF
  ;
print $LH "#define CCS_L_FL_SAME_REG " . bit_def(0) . "\n\n";

print $LH <<EOF
extern const struct ccs_limit ccs_limits[];

EOF
  ;

print $LC <<EOF
#include "ccs-limits.h"
#include "ccs-regs.h"

const struct ccs_limit ccs_limits[] = {
EOF
  ;

my $limitcount = 0;
my $argdescs;
my $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";

sub name_split($$) {
 my ($name, $addr) = @_;
 my $args;

 $name =~ /([^\(]+?)(\(.*)/;
 ($name, $args) = ($1, $2);
 $args = [split /,\s*/, $args];
 foreach my $t (@$args) {
  $t =~ s/[\(\)]//g;
  $t =~ s/\//\\\//g;
 }

 return ($name, $addr, $args);
}

sub tabconv($) {
 $_ = shift;

 my @l = split "\n", $_;

 map {
  s/ {8,8}/\t/g;
  s/\t\K +//;
 } @l;

 return (join "\n", @l) . "\n";
}

sub elem_bits(@) {
 my @flags = @_;

 return 16 if grep /^16$/, @flags;
 return 32 if grep /^32$/, @flags;
 return 8;
}

sub arr_size($) {
 my $this = $_[0];
 my $size = $this->{elsize};
 my $h = $this->{argparams};

 foreach my $arg (@{$this->{args}}) {
  my $apref = $h->{$arg};

  $size *= $apref->{max} - $apref->{min} + 1;
 }

 return $size;
}

sub print_args($$$) {
 my ($this, $postfix, $is_same_reg) = @_;
 my ($args, $argparams, $name) =
   ($this->{args}, $this->{argparams}, $this->{name});
 my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
 my @mins;
 my @sorted_args = @{$this->{sorted_args}};
 my $lim_arg;
 my $size = arr_size($this);

 $argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";

 foreach my $sorted_arg (@sorted_args) {
  push @mins, $argparams->{$sorted_arg}->{min};
 }

 foreach my $sorted_arg (@sorted_args) {
  my $h = $argparams->{$sorted_arg};

  $argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";

  $lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
 }

 $argdescs .= "};\n\n";

 $reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
   "), $size, sizeof($varname) / sizeof(*$varname)," .
     " \"" . (lc $name) . "\", $varname },\n";

 print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
   $size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
     ", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
       if is_limit_reg $this->{base_addr};
}

my $hdr_data;

while (<$R>) {
 chop;
 s/^\s*//;
 next if /^[#;]/ || /^$/;
 if (s/^-\s*//) {
  if (s/^b\s*//) {
   my ($bit, $addr) = split /\t+/;
   $bit = uc $bit;
   $hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
  } elsif (s/^f\s*//) {
   s/[,\.-]/_/g;
   my @a = split /\s+/;
   my ($msb, $lsb, $this_field) = reverse @a;
          @a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
          { "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
   $this{"field"} = $this_field;
   foreach my $ar (@a) {
    #print $ar->{fmt}."\n";
    $hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
   }
  } elsif (s/^e\s*//) {
   s/[,\.-]/_/g;
   my ($enum, $addr) = split /\s+/;
   $enum = uc $enum;
   $hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
  } elsif (s/^l\s*//) {
   my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
   my $size;

   foreach my $num ($min, $max) {
    $num = hex $num if $num =~ /0x/i;
   }

   $hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
   $hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";

   my $h = $this{argparams};

   $h->{$arg} = { "min" => $min,
           "max" => $max,
           "elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
           "discontig" => \@discontig };

   $this{discontig} = $arg if @discontig;

   next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};

   my $reg_formula = "$this{addr}";
   my $lim_formula;

   chop $reg_formula;

   $reg_formula = "(" . $reg_formula if $this{flagstring} ne "";

   foreach my $arg (@{$this{args}}) {
    my $d = $h->{$arg}->{discontig};
    my $times = $h->{$arg}->{elsize} != 1 ?
      " * " . $h->{$arg}->{elsize} : "";

    if (@$d) {
     my ($lim, $offset) = split /,/, $d->[0];

     $reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
    } else {
     $reg_formula .= " + ($arg)$times";
    }

    $lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
   }

   $reg_formula .= ")";
   $lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;

   print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
       $this{arglist}, $reg_formula .
       (($this{flagstring} eq "") ? "" :
        " | " . $this{flagstring} . ")") . "\n");

   print $H tabconv $hdr_data;
   undef $hdr_data;

   # Sort arguments in descending order by size
   @{$this{sorted_args}} = sort {
    $h->{$a}->{elsize} <= $h->{$b}->{elsize}
   } @{$this{args}};

   if (defined $this{discontig}) {
    my $da = $this{argparams}->{$this{discontig}};
    my ($first_discontig) = split /,/, $da->{discontig}->[0];
    my $max = $da->{max};

    $da->{max} = $first_discontig - 1;
    print_args(\%this, "", 0);

    $da->{min} = $da->{max} + 1;
    $da->{max} = $max;
    print_args(\%this, $first_discontig, 1);
   } else {
    print_args(\%this, "", 0);
   }

   next unless is_limit_reg $this{base_addr};

   print $LH tabconv sprintf "#define %-63s%s\n",
     "CCS_L_" . (uc $this{name}) . "_OFFSET(" .
       (join ", ", @{$this{args}}) . ")", "($lim_formula)";
  }

  if (! @{$this{args}}) {
   print $H tabconv($hdr_data);
   undef $hdr_data;
  }

  next;
 }

 my ($name, $addr, @flags) = split /\t+/, $_;
 my $args = [];

 my $sp;

 ($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;

 $name =~ s/[,\.-]/_/g;

 my $flagstring = "";
 my $bits = elem_bits(@flags);
 if (! defined $kernel) {
  $flagstring .= "| CCS_FL_16BIT " if $bits == 16;
  $flagstring .= "| CCS_FL_32BIT " if $bits == 32;
 }
 $flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
 $flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
 $flagstring =~ s/^\| //;
 $flagstring =~ s/ $//;
 $flagstring = "($flagstring)" if $flagstring =~ /\|/;
 my $base_addr = $addr;
 $addr = "CCI_REG$bits($addr)" if defined $kernel;

 if ($flagstring ne "" && !@$args) {
  $addr = "($addr | $flagstring)";
  $flagstring = "";
 }

 my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
 $hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
   if !@$args;

 $name =~ s/\(.*//;

 %this = ( name => $name,
    addr => $addr,
    flagstring => $flagstring,
    base_addr => $base_addr,
    argparams => {},
    args => $args,
    arglist => $arglist,
    elsize => $bits / 8,
  );

 if (!@$args) {
  $reglist .= "\t{ CCS_R_" . (uc $name) . ", 1,  0, \"" . (lc $name) . "\", NULL },\n";
  print $H tabconv $hdr_data;
  undef $hdr_data;

  print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
    $this{elsize} . ", 0, \"$name\" },\n"
      if is_limit_reg $this{base_addr};
 }

 print $LH tabconv sprintf "#define %-63s%s\n",
   "CCS_L_" . (uc $this{name}), $limitcount++
     if is_limit_reg $this{base_addr};
}

if (defined $A) {
 print $A $argdescs, $reglist;

 print $A "\t{ 0 }\n";

 print $A "};\n";
}

print $H "\n#endif /* __${uc_header}__ */\n";

print $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;

print $LH "\n#endif /* __${uc_limith}__ */\n";

print $LC "\t{ 0 } /* Guardian */\n";
print $LC "};\n";

close($R);
close($H);
close($A) if defined $A;
close($LC);
close($LH);

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.