Загрузка данных


sub generate_xport
{
    my ($outDir, $cfgRef) = @_;

    # Loop over xport types
    foreach my $xpt (@xportTypes)
    {
        my $lcXpt = lc $xpt;
        my @list = grep((/^CHANNEL\b/ && /\bxport=$lcXpt\b/)
            || /^MAILBOX\b/ || /^LM\d*\b/, @$cfgRef);
        my @chnList = grep(/^CHANNEL\b/, @list);
        my $num = @chnList;

        # Log xport info
        &log_array('Transort info (' . $xpt . ')', \@list);

        # Channels found?
        if ($num > 0)
        {
            my $fileName = 'config_' . $lcXpt . '.h';
            my $i;
            my $rpcType = '<invalid>';
            my %rpcChannel;
            my $mbType = '<invalid>';
            my %mbInst;
            my %crc;
            
            # Open file
            open my $out, '>', $outDir . '/' . $fileName
                or die "error: failure to open: $outDir/$fileName, $!";
            if ($verbose)
            {
                my $fn = fileparse($fileName);
                printf("Generating $fn ...\n");
            }

            # Output header
            print $out &header($xpt, $xpt);

            print $out '/* Includes */' . "\n\n";
            print $out '#include "config_user.h"' . "\n";
            print $out '#include "rpc_' . $lcXpt . '_config.h"' . "\n\n";
            print $out '/* Defines */' . "\n\n";

            # Loop over the LM+MU+CHN list
            $i = 0;
            foreach my $mb (@list)
            {
                # Handle LM
                if ($mb =~ /^(LM\d*)\b/)
                {
                    my $line = $1 . ' ' . $xpt . ' Config';
                    if ((my $parm = &param($mb, 'name')) ne '!')
                    {
                        $parm =~ s/\"//g;
                        $line .= ' (' . $parm . ')';
                    }

                    print $out &banner($line);
                    next;
                }

                # Handle MB
                if ($mb =~ /^MAILBOX\b/)
                {
	                if ((my $parm = &param($mb, 'type')) ne '!')
	                {
	                    $mbType = 'MB_' . uc $parm;
	                    $mbInst{$mbType}++;
	                }
                    next;
                }

                # Handle channel
                if ($mb =~ /^CHANNEL\b/)
                {
	                if ((my $parm = &param($mb, 'rpc')) ne '!')
	                {
	                    $rpcType = 'RPC_' . uc $parm;
	                    $rpcChannel{$rpcType}++;
	                }

	                # Check for default channel
	                if ($mbType eq '<invalid>')
	                {
	                    error_line('no mailbox', $mb);
	                }

	                # Output channel define
					print $out '/*! Config for ' . $xpt . ' channel ' . $i
						. ' */' . "\n";
	                print $out '#define SM_' . $xpt . '_CHN'
	                    . $i . '_CONFIG \\' . "\n";
	                print $out '    { \\' . "\n";
	                print $out '        .rpcType = SM_' . $rpcType
	                    . ', \\' . "\n";
	                print $out '        .rpcChannel = ' . ($rpcChannel{$rpcType}
	                    - 1) . 'U, \\' . "\n";
	                print $out '        .mbType = SM_' . $mbType
	                    . ', \\' . "\n";
	                print $out '        .mbInst = ' . ($mbInst{$mbType}
	                    - 1) . 'U, \\' . "\n";
	                if ((my $parm = &param($mb, 'db')) ne '!')
	                {
	                    print $out '        .mbDoorbell = ' . $parm
	                        . 'U, \\' . "\n";
	                }
	                if ((my $parm = &param($mb, 'check')) ne '!')
	                {
	                    $crc{$parm}++;
	                    print $out '        .crc = SM_SMT_CRC_'
	                        . uc $parm . ', \\' . "\n";
	                }
	                print $out '    }' . "\n\n";

	                $i++;
	            }
            }

            # Output collected define
            print $out &banner($xpt . ' Config');
			print $out '/*! Config for number of ' . $xpt . ' channels'
						. ' */' . "\n";
            print $out '#define SM_NUM_' . $xpt . '_CHN  '
                . $num . 'U' . "\n\n";

            # Loop over the channel list
            $i = 0;
			print $out '/*! Config data array for ' . $xpt . ' channels */' . "\n";
            print $out '#define SM_' . $xpt . '_CHN_CONFIG_DATA';
            foreach my $chn (@chnList)
            {
                if ($i != 0)
                {
                    print $out ',';
                }
                print $out ' \\' . "\n" . '    SM_' . $xpt . '_CHN'
                    . $i . '_CONFIG';
                $i++;
            }
            print $out "\n\n";

            # Output defines for MU type support
            print $out '/* Mailbox and CRC types to support */'
                . "\n";
            foreach my $key (keys %mbInst)
            {
                my $value = $mbInst{$key};

                if ($value != 0)
                {
					print $out '/*! Config for ' . uc $key . ' use */' . "\n";
                    print $out '#define USES_' . uc $key . "\n";
                }
            }

            # Output defines for CRC support
            foreach my $key (sort keys %crc)
            {
                my $value = $crc{$key};

                if ($value != 0)
                {
					print $out '/*! Config for ' . uc $key . ' CRC use */' . "\n";
                    print $out '#define USES_CRC_' . uc $key . "\n";
                }
            }

            # Output footer
            print $out &footer($xpt);

            # Close file
            close($out);

            # Include in make
            $makeInclude{$xpt} = 'rpc/' . $lcXpt;
        }
    }
}

