blob: d853ae4e74e4baa4b116f9a16ed95028a23296bd [file] [log] [blame]
#include "../include/phynand.h"
#ifndef AML_NAND_UBOOT
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/crc32.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/amlogic/securitykey.h>
#endif
extern int amlnand_read_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size);
extern int amlnand_save_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size);
extern int amlnand_info_init(struct amlnand_chip *aml_chip, u8 * info,u8 * buf, u8 *name,unsigned size);
//#define KEYSIZE (CONFIG_KEYSIZE - (sizeof(uint32_t)))
static struct amlnand_chip *aml_chip_key = NULL;
int aml_nand_update_key(struct amlnand_chip * aml_chip, char *key_ptr)
{
int ret = 0;
int malloc_flag = 0;
char *key_buf = NULL;
if (key_buf == NULL) {
key_buf = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL);
malloc_flag = 1;
if (key_buf == NULL)
return -ENOMEM;
memset(key_buf,0,CONFIG_KEYSIZE);
ret = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_buf,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
if (ret) {
aml_nand_msg("read key error,%s\n",__func__);
ret = -EFAULT;
goto exit;
}
}else{
key_buf = key_ptr;
}
aml_nand_msg("aml_chip->nand_key : arg_type%d valid %d,update_flag %d,valid_blk_addr %d,valid_page_addr %d",aml_chip->nand_key.arg_type,aml_chip->nand_key.arg_valid,\
aml_chip->nand_key.update_flag,aml_chip->nand_key.valid_blk_addr,aml_chip->nand_key.valid_page_addr);
ret = amlnand_save_info_by_name( aml_chip,(u8 *)&(aml_chip->nand_key),(u8 *)key_buf, (u8 *)KEY_INFO_HEAD_MAGIC,CONFIG_KEYSIZE);
if (ret < 0) {
aml_nand_msg("aml_nand_update_key : save key info failed");
}
exit:
if (malloc_flag &&(key_buf)) {
kfree(key_buf);
key_buf = NULL;
}
return 0;
}
/*
* This funcion reads the u-boot keyionment variables.
* The f_pos points directly to the key location.
*/
static int nand_key_read(struct aml_keybox_provider_s * provider, u8 * buf, int len, int flags)
{
struct amlnand_chip * aml_chip = provider->priv;
struct nand_menson_key *key_ptr = NULL;
//int error = 0,i=0;
int error = 0;
if (len > CONFIG_KEYSIZE)
{
printk("key data len too much,%s\n",__func__);
return -EFAULT;
}
key_ptr = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL);
if (key_ptr == NULL)
return -ENOMEM;
memset(key_ptr, 0, CONFIG_KEYSIZE);
error = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key), (u8 *)key_ptr, (u8*)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
//error = aml_nand_read_key(aml_chip, (u_char *)key_ptr);
if (error)
{
printk("read key error,%s\n",__func__);
error = -EFAULT;
goto exit;
}
memcpy(buf, key_ptr->data, len);
exit:
kfree(key_ptr);
return 0;
}
static int nand_key_write(struct aml_keybox_provider_s * provider, u8 *buf,int len)
{
struct amlnand_chip * aml_chip = provider->priv;
struct nand_menson_key *key_ptr = NULL;
//int error = 0,i=0;
int error = 0;
if (len > CONFIG_KEYSIZE)
{
printk("key data len too much,%s\n",__func__);
return -EFAULT;
}
key_ptr = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL);
if (key_ptr == NULL)
return -ENOMEM;
memset(key_ptr,0,CONFIG_KEYSIZE);
memcpy(key_ptr->data + 0, buf, len);
error = amlnand_save_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
if (error)
{
printk("save key error,%s\n",__func__);
error = -EFAULT;
goto exit;
}
exit:
kfree(key_ptr);
return error;
}
static struct aml_keybox_provider_s nand_provider={
.name="nand_key",
.read=nand_key_read,
.write=nand_key_write,
};
int aml_key_init(struct amlnand_chip *aml_chip)
{
int ret = 0;
struct nand_menson_key *key_ptr = NULL;
struct aml_keybox_provider_s * provider;
key_ptr = aml_nand_malloc(CONFIG_KEYSIZE);
if (key_ptr == NULL) {
aml_nand_msg("nand malloc for key_ptr failed");
ret = -1;
goto exit_error0;
}
memset(key_ptr,0x0,CONFIG_KEYSIZE);
aml_nand_msg("nand key: nand_key_probe. ");
ret = amlnand_info_init(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
if (ret < 0) {
aml_nand_msg("invalid nand key\n");
}
aml_chip_key = aml_chip;
nand_provider.priv=aml_chip_key;
provider = aml_keybox_provider_get(nand_provider.name);
if (provider) {
return ret;
}
ret = aml_keybox_provider_register(&nand_provider);
if (ret) {
BUG();
}
exit_error0:
if (key_ptr) {
aml_nand_free(key_ptr);
key_ptr =NULL;
}
return ret;
}
#ifdef AML_NAND_UBOOT
int nandkey_provider_register(void)
{
int ret = 0;
#if 0
ret = aml_keybox_provider_register(&nand_provider);
if (ret) {
BUG();
}
#endif
return ret;
}
#endif