source: svn/newcon3bcm2_21bu/nexus/build/tools/common/bapi_classes.pm

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 14.3 KB
Line 
1#!/usr/bin/perl
2#     (c)2003-2011 Broadcom Corporation
3#
4#  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5#  and may only be used, duplicated, modified or distributed pursuant to the terms and
6#  conditions of a separate, written license agreement executed between you and Broadcom
7#  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8#  no license (express or implied), right to use, or waiver of any kind with respect to the
9#  Software, and Broadcom expressly reserves all rights in and to the Software and all
10#  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11#  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12#  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13#
14#  Except as expressly set forth in the Authorized License,
15#
16#  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17#  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18#  and to use this information only in connection with your use of Broadcom integrated circuit products.
19#
20#  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21#  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22#  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23#  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24#  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25#  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26#  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27#  USE OR PERFORMANCE OF THE SOFTWARE.
28#
29#  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30#  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31#  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32#  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33#  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34#  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35#  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36#  ANY LIMITED REMEDY.
37#
38# $brcm_Workfile: bapi_classes.pm $
39# $brcm_Revision: 1 $
40# $brcm_Date: 12/7/11 10:41a $
41#
42# File Description:
43#
44# Revision History:
45#
46# $brcm_Log: /nexus/build/tools/common/bapi_classes.pm $
47#
48# 1   12/7/11 10:41a erickson
49# SW7420-2141: merge as much duplicated kernelmode proxy/usermode ipc
50#  perl code as possible
51#
52#############################################################################
53use strict;
54
55package bapi_classes;
56
57# generate hash of destructor functions mapped to their various destructors by attr
58# the key is the constructor
59# one destructor per attr per function
60# the validation of destructors happens only here. every one else trusts this output.
61sub get_destructors
62{
63    my ($funcs) = @_;
64    my $func;
65    my ($attr,$value);
66    my %destructors;
67
68    for $func (@$funcs) {
69        if(exists $func->{ATTR}) {
70            while (($attr, $value) = each %{$func->{ATTR}} ) {
71                # one "if" clause for each prototype of destructor. valid prototypes are:
72                # 1) void destructor(resource_handle)
73                # 2) void destructor(main_handle, resource_handle)
74                if($attr eq 'destructor' || $attr eq 'release' || $attr eq 'dealloc') {
75                    my $destructor;
76                    for (@$funcs) {
77                        if ($value eq $_->{FUNCNAME}) {
78                            $destructor = $_;
79                            last;
80                        }
81                    }
82                    if ($attr eq 'dealloc') {
83                        # dealloc destructor param type is not class type
84                        if (defined $destructor && $destructor->{RETTYPE} eq 'void' &&
85                            (scalar @{$destructor->{PARAMS}}) == 1 )
86                        {
87                            $destructors{$func}->{$attr} = $destructor;
88                            next;
89                        }
90                    }
91                    else {
92                       if (defined $destructor && $destructor->{RETTYPE} eq 'void' &&
93                           (scalar @{$destructor->{PARAMS}}) == 1 &&
94                           ${$destructor->{PARAMS}}[0]->{TYPE} eq $func->{RETTYPE} )
95                        {
96                            $destructors{$func}->{$attr} = $destructor;
97                            next;
98                        }
99                    }
100                    print STDERR "ERROR: invalid $attr $value in function $func->{FUNCNAME}\n";
101                }
102                elsif($attr eq 'secondary_destructor') {
103                    my $destructor;
104                    for (@$funcs) {
105                        if ($value eq $_->{FUNCNAME}) {
106                            $destructor = $_;
107                            last;
108                        }
109                    }
110                    if (defined $destructor && $destructor->{RETTYPE} eq 'NEXUS_Error' &&
111                        (scalar @{$destructor->{PARAMS}}) == 2 &&
112                        ${$destructor->{PARAMS}}[0]->{TYPE} eq ${$func->{PARAMS}}[0]->{TYPE} &&
113                        ${$destructor->{PARAMS}}[1]->{TYPE} eq $func->{RETTYPE} )
114                    {
115                        # TODO: this only allows one type of secondary destructor. may need to expand this.
116                        $destructors{$func}->{$attr} = $destructor;
117                        next;
118                    }
119                    print STDERR "ERROR: invalid $attr $value in function $func->{FUNCNAME}\n";
120                }
121            }
122        }
123    }
124    return \%destructors;
125}
126
127# check if a function is a destructor and which handle is being destroyed
128sub get_stopcallbacks_handle
129{
130    my ($func, $destructors) = @_;
131    my $d;
132
133    for $d (keys %{$destructors}) {
134        if ($destructors->{$d}->{'destructor'} == $func) {
135            return $func->{PARAMS}[0]->{NAME};
136        }
137    }
138    for $d (keys %{$destructors}) {
139        if ($destructors->{$d}->{'secondary_destructor'} == $func) {
140            return $func->{PARAMS}[1]->{NAME};
141        }
142    }
143    return undef;
144}
145
146# return a list of classes
147sub get_classes
148{
149    my ($funcs, $destructors) = @_;
150    my $func;
151    my %classes;
152    my $class;
153
154    for $func (@$funcs) {
155        my $attr;
156        foreach $attr (keys %{$destructors->{$func}}) {
157            my $destructor = $destructors->{$func}->{$attr};
158
159            #print "$func->{FUNCNAME} $attr -> $destructor->{FUNCNAME}\n";
160            if ($attr eq "release") {
161                my $class_type = $func->{RETTYPE};
162                $class = $classes{$class_type};
163
164                if(defined $class && defined $class->{RELEASE}) {
165                    print STDERR "ERROR: cannot have more than one acquire/release acquire=$func->{FUNCNAME}, release=$destructor->{FUNCNAME}\n";
166                }
167                else {
168                    $class->{RELEASE} = $destructor;
169                    $class->{ACQUIRE} = $func;
170                    $classes{$class_type} = $class;
171                }
172            }
173            elsif ($attr eq "secondary_destructor") {
174                my $class_type = $func->{RETTYPE};
175                $class = $classes{$class_type};
176                push @{$class->{SECONDARY_DESTRUCTORS}}, $destructor;
177                # secondary_destructor must follow primary destructor
178                $classes{$class_type} = $class;
179            }
180            else {
181                my $class_type = $func->{RETTYPE};
182
183                if ($attr eq "dealloc") {
184                    # dealloc doesn't have handle. use destructor func name instead
185                    $class_type = $destructor->{FUNCNAME};
186                }
187
188                $class = $classes{$class_type};
189
190                if(defined $class && $class->{DESTRUCTOR}) {
191                    # you can have more than one constructor per class, but only one destructor per class
192                    if($class->{DESTRUCTOR} == $destructor) {
193                        push @{$class->{CONSTRUCTORS}}, $func;
194                    } else {
195                        print STDERR "ERROR: destructor mismatch $destructor->{FUNCNAME} for function $func->{FUNCNAME}:$func->{RETTYPE}\n";
196                        print STDERR "  $class->{DESTRUCTOR} != $destructor\n";
197                    }
198                } else {
199                    $class->{DESTRUCTOR} = $destructor;
200                    $class->{CONSTRUCTORS} = [$func];
201                    $class->{DESTRUCTOR_TYPE} = $attr;
202                    $class->{CLASS_TYPE} = $class_type;
203                    $classes{$class_type} = $class;
204                }
205            }
206        }
207        if (exists $func->{ATTR}->{"shutdown"}) {
208            my $class_type = $func->{PARAMS}[0]->{TYPE};
209            $class = $classes{$class_type};
210            my $shutdown;
211            $shutdown->{'shutdown_target'} = $func->{ATTR}->{'shutdown'};
212            $shutdown->{'shutdown_get_connector'} = $func->{FUNCNAME};
213            push @{$class->{SHUTDOWN}}, $shutdown;
214            $classes{$class_type} = $class;
215        }
216       
217    }
218
219    my @c = values %classes;
220    return \@c;
221}
222
223sub callable_by_untrusted
224{
225    my ($func, $classes, $untrusted_api) = @_;
226
227    my $allow_funcs = $untrusted_api->{'allow_funcs'};
228    my $deny_funcs = $untrusted_api->{'deny_funcs'};
229    my $params = $func->{PARAMS};
230
231    if (grep {$_ eq $func->{FUNCNAME}} @$allow_funcs) {
232        return 1;
233    }
234
235    if (grep {$_ eq $func->{FUNCNAME}} @$deny_funcs) {
236        return 0;
237    }
238
239    if ((scalar @{$params}) == 1 && !${$params}[0]->{INPARAM}) {
240        # GetDefaultSettings allowed
241        return 1;
242    }
243
244    # first param is validated handle
245    if ((scalar @{$params}) >= 1) {
246        if (${$params}[0]->{TYPE} eq 'NEXUS_HeapHandle') {
247            return 1;
248        }
249        for (@$classes) {
250            my $class = $_;
251            my $handletype = $class->{CLASS_TYPE};
252            if (${$params}[0]->{TYPE} eq $handletype) {
253                return 1;
254            }
255        }
256    }
257
258    # untrusted
259    return 0;
260}
261
262sub skip_thunk
263{
264    my $file = shift;
265    return $file =~ /_init.h$/ ||
266        $file =~ /nexus_platform_client.h$/ ||
267        $file =~ /nexus_base\w*.h$/;
268}
269
270# generate global functions which verify handles per module
271# this prevents the need for a global class database. $class_id can remain local.
272sub generate_class_verify_functions
273{
274    my ($file, $classes, $module) = @_;
275    my $class_id = 0;
276    $module = lc $module;
277    for (@$classes) {
278        my $class = $_;
279        my $handletype = $_->{CLASS_TYPE};
280
281        # required for cross-module handle verification
282        print $file "int nexus_driver_verify_$handletype(void *client_id, void *object) {\n";
283        print $file "  return b_objdb_verify_locked(&nexus_driver_module_state.header.objdb.class_table[$class_id], object, client_id);\n";
284        print $file "}\n";
285
286        # these functions can be called from inside nexus modules
287        print $file "/* adds/removes handle from objdb */\n";
288        print $file "int nexus_register_${handletype}(void *client, void *handle, bool acquire) {\n";
289        print $file "  NEXUS_ASSERT_MODULE();\n";
290        print $file "  return b_objdb_insert_locked(&nexus_driver_module_state.header.objdb.class_table[$class_id], handle, client, acquire);\n";
291        print $file "}\n";
292        print $file "void nexus_unregister_${handletype}(void *client, void *handle, bool release) {\n";
293        # can't NEXUS_ASSERT_MODULE because we could be in module uninit
294        print $file "  b_objdb_remove_locked(&nexus_driver_module_state.header.objdb.class_table[$class_id], handle, client, release);\n";
295        print $file "}\n";
296        ++$class_id;
297    }
298    print $file "/* returns the client current inside this module */\n";
299    print $file "void *nexus_${module}_client(void) {\n";
300    print $file "  NEXUS_ASSERT_MODULE();\n";
301    print $file "  return (nexus_driver_module_state.header.current_client?nexus_driver_module_state.header.current_client:&nexus_driver_get_server()->client);\n";
302    print $file "}\n";
303}
304
305sub generate_class_table
306{
307    my ($file, $classes)=@_;
308    if(scalar @$classes) {
309        my $class;
310               
311        # create local close function so that pre-close functions can be called
312        for $class (@$classes) {
313            next if ($class->{DESTRUCTOR_TYPE} ne 'destructor');
314            next if (!exists $class->{SHUTDOWN});
315           
316            my $handletype = $class->{CLASS_TYPE};
317            my $func = $class->{DESTRUCTOR};
318           
319            # shutdown_close will perform a platform-level shutdown of the connector, then close.
320            print $file "static void nexus_driver_shutdown_close_$handletype($handletype handle)\n";
321            print $file "{\n";
322            print $file "  NEXUS_UnlockModule();\n";
323            for (@{$class->{SHUTDOWN}}) {
324                my $shutdown_target = $_->{'shutdown_target'};
325                my $shutdown_get_connector = $_->{'shutdown_get_connector'};
326                my $params = $func->{PARAMS};
327                print $file "  nexus_driver_shutdown_$shutdown_target($shutdown_get_connector(handle));\n";
328            }
329            print $file "  NEXUS_LockModule();\n";
330            # actual close
331            print $file "  $func->{FUNCNAME}(handle);\n";
332            print $file "}\n\n";
333           
334        }
335       
336        print $file "B_OBJDB_TABLE_BEGIN(NEXUS_DRIVER_MODULE_CLASS_TABLE)\n";
337        for $class (@$classes) {
338            my $handletype = $class->{CLASS_TYPE};
339            my $destructorfunc;
340            if ($class->{DESTRUCTOR_TYPE} eq 'destructor' && exists $class->{SHUTDOWN}) {
341                $destructorfunc = "nexus_driver_shutdown_close_$handletype";
342            }
343            else {
344                $destructorfunc = $class->{DESTRUCTOR}->{FUNCNAME};
345            }
346            my $releasefunc = $class->{RELEASE}->{FUNCNAME};
347            if (!defined $destructorfunc) {
348                $destructorfunc = "ERROR: missing destructor"; # required. this will cause the compilation to fail.
349            }
350            if (!defined $releasefunc) {
351                $releasefunc = "NULL"; # not required
352            }
353            print $file "    B_OBJDB_TABLE_ENTRY($handletype,$releasefunc,$destructorfunc)\n";
354        }
355        print $file "B_OBJDB_TABLE_END\n";
356    }
357}
358
3591;
Note: See TracBrowser for help on using the repository browser.