###############################################################################

sub generate_scmi
{
    my ($outDir, $cfgRef) = @_;
    my $fileName = 'config_scmi.h';
    my @list = @$cfgRef;
    my @chnList = grep(/^CHANNEL\b/ && /\brpc=scmi\b/, @list);
    my $numChn = @chnList;
    my @agntList = grep(/^SCMI_AGENT\d*\b/, @list);
    my $numAgnt = @agntList;
    my $i;
    my %xportInst;

    # Open file
    open my $out, '>', $outDir . '/' . $fileName
        or die "error: failure to open: $outDir/$fileName, $!";
    if ($verbose)
    {
        my $fn = fileparse($fileName);
        printf("Generating $fn ...\n");
    }

    # Log channel info
    &log_array('SCMI channel info', \@chnList);

    # Log agent info
    &log_array('SCMI agent info', \@agntList);

    # Output header
    print $out &header('SCMI', 'SCMI RPC');

    print $out '/* Includes */' . "\n\n";
    print $out '#include "config_user.h"' . "\n\n";
    print $out '/* Defines */' . "\n\n";

    # Loop over the list
    my $scmiInst = -1;
    my $lmName = '<invalid>';
    my $did = '<invalid>';
    my $lmId = -1;
    my $agnt = -1;
    my $numAgents = 0;
    my $firstAgent;
    my $chn = 0;
    my $notify = 20;
    my $safe = 0;
    foreach my $dat (@list)
    {
        # Handle LM and EOF
        if (($dat =~ /^(LM\d*)\b/) || ($dat =~ /^EOF\b/)) 
        {
            # Non-first LM
            if ($scmiInst != -1)
            {
                if ($lmName eq '<invalid>')
                {
                    error_line('missing LM name, invalid SCMI instance', $dat);
                }

                my $line = 'SCMI Instance ' . $scmiInst
                    . ' Config (' . $lmName . ')';
                print $out &banner($line);

				print $out '/*! Config for SCMI instance ' . $scmiInst
					. ' */' . "\n";
                print $out '#define SM_SCMI' . $scmiInst
                    . '_CONFIG \\' . "\n";
                print $out '    { \\' . "\n";
                print $out '        .lmId = ' . $lmId
                    . 'U, \\' . "\n";
                print $out '        .numAgents = ' . $numAgents
                    . 'U, \\' . "\n";
                print $out '        .firstAgent = ' . $firstAgent
                    . 'U, \\' . "\n";

                print $out '    }' . "\n\n";

                $numAgents = 0;
            }

            # Handle LM
            if ($dat =~ /^(LM\d*)\b/)
            {
                # SCMI LM?
                if ($dat =~ /\brpc=scmi\b/)
                {
                    if ((my $parm = &param($dat, 'name')) ne '!')
                    {
                        $parm =~ s/\"//g;
                        $lmName = $parm;
                    }
                    if ((my $parm = &param($dat, 'did')) ne '!')
                    {
                        $did = $parm;
                    }
                    $scmiInst++;
                }
                else
                {
                    $lmName = '<invalid>';
                    $did = '<invalid>';
                }
                $firstAgent = $agnt + 1;
                $lmId++;

                # Check safety type
                $safe = 0;
       	        if ((my $parm = &param($dat, 'safe')) ne '!')
    	        {
                    if ($parm eq 'seenv')
                    {
                        $safe = 1;
                    }
    	        }
            }

            next;
        }

        # Handle agent
        if ($dat =~ /^(SCMI_AGENT\d*)\b/)
        {
            my $agentToken = $1;
            $agentToken =~ s/_/ /g; 
            my $line = $agentToken . ' Config';
    		my $secure = 0;
            my $dup;
            if ((my $parm = &param($dat, 'name')) ne '!')
            {
                $parm =~ s/\"//g;
                $line .= ' (' . $parm . ')';
            }
            else
            {
                error_line('missing agent name', $dat);
            }
            if ((my $parm = &param($dat, 'did')) ne '!')
            {
                $did = $parm;
            }
            if ($dat =~ /secure /)
            {
                $secure = 1;
            }
            else
            {
                $secure = 0;
            }
            $agnt++;
            $numAgents++;
            if ((my $parm = &param($dat, 'dup')) ne '!')
            {
                $dup = $parm;
            }
            else
            {
                $dup = $agnt;
            }

            if ($safe == 1)
            {
                $seenvid++;
            }

            # Output banner
            print $out &banner($line);

            # Check SCMI instance
            if ($scmiInst < 0)
            {
                error_line('missing LM, invalid SCMI instance', $dat);
            }

            # Get perms
            my @perms = &get_perms($cfgRef, $dup);

            # Output agent info
			print $out '/*! Config for SCMI agent ' . $agnt
				. ' */' . "\n";
            print $out '#define SM_SCMI_AGNT' . $agnt . '_CONFIG \\'
                . "\n";
            print $out '    { \\' . "\n";
            if ((my $parm = &param($dat, 'name')) ne '!')
            {
                $parm =~ s/\"//g;
                print $out '        .name = "' . $parm . '", \\' . "\n";
            }
            print $out '        .scmiInst = ' . $scmiInst . 'U, \\' . "\n";
            print $out '        .domId = ' . $did . 'U, \\' . "\n";
            print $out '        .secure = ' . $secure . 'U, \\' . "\n";
            if ($safe == 1)
            {
                print $out '        .seenvId = ' . $seenvid . 'U, \\' . "\n";
            }

            # Loop over perms
            $i = 0;
            foreach my $perm (@perms)
            {
                print $out '        ' . $perm . ', \\' . "\n";
                $i++;
            }
            print $out '    }' . "\n\n";

            next;
        }

        # Handle channel
        if ($dat =~ /^CHANNEL\b/)
        {
            if ((my $parm = &param($dat, 'xport')) ne '!')
            {
                $xportInst{$parm}++;
            }
            if ((my $parm = &param($dat, 'rpc')) eq 'scmi')
            {
				print $out '/*! Config for SCMI channel ' . $chn
					. ' */' . "\n";
	            print $out '#define SM_SCMI_CHN' . $chn
	                . '_CONFIG \\' . "\n";
	            print $out '    { \\' . "\n";
	            print $out '        .agentId = ' . $agnt . 'U, \\' . "\n";
	            if ((my $parm = &param($dat, 'type')) ne '!')
	            {
	                print $out '        .type = SM_SCMI_CHN_'
	                    . uc $parm . ', \\' . "\n";
	            }
	            if ((my $parm = &param($dat, 'sequence')) ne '!')
	            {
	                print $out '        .sequence = SM_SCMI_SEQ_'
	                    . uc $parm . ', \\' . "\n";
	            }
	            if ((my $parm = &param($dat, 'xport')) ne '!')
	            {
	                print $out '        .xportType = SM_XPORT_'
	                    . uc $parm . ', \\' . "\n";
	                print $out '        .xportChannel = '
	                    . ($xportInst{$parm} - 1) . 'U, \\' . "\n";
	            }
	            if ((my $parm = &param($dat, 'notify')) ne '!')
	            {
	                $notify = $parm;
	            }
	            print $out '    }' . "\n\n";
	            $chn++;

	            # Include in make
	            $makeInclude{SCMI} = 'rpc/scmi';
	        }

            next;
        }
   }

    # Output collected agent define
    print $out &banner('SCMI Agent Config');
	print $out '/*! Config for number of SCMI agents */' . "\n";
    print $out '#define SM_SCMI_NUM_AGNT  ' . $numAgnt . 'U' . "\n\n";

    # Loop over the agent list
	print $out '/*! Config data array for SCMI agents */' . "\n";
    print $out '#define SM_SCMI_AGNT_CONFIG_DATA';
    foreach my $i (0..($numAgnt - 1))
    {
        if ($i != 0)
        {
            print $out ',';
        }
        print $out ' \\' . "\n" . '    SM_SCMI_AGNT' . $i . '_CONFIG';
    }
    print $out "\n\n";

    # Output collected channel define
    print $out &banner('SCMI Channel Config');
	print $out '/*! Config for number of SCMI channels */' . "\n";
    print $out '#define SM_SCMI_NUM_CHN  ' . $numChn . 'U' . "\n\n";

    # Loop over the channel list
	print $out '/*! Config data array for SCMI channels */' . "\n";
    print $out '#define SM_SCMI_CHN_CONFIG_DATA';
    foreach my $i (0..($numChn - 1))
    {
        if ($i != 0)
        {
            print $out ',';
        }
        print $out ' \\' . "\n" . '    SM_SCMI_CHN' . $i . '_CONFIG';
    }
    print $out "\n\n";

    # Output collected SCMI define
    print $out &banner('SCMI Config');
	print $out '/*! Config for number of SCMI instances */' . "\n";
    print $out '#define SM_NUM_SCMI  ' . ($scmiInst + 1) . 'U' . "\n\n";

    # Loop over the SCMI list
	print $out '/*! Config data array for SCMI instances */' . "\n";
    print $out '#define SM_SCMI_CONFIG_DATA';
    foreach my $i (0..$scmiInst)
    {
        if ($i != 0)
        {
            print $out ',';
        }
        print $out ' \\' . "\n" . '    SM_SCMI' . $i . '_CONFIG';
    }
    print $out "\n\n";

    print $out '/*! Max words to buffer for notification messages */'
        . "\n";
    print $out '#define SM_SCMI_MAX_NOTIFY  ' . $notify . 'U' . "\n";

    # Output footer
    print $out &footer('SCMI');

    # Close file
    close($out);
}