1 /* 2 * QTest testcase for PowerNV 10 Seeprom Communications 3 * 4 * Copyright (c) 2024, IBM Corporation. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 #include <unistd.h> 9 #include "qemu/osdep.h" 10 #include "libqtest.h" 11 #include "qemu/bswap.h" 12 #include "hw/ssi/pnv_spi_regs.h" 13 #include "pnv-xscom.h" 14 15 #define FLASH_SIZE (512 * 1024) 16 #define SPIC2_XSCOM_BASE 0xc0040 17 18 /* To transmit READ opcode and address */ 19 #define READ_OP_TDR_DATA 0x0300010000000000 20 /* 21 * N1 shift - tx 4 bytes (transmit opcode and address) 22 * N2 shift - tx and rx 8 bytes. 23 */ 24 #define READ_OP_COUNTER_CONFIG 0x2040000000002b00 25 /* SEQ_OP_SELECT_RESPONDER - N1 Shift - N2 Shift * 5 - SEQ_OP_STOP */ 26 #define READ_OP_SEQUENCER 0x1130404040404010 27 28 /* To transmit WREN(Set Write Enable Latch in status0 register) opcode */ 29 #define WRITE_OP_WREN 0x0600000000000000 30 /* To transmit WRITE opcode, address and data */ 31 #define WRITE_OP_TDR_DATA 0x0300010012345678 32 /* N1 shift - tx 8 bytes (transmit opcode, address and data) */ 33 #define WRITE_OP_COUNTER_CONFIG 0x4000000000002000 34 /* SEQ_OP_SELECT_RESPONDER - N1 Shift - SEQ_OP_STOP */ 35 #define WRITE_OP_SEQUENCER 0x1130100000000000 36 37 static void pnv_spi_xscom_write(QTestState *qts, const PnvChip *chip, 38 uint32_t reg, uint64_t val) 39 { 40 uint32_t pcba = SPIC2_XSCOM_BASE + reg; 41 qtest_writeq(qts, pnv_xscom_addr(chip, pcba), val); 42 } 43 44 static uint64_t pnv_spi_xscom_read(QTestState *qts, const PnvChip *chip, 45 uint32_t reg) 46 { 47 uint32_t pcba = SPIC2_XSCOM_BASE + reg; 48 return qtest_readq(qts, pnv_xscom_addr(chip, pcba)); 49 } 50 51 static void spi_seeprom_transaction(QTestState *qts, const PnvChip *chip) 52 { 53 /* SPI transactions to SEEPROM to read from SEEPROM image */ 54 pnv_spi_xscom_write(qts, chip, SPI_CTR_CFG_REG, READ_OP_COUNTER_CONFIG); 55 pnv_spi_xscom_write(qts, chip, SPI_SEQ_OP_REG, READ_OP_SEQUENCER); 56 pnv_spi_xscom_write(qts, chip, SPI_XMIT_DATA_REG, READ_OP_TDR_DATA); 57 pnv_spi_xscom_write(qts, chip, SPI_XMIT_DATA_REG, 0); 58 /* Read 5*8 bytes from SEEPROM at 0x100 */ 59 uint64_t rdr_val = pnv_spi_xscom_read(qts, chip, SPI_RCV_DATA_REG); 60 g_test_message("RDR READ = 0x%" PRIx64, rdr_val); 61 rdr_val = pnv_spi_xscom_read(qts, chip, SPI_RCV_DATA_REG); 62 rdr_val = pnv_spi_xscom_read(qts, chip, SPI_RCV_DATA_REG); 63 rdr_val = pnv_spi_xscom_read(qts, chip, SPI_RCV_DATA_REG); 64 rdr_val = pnv_spi_xscom_read(qts, chip, SPI_RCV_DATA_REG); 65 g_test_message("RDR READ = 0x%" PRIx64, rdr_val); 66 67 /* SPI transactions to SEEPROM to write to SEEPROM image */ 68 pnv_spi_xscom_write(qts, chip, SPI_CTR_CFG_REG, WRITE_OP_COUNTER_CONFIG); 69 /* Set Write Enable Latch bit of status0 register */ 70 pnv_spi_xscom_write(qts, chip, SPI_SEQ_OP_REG, WRITE_OP_SEQUENCER); 71 pnv_spi_xscom_write(qts, chip, SPI_XMIT_DATA_REG, WRITE_OP_WREN); 72 /* write 8 bytes to SEEPROM at 0x100 */ 73 pnv_spi_xscom_write(qts, chip, SPI_SEQ_OP_REG, WRITE_OP_SEQUENCER); 74 pnv_spi_xscom_write(qts, chip, SPI_XMIT_DATA_REG, WRITE_OP_TDR_DATA); 75 } 76 77 static void test_spi_seeprom(const void *data) 78 { 79 const PnvChip *chip = data; 80 QTestState *qts = NULL; 81 g_autofree char *tmp_path = NULL; 82 int ret; 83 int fd; 84 85 /* Create a temporary raw image */ 86 fd = g_file_open_tmp("qtest-seeprom-XXXXXX", &tmp_path, NULL); 87 g_assert(fd >= 0); 88 ret = ftruncate(fd, FLASH_SIZE); 89 g_assert(ret == 0); 90 close(fd); 91 92 qts = qtest_initf("-machine powernv10 -smp 2,cores=2," 93 "threads=1 -accel tcg,thread=single -nographic " 94 "-blockdev node-name=pib_spic2,driver=file," 95 "filename=%s -device 25csm04,bus=pnv-spi-bus.2,cs=0," 96 "drive=pib_spic2", tmp_path); 97 spi_seeprom_transaction(qts, chip); 98 qtest_quit(qts); 99 unlink(tmp_path); 100 } 101 102 int main(int argc, char **argv) 103 { 104 g_test_init(&argc, &argv, NULL); 105 char *tname = g_strdup_printf("pnv-xscom/spi-seeprom/%s", 106 pnv_chips[3].cpu_model); 107 qtest_add_data_func(tname, &pnv_chips[3], test_spi_seeprom); 108 g_free(tname); 109 return g_test_run(); 110 } 111