blob: d2eb4c524cb50b996a26123666f814caf7a9c8d8 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/testing/json/spi_passthru.h"
#include <stdbool.h>
#include <stdint.h>
#include "sw/device/lib/base/status.h"
#include "sw/device/lib/dif/dif_spi_device.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/json/command.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_flow_control.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"
#include "sw/device/lib/testing/test_framework/ujson_ottf.h"
#include "sw/device/lib/ujson/ujson.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
static dif_spi_device_handle_t spid;
status_t configure_jedec_id(ujson_t *uj, dif_spi_device_handle_t *spid) {
config_jedec_id_t config;
TRY(ujson_deserialize_config_jedec_id_t(uj, &config));
dif_spi_device_flash_id_t id = {
.device_id = config.device_id,
.manufacturer_id = config.manufacturer_id,
.continuation_code = config.continuation_code,
.num_continuation_code = config.continuation_len,
};
TRY(dif_spi_device_set_flash_id(spid, id));
dif_spi_device_flash_command_t read_id = {
.opcode = 0x9F,
.address_type = kDifSpiDeviceFlashAddrDisabled,
.dummy_cycles = 0,
.payload_io_type = kDifSpiDevicePayloadIoSingle,
.passthrough_swap_address = false,
.payload_dir_to_host = true,
.payload_swap_enable = false,
.upload = false,
.set_busy_status = false,
};
TRY(dif_spi_device_set_flash_command_slot(spid, 3, kDifToggleEnabled,
read_id));
return RESP_OK_STATUS(uj);
}
status_t command_processor(ujson_t *uj) {
while (true) {
test_command_t command;
TRY(ujson_deserialize_test_command_t(uj, &command));
switch (command) {
case kTestCommandSpiConfigureJedecId:
RESP_ERR(uj, configure_jedec_id(uj, &spid));
break;
default:
LOG_ERROR("Unrecognized command: %d", command);
RESP_ERR(uj, INVALID_ARGUMENT());
}
}
// We should never reach here.
return INTERNAL();
}
bool test_main(void) {
CHECK_DIF_OK(dif_spi_device_init_handle(
mmio_region_from_addr(TOP_EARLGREY_SPI_DEVICE_BASE_ADDR), &spid));
dif_spi_device_config_t dev_cfg = {
.clock_polarity = kDifSpiDeviceEdgePositive,
.data_phase = kDifSpiDeviceEdgeNegative,
.tx_order = kDifSpiDeviceBitOrderMsbToLsb,
.rx_order = kDifSpiDeviceBitOrderMsbToLsb,
.device_mode = kDifSpiDeviceModePassthrough,
};
CHECK_DIF_OK(dif_spi_device_configure(&spid, dev_cfg));
dif_spi_device_passthrough_intercept_config_t passthru_cfg = {
.status = true,
.jedec_id = true,
.sfdp = true,
.mailbox = false,
};
CHECK_DIF_OK(
dif_spi_device_set_passthrough_intercept_config(&spid, passthru_cfg));
ujson_t uj = ujson_ottf_console();
status_t s = command_processor(&uj);
LOG_INFO("status = %r", s);
return status_ok(s);
}