1259 lines
34 KiB
C
1259 lines
34 KiB
C
|
/*
|
||
|
* Copyright (C) 2012 Apple Inc. All rights reserved.
|
||
|
*
|
||
|
* This document is the property of Apple Computer, Inc.
|
||
|
* It is considered confidential and proprietary.
|
||
|
*
|
||
|
* This document may not be reproduced or transmitted in any form,
|
||
|
* in whole or in part, without the express written permission of
|
||
|
* Apple Inc.
|
||
|
*/
|
||
|
|
||
|
#define ASP_TARGET_RTXC 1
|
||
|
#define CASSERT(x, name) typedef char __ASP_CASSERT_##name[(x) ? 1 : -1]
|
||
|
#include <stdint.h>
|
||
|
#include <csi_ipc_protocol.h>
|
||
|
#include <arch.h>
|
||
|
#include <aspcore_mbox.h>
|
||
|
#include <aspcore_protocol.h>
|
||
|
#include <debug.h>
|
||
|
#include <drivers/asp.h>
|
||
|
#include <drivers/csi.h>
|
||
|
#include <lib/env.h>
|
||
|
#include <lib/heap.h>
|
||
|
#include <lib/partition.h>
|
||
|
#include <platform.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys.h>
|
||
|
#include <sys/menu.h>
|
||
|
#include "common_util.h"
|
||
|
#include <target/aspnandconfig.h>
|
||
|
|
||
|
extern asp_t asp;
|
||
|
extern aspproto_nand_geom_t nand_info;
|
||
|
extern struct blockdev *asp_nand_dev;
|
||
|
extern struct blockdev *asp_nvram_dev;
|
||
|
extern struct blockdev *asp_firmware_dev;
|
||
|
extern struct blockdev *asp_llb_dev;
|
||
|
extern struct blockdev *asp_effaceable_dev;
|
||
|
extern struct blockdev *asp_syscfg_dev;
|
||
|
extern struct blockdev *asp_paniclog_dev;
|
||
|
|
||
|
char *asp_names[] = {"unknown", "NAND", "NVRAM", "FIRMWARE", "LLB", "EFFACEABLE", "SYSCFG", "PANICLOG"};
|
||
|
|
||
|
|
||
|
aspproto_cmd_t * asp_get_cmd_for_tag(uint32_t tag)
|
||
|
{
|
||
|
|
||
|
uint8_t * base = (uint8_t *) asp.asp_command;
|
||
|
uint8_t * offset = NULL;
|
||
|
|
||
|
if (tag > ASP_NUM_TAGS)
|
||
|
{
|
||
|
panic("Invalid tag %d given to asp_get_cmd_for_tag!\n", tag);
|
||
|
}
|
||
|
|
||
|
offset = base + (tag * ASPPROTO_CMD_LINES * CACHELINE_BYTES);
|
||
|
|
||
|
memset(offset, 0x00, ASPPROTO_CMD_LINES * CACHELINE_BYTES);
|
||
|
((aspproto_cmd_t *)offset)->tag = tag;
|
||
|
|
||
|
return ((aspproto_cmd_t *)offset);
|
||
|
|
||
|
}
|
||
|
|
||
|
#if WITH_NON_COHERENT_DMA
|
||
|
|
||
|
int asp_send_command(uint32_t tag)
|
||
|
{
|
||
|
uint32_t cmd_mem_size;
|
||
|
void *cmd_mem_base;
|
||
|
int return_val;
|
||
|
|
||
|
cmd_mem_size = ASPPROTO_CMD_LINES * CACHELINE_BYTES;
|
||
|
cmd_mem_base = (void*)((uintptr_t)asp.asp_command + (tag * cmd_mem_size));
|
||
|
|
||
|
platform_cache_operation(CACHE_CLEAN, cmd_mem_base, cmd_mem_size);
|
||
|
|
||
|
if (csi_send_message(asp.csi_token, ASPMBOX_MAKE_CMD_NEW1(tag)) != CSI_STATUS_OK)
|
||
|
{
|
||
|
return ASPPROTO_CMD_STATUS_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
return_val = asp_wait_for_completion(tag);
|
||
|
platform_cache_operation(CACHE_INVALIDATE, cmd_mem_base, cmd_mem_size);
|
||
|
|
||
|
return return_val;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
int asp_send_command(uint32_t tag)
|
||
|
{
|
||
|
uint64_t payload;
|
||
|
|
||
|
payload = ASPMBOX_MAKE_CMD_NEW1(tag);
|
||
|
|
||
|
if (csi_send_message(asp.csi_token, payload) != CSI_STATUS_OK)
|
||
|
{
|
||
|
return ASPPROTO_CMD_STATUS_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
return asp_wait_for_completion(tag);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
int asp_wait_for_completion(uint32_t tag)
|
||
|
{
|
||
|
|
||
|
msg_payload_t msg;
|
||
|
uint32_t rx_type;
|
||
|
uint32_t rx_tag;
|
||
|
uint32_t status;
|
||
|
csi_status_t result;
|
||
|
|
||
|
again:
|
||
|
|
||
|
#if ASP_ENABLE_TIMEOUTS
|
||
|
if (!event_wait_timeout(&asp.msg_event, ASP_IO_TIMEOUT_US))
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "ASP - I/O timed out for tag %d!", tag);
|
||
|
asp.state = ASP_STATE_TIMEOUT;
|
||
|
return ASPPROTO_CMD_STATUS_TIMEOUT;
|
||
|
}
|
||
|
#else
|
||
|
event_wait(&asp.msg_event);
|
||
|
#endif
|
||
|
|
||
|
result = csi_receive_message(asp.csi_token, &msg);
|
||
|
|
||
|
if (result != CSI_STATUS_OK)
|
||
|
{
|
||
|
// REVISIT - Change this after defining ASPPROTO_CMD_STATUS_ERROR
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
rx_type = ASPMBOX_GET_TYPE(msg);
|
||
|
|
||
|
switch (rx_type)
|
||
|
{
|
||
|
case ASPMBOX_TYPE_CMD_FIN :
|
||
|
{
|
||
|
rx_tag = ASPMBOX_FIN_GET_TAG(msg);
|
||
|
|
||
|
if (tag != rx_tag)
|
||
|
{
|
||
|
// REVISIT - Change this after defining ASPPROTO_CMD_STATUS_ERROR
|
||
|
status = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = ASPMBOX_FIN_GET_ERRCODE(msg);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ASPMBOX_TYPE_CMD_UNSOLICITED :
|
||
|
{
|
||
|
// ignore and try again
|
||
|
goto again;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default :
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Invalid message type %d received", rx_type);
|
||
|
status = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return status;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool asp_set_writable(void)
|
||
|
{
|
||
|
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_SETWRITABLE;
|
||
|
|
||
|
asp.writable = false;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "ASP setWritable Failed\n");
|
||
|
return false;
|
||
|
|
||
|
}
|
||
|
|
||
|
asp.writable = true;
|
||
|
printf("******IMPORTANT NOTE: IBOOT CAN NOW WRITE TO NAND AND POTENTIALLY CHANGE STATE OF THE DRIVE\n");
|
||
|
printf(" REBOOT IF THIS IS NOT WHAT YOU INTENDED\n");
|
||
|
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool asp_get_geometry(void)
|
||
|
{
|
||
|
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_GET_GEOM;
|
||
|
|
||
|
while ( 1 )
|
||
|
{
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to read ASP geometry\n");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( command->geom.pendingLoad != 0 )
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "ASP: Pending load is set in geometry. Will retry in 50ms\n" );
|
||
|
task_sleep ( 50 * 1000 ); // sleep for 50mS.
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
asp.num_lbas = command->geom.num_lbas;
|
||
|
asp.bytes_per_lba = command->geom.bytes_per_lba;
|
||
|
asp.lastUserBand = command->geom.lastUserBand;
|
||
|
asp.lastBand = command->geom.lastBand;
|
||
|
asp.numVirtualSLCBonfireBands = command->geom.numVirtualSLCBonfireBands;
|
||
|
asp.firstIntermediateBand = command->geom.firstIntermediateBand;
|
||
|
asp.lastIntermediateBand = command->geom.lastIntermediateBand;
|
||
|
if (command->geom.utilFormatted) asp.util_formatted = true;
|
||
|
if (command->geom.lbaFormatted) asp.lba_formatted = true;
|
||
|
|
||
|
memcpy(asp.chip_id, command->geom.chip_id, ANC_MAX_BUSSES * ANC_NAND_ID_SIZE);
|
||
|
memcpy(asp.mfg_id, command->geom.mfg_id, ANC_MAX_BUSSES * ANC_NAND_ID_SIZE);
|
||
|
dprintf(DEBUG_CRITICAL, "ASP Block Device %d lbas, %d bytes per lba, utilFormatted:%d lbaFormatted:%d\n",
|
||
|
asp.num_lbas, asp.bytes_per_lba, asp.util_formatted, asp.lba_formatted);
|
||
|
|
||
|
if (command->geom.total_user_lbas == 0)
|
||
|
return false; //asp init failed, don't publish a block device
|
||
|
|
||
|
if (asp.state != ASP_STATE_READY) asp.state = ASP_STATE_INITIALIZED;
|
||
|
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool asp_create_block_device(uint8_t type)
|
||
|
{
|
||
|
|
||
|
struct blockdev * blkdevice;
|
||
|
uint32_t result;
|
||
|
|
||
|
if (((asp.util_formatted == false) && (type!=ASP_NVRAM)) ||
|
||
|
((asp.lba_formatted == false) && (type==ASP_NAND)))
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Cannot create blockdevice(%d) as media is not formatted!\n",type);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
blkdevice = calloc(1, sizeof(struct blockdev));
|
||
|
|
||
|
if (!blkdevice)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to allocate blockdev\n");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
|
||
|
case ASP_NAND:
|
||
|
result = construct_blockdev(blkdevice, "asp_nand", (uint64_t)asp.num_lbas * asp.bytes_per_lba, asp.bytes_per_lba);
|
||
|
break;
|
||
|
|
||
|
case ASP_NVRAM:
|
||
|
result = construct_blockdev(blkdevice, "nvram", (uint64_t)ASP_NVRAM_NUMBLKS * ASP_NVRAM_BLKSZ, ASP_NVRAM_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
result = construct_blockdev(blkdevice, "asp_fw", (uint64_t)ASP_FIRMWARE_NUMBLKS * ASP_FIRMWARE_BLKSZ, ASP_FIRMWARE_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
case ASP_LLB:
|
||
|
result = construct_blockdev(blkdevice, "asp_llb", (uint64_t)ASP_LLB_NUMBLKS * ASP_LLB_BLKSZ, ASP_LLB_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
result = construct_blockdev(blkdevice, "asp_effaceable", (uint64_t)ASP_EFFACEABLE_NUMBLKS * ASP_EFFACEABLE_BLKSZ, ASP_EFFACEABLE_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
case ASP_SYSCFG:
|
||
|
result = construct_blockdev(blkdevice, "nand_syscfg", (uint64_t)ASP_SYSCFG_NUMBLKS * ASP_SYSCFG_BLKSZ, ASP_SYSCFG_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
case ASP_PANICLOG:
|
||
|
result = construct_blockdev(blkdevice, "paniclog", (uint64_t)ASP_PANICLOG_NUMBLKS * ASP_PANICLOG_BLKSZ, ASP_PANICLOG_BLKSZ);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
result = -1;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (result != 0)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to contruct blockdev\n");
|
||
|
free(blkdevice);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
blkdevice->read_block_hook = &asp_read_block;
|
||
|
|
||
|
if (type == ASP_NVRAM)
|
||
|
{
|
||
|
blkdevice->write_block_hook = &asp_write_block;
|
||
|
}
|
||
|
|
||
|
#if !RELEASE_BUILD
|
||
|
if (type == ASP_LLB)
|
||
|
{
|
||
|
blkdevice->erase_hook = &asp_erase_block;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (type == ASP_PANICLOG)
|
||
|
{
|
||
|
blkdevice->write_block_hook = &asp_write_block;
|
||
|
}
|
||
|
|
||
|
#if ASP_ENABLE_WRITES
|
||
|
else
|
||
|
{
|
||
|
blkdevice->write_block_hook = &asp_write_block;
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (register_blockdev(blkdevice) != 0)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to register blockdev\n");
|
||
|
free(blkdevice);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
asp_set_blkdev_for_type(type, blkdevice);
|
||
|
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
bool asp_set_photoflow_mode(core_flow_mode_e slc_mode)
|
||
|
{
|
||
|
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_SET_PHOTOFLOW_MODE;
|
||
|
command->tunnel.options.value = (uint32_t) slc_mode;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to asp_enable_slc\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_enable_bg(void)
|
||
|
{
|
||
|
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_ENABLE_BG;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to asp_enable_bg\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_disable_bg(void)
|
||
|
{
|
||
|
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_DISABLE_BG;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to asp_disable_bg\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_set_dies_in_parallel(uint32_t mlc_slc_write_dies,
|
||
|
uint32_t mlc_read_dies,
|
||
|
uint32_t mlc_erase_dies,
|
||
|
uint32_t mlc_mlc_write_dies,
|
||
|
uint32_t tlc_slc_write_dies,
|
||
|
uint32_t tlc_read_dies,
|
||
|
uint32_t tlc_erase_dies,
|
||
|
uint32_t tlc_tlc_write_dies,
|
||
|
CorePowerState_e power_level)
|
||
|
{
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
if (nand_info.num_bus==0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (CORE_POWERSTATE_HIGH_POWER == power_level) {
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_SET_MAX_DIES_IN_PARALLEL;
|
||
|
dprintf(DEBUG_SPEW, "setting for MLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,MLC_WRITE=%d) high power parallel per channel\n",
|
||
|
mlc_slc_write_dies / nand_info.num_bus,
|
||
|
mlc_read_dies / nand_info.num_bus,
|
||
|
mlc_erase_dies / nand_info.num_bus,
|
||
|
mlc_mlc_write_dies / nand_info.num_bus);
|
||
|
|
||
|
dprintf(DEBUG_SPEW, "setting for TLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,TLC_WRITE=%d) high power parallel per channel\n",
|
||
|
tlc_slc_write_dies / nand_info.num_bus,
|
||
|
tlc_read_dies / nand_info.num_bus,
|
||
|
tlc_erase_dies / nand_info.num_bus,
|
||
|
tlc_tlc_write_dies / nand_info.num_bus);
|
||
|
} else if (CORE_POWERSTATE_LOW_POWER == power_level) {
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_SET_LOW_POWER_MAX_DIES_IN_PARALLEL;
|
||
|
dprintf(DEBUG_SPEW, "setting for MLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,MLC_WRITE=%d) low power parallel per channel\n",
|
||
|
mlc_slc_write_dies / nand_info.num_bus,
|
||
|
mlc_read_dies / nand_info.num_bus,
|
||
|
mlc_erase_dies / nand_info.num_bus,
|
||
|
mlc_mlc_write_dies / nand_info.num_bus);
|
||
|
|
||
|
dprintf(DEBUG_SPEW, "setting for TLC: (SLC_WRITE=%d,READ=%d,ERASE=%d,TLC_WRITE=%d) low power parallel per channel\n",
|
||
|
tlc_slc_write_dies / nand_info.num_bus,
|
||
|
tlc_read_dies / nand_info.num_bus,
|
||
|
tlc_erase_dies / nand_info.num_bus,
|
||
|
tlc_tlc_write_dies / nand_info.num_bus);
|
||
|
} else {
|
||
|
dprintf(DEBUG_CRITICAL, "Powerlevel 0x%x is not configurable\n", power_level);
|
||
|
return false;
|
||
|
}
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.buffer_paddr = 0;
|
||
|
command->tunnel.bufferLen = 0;
|
||
|
command->tunnel.options.mask = (1 << ANC_MAX_BUSSES) - 1;
|
||
|
command->tunnel.options.dies_in_parallel.mlc_mlc_write_dies = mlc_mlc_write_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.mlc_slc_write_dies = mlc_slc_write_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.mlc_erase_dies = mlc_erase_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.mlc_read_dies = mlc_read_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.tlc_tlc_write_dies = tlc_tlc_write_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.tlc_slc_write_dies = tlc_slc_write_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.tlc_erase_dies = tlc_erase_dies / nand_info.num_bus;
|
||
|
command->tunnel.options.dies_in_parallel.tlc_read_dies = tlc_read_dies / nand_info.num_bus;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to set dies in parallel\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_set_power_state(CorePowerState_e powerState) {
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_SET_POWER_STATE;
|
||
|
command->tunnel.options.value = powerState;
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "setting asp to high power mode\n");
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "setting asp to high power failed\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_set_indirection_memory(uint32_t indirection_memory, uint32_t legacy_memory) {
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_CORE_DEBUG;
|
||
|
command->tunnel.core_opcode = CORE_DEBUG_SET_INDIRECTION_MEMORY;
|
||
|
command->tunnel.options.indirection_memory.heapIndMemory = indirection_memory;
|
||
|
command->tunnel.options.indirection_memory.legacyIndMemory = legacy_memory;
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "setting indirection memory failed\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool asp_test_scratchpad(void)
|
||
|
{
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_NAND_DEBUG;
|
||
|
command->tunnel.opcode = NAND_DEBUG_TEST_SCRATCHPAD;
|
||
|
command->tunnel.options.mask = (1<<ANC_MAX_BUSSES)-1;
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "testing scratchpad\n");
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "scratchpad failed\n");
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#if !RELEASE_BUILD && WITH_MENU
|
||
|
int asp_update_ppn_firmware(const void *fw_buffer, size_t fw_length)
|
||
|
{
|
||
|
int err = 0;
|
||
|
void *fw_buffer_aligned = NULL;
|
||
|
|
||
|
asp_disable_bg();
|
||
|
|
||
|
//allocate buffer
|
||
|
fw_buffer_aligned = memalign(fw_length, 4096);
|
||
|
if(!fw_buffer_aligned)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to allocate data_buffer\n");
|
||
|
return -1;
|
||
|
}
|
||
|
memcpy(fw_buffer_aligned, fw_buffer, fw_length);
|
||
|
|
||
|
//set up the tunnel command
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_NAND_DEBUG;
|
||
|
command->tunnel.opcode = NAND_DEBUG_PPN_FIRMWARE_UPDATE;
|
||
|
command->tunnel.buffer_paddr = VADDR_TO_PADDR32(fw_buffer_aligned);
|
||
|
command->tunnel.bufferLen = fw_length;
|
||
|
command->tunnel.options.mask = (1 << ANC_MAX_BUSSES) - 1;
|
||
|
command->tunnel.options.value = 0;
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "Begin PPN firmware update\n");
|
||
|
|
||
|
if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "ERROR: PPN firmware update failed\n\n");
|
||
|
asp.state = ASP_STATE_ERROR_INVALID_PPNFW;
|
||
|
err = -1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (asp.state == ASP_STATE_ERROR_INVALID_PPNFW)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "PPN firmware successfully recovered, reboot required\n\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "PPN firmware update succeeded\n\n");
|
||
|
}
|
||
|
asp_set_default_dies_in_parallel();
|
||
|
}
|
||
|
|
||
|
asp_enable_bg();
|
||
|
|
||
|
free(fw_buffer_aligned);
|
||
|
return err;
|
||
|
}
|
||
|
#endif // #if !RELEASE_BUILD && WITH_MENU
|
||
|
|
||
|
#if !RELEASE_BUILD
|
||
|
int asp_erase_block(struct blockdev * _dev, off_t offset, uint64_t len)
|
||
|
{
|
||
|
block_addr start_block = 0;
|
||
|
uint32_t num_blocks = 0, returned_blocks = 0, blk_size = 0;
|
||
|
uint8_t *data_buffer = NULL;
|
||
|
int type = -1;
|
||
|
|
||
|
if(len == 0)
|
||
|
{
|
||
|
len = _dev->total_len;
|
||
|
printf("len = 0 will erase entire dev.\n");
|
||
|
}
|
||
|
if((offset + len) > _dev->total_len)
|
||
|
{
|
||
|
printf("Invalid parameter. Size should be > 0 and (Size + Offset) should be < %lld\n", _dev->total_len);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
type = asp_type_from_blkdev(_dev);
|
||
|
switch (type)
|
||
|
{
|
||
|
case ASP_LLB:
|
||
|
blk_size = ASP_LLB_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
#if ASP_ENABLE_WRITES
|
||
|
case ASP_NVRAM:
|
||
|
blk_size = ASP_NVRAM_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_NAND:
|
||
|
blk_size = ASP_NAND_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
blk_size = ASP_FIRMWARE_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
blk_size = ASP_EFFACEABLE_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_SYSCFG:
|
||
|
blk_size = ASP_SYSCFG_BLKSZ;
|
||
|
break;
|
||
|
#endif // ASP_ENABLE_WRITES
|
||
|
|
||
|
default:
|
||
|
dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_erase_block!\n", type);
|
||
|
return -1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if((0 != (len % blk_size)) || (0 != (offset % blk_size)))
|
||
|
{
|
||
|
printf("len and offset are expected to be multiple of block sizez: %d\n", blk_size);
|
||
|
return -1;
|
||
|
}
|
||
|
start_block = offset / blk_size;
|
||
|
num_blocks = len / blk_size;
|
||
|
|
||
|
data_buffer = memalign(num_blocks * blk_size, 4096);
|
||
|
if(!data_buffer)
|
||
|
{
|
||
|
printf("Could not allocate data buffer\n");
|
||
|
return -1;
|
||
|
}
|
||
|
//erasing is actually writing out 0's.
|
||
|
memset(data_buffer, 0x00, num_blocks * blk_size);
|
||
|
|
||
|
returned_blocks = asp_write_block(_dev, data_buffer, start_block, num_blocks);
|
||
|
|
||
|
if (returned_blocks != num_blocks)
|
||
|
{
|
||
|
printf("Error. Expected to erase %d blocks. Erased %d blocks\n", num_blocks, returned_blocks);
|
||
|
free(data_buffer);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
free(data_buffer);
|
||
|
return len;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
int asp_read_block(struct blockdev *_dev, void *ptr, block_addr block, uint32_t count)
|
||
|
{
|
||
|
|
||
|
uintptr_t paddr = mem_static_map_physical((addr_t)ptr);
|
||
|
uint32_t paddr32 = paddr >> ASP_NAND_BLK_ALIGN_SHIFT;
|
||
|
int type = -1;
|
||
|
aspproto_cmd_t * command;
|
||
|
uint8_t * bounce_buffer = NULL;
|
||
|
uint32_t num_blks_allowed;
|
||
|
uint32_t blk_size;
|
||
|
int total_count;
|
||
|
int return_count;
|
||
|
void *vaddr;
|
||
|
|
||
|
type = asp_type_from_blkdev(_dev);
|
||
|
if (asp.state != ASP_STATE_READY && type != ASP_NVRAM)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "ASP is not ready! Current state is %d\n", asp.state);
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
else if (csi_is_panic_recovery(asp.coproc))
|
||
|
{
|
||
|
asp_panic_recover();
|
||
|
dprintf(DEBUG_CRITICAL, "ASP is panicked; ignoring read\n");
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
|
||
|
vaddr = ptr;
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
|
||
|
case ASP_NAND:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_NAND);
|
||
|
command->op = ASPPROTO_CMD_READ;
|
||
|
num_blks_allowed = asp.num_lbas;
|
||
|
blk_size = ASP_NAND_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_NVRAM:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_NVRAM);
|
||
|
command->op = ASPPROTO_CMD_READ_NVRAM;
|
||
|
num_blks_allowed = ASP_NVRAM_NUMBLKS;
|
||
|
blk_size = ASP_NVRAM_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_FIRMWARE);
|
||
|
command->op = ASPPROTO_CMD_READ_FW;
|
||
|
num_blks_allowed = ASP_FIRMWARE_NUMBLKS;
|
||
|
blk_size = ASP_FIRMWARE_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_LLB:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_LLB);
|
||
|
command->op = ASPPROTO_CMD_READ_LLB;
|
||
|
num_blks_allowed = ASP_LLB_NUMBLKS;
|
||
|
blk_size = ASP_LLB_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_EFFACEABLE);
|
||
|
command->op = ASPPROTO_CMD_READ_EFFACEABLE;
|
||
|
num_blks_allowed = ASP_EFFACEABLE_NUMBLKS;
|
||
|
blk_size = ASP_EFFACEABLE_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_SYSCFG:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_SYSCFG);
|
||
|
command->op = ASPPROTO_CMD_READ_SYSCFG;
|
||
|
num_blks_allowed = ASP_SYSCFG_NUMBLKS;
|
||
|
blk_size = ASP_SYSCFG_BLKSZ;
|
||
|
// syscfg starts at block 2
|
||
|
if (block != 2)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Attempted to read nand syscfg at non-zero offset\n");
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
block = 0; // Real Syscfg is always the 1st block in the blockdevice
|
||
|
break;
|
||
|
|
||
|
case ASP_PANICLOG:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_PANICLOG);
|
||
|
command->op = ASPPROTO_CMD_READ_PANICLOG;
|
||
|
num_blks_allowed = ASP_PANICLOG_NUMBLKS;
|
||
|
blk_size = ASP_PANICLOG_BLKSZ;
|
||
|
|
||
|
if(block != 0) {
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_read_block!\n", type);
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
if ((paddr & (4096 - 1)) != 0)
|
||
|
{
|
||
|
bounce_buffer = memalign(count * blk_size, 4096);
|
||
|
|
||
|
if (!bounce_buffer)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to allocate bounce buffer\n");
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
|
||
|
paddr32 = VADDR_TO_PADDR32(bounce_buffer);
|
||
|
vaddr = bounce_buffer;
|
||
|
}
|
||
|
|
||
|
command->flags.all = 0;
|
||
|
command->flags.noAesKey = 1;
|
||
|
|
||
|
if (count > num_blks_allowed)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Trimming supported read size of %d 4KB blks to "
|
||
|
"%d 4KB blocks for NAND dev type %d\n", count, num_blks_allowed, type);
|
||
|
count = num_blks_allowed;
|
||
|
}
|
||
|
|
||
|
total_count = count;
|
||
|
|
||
|
if (type == ASP_NVRAM || type == ASP_SYSCFG)
|
||
|
{
|
||
|
count = count * 2; //Since NVRAM and SYSCFG blkdev publishes 8KB while NAND blksz is 4KB
|
||
|
}
|
||
|
|
||
|
#if WITH_NON_COHERENT_DMA
|
||
|
platform_cache_operation(CACHE_CLEAN | CACHE_INVALIDATE, vaddr, count * ASP_NAND_BLKSZ);
|
||
|
#endif
|
||
|
|
||
|
if (type != ASP_PANICLOG)
|
||
|
{
|
||
|
return_count = total_count;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return_count = 0;
|
||
|
}
|
||
|
|
||
|
while (count)
|
||
|
{
|
||
|
uint32_t lbas = MIN(count, MAX_SGL_ENTRIES);
|
||
|
uint32_t lba;
|
||
|
int ret;
|
||
|
command->lba = block;
|
||
|
|
||
|
for (lba = 0; lba < lbas; lba++)
|
||
|
{
|
||
|
command->sglAndIv[lba] = paddr32++;
|
||
|
}
|
||
|
|
||
|
command->count = lbas;
|
||
|
count -= lbas;
|
||
|
block += lbas;
|
||
|
|
||
|
if (type == ASP_NVRAM && !asp.util_formatted)
|
||
|
{
|
||
|
; // ignore writes
|
||
|
}
|
||
|
else if ((ret=asp_send_command(command->tag)) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
if (type == ASP_NVRAM || type == ASP_SYSCFG) // failed NVRAM reads return all FFs, not errors
|
||
|
{
|
||
|
memset(ptr, 0xff, total_count * blk_size);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to read LBA %d from bdev %s, return code=%d\n", command->lba, asp_names[type],ret);
|
||
|
return_count = -1;
|
||
|
goto ReadBlockCleanUp;
|
||
|
}
|
||
|
}
|
||
|
else if (type == ASP_PANICLOG)
|
||
|
{
|
||
|
return_count += command->count;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if WITH_NON_COHERENT_DMA
|
||
|
platform_cache_operation(CACHE_INVALIDATE, vaddr, total_count * ASP_NAND_BLKSZ);
|
||
|
#endif
|
||
|
|
||
|
if (type == ASP_NVRAM && !asp.util_formatted)
|
||
|
{
|
||
|
// fake reads return all 0xffs
|
||
|
memset(ptr, 0xff, total_count * blk_size);
|
||
|
}
|
||
|
|
||
|
ReadBlockCleanUp:
|
||
|
|
||
|
if (bounce_buffer)
|
||
|
{
|
||
|
// Buffer wasn't 4KB-aligned
|
||
|
memcpy(ptr, bounce_buffer, total_count * blk_size);
|
||
|
free(bounce_buffer);
|
||
|
}
|
||
|
|
||
|
return return_count;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
int asp_write_block(struct blockdev *_dev, const void *ptr, block_addr block, uint32_t count)
|
||
|
{
|
||
|
|
||
|
uintptr_t paddr = mem_static_map_physical((addr_t)ptr);
|
||
|
uint32_t paddr32 = paddr >> ASP_NAND_BLK_ALIGN_SHIFT;
|
||
|
int total_count;
|
||
|
int type = -1;
|
||
|
aspproto_cmd_t * command;
|
||
|
uint32_t num_blks_allowed;
|
||
|
uint32_t blk_size;
|
||
|
uint8_t *bounce_buffer = NULL;
|
||
|
void *vaddr = (void *)ptr;
|
||
|
|
||
|
type = asp_type_from_blkdev(_dev);
|
||
|
if (asp.state != ASP_STATE_READY && type != ASP_NVRAM)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "ASP is not ready! Current state is %d\n", asp.state);
|
||
|
return -1;
|
||
|
}
|
||
|
else if (csi_is_panic_recovery(asp.coproc))
|
||
|
{
|
||
|
asp_panic_recover();
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "ASP is panicked; ignoring read\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
|
||
|
case ASP_NVRAM:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_NVRAM);
|
||
|
command->op = ASPPROTO_CMD_WRITE_NVRAM;
|
||
|
num_blks_allowed = ASP_NVRAM_NUMBLKS;
|
||
|
blk_size = ASP_NVRAM_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_LLB:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_LLB);
|
||
|
command->op = ASPPROTO_CMD_WRITE_LLB;
|
||
|
num_blks_allowed = ASP_LLB_NUMBLKS;
|
||
|
blk_size = ASP_LLB_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
#if ASP_ENABLE_WRITES
|
||
|
case ASP_NAND:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_NAND);
|
||
|
command->op = ASPPROTO_CMD_WRITE;
|
||
|
num_blks_allowed = asp.num_lbas;
|
||
|
blk_size = ASP_NAND_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_FIRMWARE);
|
||
|
command->op = ASPPROTO_CMD_WRITE_FW;
|
||
|
num_blks_allowed = ASP_FIRMWARE_NUMBLKS;
|
||
|
blk_size = ASP_FIRMWARE_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_EFFACEABLE);
|
||
|
command->op = ASPPROTO_CMD_WRITE_EFFACEABLE;
|
||
|
num_blks_allowed = ASP_EFFACEABLE_NUMBLKS;
|
||
|
blk_size = ASP_EFFACEABLE_BLKSZ;
|
||
|
break;
|
||
|
#endif
|
||
|
case ASP_PANICLOG:
|
||
|
command = asp_get_cmd_for_tag(ASP_TAG_PANICLOG);
|
||
|
command->op = ASPPROTO_CMD_WRITE_PANICLOG;
|
||
|
num_blks_allowed = ASP_PANICLOG_NUMBLKS;
|
||
|
blk_size = ASP_PANICLOG_BLKSZ;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
dprintf(DEBUG_CRITICAL, "Unsupported type %d for asp_write_block!\n", type);
|
||
|
return -1;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
#if ASP_ENABLE_WRITES
|
||
|
if ((type != ASP_NVRAM)
|
||
|
&& (asp.writable == false))
|
||
|
{
|
||
|
printf("Need to make system writable. Execute 'asp setwritable' first\n");
|
||
|
return -1;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ((paddr & (4096 - 1)) != 0)
|
||
|
{
|
||
|
bounce_buffer = memalign(count * blk_size, 4096);
|
||
|
|
||
|
if (!bounce_buffer)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to allocate bounce buffer\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
paddr32 = VADDR_TO_PADDR32(bounce_buffer);
|
||
|
memcpy(bounce_buffer, ptr, count * blk_size);
|
||
|
vaddr = bounce_buffer;
|
||
|
}
|
||
|
|
||
|
#if WITH_NON_COHERENT_DMA
|
||
|
platform_cache_operation(CACHE_CLEAN, vaddr, count * blk_size);
|
||
|
#endif
|
||
|
|
||
|
command->flags.all = 0;
|
||
|
command->flags.noAesKey = 1;
|
||
|
|
||
|
if (count > num_blks_allowed)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Trimming supported read size of %d 4KB blks to "
|
||
|
"%d 4KB blocks for NAND dev type %d\n", count, num_blks_allowed, type);
|
||
|
count = num_blks_allowed;
|
||
|
}
|
||
|
|
||
|
total_count = count;
|
||
|
|
||
|
if (type == ASP_NVRAM)
|
||
|
{
|
||
|
count = count * 2; //Since NVRAM blkdev publishes 8KB while NAND blksz is 4KB
|
||
|
}
|
||
|
|
||
|
while (count)
|
||
|
{
|
||
|
uint32_t lbas = MIN(count, MAX_SGL_ENTRIES);
|
||
|
uint32_t lba;
|
||
|
command->lba = block;
|
||
|
|
||
|
for (lba = 0; lba < lbas; lba++)
|
||
|
{
|
||
|
command->sglAndIv[lba] = paddr32++;
|
||
|
}
|
||
|
|
||
|
command->count = lbas;
|
||
|
count -= lbas;
|
||
|
block += lbas;
|
||
|
|
||
|
if (type == ASP_NVRAM && !asp.util_formatted)
|
||
|
{
|
||
|
; // ignore writes
|
||
|
}
|
||
|
else if (asp_send_command(command->tag) != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to write LBA %d\n", block);
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if WITH_NON_COHERENT_DMA
|
||
|
platform_cache_operation(CACHE_INVALIDATE, vaddr, total_count * blk_size);
|
||
|
#endif
|
||
|
|
||
|
if (bounce_buffer)
|
||
|
{
|
||
|
// Buffer wasn't 4KB-aligned
|
||
|
free(bounce_buffer);
|
||
|
}
|
||
|
|
||
|
return total_count;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
bool asp_sync(void)
|
||
|
{
|
||
|
|
||
|
uint32_t status;
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_SHUTDOWNNOTIFY;
|
||
|
|
||
|
status = asp_send_command(command->tag);
|
||
|
|
||
|
if (status != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to sync: 0x%08x\n", status);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
dprintf(DEBUG_INFO, "ASP sync complete\n");
|
||
|
return true;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
#if defined(ASP_ENABLE_NEURALIZE) && ASP_ENABLE_NEURALIZE
|
||
|
bool asp_neuralize(void)
|
||
|
{
|
||
|
|
||
|
uint32_t status;
|
||
|
aspproto_cmd_t * command = asp_get_cmd_for_tag(ASP_TAG_GENERIC);
|
||
|
|
||
|
command->op = ASPPROTO_CMD_NEURALIZE;
|
||
|
|
||
|
status = asp_send_command(command->tag);
|
||
|
|
||
|
if (status != ASPPROTO_CMD_STATUS_SUCCESS)
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Failed to neuralize: 0x%08x\n", status);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
dprintf(DEBUG_INFO, "ASP neuralize complete\n");
|
||
|
return true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
int asp_type_from_blkdev (struct blockdev *device)
|
||
|
{
|
||
|
|
||
|
int type = -1;
|
||
|
|
||
|
if (device == asp_nand_dev)
|
||
|
{
|
||
|
type = ASP_NAND;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_nvram_dev)
|
||
|
{
|
||
|
type = ASP_NVRAM;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_firmware_dev)
|
||
|
{
|
||
|
type = ASP_FIRMWARE;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_llb_dev)
|
||
|
{
|
||
|
type = ASP_LLB;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_effaceable_dev)
|
||
|
{
|
||
|
type = ASP_EFFACEABLE;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_syscfg_dev)
|
||
|
{
|
||
|
type = ASP_SYSCFG;
|
||
|
}
|
||
|
|
||
|
else if (device == asp_paniclog_dev)
|
||
|
{
|
||
|
type = ASP_PANICLOG;
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_type_from_blkdev!\n", type);
|
||
|
type = -1;
|
||
|
}
|
||
|
|
||
|
return type;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
struct blockdev * asp_get_blkdev_for_type (int type)
|
||
|
{
|
||
|
|
||
|
struct blockdev * device = NULL;
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
|
||
|
case ASP_NAND:
|
||
|
device = asp_nand_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_NVRAM:
|
||
|
device = asp_nvram_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
device = asp_firmware_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_LLB:
|
||
|
device = asp_llb_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
device = asp_effaceable_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_SYSCFG:
|
||
|
device = asp_syscfg_dev;
|
||
|
break;
|
||
|
|
||
|
case ASP_PANICLOG:
|
||
|
device = asp_paniclog_dev;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_blktype_from_dev!\n", type);
|
||
|
device = NULL;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return device;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
int asp_set_blkdev_for_type (int type, struct blockdev * device)
|
||
|
{
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
|
||
|
case ASP_NAND:
|
||
|
asp_nand_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_NVRAM:
|
||
|
asp_nvram_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_FIRMWARE:
|
||
|
asp_firmware_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_LLB:
|
||
|
asp_llb_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_EFFACEABLE:
|
||
|
asp_effaceable_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_SYSCFG:
|
||
|
asp_syscfg_dev = device;
|
||
|
break;
|
||
|
|
||
|
case ASP_PANICLOG:
|
||
|
asp_paniclog_dev = device;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
dprintf(DEBUG_CRITICAL, "Wrong type %d for asp_set_blkdev_for_type!\n", type);
|
||
|
return -1;
|
||
|
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int asp_panic_recover(void)
|
||
|
{
|
||
|
if (asp.state != ASP_STATE_PANIC_RECOVERY)
|
||
|
{
|
||
|
asp.state = ASP_STATE_PANIC_RECOVERY;
|
||
|
dprintf(DEBUG_CRITICAL, "Initializing tags\n");
|
||
|
if (!asp_init_tags())
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to init tags\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
asp_reinit();
|
||
|
|
||
|
dprintf(DEBUG_CRITICAL, "Opening ASP\n");
|
||
|
if (!asp_send_open())
|
||
|
{
|
||
|
dprintf(DEBUG_CRITICAL, "Unable to open ASP\n");
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void asp_reinit(void) {
|
||
|
|
||
|
asp_set_indirection_memory(ASPNAND_INDIRECTION_MEMORY, ASPNAND_LEGACY_INDIRECTION_MEMORY);
|
||
|
asp_set_default_dies_in_parallel();
|
||
|
}
|