1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Verification Test APIs File: vapi.S
6 * This module contains special low-level routines for use
7 * by verification programs.
9 * Author: Mitch Lichtenberg (mpl@broadcom.com)
11 *********************************************************************
13 * Copyright 2000,2001,2002,2003
14 * Broadcom Corporation. All rights reserved.
16 * This software is furnished under license and may be used and
17 * copied only in accordance with the following terms and
18 * conditions. Subject to these conditions, you may download,
19 * copy, install, use, modify and distribute modified or unmodified
20 * copies of this software in source and/or binary form. No title
21 * or ownership is transferred hereby.
23 * 1) Any source code used, modified or distributed must reproduce
24 * and retain this copyright notice and list of conditions
25 * as they appear in the source file.
27 * 2) No right is granted to use any trade name, trademark, or
28 * logo of Broadcom Corporation. The "Broadcom Corporation"
29 * name may not be used to endorse or promote products derived
30 * from this software without the prior written permission of
31 * Broadcom Corporation.
33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGE.
46 ********************************************************************* */
50 #include "bsp_config.h"
51 #include "mipsmacros.h"
56 #error "CFG_VAPI is not compatible with relocatable code"
59 #include "cfe_devfuncs.h"
61 #include "sb1250_defs.h"
62 #include "sb1250_regs.h"
63 #include "sb1250_scd.h"
67 /* *********************************************************************
69 ********************************************************************* */
71 #define CALLKSEG1(x) \
76 #ifndef CFG_STACK_SIZE
77 #define STACK_SIZE 8192
79 #define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
83 /*Break compile if stack less than 4096. Vapi_puts() and vapi_dumpgprs()
84 uses high 1/4 of stack and needs between 512 and 1024 bytes */
85 #if !(STACK_SIZE & ~4095)
86 #error "To use this module the stack must be at least 4096 bytes"
89 #define REGIDX(x) ((x)*8)
91 #define SAVE_RA REGIDX(0)
92 #define SAVE_GP REGIDX(1)
93 #define SAVE_AT REGIDX(2)
94 #define SAVE_T0 REGIDX(3)
95 #define SAVE_T1 REGIDX(4)
96 #define SAVE_T2 REGIDX(5)
97 #define SAVE_T3 REGIDX(6)
98 #define SAVE_A0 REGIDX(7)
99 #define SAVE_A1 REGIDX(8)
100 #define SAVE_A2 REGIDX(9)
102 #define SAVE_SIZE REGIDX(10)
104 #define SAVETEMPS(x) \
107 sd ra,SAVE_RA(k0) ; \
108 sd gp,SAVE_GP(k0) ; \
109 sd AT,SAVE_AT(k0) ; \
110 sd t0,SAVE_T0(k0) ; \
111 sd t1,SAVE_T1(k0) ; \
112 sd t2,SAVE_T2(k0) ; \
113 sd t3,SAVE_T3(k0) ; \
114 sd a0,SAVE_A0(k0) ; \
115 sd a1,SAVE_A1(k0) ; \
116 sd a2,SAVE_A2(k0) ; \
121 #define RESTORETEMPS(x) \
124 ld ra,SAVE_RA(k0) ; \
125 ld gp,SAVE_GP(k0) ; \
126 ld AT,SAVE_AT(k0) ; \
127 ld t0,SAVE_T0(k0) ; \
128 ld t1,SAVE_T1(k0) ; \
129 ld t2,SAVE_T2(k0) ; \
130 ld t3,SAVE_T3(k0) ; \
131 ld a0,SAVE_A0(k0) ; \
132 ld a1,SAVE_A1(k0) ; \
133 ld a2,SAVE_A2(k0) ; \
138 #define CHECKPTR(label) \
139 ld RECPTR,vapi_logptr ; \
140 ld t0,vapi_logend ; \
141 beq RECPTR,zero,label ; \
144 #define SETRECTYPE(x,id) \
145 ld RECPTR,vapi_logptr ; \
146 li t2,(VAPI_CFESEAL | (x)) ; \
150 sll t0,t0,VAPI_PRNUM_SHIFT ; \
154 sd t2,VAPI_REC_SIGNATURE(RECPTR) ; \
157 sd t2,VAPI_REC_SIZE(RECPTR) ; \
158 sd ra,VAPI_REC_RA(RECPTR)
162 #define SETRECLEN_CONST(len) \
163 ld t2,VAPI_REC_SIZE(RECPTR) ; \
165 sd t2,VAPI_REC_SIZE(RECPTR)
167 #define SETRECLEN_REG(r) \
168 ld t2,VAPI_REC_SIZE(RECPTR) ; \
170 sd t2,VAPI_REC_SIZE(RECPTR)
173 /* *********************************************************************
175 ********************************************************************* */
185 vapi_logstart: .dword 0
186 vapi_logend: .dword 0
187 vapi_logptr: .dword 0
188 vapi_status: .dword -1
189 vapi_logover: .dword 0
191 .extern mem_heapstart
195 .comm vapi_regsave,REGIDX(64)
205 #include "sb1250_socregs.inc"
210 .extern cfe_warmstart
215 /* *********************************************************************
218 * Hack the return address so we will come back in KSEG0
225 ********************************************************************* */
227 LEAF(vapi_kseg0_switch)
233 END(vapi_kseg0_switch)
235 /* *********************************************************************
238 * Return from diagnostic to firmware
241 * a0 - exit status (0=ok, else error)
245 ********************************************************************* */
254 * Reinitialize the CPU and the caches
257 bal vapi_kseg1_switch
258 CALLKSEG1(sb1_cpu_init)
260 * Don't initialize the caches again. Some diags
261 * leave data in the caches and if we invalidate it
262 * now we won't be able to see what happened.
264 /* CALLKSEG1(sb1250_l1cache_init) */
265 /* CALLKSEG1(sb1250_l2cache_init) */
269 * Set back to 64-bit mode. Don't worry about the hazard
270 * here, it'll be eons before we need to use the KX space.
277 bal vapi_kseg0_switch
279 li a0,0x42424242 # 'BBBB'
287 ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
290 * Create a log record for the EXIT status.
295 SETRECTYPE(VAPI_FMT_EXIT,0)
297 sd a0,VAPI_REC_DATA(RECPTR)
299 sd RECPTR,vapi_logptr
301 li a0,0x45454545 # 'EEEE'
307 * Restart the other CPU if it was left in RESET.
310 la t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
312 dli t1,M_SYS_CPU_RESET_1 # Reset mask
313 and t0,t1 # Test if CPU is in reset
314 beq t0,zero,1f # skip if not in reset
316 li a0,1 # Whack the CPU
317 jal altcpu_cmd_stop # and put it back in idle
328 /* *********************************************************************
331 * Dump the GPRs to the console
340 * k0 - scratch register for CFE
341 ********************************************************************* */
357 sd $10,REGIDX(10)(k0)
358 sd $11,REGIDX(11)(k0)
359 sd $12,REGIDX(12)(k0)
360 sd $13,REGIDX(13)(k0)
361 sd $14,REGIDX(14)(k0)
362 sd $15,REGIDX(15)(k0)
363 sd $16,REGIDX(16)(k0)
364 sd $17,REGIDX(17)(k0)
365 sd $18,REGIDX(18)(k0)
366 sd $19,REGIDX(19)(k0)
367 sd $20,REGIDX(20)(k0)
368 sd $21,REGIDX(21)(k0)
369 sd $22,REGIDX(22)(k0)
370 sd $23,REGIDX(23)(k0)
371 sd $24,REGIDX(24)(k0)
372 sd $25,REGIDX(25)(k0)
373 sd $26,REGIDX(26)(k0) /* k0 */
374 sd $27,REGIDX(27)(k0)
375 sd $28,REGIDX(28)(k0)
376 sd $29,REGIDX(29)(k0)
377 sd $30,REGIDX(30)(k0)
378 sd $31,REGIDX(31)(k0)
381 # Save some CP0 registers here.
382 #define LSAVECP0(cp0,idx) \
384 sd t0,REGIDX(idx)(k0)
388 LSAVECP0(C0_TLBLO0,34)
389 LSAVECP0(C0_TLBLO1,35)
390 LSAVECP0(C0_CTEXT,36)
391 LSAVECP0(C0_PGMASK,37)
392 LSAVECP0(C0_WIRED,38)
393 LSAVECP0(C0_BADVADDR,39)
394 LSAVECP0(C0_COUNT,40)
395 LSAVECP0(C0_TLBHI,41)
396 LSAVECP0(C0_COMPARE,42)
398 LSAVECP0(C0_CAUSE,44)
401 LSAVECP0(C0_CONFIG,47)
402 LSAVECP0(C0_LLADDR,48)
403 LSAVECP0(C0_WATCHLO,49)
404 LSAVECP0(C0_WATCHHI,50)
405 LSAVECP0(C0_XCTEXT,51)
407 LSAVECP0(C0_CACHEERR,53)
408 LSAVECP0(C0_TAGLO,54)
409 LSAVECP0(C0_TAGHI,55)
410 LSAVECP0(C0_ERREPC,56)
413 move a0,k0 /* pass addr of regs */
416 /*use bottom 1/4 of stack so not to trash top of stack */
417 ADD sp,((CFG_HEAP_SIZE*1024)+(STACK_SIZE/4) - 8)
418 jal vapi_dodumpregs /* dump registers in 'C' */
431 ld $10,REGIDX(10)(k0)
432 ld $11,REGIDX(11)(k0)
433 ld $12,REGIDX(12)(k0)
434 ld $13,REGIDX(13)(k0)
435 ld $14,REGIDX(14)(k0)
436 ld $15,REGIDX(15)(k0)
437 ld $16,REGIDX(16)(k0)
438 ld $17,REGIDX(17)(k0)
439 ld $18,REGIDX(18)(k0)
440 ld $19,REGIDX(19)(k0)
441 ld $20,REGIDX(20)(k0)
442 ld $21,REGIDX(21)(k0)
443 ld $22,REGIDX(22)(k0)
444 ld $23,REGIDX(23)(k0)
445 ld $24,REGIDX(24)(k0)
446 ld $25,REGIDX(25)(k0)
447 /*ld $26,REGIDX(26)(k0) don't restore k0 */
448 ld $27,REGIDX(27)(k0)
449 ld $28,REGIDX(28)(k0)
450 ld $29,REGIDX(29)(k0)
451 ld $30,REGIDX(30)(k0)
452 ld $31,REGIDX(31)(k0)
460 /* *********************************************************************
461 * VAPI_SETLOG(start,end)
463 * Set the address of the log buffer. This call is required
464 * before any data will be stored in the log.
467 * a0 - start of log buffer, 64-bit aligned
468 * a1 - end of log buffer, 64-bit aligned
474 * k0 - scratch register for CFE
475 ********************************************************************* */
479 SAVETEMPS(vapi_regsave)
486 RESTORETEMPS(vapi_regsave)
492 /* *********************************************************************
495 * Store a the contents of the trace buffer to the log
498 * a0 - low 32 bits are the ID code to store with the entry
505 * k0 - scratch register for CFE
506 ********************************************************************* */
515 /* *********************************************************************
516 * VAPI_LOGSINGLE(id,value)
518 * Store a single value in the log.
521 * a0 - low 32 bits are the ID code to store with the entry
523 * a1 - value to store in the log
529 * k0 - scratch register for CFE
530 ********************************************************************* */
535 SAVETEMPS(vapi_regsave)
539 SETRECTYPE(VAPI_FMT_DATA,a0)
542 sd a1,VAPI_REC_DATA(RECPTR)
544 add RECPTR,32 # one record
545 sd RECPTR,vapi_logptr
547 99: RESTORETEMPS(vapi_regsave)
553 /* *********************************************************************
554 * VAPI_LOGDATA(id,addr,cnt)
556 * Store multiple values in the log
559 * a0 - low 32 bits are the ID code to store with the entry
561 * a1 - Address of values to store in the log
562 * a2 - number of 64-bit values to store in the log
568 * k0 - scratch register for CFE
569 ********************************************************************* */
573 SAVETEMPS(vapi_regsave)
577 SETRECTYPE(VAPI_FMT_BUFFER,a0)
579 add t1,RECPTR,VAPI_REC_DATA # a1 = ptr to data ara
584 move k0,a2 # counter for words
594 2: add k0,a2,1 # total number of words
596 sll k0,k0,3 # number of words we wrote
597 add k0,24 # size of header
599 sd RECPTR,vapi_logptr
601 99: RESTORETEMPS(vapi_regsave)
608 /* *********************************************************************
611 * Save the SOC registers in the log
614 * a0 - low 32 bits are the ID code to store with the entry
616 * a1 - bitmask of SOC agents to save
622 * k0 - scratch register for CFE
623 ********************************************************************* */
627 SAVETEMPS(vapi_regsave)
631 li t0,VAPI_CFESEAL | VAPI_FMT_SOC
637 sll t1,t1,VAPI_PRNUM_SHIFT
641 sd t0,VAPI_REC_SIGNATURE(t1)
644 sd t0,VAPI_REC_SIZE(t1)
645 sd ra,VAPI_REC_RA(t1)
647 move a2,zero # Counts how many we write
651 1: lw t0,0(t2) # get flags
653 and t0,t0,a1 # test flags
654 beq t0,zero,3f # skip if no flags set
656 lw t0,4(t2) # get address of register
658 sd t0,VAPI_REC_DATA(t1) # store address of register
659 add t1,8 # next destination addr
660 add a2,1 # count the words written
662 or t0,K1BASE # Make K1seg
663 ld t0,0(t0) # Read SOC register
665 sd t0,VAPI_REC_DATA(t1) # Store in log
666 add t1,8 # next destination addr
667 add a2,1 # count the words written
669 3: add t2,8 # next reg from table
673 2: ld t0,vapi_logptr # get original pointer
674 ld a1,VAPI_REC_SIZE(t0) # Get C0_COUNT value
675 or a1,a2 # OR in the record size
676 sd a1,VAPI_REC_SIZE(t0) # put the record size back
678 add t1,24 # Account for extra fields in record
679 sd t1,vapi_logptr # Update the pointer
681 99: RESTORETEMPS(vapi_regsave)
687 /* *********************************************************************
690 * Save the general purpose registers and certain CP0 values
694 * a0 - low 32 bits are the ID code to store with the entry
701 * k0 - scratch register for CFE
702 ********************************************************************* */
704 #define REGLOG(x) (VAPI_REC_DATA+REGIDX(x))
706 #define REGLOGMAX REGLOG(MAXREGS)
710 SAVETEMPS(vapi_regsave)
725 sd $10,REGLOG(10)(k0)
726 sd $11,REGLOG(11)(k0)
727 sd $12,REGLOG(12)(k0)
728 sd $13,REGLOG(13)(k0)
729 sd $14,REGLOG(14)(k0)
730 sd $15,REGLOG(15)(k0)
731 sd $16,REGLOG(16)(k0)
732 sd $17,REGLOG(17)(k0)
733 sd $18,REGLOG(18)(k0)
734 sd $19,REGLOG(19)(k0)
735 sd $20,REGLOG(20)(k0)
736 sd $21,REGLOG(21)(k0)
737 sd $22,REGLOG(22)(k0)
738 sd $23,REGLOG(23)(k0)
739 sd $24,REGLOG(24)(k0)
740 sd $25,REGLOG(25)(k0)
741 sd $26,REGLOG(26)(k0)
742 sd $27,REGLOG(27)(k0)
743 sd $28,REGLOG(28)(k0)
744 sd $29,REGLOG(29)(k0)
745 sd $30,REGLOG(30)(k0)
746 sd $31,REGLOG(31)(k0)
750 # Save some CP0 registers here.
751 #define SAVECP0(cp0,idx) \
753 sd t0,REGLOG(idx)(k0)
757 SAVECP0(C0_TLBLO0,34)
758 SAVECP0(C0_TLBLO1,35)
760 SAVECP0(C0_PGMASK,37)
762 SAVECP0(C0_BADVADDR,39)
765 SAVECP0(C0_COMPARE,42)
770 SAVECP0(C0_CONFIG,47)
771 SAVECP0(C0_LLADDR,48)
772 SAVECP0(C0_WATCHLO,49)
773 SAVECP0(C0_WATCHHI,50)
774 SAVECP0(C0_XCTEXT,51)
776 SAVECP0(C0_CACHEERR,53)
779 SAVECP0(C0_ERREPC,56)
781 SETRECTYPE(VAPI_FMT_GPRS,a0)
782 SETRECLEN_CONST(MAXREGS)
784 sd RECPTR,vapi_logptr
786 99: RESTORETEMPS(vapi_regsave)
793 /* *********************************************************************
796 * Save the floating point unit's registers
800 * a0 - low 32 bits are the ID code to store with the entry
807 * k0 - scratch register for CFE
808 ********************************************************************* */
811 #define SAVEFPR(cp1,idx) \
813 sd t0,FPREGLOG(idx)(k0)
814 #define SAVECP1(cp1,idx) \
816 sd t0,FPREGLOG(idx)(k0)
818 #define FPREGLOG(x) (VAPI_REC_DATA+REGIDX(x))
820 #define FPREGLOGMAX FPREGLOG(FPMAXREGS)
824 SAVETEMPS(vapi_regsave)
861 SAVECP1($0,32) /* FIR */
862 SAVECP1($31,33) /* Status */
863 SAVECP1($25,34) /* condition codes */
864 SAVECP1($26,35) /* Exceptions */
865 SAVECP1($28,36) /* enables */
867 SETRECTYPE(VAPI_FMT_FPRS,a0)
868 SETRECLEN_CONST(FPMAXREGS)
869 add RECPTR,FPREGLOGMAX
870 sd RECPTR,vapi_logptr
872 99: RESTORETEMPS(vapi_regsave)
878 /* *********************************************************************
881 * Display a string on the console
884 * a0 - pointer to null-terminated string
890 * k0 - scratch register for CFE
891 ********************************************************************* */
907 sd $10,REGIDX(10)(k0)
908 sd $11,REGIDX(11)(k0)
909 sd $12,REGIDX(12)(k0)
910 sd $13,REGIDX(13)(k0)
911 sd $14,REGIDX(14)(k0)
912 sd $15,REGIDX(15)(k0)
913 sd $16,REGIDX(16)(k0)
914 sd $17,REGIDX(17)(k0)
915 sd $18,REGIDX(18)(k0)
916 sd $19,REGIDX(19)(k0)
917 sd $20,REGIDX(20)(k0)
918 sd $21,REGIDX(21)(k0)
919 sd $22,REGIDX(22)(k0)
920 sd $23,REGIDX(23)(k0)
921 sd $24,REGIDX(24)(k0)
922 sd $25,REGIDX(25)(k0)
923 sd $26,REGIDX(26)(k0) /* k0 */
924 sd $27,REGIDX(27)(k0)
925 sd $28,REGIDX(28)(k0)
926 sd $29,REGIDX(29)(k0)
927 sd $30,REGIDX(30)(k0)
928 sd $31,REGIDX(31)(k0)
933 /*use bottom 1/4 of stack so not to trash top of stack */
934 ADD sp,((CFG_HEAP_SIZE*1024)+(STACK_SIZE/4) - 8)
936 jal vapi_doputs /* dump registers in 'C' */
949 ld $10,REGIDX(10)(k0)
950 ld $11,REGIDX(11)(k0)
951 ld $12,REGIDX(12)(k0)
952 ld $13,REGIDX(13)(k0)
953 ld $14,REGIDX(14)(k0)
954 ld $15,REGIDX(15)(k0)
955 ld $16,REGIDX(16)(k0)
956 ld $17,REGIDX(17)(k0)
957 ld $18,REGIDX(18)(k0)
958 ld $19,REGIDX(19)(k0)
959 ld $20,REGIDX(20)(k0)
960 ld $21,REGIDX(21)(k0)
961 ld $22,REGIDX(22)(k0)
962 ld $23,REGIDX(23)(k0)
963 ld $24,REGIDX(24)(k0)
964 ld $25,REGIDX(25)(k0)
965 /*ld $26,REGIDX(26)(k0) don't restore k0 */
966 ld $27,REGIDX(27)(k0)
967 ld $28,REGIDX(28)(k0)
968 ld $29,REGIDX(29)(k0)
969 ld $30,REGIDX(30)(k0)
970 ld $31,REGIDX(31)(k0)
977 /* *********************************************************************
980 * Set the onboard LEDS on the swarm board.
983 * a0 - LED value, "ABCD" is 0x41424344
989 * k0 - scratch register for CFE
990 ********************************************************************* */
995 SAVETEMPS(vapi_regsave)
999 RESTORETEMPS(vapi_regsave)
1005 /* *********************************************************************
1008 * Hack the return address so we will come back in KSEG1 (uncached)
1015 ********************************************************************* */
1017 LEAF(vapi_kseg1_switch)
1023 END(vapi_kseg1_switch)
1026 /* *********************************************************************
1029 * Jump to the diagnostic program, which must be loaded at the
1030 * special address (typically 8002_0000). First we flush the
1031 * cache, then set magic #'s in the mailbox. Finally, the core
1032 * is reset. On restart, we do minimal initialization and jump
1033 * directly to the diagnostic.
1036 * a0 - nonzero to restart uncached.
1040 ********************************************************************* */
1048 bal vapi_kseg1_switch # now running in KSEG1
1054 move s0,a0 # L2 flush trashes A0
1055 CALLKSEG1(sb1250_l1cache_flush_d)
1056 CALLKSEG1(sb1250_l1cache_inval_i)
1057 CALLKSEG1(sb1250_l2cache_flush)
1062 /* In the case of the P5064, just jump directly to the entry point */
1064 li t0,VAPI_DIAG_ENTRY
1070 * Set the magic code in the mailbox.
1074 la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU))
1077 dli t0,VAPI_MAGIC_NUMBER
1079 dli t0,VAPI_MAGIC_NUMBER_UNC
1081 dli t0,VAPI_MAGIC_NUMBER_MC
1082 1: la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU))
1086 * Whack the reset line.
1088 #if defined(_PTSWARM_)
1089 li k0,PHYS_TO_K1(0x1B0A0000+32+8*3)
1091 li k0,PHYS_TO_K1(0x100A0000+32+8*3)
1095 li t1,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
1097 dli t0,M_SYS_CPU_RESET_0 | M_SYS_CPU_RESET_1
1099 bal vapi_kseg0_switch
1101 #if defined(_CSWARM_) || defined(_SWARM_) || defined(_PTSWARM_)
1106 sync /* flush the write buffer */
1111 * And he never returned, no he never returned... and his fate
1112 * is still unknown, he will ride forever 'neath the cycles of
1113 * the SB1, he's the core that never returned!
1122 LEAF(vapi_flushtest)
1130 bal vapi_kseg1_switch # now running in KSEG1
1136 move s0,a0 # L2 flush trashes A0
1137 CALLKSEG1(sb1250_l1cache_flush_d)
1138 CALLKSEG1(sb1250_l1cache_inval_i)
1139 CALLKSEG1(sb1250_l2cache_flush)
1146 bal vapi_kseg0_switch # now running in KSEG1
1154 #endif /* CFG_VAPI */
1156 /* *********************************************************************
1158 ********************************************************************* */