![]() |
|
| VAPI API Reference Documentation 2.18.x |
|
/*================================================================================= This example shows how to get a reduced size coredump from a device running in slave mode using the VAPI library . The procedure to get a reduced size coredump is this one: 1 - Send the RDC_INIT command to the device. 2 - Save the informations returned by the RDC_INIT response (RDCA_memory_region) for further use. 3 - If a fatal Alert indication is received the application must wait for: - if PCI control, the RCD_READY indication - if CSME control, 10 seconds to make sure the RCDG is proceeded by the MSP. 4 - Proceed with the dump of the RDCA_memory_region/max_length reported by the RCD_INIT response =================================================================================*/ /* function usage: / function to be called from device initialization ... struct RCDA_DESC my_rcda; result = enable_rcd(device_id, &my_rcda, 0); ... // function to be called when a fatal ALERT indication is received result = do_rcd(&my_rcda); */ #include <vapi.h> #include <gtl.h> #include <msp.h> /*Structure to handle the RCD_INIT response*/ struct RCDA_DESC { U16 result_code; U16 max_length; U32 RDCA_memory_region; U32 RCDG_entry_point; }; /* RCDA header structure */ struct rcd_header { char signature[32]; U32 size; U32 num_of_block; U8 device_id; U8 reserved; U32 crc; }; /*================================================================================= * This function set the RCD (Reduced Size Coredump) It must be sent at device intialization time, at least before any channel creation. =================================================================================*/ VSTATUS enable_rcd(U16 device_id, struct RCDA_DESC *rcda, U16 max_rcd_size) { VSTATUS result; void *message; U32 response_len = DEFAULT_FIFO_MAX_SIZE; U8 device_response [DEFAULT_FIFO_MAX_SIZE]; struct RCDA_DESC *this_rcda; /* allocate a message to query the current options */ message = VAPI_AllocateMessage(DEFAULT_FIFO_MAX_SIZE); if (message == NULL) return -1; /* if the rcd size is not specified just enable the RCD*/ if (max_rcd_size == 0) result = VAPI_SetMessage(message, CMD_CLASS_OPEN_DIAG, CMD_TYPE_DIAG_MON_LIVE_CTRL, DIAG_RCD_INIT, 1, 0x0001); else /* if the rcd size is not specified enable the RCD with the max supported size*/ result = VAPI_SetMessage(message, CMD_CLASS_OPEN_DIAG, CMD_TYPE_DIAG_MON_LIVE_CTRL, DIAG_RCD_INIT, 2, 0x0001, max_rcd_size); if(result != SUCCESS) goto err; /* send the command, the response is stored in device_response*/ result = VAPI_SendDeviceMessage(device_id, (SMsg *)message, NULL, device_response, &response_len); this_rcda = (struct RCDA_DESC*) &device_response[sizeof(struct comcerto_api_hdr)]; memcpy(rcda, this_rcda, sizeof(struct RCDA_DESC)); printf("rcda->result_code = %d\n", rcda->result_code); printf("rcda->max_length = %d\n", rcda->max_length); printf("rcda->RDCA_memory_region = %x\n", rcda->RDCA_memory_region); printf("rcda->RCDG_entry_point = %x\n", rcda->RCDG_entry_point); err: VAPI_FreeMessage(message); return result; } /*================================================================================= This function perform the RCD (Reduced Size Coredump) It takes as param the struct RCDA_DESC filled by a previous enable_rcd. This functions has to be called when a fatal alert indication is received =================================================================================*/ VSTATUS do_rcd(struct RCDA_DESC *my_rcda, int device_id) { VSTATUS result; int file_desc; /* file descriptor to write the coredump*/ U8* core_buffer; /* buffer to save the coredump */ U32 ulDataSize = 0; /* required for VAPI_GetCoreDump() */ Boolean fLastRead = 0; /* required for VAPI_GetCoreDump() */ struct rcd_header my_rcd_buffer; /* RCD header structure */ /* Allocate a buffer to to hold the RCDA header information */ core_buffer = (U8 *) UT_AllocMem(sizeof(struct RCDA_DESC)); if(core_buffer == NULL) { printf("Can't allocate coredump buffer %d", device_id ); result = FAILURE; goto out; } /* At this point the Comcerto device must be reset If a reset procedure has been registered by the VAPI_RegisterReset() API the VAPI_GetCoreDump() will perform the device reset */ /* Make sure to wait 10 secondes after the Fatal ALERT indication has been received before dumping the memory */ result = VAPI_GetCoreDump(device_id, 0, (void *)&my_rcd_buffer, sizeof(struct rcd_header), /* read first the 48 bytes of the RCDA header*/ &ulDataSize, my_rcda->RDCA_memory_region, /* Dump the region reported by RCD_INIT */ &fLastRead, NULL, NULL); if (result != SUCCESS) { result = FAILURE; goto out; } printf("rcd_header signature = %s\n", my_rcd_buffer.signature); printf("rcd_header size = %d\n", my_rcd_buffer.size); printf("rcd_header num_of_block = %d\n", my_rcd_buffer.num_of_block); printf("rcd_header device_id = %d\n", my_rcd_buffer.device_id); printf("rcd_header crc = %d\n", my_rcd_buffer.crc); /* check if the RCD is valid */ if ((strcmp(my_rcd_buffer.signature, "RCD_gen_completed") == 0) || (strcmp(my_rcd_buffer.signature, "RCD_gen_started") == 0)) { /* Allocate a buffer with enough space to save the RCD size */ core_buffer = (U8 *) UT_AllocMem(my_rcd_buffer.size); if(core_buffer == NULL) { result = FAILURE; goto out; } ulDataSize = 0; printf("Dump valid RCD from 0x%08x size = %d\n", my_rcda->RDCA_memory_region, my_rcd_buffer.size); result = VAPI_GetCoreDump(device_id, 0, core_buffer, my_rcd_buffer.size, /* read the full RCDA */ &ulDataSize, my_rcda->RDCA_memory_region, /* Dump the region reported by RCD_INIT */ &fLastRead, NULL, NULL); if (result != SUCCESS) { free (core_buffer); goto out; } /* open a file to store the coredump buffer */ file_desc = open ("rcd.bin", O_CREAT|O_WRONLY, 0644); if (file_desc < 0) { printf("Can't open corefile %s", "rcd.bin" ); free (core_buffer); result = FAILURE; goto out; } write(file_desc, core_buffer, ulDataSize); close(file_desc); free (core_buffer); } else { printf("RCD not valid \n"); result = FAILURE; } out: return result; }