1 /*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
\r
3 Diagnostics Packet Processing Common Routines
\r
6 Core diagnostic packet processing routines that are common to all targets.
\r
8 Copyright (c) 2000-2010 by QUALCOMM, Incorporated. All Rights Reserved.
\r
9 *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
\r
11 /*===========================================================================
\r
15 $Header: //source/qcom/qct/core/pkg/2H09/halcyon_modem/rel/LA2.0/AMSS/products/7x30/core/services/diag/DCM/rtos/src/diagdiag.c#1 $
\r
17 when who what, where, why
\r
18 -------- --- ----------------------------------------------------------
\r
19 07/15/10 sg Moving diagdiag_memop_tbl_mutex to diagdiag_common.c
\r
20 07/10/10 vs Added support for diagpeek/poke registration API.
\r
21 06/22/10 is Changed external flag FEATURE_VOC_TASK into internal flag
\r
23 06/07/10 is Mainlined T_MSM3.
\r
24 06/03/10 sg Added FEATURE_VOC_TASK back
\r
25 05/10/10 JV Fix for compile error when FEATURE_DIAG_DISALLOW_MEM_OPS
\r
27 04/29/10 is Removed functionality for ERR_HAS_NV_LOG_PACKET not defined
\r
28 04/20/10 is Remove support for DIAG_GET_PROPERTY_F, DIAG_PUT_PROPERTY_F,
\r
29 DIAG_GET_PERM_PROPERTY_F, and DIAG_PUT_PERM_PROPERTY_F.
\r
30 03/11/10 sg Cleaning up FEATURE_VOC_TASK feature
\r
31 12/28/09 ps Fixed Klocwork errors & compiler warnings.
\r
32 10/29/09 sg Split file into diagdiag_common and diagdiag.c and moved common
\r
33 functionality to diagdiag_common.c
\r
35 ===========================================================================*/
\r
37 #if defined __cplusplus
\r
43 #include "customer.h"
\r
44 #include "feature.h"
\r
46 #include "diagcmd.h"
\r
48 #include "diagi_v.h"
\r
49 #include "diagdiag_v.h"
\r
50 #include "diagbuf.h" /* For diagbuf_flush */
\r
51 #include "diagtarget.h"
\r
64 #include "diagpkt.h"
\r
68 #define DIAGDIAG_MAX_MEM_OP_TBL_SIZE 5
\r
74 const diagpkt_user_table_entry_type * tbl;
\r
77 }diagdiag_memop_tbl_type;
\r
79 static diagdiag_memop_tbl_type diagdiag_memop_tbl[DIAGDIAG_MAX_MEM_OP_TBL_SIZE];
\r
83 /*==============================================================================
\r
85 FUNCTION diag_register_memory_address_cb
\r
89 This function registers a callback function to be invoked for a certain
\r
90 range of addresses specified in the parameters in the callback
\r
94 ===============================================================================*/
\r
98 diag_register_memory_address_cb (uint32 start, uint32 end,
\r
99 const diagpkt_user_table_entry_type * tbl, int count)
\r
103 boolean ret = FALSE;
\r
105 osal_lock_mutex(&diagdiag_memop_tbl_mutex);
\r
107 for (i=0; i < DIAGDIAG_MAX_MEM_OP_TBL_SIZE; i++ )
\r
109 if (diagdiag_memop_tbl[i].end == 0) {
\r
110 diagdiag_memop_tbl[i].start = start;
\r
111 diagdiag_memop_tbl[i].end = end;
\r
112 diagdiag_memop_tbl[i].tbl = tbl;
\r
113 diagdiag_memop_tbl[i].count = count;
\r
118 osal_unlock_mutex(&diagdiag_memop_tbl_mutex);
\r
125 /*==============================================================================
\r
127 FUNCTION diag_register_memory_address_cb
\r
131 This function registers a callback function to be invoked for a certain
\r
132 range of addresses specified in the parameters in the callback
\r
136 ===============================================================================*/
\r
140 diag_unregister_memory_address_cb (uint32 start, uint32 end,
\r
141 const diagpkt_user_table_entry_type * tbl)
\r
145 boolean ret = FALSE;
\r
147 osal_lock_mutex(&diagdiag_memop_tbl_mutex);
\r
149 for (i=0; i < DIAGDIAG_MAX_MEM_OP_TBL_SIZE; i++ )
\r
151 if ((diagdiag_memop_tbl[i].start == start) &&
\r
152 (diagdiag_memop_tbl[i].end == end) &&
\r
153 (diagdiag_memop_tbl[i].tbl == tbl))
\r
155 diagdiag_memop_tbl[i].start = 0;
\r
156 diagdiag_memop_tbl[i].end = 0;
\r
157 diagdiag_memop_tbl[i].tbl = NULL;
\r
158 diagdiag_memop_tbl[i].count = 0;
\r
164 osal_unlock_mutex(&diagdiag_memop_tbl_mutex);
\r
172 /*===========================================================================
\r
174 FUNCTION DIAGDIAG_PEEKB
\r
177 This procedure processes a received peek byte request. It performs the peek
\r
178 operation and formats a peek response message.
\r
180 ===========================================================================*/
\r
181 PACK(void *) diagdiag_peekb (
\r
182 PACK(void *) req_pkt,
\r
186 DIAG_PEEKB_F_req_type *req = (DIAG_PEEKB_F_req_type *) req_pkt;
\r
187 DIAG_PEEKB_F_rsp_type *rsp;
\r
188 const int rsp_len = sizeof(DIAG_PEEKB_F_rsp_type);
\r
191 PACK(byte *) src = NULL;
\r
192 PACK(byte *) dest = NULL;
\r
194 count = req->length;
\r
195 src = (byte *) req->ptr;
\r
197 /*-------------------------------------------------------------------------
\r
198 Check security, since this is a secure funciton
\r
199 --------------------------------------------------------------------------*/
\r
200 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
201 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
204 /*-------------------------------------------------------------------------
\r
205 Check memory peek length against max allowable length.
\r
206 --------------------------------------------------------------------------*/
\r
207 if (count > DIAG_MAX_PEEK_B) {
\r
208 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
212 /*-------------------------------------------------------------------------
\r
213 Check to see if block requested is within a valid range
\r
214 --------------------------------------------------------------------------*/
\r
215 if (!hw_valid_addr ((void *) src, count) ) {
\r
216 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
220 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
221 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
222 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
223 for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {
\r
224 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKB_F) &&
\r
225 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKB_F)) {
\r
226 rsp = (DIAG_PEEKB_F_rsp_type *)
\r
227 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
237 /* Allocate space for response packet */
\r
238 rsp = (DIAG_PEEKB_F_rsp_type *)diagpkt_alloc(DIAG_PEEKB_F, rsp_len);
\r
241 dest = &rsp->data[0];
\r
243 /*--------------------------------------------------------------------------
\r
244 Fill in the boilerplate for the response.
\r
245 --------------------------------------------------------------------------*/
\r
246 rsp->ptr = (byte *) src;
\r
247 rsp->length = count;
\r
251 /*----------------------------------------------------------------------
\r
252 Lock out interrupts to preserve consistency of the memory block. */
\r
254 osal_disable_interrupts();
\r
256 for (i = 0; i < count; i++) {
\r
262 osal_enable_interrupts();
\r
268 } /* diagdiag_peekb */
\r
272 /*===========================================================================
\r
274 FUNCTION DIAGDIAG_PEEKW
\r
277 This procedure processes a received peek word request. It performs the peek
\r
278 operation and formats a peek response message.
\r
280 ===========================================================================*/
\r
281 PACK(void *) diagdiag_peekw (
\r
282 PACK(void *) req_pkt,
\r
286 DIAG_PEEKW_F_req_type *req =(DIAG_PEEKW_F_req_type *)req_pkt;
\r
287 DIAG_PEEKW_F_rsp_type *rsp;
\r
288 const int rsp_len = sizeof(DIAG_PEEKW_F_rsp_type);
\r
291 PACK(word *) src = NULL;
\r
292 PACK(word *) dest = NULL;
\r
294 word * src_w; /* Unpacked word pointer */
\r
295 word val_w; /* Result of peek */
\r
297 count = req->length;
\r
298 src = (word *) req->ptr;
\r
300 /*-------------------------------------------------------------------------
\r
301 Check security, since this is a secure funciton
\r
302 --------------------------------------------------------------------------*/
\r
303 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
304 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
307 /*-------------------------------------------------------------------------
\r
308 Check block length against max allowed length.
\r
309 -------------------------------------------------------------------------*/
\r
310 if (count > DIAG_MAX_PEEK_W) {
\r
311 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
315 /*-------------------------------------------------------------------------
\r
316 Check to see that the block requested is within a valid range.
\r
317 --------------------------------------------------------------------------*/
\r
318 if (!hw_valid_addr ((void *) src, (word)(count * sizeof (word)))) {
\r
319 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
322 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
323 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
324 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
325 for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {
\r
326 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKW_F) &&
\r
327 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKW_F)) {
\r
328 rsp = (DIAG_PEEKW_F_rsp_type *)
\r
329 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
340 /* Allocate space for response packet */
\r
341 rsp = (DIAG_PEEKW_F_rsp_type *)diagpkt_alloc(DIAG_PEEKW_F, rsp_len);
\r
344 dest = &rsp->data[0];
\r
346 /*--------------------------------------------------------------------------
\r
347 Fill in the boilerplate for the response.
\r
348 --------------------------------------------------------------------------*/
\r
349 rsp->ptr = (word *) src;
\r
350 rsp->length = count;
\r
352 /* Test for alignment. If source address is word aligned, use
\r
353 non-packed word transfers. */
\r
354 if (((dword)src & 0x1) == 0x00)
\r
356 /* Copy packed pointer to non-packed pointer */
\r
357 src_w = (word*)src;
\r
359 /*----------------------------------------------------------------------
\r
360 Lock out interrupts to preserve consistency of the memory block.
\r
361 ----------------------------------------------------------------------*/
\r
363 osal_disable_interrupts();
\r
365 for (i = 0; i < count; i++) {
\r
372 osal_enable_interrupts();
\r
375 else /* Copy with packed variables */
\r
377 /*----------------------------------------------------------------------
\r
378 Lock out interrupts to preserve consistency of the memory block.
\r
379 ----------------------------------------------------------------------*/
\r
381 osal_disable_interrupts();
\r
383 for (i = 0; i < count; i++) {
\r
389 osal_enable_interrupts();
\r
396 } /* diagdiag_peekw */
\r
400 /*===========================================================================
\r
402 FUNCTION DIAGDIAG_PEEKD
\r
405 This procedure processes a received peek dword request. It performs the peek
\r
406 operation and formats a peek response message.
\r
408 ===========================================================================*/
\r
409 PACK(void *) diagdiag_peekd (
\r
410 PACK(void *) req_pkt,
\r
414 DIAG_PEEKD_F_req_type *req = (DIAG_PEEKD_F_req_type *)req_pkt;
\r
415 DIAG_PEEKD_F_rsp_type *rsp;
\r
416 const int rsp_len = sizeof(DIAG_PEEKD_F_rsp_type);
\r
419 PACK(dword *) src = NULL;
\r
420 PACK(dword *) dest = NULL;
\r
422 dword * src_dw; /* Unpacked word pointer */
\r
423 dword val_dw; /* Result of peek */
\r
425 count = req->length;
\r
426 src = (dword *) req->ptr;
\r
428 /*--------------------------------------------------------------------------
\r
429 Check security, since this is a secure funciton
\r
430 --------------------------------------------------------------------------*/
\r
431 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
432 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
435 /*--------------------------------------------------------------------------
\r
436 Check requested length against max allowable length.
\r
437 --------------------------------------------------------------------------*/
\r
438 if (count > DIAG_MAX_PEEK_D) {
\r
439 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
443 /*-------------------------------------------------------------------------
\r
444 Check to see that the block requested is within a valid range.
\r
445 --------------------------------------------------------------------------*/
\r
446 if (!hw_valid_addr ((void *) src, (word)(count * sizeof(dword)))) {
\r
447 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
450 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
451 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
452 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
453 for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {
\r
454 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKD_F) &&
\r
455 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKD_F)) {
\r
456 rsp = (DIAG_PEEKD_F_rsp_type *)
\r
457 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
468 /* Allocate space for response packet */
\r
469 rsp = (DIAG_PEEKD_F_rsp_type *)diagpkt_alloc(DIAG_PEEKD_F, rsp_len);
\r
472 dest = &rsp->data[0];
\r
474 /*--------------------------------------------------------------------------
\r
475 Fill in the boilerplate for the response.
\r
476 --------------------------------------------------------------------------*/
\r
477 rsp->ptr = (dword *) src;
\r
478 rsp->length = count;
\r
481 /* Test for alignment. If source address is dword aligned, use
\r
482 non-packed dword transfers. */
\r
483 if (((dword)src & 0x3) == 0x00)
\r
485 /* Copy packed pointer to non-packed pointer */
\r
486 src_dw = (dword*)src;
\r
488 /*----------------------------------------------------------------------
\r
489 Lock out interrupts to preserve consistency of the memory block.
\r
490 ----------------------------------------------------------------------*/
\r
492 osal_disable_interrupts();
\r
494 for (i = 0; i < count; i++) {
\r
501 osal_enable_interrupts();
\r
504 else /* Copy with packed variables */
\r
506 /*----------------------------------------------------------------------
\r
507 Lock out interrupts to preserve consistency of the memory block.
\r
508 ----------------------------------------------------------------------*/
\r
510 osal_disable_interrupts();
\r
512 for (i = 0; i < count; i++) {
\r
518 osal_enable_interrupts();
\r
525 } /* diagdiag_peekd */
\r
529 /*===========================================================================
\r
531 FUNCTION DIAGDIAG_POKEB
\r
534 This procedure pokes a byte into memory and formats a poke response
\r
537 ===========================================================================*/
\r
538 PACK(void *) diagdiag_pokeb (
\r
539 PACK(void *) req_pkt,
\r
543 DIAG_POKEB_F_req_type *req = (DIAG_POKEB_F_req_type *)req_pkt;
\r
544 DIAG_POKEB_F_rsp_type *rsp;
\r
545 const int rsp_len = sizeof(DIAG_POKEB_F_rsp_type);
\r
548 PACK(byte *) src = NULL;
\r
549 PACK(byte *) dest = NULL;
\r
551 count = req->length;
\r
552 src = &req->data[0];
\r
555 /*----------------------------------------------------------------------
\r
556 Check length of request packet.
\r
557 ----------------------------------------------------------------------*/
\r
558 if (pkt_len != sizeof (DIAG_POKEB_F_req_type))
\r
560 return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));
\r
563 /*----------------------------------------------------------------------
\r
564 Check security, since this is a secure funciton
\r
565 ----------------------------------------------------------------------*/
\r
566 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
567 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
570 /*----------------------------------------------------------------------
\r
571 Check block size against maximum allowable block size.
\r
572 ----------------------------------------------------------------------*/
\r
573 if (count > DIAG_MAX_POKE_B) {
\r
574 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
578 /*---------------------------------------------------------------------
\r
579 Check to see if address requested is within a valid range.
\r
580 ----------------------------------------------------------------------*/
\r
581 else if (!hw_valid_addr ((void *) dest, count * sizeof (byte))) {
\r
582 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
585 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
586 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
587 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
588 for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {
\r
589 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKEB_F) &&
\r
590 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKEB_F)) {
\r
591 rsp = (DIAG_POKEB_F_rsp_type *)
\r
592 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
602 /*----------------------------------------------------------------------
\r
603 Lock out interrupts to preserve consistency of the memory block.
\r
604 ----------------------------------------------------------------------*/
\r
606 osal_disable_interrupts();
\r
609 for (i = 0; i < count; i++) {
\r
615 osal_enable_interrupts();
\r
619 /*-------------------------------------------------------------------------
\r
620 Prepare the response packet.
\r
621 -------------------------------------------------------------------------*/
\r
622 rsp = (DIAG_POKEB_F_rsp_type *)diagpkt_alloc(DIAG_POKEB_F, rsp_len);
\r
631 } /* diagdiag_pokeb */
\r
634 /*===========================================================================
\r
636 FUNCTION DIAGDIAG_POKEW
\r
639 This procedure pokes a word into memory and formats a poke response
\r
642 ===========================================================================*/
\r
643 PACK(void *) diagdiag_pokew (
\r
644 PACK(void *) req_pkt,
\r
648 DIAG_POKEW_F_req_type *req = (DIAG_POKEW_F_req_type *)req_pkt;
\r
649 DIAG_POKEW_F_rsp_type *rsp;
\r
650 const int rsp_len = sizeof(DIAG_POKEW_F_rsp_type);
\r
653 PACK(word *) src = NULL;
\r
654 PACK(word *) dest = NULL;
\r
656 word * dest_w; /* Unpacked word pointer */
\r
657 word val_w; /* Value to poke */
\r
659 count = req->length;
\r
660 src = &req->data[0];
\r
663 /*----------------------------------------------------------------------
\r
664 Check length of request packet. This is critical since the download
\r
665 protocol used by QPST uses HDLC encoded packets with the equivalent
\r
666 of command code 6. Length check is the only thing that prevents
\r
668 ----------------------------------------------------------------------*/
\r
669 if (pkt_len != sizeof (DIAG_POKEW_F_req_type))
\r
671 return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));
\r
674 /*----------------------------------------------------------------------
\r
675 Check security, since this is a secure funciton
\r
676 ----------------------------------------------------------------------*/
\r
677 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
678 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
681 /*----------------------------------------------------------------------
\r
682 Check block length against maximum allowable length.
\r
683 ----------------------------------------------------------------------*/
\r
684 if (count > DIAG_MAX_POKE_W) {
\r
685 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
689 /*----------------------------------------------------------------------
\r
690 Check to be sure the block is a valid block.
\r
691 ----------------------------------------------------------------------*/
\r
692 if (!hw_valid_addr ((void *) dest, (word)(count * sizeof (word)))) {
\r
693 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
696 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
697 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
698 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
699 for (j = 0; j < diagdiag_memop_tbl[i].count; j++) {
\r
700 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKEW_F) &&
\r
701 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKEW_F)) {
\r
702 rsp = (DIAG_POKEW_F_rsp_type *)
\r
703 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
715 /* Test for alignment. If destination address is word aligned, use
\r
716 non-packed word transfers. */
\r
717 if (((dword)dest & 0x01) == 0x00)
\r
719 /* Copy packed pointer to non-packed pointer */
\r
720 dest_w = (word*)dest;
\r
722 /*----------------------------------------------------------------------
\r
723 Lock out interrupts to preserve consistency of the memory block.
\r
724 ----------------------------------------------------------------------*/
\r
726 osal_disable_interrupts();
\r
728 for (i = 0; i < count; i++) {
\r
735 osal_enable_interrupts();
\r
738 else /* Copy with packed variables */
\r
740 /*----------------------------------------------------------------------
\r
741 Lock out interrupts to preserve consistency of the memory block.
\r
742 ----------------------------------------------------------------------*/
\r
744 osal_disable_interrupts();
\r
746 for (i = 0; i < count; i++) {
\r
752 osal_enable_interrupts();
\r
757 /*----------------------------------------------------------------------
\r
758 Prepare the response packet.
\r
759 ----------------------------------------------------------------------*/
\r
760 rsp = (DIAG_POKEW_F_rsp_type *)diagpkt_alloc(DIAG_POKEW_F, rsp_len);
\r
769 } /* diagdiag_pokew */
\r
773 /*===========================================================================
\r
775 FUNCTION DIAGDIAG_POKED
\r
778 This procedure pokes a dword into memory and formats a poke response
\r
781 ===========================================================================*/
\r
782 PACK(void *) diagdiag_poked (
\r
783 PACK(void *) req_pkt,
\r
787 DIAG_POKED_F_req_type *req = (DIAG_POKED_F_req_type *)req_pkt;
\r
788 DIAG_POKED_F_rsp_type *rsp;
\r
789 const int rsp_len = sizeof(DIAG_POKED_F_rsp_type);
\r
792 PACK(dword *) src = NULL;
\r
793 PACK(dword *) dest = NULL;
\r
795 dword * dest_dw; /* Unpacked dword pointer */
\r
796 dword val_dw; /* Value to poke */
\r
799 count = req->length;
\r
800 src = &req->data[0];
\r
803 /*----------------------------------------------------------------------
\r
804 Check length of request packet.
\r
805 ----------------------------------------------------------------------*/
\r
806 if (pkt_len != sizeof (DIAG_POKED_F_req_type))
\r
808 return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));
\r
811 /*----------------------------------------------------------------------
\r
812 Check security, since this is a secure funciton
\r
813 ----------------------------------------------------------------------*/
\r
814 if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
\r
815 return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
\r
818 /*----------------------------------------------------------------------
\r
819 Check block length against maximum allowed length.
\r
820 ----------------------------------------------------------------------*/
\r
821 if (count > DIAG_MAX_POKE_D) {
\r
822 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
826 /*----------------------------------------------------------------------
\r
827 Check to see that requested block is a valid block.
\r
828 ----------------------------------------------------------------------*/
\r
829 if (!hw_valid_addr ((void *) dest, (word)(count * sizeof (dword))) ) {
\r
830 return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
\r
834 for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {
\r
835 if ( (diagdiag_memop_tbl[i].start <= (uint32)src) &&
\r
836 (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {
\r
837 for (j = 0; j < diagdiag_memop_tbl[i].count; j++) {
\r
838 if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKED_F) &&
\r
839 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKED_F)) {
\r
840 rsp = (DIAG_POKED_F_rsp_type *)
\r
841 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);
\r
852 /* Test for alignment. If destination address is dword aligned, use
\r
853 non-packed dword transfers. */
\r
854 if (((dword)dest & 0x03) == 0x00)
\r
856 /* Copy packed pointer to non-packed pointer */
\r
857 dest_dw = (dword*)dest;
\r
859 /*----------------------------------------------------------------------
\r
860 Lock out interrupts to preserve consistency of the memory block.
\r
861 ----------------------------------------------------------------------*/
\r
863 osal_disable_interrupts();
\r
866 for (i = 0; i < count; i++) {
\r
873 osal_enable_interrupts();
\r
876 else /* Copy with packed variables */
\r
879 /*----------------------------------------------------------------------
\r
880 Lock out interrupts to preserve consistency of the memory block. */
\r
882 osal_disable_interrupts();
\r
884 for (i = 0; i < count; i++) {
\r
890 osal_enable_interrupts();
\r
894 /*-----------------------------------------------------------------------
\r
895 Prepare the response packet.
\r
896 -----------------------------------------------------------------------*/
\r
897 rsp = (DIAG_POKED_F_rsp_type *)diagpkt_alloc(DIAG_POKED_F, rsp_len);
\r
906 } /* diagdiag_poked */
\r
911 /*===========================================================================
\r
913 FUNCTION DIAGDIAG_VER
\r
916 Return the diag version
\r
918 ===========================================================================*/
\r
919 PACK(void *) diagdiag_ver (
\r
920 PACK(void *) req_pkt,
\r
924 DIAG_DIAG_VER_F_rsp_type *rsp;
\r
925 const int rsp_len = sizeof (DIAG_DIAG_VER_F_rsp_type);
\r
927 (void) req_pkt; /* suppress compiler warning */
\r
928 (void) pkt_len; /* suppress compiler warning */
\r
930 rsp = (DIAG_DIAG_VER_F_rsp_type *)diagpkt_alloc(DIAG_DIAG_VER_F, rsp_len);
\r
932 /*-------------------------------------------------------------------------
\r
933 Return diag source code version
\r
934 -------------------------------------------------------------------------*/
\r
937 rsp->ver = DIAG_DIAGVER;
\r
941 } /* diagdiag_diag_ver */
\r
945 /*===========================================================================
\r
947 FUNCTION DIAGDIAG_FEATURE_QUERY
\r
950 This procedure processes a request to query for features in the current
\r
951 build. It returns a variable length bit mask where each bit corresponds to
\r
952 a particular feature defined in diagpkt.h in feature_query_enum_type.
\r
954 ============================================================================*/
\r
955 PACK(void *) diagdiag_feature_query (
\r
956 PACK(void *) req_pkt,
\r
961 DIAG_FEATURE_QUERY_F_rsp_type *rsp;
\r
962 const int rsp_len = sizeof(DIAG_FEATURE_QUERY_F_rsp_type);
\r
964 (void) req_pkt; /* suppress compiler warning */
\r
965 (void) pkt_len; /* suppress compiler warning */
\r
967 rsp =(DIAG_FEATURE_QUERY_F_rsp_type *)diagpkt_alloc(DIAG_FEATURE_QUERY_F, rsp_len);
\r
970 rsp->feature_mask_size = FEATURE_MASK_LENGTH;
\r
972 /* Copy the current mask into the diag pkt */
\r
973 memcpy( (void *) rsp->feature_mask,
\r
975 FEATURE_MASK_LENGTH
\r
978 /* return the size of the variable length packet. command_code and
\r
979 ** feature_mask_size is constant. FEATURE_MASK_LENGTH changes
\r
980 ** as more features are added
\r
985 } /* diagdiag_feature_query */
\r
989 /*===========================================================================
\r
991 FUNCTION DIAGDIAG_PASSWORD
\r
994 Processes an entry of the Security Password.
\r
995 This function compares the password in the phone to what was sent in
\r
996 the packet. If they are the same, the successful Security unlock is
\r
997 noted (setting the diag_get_security_state() mask to UNLOCKED), and a value of TRUE
\r
998 is returned to the external device.
\r
999 If they are NOT the same, Security remains locked, a value of FALSE is
\r
1000 returned to the external device, and the phone is powered off,
\r
1004 May cause the phone to power off! (After returning from this routine).
\r
1006 ===========================================================================*/
\r
1007 PACK(void *) diagdiag_password (
\r
1008 PACK(void *) req_pkt,
\r
1012 DIAG_PASSWORD_F_req_type *req = (DIAG_PASSWORD_F_req_type *) req_pkt;
\r
1013 DIAG_PASSWORD_F_rsp_type *rsp;
\r
1014 const int rsp_len = sizeof(DIAG_PASSWORD_F_rsp_type);
\r
1015 (void) pkt_len; /* suppress compiler warning */
\r
1017 rsp = (DIAG_PASSWORD_F_rsp_type *) diagpkt_alloc (DIAG_PASSWORD_F, rsp_len);
\r
1019 /*------------------------------------------------------------------------*/
\r
1021 MSG_LOW ("Security Password given", 0, 0, 0);
\r
1023 /* If the security is already unlocked, then it doesn't matter what
\r
1024 ** you give as the security code. Otherwise we need to compare
\r
1025 ** the given security code with the one in the phone.
\r
1029 if ((diag_get_security_state() == DIAG_SEC_UNLOCKED) ||
\r
1030 (diag_check_password((void *) req->password))) {
\r
1032 rsp->password_ok = TRUE;
\r
1033 (void) diag_set_security_state(DIAG_SEC_UNLOCKED);
\r
1035 /* Otherwise, the code was incorrect. Diag will now powerdown the phone.
\r
1038 rsp->password_ok = FALSE;
\r
1039 (void) diag_set_security_state(DIAG_SEC_LOCKED);
\r
1041 diagpkt_commit(rsp);
\r
1044 /* Flush DIAG's TX buffer */
\r
1047 /* Power down the phone. This function does not return.
\r
1054 } /* diagdiag_password */
\r
1058 /*===========================================================================
\r
1059 FUNCTION DIAGDIAG_TS
\r
1062 Return an IS-95/IS-2000 timestamp
\r
1068 Pointer to response packet.
\r
1072 ===========================================================================*/
\r
1073 PACK(void *) diagdiag_ts (
\r
1074 PACK(void *) req_pkt,
\r
1078 qword ts_time; /* time stamp */
\r
1079 DIAG_TS_F_rsp_type *rsp;
\r
1080 const int rsp_len = sizeof( DIAG_TS_F_rsp_type );
\r
1082 (void) req_pkt; /* suppress compiler warning */
\r
1083 (void) pkt_len; /* suppress compiler warning */
\r
1085 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
\r
1086 /*------------------------------------------------------------------------
\r
1087 Get the time, stuff the packet.
\r
1088 -------------------------------------------------------------------------*/
\r
1093 rsp = (DIAG_TS_F_rsp_type *) diagpkt_alloc (DIAG_TS_F, rsp_len);
\r
1095 qw_equ_misaligned (rsp->ts, ts_time);
\r
1099 } /* diagdiag_ts */
\r
1104 #define MSM_MEMMAP_IO_OFFSET 0x03000000
\r
1106 /*===========================================================================
\r
1108 FUNCTION DIAGDIAG_OUTP
\r
1111 This procedure processes a received command to write a byte to a port.
\r
1112 The byte is written to the input port and a response packet is built.
\r
1118 Pointer to response packet.
\r
1123 ===========================================================================*/
\r
1124 PACK(void *) diagdiag_outp (
\r
1125 PACK(void *) req_pkt,
\r
1129 DIAG_OUTP_F_rsp_type *rsp;
\r
1130 const int rsp_len = sizeof( DIAG_OUTP_F_rsp_type );
\r
1131 DIAG_OUTP_F_req_type *req = (DIAG_OUTP_F_req_type *) req_pkt;
\r
1133 /*----------------------------------------------------------------------
\r
1134 Check security, since this is a secure function
\r
1135 ----------------------------------------------------------------------*/
\r
1136 if (diag_get_security_state() == DIAG_SEC_LOCKED) {
\r
1137 rsp = (DIAG_OUTP_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );
\r
1141 /*----------------------------------------------------------------------
\r
1142 Write byte to port
\r
1143 ----------------------------------------------------------------------*/
\r
1144 (void) outp( req->port + MSM_MEMMAP_IO_OFFSET, req->data );
\r
1146 /*-----------------------------------------------------------------------
\r
1147 Prepare the response packet.
\r
1148 -----------------------------------------------------------------------*/
\r
1149 /* Allocate space for rsponse packet */
\r
1150 rsp = (DIAG_OUTP_F_rsp_type *)diagpkt_alloc( DIAG_OUTP_F, rsp_len );
\r
1154 rsp->port = req->port;
\r
1155 rsp->data = req->data;
\r
1160 } /* diagdiag_outp */
\r
1164 /*===========================================================================
\r
1166 FUNCTION DIAGDIAG_OUTPW
\r
1169 This procedure processes a received command to write a word to a port.
\r
1170 The word is written to the input port and a response packet is built.
\r
1176 Pointer to response packet.
\r
1181 ===========================================================================*/
\r
1182 PACK(void *) diagdiag_outpw (
\r
1183 PACK(void *) req_pkt,
\r
1187 DIAG_OUTPW_F_rsp_type *rsp;
\r
1188 const int rsp_len = sizeof( DIAG_OUTPW_F_rsp_type );
\r
1189 DIAG_OUTPW_F_req_type *req = (DIAG_OUTPW_F_req_type *) req_pkt;
\r
1191 /*----------------------------------------------------------------------
\r
1192 Check security, since this is a secure funciton
\r
1193 ----------------------------------------------------------------------*/
\r
1194 if (diag_get_security_state() == DIAG_SEC_LOCKED) {
\r
1195 rsp = (DIAG_OUTPW_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );
\r
1199 /*----------------------------------------------------------------------
\r
1200 Write word to port
\r
1201 ----------------------------------------------------------------------*/
\r
1202 (void) outpw( req->port+ MSM_MEMMAP_IO_OFFSET, req->data );
\r
1204 /*-----------------------------------------------------------------------
\r
1205 Prepare the response packet.
\r
1206 -----------------------------------------------------------------------*/
\r
1207 /* Allocate space for rsponse packet */
\r
1208 rsp = (DIAG_OUTPW_F_rsp_type *)diagpkt_alloc( DIAG_OUTPW_F, rsp_len );
\r
1212 rsp->port = req->port;
\r
1213 rsp->data = req->data;
\r
1218 } /* diagdiag_outpw */
\r
1222 /*===========================================================================
\r
1224 FUNCTION DIAGDIAG_INP
\r
1227 This procedure processes a received command to read a byte from a port.
\r
1228 The byte is read from the port and a response packet is built.
\r
1234 Pointer to response packet.
\r
1239 ===========================================================================*/
\r
1240 PACK(void *) diagdiag_inp (
\r
1241 PACK(void *) req_pkt,
\r
1245 DIAG_INP_F_rsp_type *rsp;
\r
1246 const int rsp_len = sizeof( DIAG_INP_F_rsp_type );
\r
1247 DIAG_INP_F_req_type *req = (DIAG_INP_F_req_type *) req_pkt;
\r
1249 /*----------------------------------------------------------------------
\r
1250 Check security, since this is a secure funciton
\r
1251 ----------------------------------------------------------------------*/
\r
1252 if (diag_get_security_state() == DIAG_SEC_LOCKED) {
\r
1253 rsp = ( DIAG_INP_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );
\r
1257 /* Allocate space for rsponse packet */
\r
1258 rsp = (DIAG_INP_F_rsp_type *)diagpkt_alloc( DIAG_INP_F, rsp_len );
\r
1260 /*------------------------------------------------------------------------
\r
1261 Fill in the boilerplate for the response packet, then read the byte in
\r
1263 ------------------------------------------------------------------------*/
\r
1266 rsp->port = req->port;
\r
1267 rsp->data = (byte) inp( req->port + MSM_MEMMAP_IO_OFFSET );
\r
1271 } /* diagdiag_inp */
\r
1275 /*===========================================================================
\r
1277 FUNCTION DIAGDIAG_INPW
\r
1280 This procedure processes a received command to read a word from a port.
\r
1281 The word is read from the port and a response packet is built.
\r
1287 Pointer to response packet.
\r
1292 ===========================================================================*/
\r
1293 PACK(void *) diagdiag_inpw (
\r
1294 PACK(void *) req_pkt,
\r
1298 DIAG_INPW_F_rsp_type *rsp;
\r
1299 const int rsp_len = sizeof( DIAG_INPW_F_rsp_type );
\r
1300 DIAG_INPW_F_req_type *req = (DIAG_INPW_F_req_type *) req_pkt;
\r
1302 /*----------------------------------------------------------------------
\r
1303 Check security, since this is a secure funciton
\r
1304 ----------------------------------------------------------------------*/
\r
1305 if (diag_get_security_state() == DIAG_SEC_LOCKED) {
\r
1306 rsp = (DIAG_INPW_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );
\r
1310 /* Allocate space for rsponse packet */
\r
1311 rsp = (DIAG_INPW_F_rsp_type *)diagpkt_alloc( DIAG_INPW_F, rsp_len );
\r
1313 /*------------------------------------------------------------------------
\r
1314 Fill in the boilerplate for the response, then input the word directly
\r
1315 into the response packet.
\r
1316 -------------------------------------------------------------------------*/
\r
1319 rsp->port = req->port;
\r
1320 rsp->data = inpw( req->port + MSM_MEMMAP_IO_OFFSET );
\r
1324 } /* diagdiag_inpw */
\r
1326 #if 1 //For now, use a fake GUID. -LD
\r
1327 /* Default GUID (since it was unspecified) */
\r
1328 static const diag_guid_type diag_guid =
\r
1338 LOCAL diag_prop_struct_type diag_prop_table[DIAG_MAX_NUM_PROPS];
\r
1340 /*===========================================================================
\r
1342 FUNCTION DIAG_LOOKUP_PROP
\r
1345 Looks up the address of a callback function given its name.
\r
1351 The address of the function or NULL if the function is not found in the
\r
1357 ===========================================================================*/
\r
1358 void *diag_lookup_prop
\r
1365 if ( prop_name == NULL )
\r
1367 return (void *) NULL;
\r
1370 while ( diag_prop_table[ i ].name != NULL )
\r
1373 diag_prop_table[ i ].name,
\r
1375 DIAG_MAX_PROPERTY_NAME_SIZE
\r
1378 return diag_prop_table[ i ].address;
\r
1381 if ( i >= DIAG_MAX_NUM_PROPS )
\r
1384 ** Will get here only if the properties table has been corrupted.
\r
1389 return (void *) NULL;
\r
1390 } /* diag_lookup_prop */
\r
1394 /*===========================================================================
\r
1396 FUNCTION DIAG_GUID_IS_VALID
\r
1399 This static function returns true or false depending on whether the
\r
1400 input guid (globally unique identifier) matches that of the current build.
\r
1406 TRUE if the input guid is valid, FALSE otherwise.
\r
1411 ===========================================================================*/
\r
1412 LOCAL boolean diag_guid_is_valid
\r
1414 diag_guid_type guid
\r
1417 if ( ( guid[ 0 ] == diag_guid[ 0 ] ) &&
\r
1418 ( guid[ 1 ] == diag_guid[ 1 ] ) &&
\r
1419 ( guid[ 2 ] == diag_guid[ 2 ] ) &&
\r
1420 ( guid[ 3 ] == diag_guid[ 3 ] ) )
\r
1428 } /* diag_guid_is_valid */
\r
1431 /*===========================================================================
\r
1433 FUNCTION DIAGDIAG_GET_GUID
\r
1436 This procedure processes a get_guid request. The GUID (globally unique
\r
1437 identifier) for this build is retrieved and returned in the response
\r
1438 packet. The GUID is stored during the build process.
\r
1440 ===========================================================================*/
\r
1441 PACK(void *) diagdiag_get_guid
\r
1443 PACK(void *) req_pkt, /* pointer to request packet */
\r
1444 uint16 pkt_len /* length of request packet */
\r
1447 DIAG_GET_GUID_F_rsp_type *rsp;
\r
1448 const unsigned int rsp_len = sizeof (DIAG_GET_GUID_F_rsp_type);
\r
1450 (void) req_pkt; /* suppress compiler warning */
\r
1451 (void) pkt_len; /* suppress compiler warning */
\r
1453 /*--------------------------------------------
\r
1454 Allocate buffer space for response packet.
\r
1455 --------------------------------------------*/
\r
1456 rsp = (DIAG_GET_GUID_F_rsp_type *) diagpkt_alloc (DIAG_GET_GUID_F, rsp_len);
\r
1458 memcpy((void *) &rsp->guid[0],
\r
1459 (const void *) &diag_guid[0],
\r
1460 sizeof(diag_guid_type));
\r
1464 } /* diagdiag_get_guid */
\r
1468 /*===========================================================================
\r
1469 FUNCTION DIAGDIAG_EVENT_LISTENER
\r
1471 DESCRIPTION The event has been removed from listening
\r
1472 ============================================================================*/
\r
1474 diagdiag_event_listener (uint32 seq_num, const diag_event_type * event, void * param)
\r
1476 MSG_3 (MSG_SSID_DIAG, MSG_LEGACY_HIGH,
\r
1477 "Event listener 0x%04X param:0x%08X seq:%d",
\r
1478 event->event_id, (uint32) param, seq_num);
\r
1481 /*===========================================================================
\r
1482 FUNCTION DIAGDIAG_LOG_LISTENER
\r
1484 DESCRIPTION The log has been added to listen
\r
1485 ============================================================================*/
\r
1487 diagdiag_log_listener (uint32 seq_num, const byte * log, unsigned int length,
\r
1490 MSG_3 (MSG_SSID_DIAG, MSG_LEGACY_HIGH,
\r
1491 "Log listener 0x%04X param:0x%08X seq:%d",
\r
1492 log_get_code ((PACK(void *)) log), (uint32) param, seq_num);
\r
1496 /*===========================================================================
\r
1497 FUNCTION DIAGDIAG_LISTENER_PKT
\r
1500 This procedure tests the following:
\r
1501 1) Add log listener
\r
1502 2) Remove log listener
\r
1503 3) Add event listener
\r
1504 4) Remove event listener
\r
1507 Pointer to response packet.
\r
1509 ============================================================================*/
\r
1511 diagdiag_listener_pkt (PACK(void *) req_pkt, uint16 pkt_len)
\r
1513 diag_log_event_listener_rsp_type *rsp;
\r
1514 diag_log_event_listener_req_type *req =
\r
1515 (diag_log_event_listener_req_type *) req_pkt;
\r
1517 diagpkt_subsys_cmd_code_type cmd_code = diagpkt_subsys_get_cmd_code (req);
\r
1519 const int rsp_len = pkt_len;
\r
1521 /* Allocate the same length as the request */
\r
1522 rsp = (diag_log_event_listener_rsp_type *)
\r
1523 diagpkt_subsys_alloc (DIAG_SUBSYS_DIAG_SERV, cmd_code, rsp_len);
\r
1525 /* Send the response acknowledging that the packet has been started */
\r
1528 memcpy ((void *) rsp, (void *) req, rsp_len);
\r
1532 case DIAGDIAG_ADD_EVENT_LISTENER_F:
\r
1533 (void) diag_add_event_listener (req->id, diagdiag_event_listener, (void *) req->param);
\r
1535 case DIAGDIAG_REMOVE_EVENT_LISTENER_F:
\r
1536 (void) diag_remove_event_listener (req->id, diagdiag_event_listener, (void *) req->param);
\r
1538 case DIAGDIAG_ADD_LOG_LISTENER_F:
\r
1539 (void) diag_add_log_listener (req->id, diagdiag_log_listener, (void *) req->param);
\r
1541 case DIAGDIAG_REMOVE_LOG_LISTENER_F:
\r
1542 (void) diag_remove_log_listener (req->id, diagdiag_log_listener, (void *) req->param);
\r
1551 } /* diagdiag_cmd_request_handler */
\r
1553 #ifdef FEATURE_TECHNICS_DIAG
\r
1554 #include "mobile.h"
\r
1556 #include "flash_nand.h"
\r
1557 #include "diagsec.h"
\r
1558 #include "diagd3des.h"
\r
1560 byte diagdiag_des_sec_rand[8] = {0, 0, 0, 0, 0, 0, 0, 0};
\r
1561 extern const byte diag_cal_des_sec_code[] ;
\r
1562 extern const byte diag_cal_des_sec_key[] ;
\r
1563 extern const byte diag_tool_des_sec_code[] ;
\r
1564 extern const byte diag_tool_des_sec_key[] ;
\r
1566 static byte *diag_des_sec_code;
\r
1567 static byte *diag_des_sec_key;
\r
1568 dword diag_rand_init;
\r
1569 boolean diag_des_ulock_stat = FALSE;
\r
1571 /*===========================================================================
\r
1573 FUNCTION DIAGDIAG_MANUFACTURE_TEST
\r
1576 This procedure processes a request to poke into Non-Volatile memory.
\r
1582 Pointer to response packet.
\r
1587 ===========================================================================*/
\r
1588 PACK(void *) diagdiag_manufacture_test (PACK(void *) req_pkt, uint16 pkt_len)
\r
1593 static byte dir_number[] =
\r
1594 { '0','1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, 0,0};
\r
1595 //uim_status_type uim_status;
\r
1596 byte diagdiag_des_sec_para[16];
\r
1597 byte diagdiag_des_sec_scrunch[8];
\r
1598 boolean diagdiag_des_sec_ok;
\r
1599 dword* sec_rand_ptr;
\r
1600 #ifdef FEATURE_INFO_BAK
\r
1601 unsigned char need_data[INFO_BAK_SIZE];
\r
1604 DIAG_MANUFACTURE_TEST_F_req_type *req = (DIAG_MANUFACTURE_TEST_F_req_type *) req_pkt;
\r
1605 DIAG_MANUFACTURE_TEST_F_rsp_type *rsp;
\r
1606 const int rsp_len = sizeof(DIAG_MANUFACTURE_TEST_F_rsp_type);
\r
1608 //ran_seed(diag_rand_init);
\r
1610 /* Allocate space for response packet */
\r
1611 rsp = (DIAG_MANUFACTURE_TEST_F_rsp_type *)diagpkt_alloc(DIAG_MANUFACTURE_TEST_F, rsp_len);
\r
1614 for (i=0 ; i < 16; i++)
\r
1616 rsp->data[i] = 0x00;
\r
1623 for ( i=0; i<14; i++ )
\r
1625 rsp->data[i] = mob_sw_rev[i];
\r
1632 uim_status = uim_get_uim_status();
\r
1633 if (uim_status == UIM_ERR_S)
\r
1636 for (i=0 ; i < 16; i++)
\r
1638 rsp->data[i] = 0x00;
\r
1641 /* Select the CDMA DF to check if the card is an R-UIM card */
\r
1646 diag_nv_read(NV_DIR_NUMBER_PCS_I, &nitem);
\r
1648 rsp->data[0] = 0x01;
\r
1650 for (i=1 ; i < NV_DIR_NUMB_PCS_SIZ; i++)
\r
1652 rsp->data[i] = dir_number[ nitem.mob_dir_number.digitn[i-1]];
\r
1659 {//read the BT address
\r
1660 nv_item_type nv_item;
\r
1661 uint16 bt_add,bt_temp;
\r
1662 uint16 mac_add,mac_temp;
\r
1664 if(diag_nv_read(NV_BD_ADDR_I,&nv_item) != NV_DONE_S)
\r
1670 for(i = 0;i < NV_BD_ADDR_SIZE;i++)
\r
1672 bt_add = (uint16)nv_item.bd_addr.bd_addr[i];
\r
1673 bt_temp = bt_add & 0x000F;
\r
1674 rsp->data[NV_BD_ADDR_SIZE*2 -1 - i*2] = (unsigned char) (( bt_temp <= 9 ) ? bt_temp + '0' : bt_temp - 10 + 'A');
\r
1675 bt_temp = (bt_add >> 4) & 0x000F;
\r
1676 rsp->data[NV_BD_ADDR_SIZE*2 -2 - i*2] = (unsigned char) (( bt_temp <= 9 ) ? bt_temp + '0' : bt_temp - 10 + 'A');
\r
1680 rsp->mask=req->mask;
\r
1684 {//write the BT address
\r
1685 nv_item_type nv_item;
\r
1686 uint16 bt_add,bt_temp;
\r
1687 uint16 mac_add,mac_temp;
\r
1689 for(i = 0;i < NV_BD_ADDR_SIZE;i++)
\r
1693 if(req->data[2*i] <= 0x39)
\r
1695 bt_add = req->data[2*i] - '0';
\r
1699 bt_add = req->data[2*i] - 'A' + 10;
\r
1702 if(req->data[2*i + 1] <= 0x39)
\r
1704 bt_temp = req->data[2*i + 1] - '0';
\r
1708 bt_temp = req->data[2*i + 1] - 'A' + 10;
\r
1711 bt_temp |= (bt_add << 4);
\r
1712 nv_item.bd_addr.bd_addr[NV_BD_ADDR_SIZE -1 - i] = bt_temp;
\r
1715 if(diag_nv_write(NV_BD_ADDR_I,&nv_item) != NV_DONE_S)
\r
1724 rsp->mask=req->mask;
\r
1730 diag_des_sec_key = (byte *)diag_tool_des_sec_key;
\r
1731 diag_des_sec_code = (byte *)diag_tool_des_sec_code;
\r
1734 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];
\r
1736 *sec_rand_ptr = ran_next ();
\r
1738 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];
\r
1740 *sec_rand_ptr = ran_next ();
\r
1741 diag_rand_init = *sec_rand_ptr;
\r
1743 memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));
\r
1745 diag_deskey(diagdiag_des_sec_scrunch, EN0);
\r
1747 diag_des( &diagdiag_des_sec_rand[0],&rsp->data[0]);
\r
1753 diag_des_sec_key = (byte *)diag_tool_des_sec_key;
\r
1754 diag_des_sec_code = (byte *)diag_tool_des_sec_code;
\r
1757 memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));
\r
1759 diag_deskey(diagdiag_des_sec_scrunch, DE1);
\r
1761 diag_des(&req->data[0], &diagdiag_des_sec_para[0]);
\r
1763 diagdiag_des_sec_ok = TRUE;
\r
1765 if((diagdiag_des_sec_rand[0] == 0) &&
\r
1766 (diagdiag_des_sec_rand[1] == 0) &&
\r
1767 (diagdiag_des_sec_rand[2] == 0) &&
\r
1768 (diagdiag_des_sec_rand[3] == 0) &&
\r
1769 (diagdiag_des_sec_rand[4] == 0) &&
\r
1770 (diagdiag_des_sec_rand[5] == 0) &&
\r
1771 (diagdiag_des_sec_rand[6] == 0) &&
\r
1772 (diagdiag_des_sec_rand[7] == 0) )
\r
1774 diagdiag_des_sec_ok = FALSE;
\r
1781 for (i = 0; i < 8; i++)
\r
1783 if(diag_des_sec_code[i] != (diagdiag_des_sec_para[i] ^ diagdiag_des_sec_rand[i]))
\r
1785 diagdiag_des_sec_ok = FALSE;
\r
1793 if(diagdiag_des_sec_ok == TRUE)
\r
1795 rsp->data[0] = 0x01;
\r
1799 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];
\r
1801 *sec_rand_ptr = ran_next ();
\r
1803 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];
\r
1805 *sec_rand_ptr = ran_next ();
\r
1806 diag_rand_init = *sec_rand_ptr;
\r
1807 diag_des_ulock_stat = TRUE;
\r
1812 {//read the wlan mac address
\r
1813 nv_item_type nv_item;
\r
1814 uint16 mac_add,mac_temp;
\r
1816 if(diag_nv_read(NV_WLAN_MAC_ADDRESS_I,&nv_item) != NV_DONE_S)
\r
1822 for(i = 0;i < 6;i++)
\r
1824 mac_add = (uint16)nv_item.wlan_mac_address[i];
\r
1825 mac_temp = mac_add & 0x000F;
\r
1826 rsp->data[6*2 -1 - i*2] = (unsigned char) (( mac_temp <= 9 ) ? mac_temp + '0' : mac_temp - 10 + 'A');
\r
1827 mac_temp = (mac_add >> 4) & 0x000F;
\r
1828 rsp->data[6*2 -2 - i*2] = (unsigned char) (( mac_temp <= 9 ) ? mac_temp + '0' : mac_temp - 10 + 'A');
\r
1832 rsp->mask=req->mask;
\r
1836 {//write the wlan mac address
\r
1837 nv_item_type nv_item;
\r
1838 uint16 mac_add,mac_temp;
\r
1840 for(i = 0;i < 6;i++)
\r
1844 if(req->data[2*i] <= 0x39)
\r
1846 mac_add = req->data[2*i] - '0';
\r
1850 mac_add = req->data[2*i] - 'A' + 10;
\r
1853 if(req->data[2*i + 1] <= 0x39)
\r
1855 mac_temp = req->data[2*i + 1] - '0';
\r
1859 mac_temp = req->data[2*i + 1] - 'A' + 10;
\r
1862 mac_temp |= (mac_add << 4);
\r
1863 nv_item.wlan_mac_address[6 -1 - i] = mac_temp;
\r
1866 if(diag_nv_write(NV_WLAN_MAC_ADDRESS_I,&nv_item) != NV_DONE_S)
\r
1875 rsp->mask=req->mask;
\r
1879 #ifdef FEATURE_NV_BAK
\r
1882 #ifdef FEATURE_INFO_BAK
\r
1883 efs_device_write_info_bak_data();
\r
1885 if(efs_device_bak_nv_data(FALSE) == 0)
\r
1887 rsp->data[0] = 0x01;
\r
1891 rsp->data[0] = 0x00;
\r
1900 if(efs_device_restore_nv_data() == FALSE)
\r
1902 rsp->data[0] = 0x01;
\r
1906 #ifdef FEATURE_INFO_BAK
\r
1908 if(efs_device_restore_info_bak_file() == TRUE)
\r
1910 if(efs_device_get_info_bak_data(&need_data[0]) == FALSE)//read BOARDNO, MSNO and PHONEID data, ssd add 2008-12-23
\r
1912 rsp->data[0] = 0x01;//¶Áȡʧ°Ü
\r
1916 rsp->data[0] = 0x00;//¶ÁÈ¡³É¹¦
\r
1918 for(i=0; i<BOARDNO_MAX_SIZE; i++)
\r
1920 rsp->data[i+1] = need_data[i];
\r
1923 rsp->data[BOARDNO_MAX_SIZE+1] = 0x00;//0x00·Ö¸ôBOARDNOºÍPHONEIDÊý¾Ý
\r
1925 for(i=0; i<PHONEID_MAX_SIZE; i++)
\r
1927 rsp->data[BOARDNO_MAX_SIZE+2+i] = need_data[BOARDNO_MAX_SIZE+i];
\r
1930 rsp->data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+2] = 0x00;//0x00·Ö¸ôPHONEIDºÍMSNOÊý¾Ý
\r
1932 for(i=0; i<MSNO_MAX_SIZE; i++)
\r
1934 rsp->data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+3+i] = need_data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+i];
\r
1940 rsp->data[0] = 0x01;//»Ö¸´Ê§°Ü
\r
1943 rsp->data[0] = 0x00;//»Ö¸´³É¹¦
\r
1954 for (i=0 ; i < NV_DIR_NUMB_PCS_SIZ; i++)
\r
1956 rsp->data[i] = 0xFF;
\r
1964 /*===========================================================================
\r
1966 FUNCTION DIAGDIAG_FACTORY_TEST
\r
1969 This procedure processes a request to poke into Non-Volatile memory.
\r
1975 Pointer to response packet.
\r
1980 ===========================================================================*/
\r
1981 PACK(void *) diagdiag_factory_test (PACK(void *) req_pkt, uint16 pkt_len)
\r
1985 DIAG_FACTORY_TEST_F_req_type *req = (DIAG_FACTORY_TEST_F_req_type *) req_pkt;
\r
1986 DIAG_FACTORY_TEST_F_rsp_type *rsp;
\r
1987 const int rsp_len = sizeof(DIAG_FACTORY_TEST_F_rsp_type);
\r
1989 /* Allocate space for response packet */
\r
1990 rsp = (DIAG_FACTORY_TEST_F_rsp_type *)diagpkt_alloc(DIAG_FACTORY_TEST_F, rsp_len);
\r
1993 for (i=0 ; i < 16; i++)
\r
1995 rsp->data[i] = 0x00;
\r
2013 /*===========================================================================
\r
2015 FUNCTION DIAGDIAG_ENCRYPT_TEST
\r
2023 Pointer to response packet.
\r
2028 ===========================================================================*/
\r
2029 PACK(void *) diagdiag_encrypt_test (PACK(void *) req_pkt, uint16 pkt_len)
\r
2031 byte diagdiag_des_sec_para[16];
\r
2032 byte diagdiag_des_sec_scrunch[8];
\r
2033 boolean diagdiag_des_sec_ok;
\r
2034 dword* sec_rand_ptr;
\r
2039 extern int efs_device_bak_nv_data(PACKED const byte *data_ptr,int data_size,boolean erase);
\r
2042 DIAG_ENCRYPT_TEST_F_req_type *req = (DIAG_ENCRYPT_TEST_F_req_type *) req_pkt;
\r
2043 DIAG_ENCRYPT_TEST_F_rsp_type *rsp;
\r
2044 const int rsp_len = sizeof(DIAG_ENCRYPT_TEST_F_rsp_type);
\r
2046 /* Allocate space for response packet */
\r
2047 rsp = (DIAG_ENCRYPT_TEST_F_rsp_type *)diagpkt_alloc(DIAG_ENCRYPT_TEST_F, rsp_len);
\r
2050 for (i=0 ; i < 16; i++)
\r
2052 rsp->data[i] = 0x00;
\r
2058 diag_des_sec_key = (byte *)diag_tool_des_sec_key;
\r
2059 diag_des_sec_code = (byte *)diag_tool_des_sec_code;
\r
2062 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];
\r
2064 *sec_rand_ptr = ran_next ();
\r
2066 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];
\r
2068 *sec_rand_ptr = ran_next ();
\r
2070 memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));
\r
2072 diag_deskey(diagdiag_des_sec_scrunch, EN0);
\r
2074 diag_des( &diagdiag_des_sec_rand[0],&rsp->data[0]);
\r
2079 diag_des_sec_key =(byte *) diag_tool_des_sec_key;
\r
2080 diag_des_sec_code =(byte *) diag_tool_des_sec_code;
\r
2084 memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));
\r
2086 diag_deskey(diagdiag_des_sec_scrunch, DE1);
\r
2088 diag_des(&req->data[0], &diagdiag_des_sec_para[0]);
\r
2090 diagdiag_des_sec_ok = TRUE;
\r
2092 if((diagdiag_des_sec_rand[0] == 0) &&
\r
2093 (diagdiag_des_sec_rand[1] == 0) &&
\r
2094 (diagdiag_des_sec_rand[2] == 0) &&
\r
2095 (diagdiag_des_sec_rand[3] == 0) &&
\r
2096 (diagdiag_des_sec_rand[4] == 0) &&
\r
2097 (diagdiag_des_sec_rand[5] == 0) &&
\r
2098 (diagdiag_des_sec_rand[6] == 0) &&
\r
2099 (diagdiag_des_sec_rand[7] == 0) )
\r
2101 diagdiag_des_sec_ok = FALSE;
\r
2108 for (i = 0; i < 8; i++)
\r
2110 if(diag_des_sec_code[i] != (diagdiag_des_sec_para[i] ^ diagdiag_des_sec_rand[i]))
\r
2112 diagdiag_des_sec_ok = FALSE;
\r
2120 if(diagdiag_des_sec_ok == TRUE)
\r
2122 rsp->data[0] = 0x01;
\r
2126 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];
\r
2128 *sec_rand_ptr = ran_next ();
\r
2130 sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];
\r
2132 *sec_rand_ptr = ran_next ();
\r
2138 for (i=0 ; i < sizeof(rsp->data); i++)
\r
2140 rsp->data[i] = 0xFF;
\r
2149 #define DISPATCH_DECLARE(func) \
\r
2150 extern PACK(void *) func(PACK(void *) req_pkt, word len)
\r
2152 #if defined(FEATURE_DIAG_RPC)
\r
2153 #error code not present
\r
2154 #endif /* FEATURE_DIAG_RPC */
\r
2156 #ifndef FEATURE_DIAG_DISALLOW_MEM_OPS
\r
2157 static const diagpkt_user_table_entry_type diagdiag_tbl_mem_ops[] =
\r
2159 {DIAG_PEEKB_F, DIAG_PEEKB_F, diagdiag_peekb},
\r
2160 {DIAG_PEEKW_F, DIAG_PEEKW_F, diagdiag_peekw},
\r
2161 {DIAG_PEEKD_F, DIAG_PEEKD_F, diagdiag_peekd},
\r
2162 {DIAG_POKEB_F, DIAG_POKEB_F, diagdiag_pokeb},
\r
2163 {DIAG_POKEW_F, DIAG_POKEW_F, diagdiag_pokew},
\r
2164 {DIAG_POKED_F, DIAG_POKED_F, diagdiag_poked},
\r
2165 {DIAG_OUTP_F, DIAG_OUTP_F, diagdiag_outp},
\r
2166 {DIAG_OUTPW_F, DIAG_OUTPW_F, diagdiag_outpw},
\r
2167 {DIAG_INP_F, DIAG_INP_F, diagdiag_inp},
\r
2168 {DIAG_INPW_F, DIAG_INPW_F, diagdiag_inpw},
\r
2172 static const diagpkt_user_table_entry_type diagdiag_tbl_ts[]=
\r
2174 {DIAG_TS_F, DIAG_TS_F, diagdiag_ts},
\r
2178 #ifdef FEATURE_TECHNICS_DIAG
\r
2179 static const diagpkt_user_table_entry_type diagdiag_tbl_technics[]=
\r
2181 {DIAG_ENCRYPT_TEST_F,DIAG_ENCRYPT_TEST_F, diagdiag_encrypt_test },
\r
2182 {DIAG_MANUFACTURE_TEST_F,DIAG_MANUFACTURE_TEST_F, diagdiag_manufacture_test },
\r
2183 {DIAG_FACTORY_TEST_F,DIAG_FACTORY_TEST_F, diagdiag_factory_test },
\r
2187 static const diagpkt_user_table_entry_type diagdiag_tbl_feature[]=
\r
2189 {DIAG_FEATURE_QUERY_F, DIAG_FEATURE_QUERY_F, diagdiag_feature_query},
\r
2192 static const diagpkt_user_table_entry_type diagdiag_tbl_misc[]=
\r
2195 #if defined(FEATURE_DIAG_RPC)
\r
2196 #error code not present
\r
2198 {DIAG_DIAG_VER_F, DIAG_DIAG_VER_F, diagdiag_ver},
\r
2199 {DIAG_PASSWORD_F, DIAG_PASSWORD_F, diagdiag_password},
\r
2200 {DIAG_GET_GUID_F, DIAG_GET_GUID_F, diagdiag_get_guid },
\r
2203 static const diagpkt_user_table_entry_type diagdiag_tbl_listener[] =
\r
2205 {DIAGDIAG_ADD_EVENT_LISTENER_F, DIAGDIAG_REMOVE_LOG_LISTENER_F, diagdiag_listener_pkt},
\r
2209 void diagdiag_tbl_init()
\r
2211 #ifndef FEATURE_DIAG_DISALLOW_MEM_OPS
\r
2212 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_mem_ops);
\r
2214 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_feature);
\r
2215 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_ts);
\r
2216 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_misc);
\r
2217 #ifdef FEATURE_TECHNICS_DIAG
\r
2218 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC(DIAG_MODEM_PROC,DIAGPKT_NO_SUBSYS_ID,diagdiag_tbl_technics);
\r
2220 #if defined(DIAG_IMAGE_APPS_PROC)
\r
2221 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC( DIAG_APP_PROC, DIAG_SUBSYS_DIAG_SERV, diagdiag_tbl_listener);
\r
2223 #if defined(DIAG_IMAGE_MODEM_PROC)|| defined(DIAG_SINGLE_PROC)
\r
2224 DIAGPKT_DISPATCH_TABLE_REGISTER_PROC( DIAG_MODEM_PROC, DIAG_SUBSYS_DIAG_SERV, diagdiag_tbl_listener);
\r
2229 #if defined __cplusplus
\r