xref: /linux/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs (revision 06d07429858317ded2db7986113a9e0129cd599b)
11ec0b899SSakari Ailus#!/usr/bin/perl -w
21ec0b899SSakari Ailus# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
31ec0b899SSakari Ailus# Copyright (C) 2019--2020 Intel Corporation
41ec0b899SSakari Ailus
51ec0b899SSakari Ailususe Getopt::Long qw(:config no_ignore_case);
61ec0b899SSakari Ailususe File::Basename;
71ec0b899SSakari Ailus
83bf10ebcSSakari Ailusmy $ccsregs = "ccs-regs.asc";
91ec0b899SSakari Ailusmy $header;
101ec0b899SSakari Ailusmy $regarray;
111ec0b899SSakari Ailusmy $limitc;
121ec0b899SSakari Ailusmy $limith;
131ec0b899SSakari Ailusmy $kernel;
141ec0b899SSakari Ailusmy $help;
151ec0b899SSakari Ailus
161ec0b899SSakari AilusGetOptions("ccsregs|c=s" => \$ccsregs,
171ec0b899SSakari Ailus	   "header|e=s" => \$header,
181ec0b899SSakari Ailus	   "regarray|r=s" => \$regarray,
191ec0b899SSakari Ailus	   "limitc|l=s" => \$limitc,
201ec0b899SSakari Ailus	   "limith|L=s" => \$limith,
211ec0b899SSakari Ailus	   "kernel|k" => \$kernel,
221ec0b899SSakari Ailus	   "help|h" => \$help) or die "can't parse options";
231ec0b899SSakari Ailus
241ec0b899SSakari Ailus$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;
251ec0b899SSakari Ailus
261ec0b899SSakari Ailusif (defined $help) {
271ec0b899SSakari Ailus	print <<EOH
281ec0b899SSakari Ailus$0 - Create CCS register definitions for C
291ec0b899SSakari Ailus
303bf10ebcSSakari Ailususage: $0 -c ccs-regs.asc -e header -r regarray -l limit-c -L limit-header [-k]
311ec0b899SSakari Ailus
321ec0b899SSakari Ailus	-c ccs register file
331ec0b899SSakari Ailus	-e header file name
341ec0b899SSakari Ailus	-r register description array file name
351ec0b899SSakari Ailus	-l limit and capability array file name
361ec0b899SSakari Ailus	-L limit and capability header file name
371ec0b899SSakari Ailus	-k generate files for kernel space consumption
381ec0b899SSakari AilusEOH
391ec0b899SSakari Ailus	  ;
401ec0b899SSakari Ailus	exit 0;
411ec0b899SSakari Ailus}
421ec0b899SSakari Ailus
431ec0b899SSakari Ailusmy $lh_hdr = ! defined $kernel
441ec0b899SSakari Ailus	? '#include "ccs-os.h"' . "\n"
451ec0b899SSakari Ailus	: "#include <linux/bits.h>\n#include <linux/types.h>\n";
461ec0b899SSakari Ailusmy $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
471ec0b899SSakari Ailusmy $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';
481ec0b899SSakari Ailus
491ec0b899SSakari Ailusopen(my $R, "< $ccsregs") or die "can't open $ccsregs";
501ec0b899SSakari Ailus
511ec0b899SSakari Ailusopen(my $H, "> $header") or die "can't open $header";
521ec0b899SSakari Ailusmy $A;
531ec0b899SSakari Ailusif (defined $regarray) {
541ec0b899SSakari Ailus	open($A, "> $regarray") or die "can't open $regarray";
551ec0b899SSakari Ailus}
561ec0b899SSakari Ailusopen(my $LC, "> $limitc") or die "can't open $limitc";
571ec0b899SSakari Ailusopen(my $LH, "> $limith") or die "can't open $limith";
581ec0b899SSakari Ailus
591ec0b899SSakari Ailusmy %this;
601ec0b899SSakari Ailus
611ec0b899SSakari Ailussub is_limit_reg($) {
621ec0b899SSakari Ailus	my $addr = hex $_[0];
631ec0b899SSakari Ailus
641ec0b899SSakari Ailus	return 0 if $addr < 0x40; # weed out status registers
651ec0b899SSakari Ailus	return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers
661ec0b899SSakari Ailus
671ec0b899SSakari Ailus	return 1;
681ec0b899SSakari Ailus}
691ec0b899SSakari Ailus
701ec0b899SSakari Ailusmy $uc_header = basename uc $header;
711ec0b899SSakari Ailus$uc_header =~ s/[^A-Z0-9]/_/g;
721ec0b899SSakari Ailus
731ec0b899SSakari Ailusmy $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
741ec0b899SSakari Ailusmy $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
75caad7940SBernhard Wimmermy $note = "/*\n * Generated by $0;\n * do not modify.\n */\n";
761ec0b899SSakari Ailus
771ec0b899SSakari Ailusfor my $fh ($A, $LC) {
78caad7940SBernhard Wimmer	print $fh "// $license\n$copyright$note\n" if defined $fh;
791ec0b899SSakari Ailus}
801ec0b899SSakari Ailus
811ec0b899SSakari Ailusfor my $fh ($H, $LH) {
82caad7940SBernhard Wimmer	print $fh "/* $license */\n$copyright$note\n";
831ec0b899SSakari Ailus}
841ec0b899SSakari Ailus
851ec0b899SSakari Ailusprint $H <<EOF
861ec0b899SSakari Ailus#ifndef __${uc_header}__
871ec0b899SSakari Ailus#define __${uc_header}__
881ec0b899SSakari Ailus
891ec0b899SSakari AilusEOF
901ec0b899SSakari Ailus  ;
911ec0b899SSakari Ailus
921ec0b899SSakari Ailusprint $H <<EOF
93*5d6ce399SSakari Ailus#include <linux/bits.h>
94*5d6ce399SSakari Ailus
95*5d6ce399SSakari Ailus#include <media/v4l2-cci.h>
96*5d6ce399SSakari Ailus
971ec0b899SSakari AilusEOF
98*5d6ce399SSakari Ailus	if defined $kernel;
991ec0b899SSakari Ailus
100*5d6ce399SSakari Ailusprint $H "#define CCS_FL_BASE		" .
101*5d6ce399SSakari Ailus    (defined $kernel ? "CCI_REG_PRIVATE_SHIFT" : 16) . "\n";
102*5d6ce399SSakari Ailus
103*5d6ce399SSakari Ailusmy $flag = -1;
104*5d6ce399SSakari Ailusmy $all_flags;
105*5d6ce399SSakari Ailus
106*5d6ce399SSakari Ailussub bit_def($) {
107*5d6ce399SSakari Ailus	my $bit = shift @_;
108*5d6ce399SSakari Ailus
109*5d6ce399SSakari Ailus	if (defined $kernel) {
110*5d6ce399SSakari Ailus		return "BIT$bit" if $bit =~ /^\(.*\)$/;
111*5d6ce399SSakari Ailus		return "BIT($bit)";
112*5d6ce399SSakari Ailus	}
113*5d6ce399SSakari Ailus	return "(1U << $bit)";
114*5d6ce399SSakari Ailus}
115*5d6ce399SSakari Ailus
116*5d6ce399SSakari Ailussub flag_str($$) {
117*5d6ce399SSakari Ailus	my ($flag, $check) = @_;
118*5d6ce399SSakari Ailus
119*5d6ce399SSakari Ailus	$$flag++;
120*5d6ce399SSakari Ailus
121*5d6ce399SSakari Ailus	my $flag_str = !$$flag ? "CCS_FL_BASE" : "(CCS_FL_BASE + $$flag)";
122*5d6ce399SSakari Ailus
123*5d6ce399SSakari Ailus	$flag_str = bit_def($flag_str);
124*5d6ce399SSakari Ailus
125*5d6ce399SSakari Ailus	$$check .= " | " if defined $$check;
126*5d6ce399SSakari Ailus
127*5d6ce399SSakari Ailus	$$check .= $flag_str;
128*5d6ce399SSakari Ailus
129*5d6ce399SSakari Ailus	return $flag_str;
130*5d6ce399SSakari Ailus}
131*5d6ce399SSakari Ailus
132*5d6ce399SSakari Ailusif (! defined $kernel) {
133*5d6ce399SSakari Ailus	print $H "#define CCS_FL_16BIT		" . flag_str(\$flag, \$all_flags) . "\n";
134*5d6ce399SSakari Ailus	print $H "#define CCS_FL_32BIT		" . flag_str(\$flag, \$all_flags) . "\n";
135*5d6ce399SSakari Ailus}
136*5d6ce399SSakari Ailus
137*5d6ce399SSakari Ailusprint $H "#define CCS_FL_FLOAT_IREAL	" . flag_str(\$flag, \$all_flags) . "\n";
138*5d6ce399SSakari Ailusprint $H "#define CCS_FL_IREAL		" . flag_str(\$flag, \$all_flags) . "\n";
139*5d6ce399SSakari Ailusprint $H "#define CCS_BUILD_BUG \\
140*5d6ce399SSakari Ailus	BUILD_BUG_ON(~CCI_REG_PRIVATE_MASK & ($all_flags))\n"
141*5d6ce399SSakari Ailus    if defined $kernel;
1421ec0b899SSakari Ailus
1431ec0b899SSakari Ailusprint $H <<EOF
144*5d6ce399SSakari Ailus
1451ec0b899SSakari Ailus#define CCS_R_ADDR(r)		((r) & 0xffff)
1461ec0b899SSakari Ailus
1471ec0b899SSakari AilusEOF
148*5d6ce399SSakari Ailus    if ! defined $kernel;
1491ec0b899SSakari Ailus
1501ec0b899SSakari Ailusprint $A <<EOF
1511ec0b899SSakari Ailus#include <stdint.h>
1521ec0b899SSakari Ailus#include <stdio.h>
1531ec0b899SSakari Ailus#include "ccs-extra.h"
1541ec0b899SSakari Ailus#include "ccs-regs.h"
1551ec0b899SSakari Ailus
1561ec0b899SSakari AilusEOF
1571ec0b899SSakari Ailus	if defined $A;
1581ec0b899SSakari Ailus
1591ec0b899SSakari Ailusmy $uc_limith = basename uc $limith;
1601ec0b899SSakari Ailus$uc_limith =~ s/[^A-Z0-9]/_/g;
1611ec0b899SSakari Ailus
1621ec0b899SSakari Ailusprint $LH <<EOF
1631ec0b899SSakari Ailus#ifndef __${uc_limith}__
1641ec0b899SSakari Ailus#define __${uc_limith}__
1651ec0b899SSakari Ailus
1661ec0b899SSakari Ailus$lh_hdr
1671ec0b899SSakari Ailusstruct ccs_limit {
1681ec0b899SSakari Ailus	$uint32_t reg;
1691ec0b899SSakari Ailus	$uint16_t size;
1701ec0b899SSakari Ailus	$uint16_t flags;
1711ec0b899SSakari Ailus	const char *name;
1721ec0b899SSakari Ailus};
1731ec0b899SSakari Ailus
1741ec0b899SSakari AilusEOF
1751ec0b899SSakari Ailus  ;
1761ec0b899SSakari Ailusprint $LH "#define CCS_L_FL_SAME_REG	" . bit_def(0) . "\n\n";
1771ec0b899SSakari Ailus
1781ec0b899SSakari Ailusprint $LH <<EOF
1791ec0b899SSakari Ailusextern const struct ccs_limit ccs_limits[];
1801ec0b899SSakari Ailus
1811ec0b899SSakari AilusEOF
1821ec0b899SSakari Ailus  ;
1831ec0b899SSakari Ailus
1841ec0b899SSakari Ailusprint $LC <<EOF
1851ec0b899SSakari Ailus#include "ccs-limits.h"
1861ec0b899SSakari Ailus#include "ccs-regs.h"
1871ec0b899SSakari Ailus
1881ec0b899SSakari Ailusconst struct ccs_limit ccs_limits[] = {
1891ec0b899SSakari AilusEOF
1901ec0b899SSakari Ailus  ;
1911ec0b899SSakari Ailus
1921ec0b899SSakari Ailusmy $limitcount = 0;
1931ec0b899SSakari Ailusmy $argdescs;
1941ec0b899SSakari Ailusmy $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";
1951ec0b899SSakari Ailus
1961ec0b899SSakari Ailussub name_split($$) {
1971ec0b899SSakari Ailus	my ($name, $addr) = @_;
1981ec0b899SSakari Ailus	my $args;
1991ec0b899SSakari Ailus
2001ec0b899SSakari Ailus	$name =~ /([^\(]+?)(\(.*)/;
2011ec0b899SSakari Ailus	($name, $args) = ($1, $2);
2021ec0b899SSakari Ailus	$args = [split /,\s*/, $args];
2031ec0b899SSakari Ailus	foreach my $t (@$args) {
2041ec0b899SSakari Ailus		$t =~ s/[\(\)]//g;
2051ec0b899SSakari Ailus		$t =~ s/\//\\\//g;
2061ec0b899SSakari Ailus	}
2071ec0b899SSakari Ailus
2081ec0b899SSakari Ailus	return ($name, $addr, $args);
2091ec0b899SSakari Ailus}
2101ec0b899SSakari Ailus
2111ec0b899SSakari Ailussub tabconv($) {
2121ec0b899SSakari Ailus	$_ = shift;
2131ec0b899SSakari Ailus
2141ec0b899SSakari Ailus	my @l = split "\n", $_;
2151ec0b899SSakari Ailus
2161ec0b899SSakari Ailus	map {
2171ec0b899SSakari Ailus		s/ {8,8}/\t/g;
2181ec0b899SSakari Ailus		s/\t\K +//;
2191ec0b899SSakari Ailus	} @l;
2201ec0b899SSakari Ailus
2211ec0b899SSakari Ailus	return (join "\n", @l) . "\n";
2221ec0b899SSakari Ailus}
2231ec0b899SSakari Ailus
224*5d6ce399SSakari Ailussub elem_bits(@) {
2251ec0b899SSakari Ailus	my @flags = @_;
2261ec0b899SSakari Ailus
227*5d6ce399SSakari Ailus	return 16 if grep /^16$/, @flags;
228*5d6ce399SSakari Ailus	return 32 if grep /^32$/, @flags;
229*5d6ce399SSakari Ailus	return 8;
2301ec0b899SSakari Ailus}
2311ec0b899SSakari Ailus
2321ec0b899SSakari Ailussub arr_size($) {
2331ec0b899SSakari Ailus	my $this = $_[0];
2341ec0b899SSakari Ailus	my $size = $this->{elsize};
2351ec0b899SSakari Ailus	my $h = $this->{argparams};
2361ec0b899SSakari Ailus
2371ec0b899SSakari Ailus	foreach my $arg (@{$this->{args}}) {
2381ec0b899SSakari Ailus		my $apref = $h->{$arg};
2391ec0b899SSakari Ailus
2401ec0b899SSakari Ailus		$size *= $apref->{max} - $apref->{min} + 1;
2411ec0b899SSakari Ailus	}
2421ec0b899SSakari Ailus
2431ec0b899SSakari Ailus	return $size;
2441ec0b899SSakari Ailus}
2451ec0b899SSakari Ailus
2461ec0b899SSakari Ailussub print_args($$$) {
2471ec0b899SSakari Ailus	my ($this, $postfix, $is_same_reg) = @_;
2481ec0b899SSakari Ailus	my ($args, $argparams, $name) =
2491ec0b899SSakari Ailus	  ($this->{args}, $this->{argparams}, $this->{name});
2501ec0b899SSakari Ailus	my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
2511ec0b899SSakari Ailus	my @mins;
2521ec0b899SSakari Ailus	my @sorted_args = @{$this->{sorted_args}};
2531ec0b899SSakari Ailus	my $lim_arg;
2541ec0b899SSakari Ailus	my $size = arr_size($this);
2551ec0b899SSakari Ailus
2561ec0b899SSakari Ailus	$argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";
2571ec0b899SSakari Ailus
2581ec0b899SSakari Ailus	foreach my $sorted_arg (@sorted_args) {
2591ec0b899SSakari Ailus		push @mins, $argparams->{$sorted_arg}->{min};
2601ec0b899SSakari Ailus	}
2611ec0b899SSakari Ailus
2621ec0b899SSakari Ailus	foreach my $sorted_arg (@sorted_args) {
2631ec0b899SSakari Ailus		my $h = $argparams->{$sorted_arg};
2641ec0b899SSakari Ailus
2651ec0b899SSakari Ailus		$argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";
2661ec0b899SSakari Ailus
2671ec0b899SSakari Ailus		$lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
2681ec0b899SSakari Ailus	}
2691ec0b899SSakari Ailus
2701ec0b899SSakari Ailus	$argdescs .= "};\n\n";
2711ec0b899SSakari Ailus
2721ec0b899SSakari Ailus	$reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
2731ec0b899SSakari Ailus	  "), $size, sizeof($varname) / sizeof(*$varname)," .
2741ec0b899SSakari Ailus	    " \"" . (lc $name) . "\", $varname },\n";
2751ec0b899SSakari Ailus
2761ec0b899SSakari Ailus	print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
2771ec0b899SSakari Ailus	  $size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
2781ec0b899SSakari Ailus	    ", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
2791ec0b899SSakari Ailus	      if is_limit_reg $this->{base_addr};
2801ec0b899SSakari Ailus}
2811ec0b899SSakari Ailus
2821ec0b899SSakari Ailusmy $hdr_data;
2831ec0b899SSakari Ailus
2841ec0b899SSakari Ailuswhile (<$R>) {
2851ec0b899SSakari Ailus	chop;
2861ec0b899SSakari Ailus	s/^\s*//;
2871ec0b899SSakari Ailus	next if /^[#;]/ || /^$/;
2881ec0b899SSakari Ailus	if (s/^-\s*//) {
2891ec0b899SSakari Ailus		if (s/^b\s*//) {
2901ec0b899SSakari Ailus			my ($bit, $addr) = split /\t+/;
2911ec0b899SSakari Ailus			$bit = uc $bit;
2921ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
2931ec0b899SSakari Ailus		} elsif (s/^f\s*//) {
2941ec0b899SSakari Ailus			s/[,\.-]/_/g;
2951ec0b899SSakari Ailus			my @a = split /\s+/;
2961ec0b899SSakari Ailus			my ($msb, $lsb, $this_field) = reverse @a;
2971ec0b899SSakari Ailus		        @a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
2981ec0b899SSakari Ailus			       { "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
2991ec0b899SSakari Ailus			$this{"field"} = $this_field;
3001ec0b899SSakari Ailus			foreach my $ar (@a) {
3011ec0b899SSakari Ailus				#print $ar->{fmt}."\n";
3021ec0b899SSakari Ailus				$hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
3031ec0b899SSakari Ailus			}
3041ec0b899SSakari Ailus		} elsif (s/^e\s*//) {
3051ec0b899SSakari Ailus			s/[,\.-]/_/g;
3061ec0b899SSakari Ailus			my ($enum, $addr) = split /\s+/;
3071ec0b899SSakari Ailus			$enum = uc $enum;
3081ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
3091ec0b899SSakari Ailus		} elsif (s/^l\s*//) {
3101ec0b899SSakari Ailus			my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
3111ec0b899SSakari Ailus			my $size;
3121ec0b899SSakari Ailus
3131ec0b899SSakari Ailus			foreach my $num ($min, $max) {
3141ec0b899SSakari Ailus				$num = hex $num if $num =~ /0x/i;
3151ec0b899SSakari Ailus			}
3161ec0b899SSakari Ailus
3171ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
3181ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";
3191ec0b899SSakari Ailus
3201ec0b899SSakari Ailus			my $h = $this{argparams};
3211ec0b899SSakari Ailus
3221ec0b899SSakari Ailus			$h->{$arg} = { "min" => $min,
3231ec0b899SSakari Ailus				       "max" => $max,
3241ec0b899SSakari Ailus				       "elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
3251ec0b899SSakari Ailus				       "discontig" => \@discontig };
3261ec0b899SSakari Ailus
3271ec0b899SSakari Ailus			$this{discontig} = $arg if @discontig;
3281ec0b899SSakari Ailus
3291ec0b899SSakari Ailus			next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
3301ec0b899SSakari Ailus
331*5d6ce399SSakari Ailus			my $reg_formula = "$this{addr}";
3321ec0b899SSakari Ailus			my $lim_formula;
3331ec0b899SSakari Ailus
334*5d6ce399SSakari Ailus			chop $reg_formula;
335*5d6ce399SSakari Ailus
336*5d6ce399SSakari Ailus			$reg_formula = "(" . $reg_formula if $this{flagstring} ne "";
337*5d6ce399SSakari Ailus
3381ec0b899SSakari Ailus			foreach my $arg (@{$this{args}}) {
3391ec0b899SSakari Ailus				my $d = $h->{$arg}->{discontig};
3401ec0b899SSakari Ailus				my $times = $h->{$arg}->{elsize} != 1 ?
3411ec0b899SSakari Ailus				  " * " . $h->{$arg}->{elsize} : "";
3421ec0b899SSakari Ailus
3431ec0b899SSakari Ailus				if (@$d) {
3441ec0b899SSakari Ailus					my ($lim, $offset) = split /,/, $d->[0];
3451ec0b899SSakari Ailus
3461ec0b899SSakari Ailus					$reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
3471ec0b899SSakari Ailus				} else {
3481ec0b899SSakari Ailus					$reg_formula .= " + ($arg)$times";
3491ec0b899SSakari Ailus				}
3501ec0b899SSakari Ailus
3511ec0b899SSakari Ailus				$lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
3521ec0b899SSakari Ailus			}
3531ec0b899SSakari Ailus
354*5d6ce399SSakari Ailus			$reg_formula .= ")";
3551ec0b899SSakari Ailus			$lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
3561ec0b899SSakari Ailus
3571ec0b899SSakari Ailus			print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
358*5d6ce399SSakari Ailus						 $this{arglist}, $reg_formula .
359*5d6ce399SSakari Ailus						 (($this{flagstring} eq "") ? "" :
360*5d6ce399SSakari Ailus						  " | " . $this{flagstring} . ")") . "\n");
3611ec0b899SSakari Ailus
3621ec0b899SSakari Ailus			print $H tabconv $hdr_data;
3631ec0b899SSakari Ailus			undef $hdr_data;
3641ec0b899SSakari Ailus
3651ec0b899SSakari Ailus			# Sort arguments in descending order by size
3661ec0b899SSakari Ailus			@{$this{sorted_args}} = sort {
3671ec0b899SSakari Ailus				$h->{$a}->{elsize} <= $h->{$b}->{elsize}
3681ec0b899SSakari Ailus			} @{$this{args}};
3691ec0b899SSakari Ailus
3701ec0b899SSakari Ailus			if (defined $this{discontig}) {
3711ec0b899SSakari Ailus				my $da = $this{argparams}->{$this{discontig}};
3721ec0b899SSakari Ailus				my ($first_discontig) = split /,/, $da->{discontig}->[0];
3731ec0b899SSakari Ailus				my $max = $da->{max};
3741ec0b899SSakari Ailus
3751ec0b899SSakari Ailus				$da->{max} = $first_discontig - 1;
3761ec0b899SSakari Ailus				print_args(\%this, "", 0);
3771ec0b899SSakari Ailus
3781ec0b899SSakari Ailus				$da->{min} = $da->{max} + 1;
3791ec0b899SSakari Ailus				$da->{max} = $max;
3801ec0b899SSakari Ailus				print_args(\%this, $first_discontig, 1);
3811ec0b899SSakari Ailus			} else {
3821ec0b899SSakari Ailus				print_args(\%this, "", 0);
3831ec0b899SSakari Ailus			}
3841ec0b899SSakari Ailus
3851ec0b899SSakari Ailus			next unless is_limit_reg $this{base_addr};
3861ec0b899SSakari Ailus
3871ec0b899SSakari Ailus			print $LH tabconv sprintf "#define %-63s%s\n",
3881ec0b899SSakari Ailus			  "CCS_L_" . (uc $this{name}) . "_OFFSET(" .
3891ec0b899SSakari Ailus			    (join ", ", @{$this{args}}) . ")", "($lim_formula)";
3901ec0b899SSakari Ailus		}
3911ec0b899SSakari Ailus
3921ec0b899SSakari Ailus		if (! @{$this{args}}) {
3931ec0b899SSakari Ailus			print $H tabconv($hdr_data);
3941ec0b899SSakari Ailus			undef $hdr_data;
3951ec0b899SSakari Ailus		}
3961ec0b899SSakari Ailus
3971ec0b899SSakari Ailus		next;
3981ec0b899SSakari Ailus	}
3991ec0b899SSakari Ailus
4001ec0b899SSakari Ailus	my ($name, $addr, @flags) = split /\t+/, $_;
4011ec0b899SSakari Ailus	my $args = [];
4021ec0b899SSakari Ailus
4031ec0b899SSakari Ailus	my $sp;
4041ec0b899SSakari Ailus
4051ec0b899SSakari Ailus	($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;
4061ec0b899SSakari Ailus
4071ec0b899SSakari Ailus	$name =~ s/[,\.-]/_/g;
4081ec0b899SSakari Ailus
4091ec0b899SSakari Ailus	my $flagstring = "";
410*5d6ce399SSakari Ailus	my $bits = elem_bits(@flags);
411*5d6ce399SSakari Ailus	if (! defined $kernel) {
412*5d6ce399SSakari Ailus		$flagstring .= "| CCS_FL_16BIT " if $bits == 16;
413*5d6ce399SSakari Ailus		$flagstring .= "| CCS_FL_32BIT " if $bits == 32;
414*5d6ce399SSakari Ailus	}
4151ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
4161ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
4171ec0b899SSakari Ailus	$flagstring =~ s/^\| //;
4181ec0b899SSakari Ailus	$flagstring =~ s/ $//;
4191ec0b899SSakari Ailus	$flagstring = "($flagstring)" if $flagstring =~ /\|/;
4201ec0b899SSakari Ailus	my $base_addr = $addr;
421*5d6ce399SSakari Ailus	$addr = "CCI_REG$bits($addr)" if defined $kernel;
422*5d6ce399SSakari Ailus
423*5d6ce399SSakari Ailus	if ($flagstring ne "" && !@$args) {
424*5d6ce399SSakari Ailus		$addr = "($addr | $flagstring)";
425*5d6ce399SSakari Ailus		$flagstring = "";
426*5d6ce399SSakari Ailus	}
4271ec0b899SSakari Ailus
4281ec0b899SSakari Ailus	my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
4291ec0b899SSakari Ailus	$hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
4301ec0b899SSakari Ailus	  if !@$args;
4311ec0b899SSakari Ailus
4321ec0b899SSakari Ailus	$name =~ s/\(.*//;
4331ec0b899SSakari Ailus
4341ec0b899SSakari Ailus	%this = ( name => $name,
4351ec0b899SSakari Ailus		  addr => $addr,
436*5d6ce399SSakari Ailus		  flagstring => $flagstring,
4371ec0b899SSakari Ailus		  base_addr => $base_addr,
4381ec0b899SSakari Ailus		  argparams => {},
4391ec0b899SSakari Ailus		  args => $args,
4401ec0b899SSakari Ailus		  arglist => $arglist,
441*5d6ce399SSakari Ailus		  elsize => $bits / 8,
4421ec0b899SSakari Ailus		);
4431ec0b899SSakari Ailus
4441ec0b899SSakari Ailus	if (!@$args) {
4451ec0b899SSakari Ailus		$reglist .= "\t{ CCS_R_" . (uc $name) . ", 1,  0, \"" . (lc $name) . "\", NULL },\n";
4461ec0b899SSakari Ailus		print $H tabconv $hdr_data;
4471ec0b899SSakari Ailus		undef $hdr_data;
4481ec0b899SSakari Ailus
4491ec0b899SSakari Ailus		print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
4501ec0b899SSakari Ailus		  $this{elsize} . ", 0, \"$name\" },\n"
4511ec0b899SSakari Ailus		    if is_limit_reg $this{base_addr};
4521ec0b899SSakari Ailus	}
4531ec0b899SSakari Ailus
4541ec0b899SSakari Ailus	print $LH tabconv sprintf "#define %-63s%s\n",
4551ec0b899SSakari Ailus	  "CCS_L_" . (uc $this{name}), $limitcount++
4561ec0b899SSakari Ailus	    if is_limit_reg $this{base_addr};
4571ec0b899SSakari Ailus}
4581ec0b899SSakari Ailus
4591ec0b899SSakari Ailusif (defined $A) {
4601ec0b899SSakari Ailus	print $A $argdescs, $reglist;
4611ec0b899SSakari Ailus
4621ec0b899SSakari Ailus	print $A "\t{ 0 }\n";
4631ec0b899SSakari Ailus
4641ec0b899SSakari Ailus	print $A "};\n";
4651ec0b899SSakari Ailus}
4661ec0b899SSakari Ailus
4671ec0b899SSakari Ailusprint $H "\n#endif /* __${uc_header}__ */\n";
4681ec0b899SSakari Ailus
4691ec0b899SSakari Ailusprint $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;
4701ec0b899SSakari Ailus
4711ec0b899SSakari Ailusprint $LH "\n#endif /* __${uc_limith}__ */\n";
4721ec0b899SSakari Ailus
4731ec0b899SSakari Ailusprint $LC "\t{ 0 } /* Guardian */\n";
4741ec0b899SSakari Ailusprint $LC "};\n";
4751ec0b899SSakari Ailus
4761ec0b899SSakari Ailusclose($R);
4771ec0b899SSakari Ailusclose($H);
4781ec0b899SSakari Ailusclose($A) if defined $A;
4791ec0b899SSakari Ailusclose($LC);
4801ec0b899SSakari Ailusclose($LH);
481