blob: 0c28f27b36190edaf46a283caea4a8cc9b0075dd [file] [log] [blame]
/**
* @file oss_ramdump_osa.c
* @brief Implementation of Ramdump os adapt
*
* Copyright (C) 2017 Sanechips Technology Co., Ltd.
* @author Qing Wang <wang.qing@sanechips.com.cn>
* @ingroup si_ap_oss_ramdump_id
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*******************************************************************************
* Include header files *
******************************************************************************/
#include "ramdump.h"
#include "ramdump_emmc.h"
#include "ram_config.h"
#include "ramdump_compress.h"
#include <linux/lzo.h>
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Extern function declarations *
*******************************************************************************/
/*******************************************************************************
* Extern variable declarations *
*******************************************************************************/
extern unsigned char *ramdump_shared_mem_base;
extern unsigned char *ramdump_emmc_flag_base;
extern unsigned int ramdump_compress_flag;
/*******************************************************************************
* Macro definitions *
******************************************************************************/
#define RAMDUMP_DELAY_MS_COUNT (2500)
/*******************************************************************************
* Type definitions *
******************************************************************************/
/*******************************************************************************
* Local function declarations *
******************************************************************************/
/*******************************************************************************
* Local variable definitions *
******************************************************************************/
/*******************************************************************************
* Global variable definitions *
******************************************************************************/
unsigned int ramdump_emmc_size = 0;
volatile unsigned int ramdump_emmc_offset = 0;
extern unsigned int ramdump_device_file_cnt;
/*******************************************************************************
* Inline function implementations *
******************************************************************************/
static inline void ramdump_wait_delay( unsigned long ms)
{
volatile int j = 0;
for (j = 0; j < 10000; j++);
}
/*******************************************************************************
* Local function implementations *
******************************************************************************/
int ramdump_emmc_init(ramdump_file_t *fp)
{
fp->magic = 0x2A2A2A2A;
ramdump_emmc_offset = roundup(sizeof(ramdump_file_t), RAMDUMP_EMMC_ALIGN_SIZE);
if(RAMDUMP_TRANS_EMMC_LEN > ramdump_emmc_offset)
{
ramdump_emmc_size = RAMDUMP_TRANS_EMMC_LEN - ramdump_emmc_offset;
}
else
{
printk("[ramdump] emmc start addr is %ld, emmc size= %ld, error: size smaller than ramdump file header, return!\n", sysctl_ramdump_emmc_start_addr, sysctl_ramdump_emmc_size);
return -1;
}
if(mmc_ramdump_init()){
ramdump_printf("EMMC init failed! No ramdump data trans to emmc!\n");
return -1;
}
return 0;
}
int ramdump_emmc_write_file(char *file_name, unsigned int file_size, ramdump_file_t *fp)
{
if (ramdump_device_file_cnt >= RAMDUMP_FILE_NUM_MAX)
return -1;
if (ramdump_emmc_offset >= RAMDUMP_TRANS_EMMC_LEN)
return -1;
fp->file_fp[ramdump_device_file_cnt].magic = 0x3A3A3A3A;
strncpy(fp->file_fp[ramdump_device_file_cnt].file_name, file_name, RAMDUMP_RAMCONF_FILENAME_MAXLEN - 1);
fp->file_fp[ramdump_device_file_cnt].offset = ramdump_emmc_offset;
fp->file_fp[ramdump_device_file_cnt].size = file_size;
return 0;
}
int ramdump_emmc_write_file_head(ramdump_file_t *fp)
{
int ret = -1;
mmc_bwrite(RAMDUMP_EMMC_ADDR, roundup(sizeof(ramdump_file_t), RAMDUMP_EMMC_ALIGN_SIZE), fp);
return ret;
}
int ramdump_emmc_write_data(ramdump_shmem_t *msg, ramdump_file_t *fp, unsigned int size)
{
int ret = 0;
unsigned int buffer = RAMDUMP_EMMC_ADDR + ramdump_emmc_offset;
if (ramdump_device_file_cnt >= RAMDUMP_FILE_NUM_MAX)
return -1;
while(1){
if ((msg->core_flag == 1) && (msg->rw_flag == 2)){
if(msg->size >= (ramdump_emmc_size - fp->file_fp[ramdump_device_file_cnt].offset))
return -1;
ret = mmc_bwrite(buffer, msg->size, msg->buf);
ramdump_emmc_offset = ramdump_emmc_offset + roundup(msg->size, RAMDUMP_EMMC_ALIGN_SIZE);
msg->core_flag = 1;
msg->rw_flag = 1;
ret = msg->size;
break;
}
else
ramdump_wait_delay(0);
}
return ret;
}
int ramdump_emmc_read(char *buffer, ramdump_shmem_t *msg, unsigned int size)
{
int ret = 0;
return ret;
}
void ramdump_emmc_close(ramdump_file_t *fp)
{
fp->file_size = ramdump_emmc_offset;
ramdump_emmc_write_file_head(fp);
ramdump_printf("ramdump trans emmc finished!\n");
}
#ifdef __cplusplus
}
#endif