1c76d4239SHadi Asyrafi /* 2c76d4239SHadi Asyrafi * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. 3c76d4239SHadi Asyrafi * 4c76d4239SHadi Asyrafi * SPDX-License-Identifier: BSD-3-Clause 5c76d4239SHadi Asyrafi */ 6c76d4239SHadi Asyrafi 7c76d4239SHadi Asyrafi #include <assert.h> 8c76d4239SHadi Asyrafi #include <common/debug.h> 9c76d4239SHadi Asyrafi #include <common/runtime_svc.h> 10*13d33d52SHadi Asyrafi #include <lib/mmio.h> 11c76d4239SHadi Asyrafi #include <tools_share/uuid.h> 12c76d4239SHadi Asyrafi 13c76d4239SHadi Asyrafi #include "socfpga_mailbox.h" 14d25041bfSHadi Asyrafi #include "socfpga_sip_svc.h" 15c76d4239SHadi Asyrafi 16c76d4239SHadi Asyrafi /* Number of SiP Calls implemented */ 17c76d4239SHadi Asyrafi #define SIP_NUM_CALLS 0x3 18c76d4239SHadi Asyrafi 19c76d4239SHadi Asyrafi /* Total buffer the driver can hold */ 20c76d4239SHadi Asyrafi #define FPGA_CONFIG_BUFFER_SIZE 4 21c76d4239SHadi Asyrafi 22cefb37ebSTien Hock, Loh static int current_block; 23cefb37ebSTien Hock, Loh static int read_block; 24cefb37ebSTien Hock, Loh static int current_buffer; 25cefb37ebSTien Hock, Loh static int send_id; 26cefb37ebSTien Hock, Loh static int rcv_id; 27cefb37ebSTien Hock, Loh static int max_blocks; 28cefb37ebSTien Hock, Loh static uint32_t bytes_per_block; 29cefb37ebSTien Hock, Loh static uint32_t blocks_submitted; 30c76d4239SHadi Asyrafi 31c76d4239SHadi Asyrafi struct fpga_config_info { 32c76d4239SHadi Asyrafi uint32_t addr; 33c76d4239SHadi Asyrafi int size; 34c76d4239SHadi Asyrafi int size_written; 35c76d4239SHadi Asyrafi uint32_t write_requested; 36c76d4239SHadi Asyrafi int subblocks_sent; 37c76d4239SHadi Asyrafi int block_number; 38c76d4239SHadi Asyrafi }; 39c76d4239SHadi Asyrafi 40c76d4239SHadi Asyrafi /* SiP Service UUID */ 41c76d4239SHadi Asyrafi DEFINE_SVC_UUID2(intl_svc_uid, 42c76d4239SHadi Asyrafi 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a, 43c76d4239SHadi Asyrafi 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81); 44c76d4239SHadi Asyrafi 45c76d4239SHadi Asyrafi uint64_t socfpga_sip_handler(uint32_t smc_fid, 46c76d4239SHadi Asyrafi uint64_t x1, 47c76d4239SHadi Asyrafi uint64_t x2, 48c76d4239SHadi Asyrafi uint64_t x3, 49c76d4239SHadi Asyrafi uint64_t x4, 50c76d4239SHadi Asyrafi void *cookie, 51c76d4239SHadi Asyrafi void *handle, 52c76d4239SHadi Asyrafi uint64_t flags) 53c76d4239SHadi Asyrafi { 54c76d4239SHadi Asyrafi ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); 55c76d4239SHadi Asyrafi SMC_RET1(handle, SMC_UNK); 56c76d4239SHadi Asyrafi } 57c76d4239SHadi Asyrafi 58c76d4239SHadi Asyrafi struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; 59c76d4239SHadi Asyrafi 607c58fd4eSHadi Asyrafi static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) 61c76d4239SHadi Asyrafi { 62c76d4239SHadi Asyrafi uint32_t args[3]; 63c76d4239SHadi Asyrafi 64c76d4239SHadi Asyrafi while (max_blocks > 0 && buffer->size > buffer->size_written) { 65c76d4239SHadi Asyrafi args[0] = (1<<8); 66c76d4239SHadi Asyrafi args[1] = buffer->addr + buffer->size_written; 677c58fd4eSHadi Asyrafi if (buffer->size - buffer->size_written <= bytes_per_block) { 68c76d4239SHadi Asyrafi args[2] = buffer->size - buffer->size_written; 69c76d4239SHadi Asyrafi current_buffer++; 70c76d4239SHadi Asyrafi current_buffer %= FPGA_CONFIG_BUFFER_SIZE; 717c58fd4eSHadi Asyrafi } else 72c76d4239SHadi Asyrafi args[2] = bytes_per_block; 737c58fd4eSHadi Asyrafi 747c58fd4eSHadi Asyrafi buffer->size_written += args[2]; 75cefb37ebSTien Hock, Loh mailbox_send_cmd_async( 76cefb37ebSTien Hock, Loh send_id++ % MBOX_MAX_JOB_ID, 77c76d4239SHadi Asyrafi MBOX_RECONFIG_DATA, 78c76d4239SHadi Asyrafi args, 3, 0); 797c58fd4eSHadi Asyrafi 80c76d4239SHadi Asyrafi buffer->subblocks_sent++; 81c76d4239SHadi Asyrafi max_blocks--; 82c76d4239SHadi Asyrafi } 837c58fd4eSHadi Asyrafi 847c58fd4eSHadi Asyrafi return !max_blocks; 85c76d4239SHadi Asyrafi } 86c76d4239SHadi Asyrafi 87c76d4239SHadi Asyrafi static int intel_fpga_sdm_write_all(void) 88c76d4239SHadi Asyrafi { 897c58fd4eSHadi Asyrafi for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) 907c58fd4eSHadi Asyrafi if (intel_fpga_sdm_write_buffer( 917c58fd4eSHadi Asyrafi &fpga_config_buffers[current_buffer])) 927c58fd4eSHadi Asyrafi break; 93c76d4239SHadi Asyrafi return 0; 94c76d4239SHadi Asyrafi } 95c76d4239SHadi Asyrafi 96c76d4239SHadi Asyrafi uint32_t intel_mailbox_fpga_config_isdone(void) 97c76d4239SHadi Asyrafi { 987c58fd4eSHadi Asyrafi uint32_t ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS); 997c58fd4eSHadi Asyrafi 1007c58fd4eSHadi Asyrafi if (ret) { 1017c58fd4eSHadi Asyrafi if (ret == MBOX_CFGSTAT_STATE_CONFIG) 1027c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_BUSY; 1037c58fd4eSHadi Asyrafi else 1047c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_ERROR; 1057c58fd4eSHadi Asyrafi } 1067c58fd4eSHadi Asyrafi 1077c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_OK; 108c76d4239SHadi Asyrafi } 109c76d4239SHadi Asyrafi 110c76d4239SHadi Asyrafi static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) 111c76d4239SHadi Asyrafi { 112c76d4239SHadi Asyrafi int i; 113c76d4239SHadi Asyrafi 114c76d4239SHadi Asyrafi for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 115c76d4239SHadi Asyrafi if (fpga_config_buffers[i].block_number == current_block) { 116c76d4239SHadi Asyrafi fpga_config_buffers[i].subblocks_sent--; 117c76d4239SHadi Asyrafi if (fpga_config_buffers[i].subblocks_sent == 0 118c76d4239SHadi Asyrafi && fpga_config_buffers[i].size <= 119c76d4239SHadi Asyrafi fpga_config_buffers[i].size_written) { 120c76d4239SHadi Asyrafi fpga_config_buffers[i].write_requested = 0; 121c76d4239SHadi Asyrafi current_block++; 122c76d4239SHadi Asyrafi *buffer_addr_completed = 123c76d4239SHadi Asyrafi fpga_config_buffers[i].addr; 124c76d4239SHadi Asyrafi return 0; 125c76d4239SHadi Asyrafi } 126c76d4239SHadi Asyrafi } 127c76d4239SHadi Asyrafi } 128c76d4239SHadi Asyrafi 129c76d4239SHadi Asyrafi return -1; 130c76d4239SHadi Asyrafi } 131c76d4239SHadi Asyrafi 132c76d4239SHadi Asyrafi int intel_fpga_config_completed_write(uint32_t *completed_addr, 133c76d4239SHadi Asyrafi uint32_t *count) 134c76d4239SHadi Asyrafi { 135c76d4239SHadi Asyrafi uint32_t status = INTEL_SIP_SMC_STATUS_OK; 136c76d4239SHadi Asyrafi *count = 0; 137c76d4239SHadi Asyrafi int resp_len = 0; 138c76d4239SHadi Asyrafi uint32_t resp[5]; 139c76d4239SHadi Asyrafi int all_completed = 1; 140c76d4239SHadi Asyrafi 141cefb37ebSTien Hock, Loh while (*count < 3) { 142c76d4239SHadi Asyrafi 14396612fcaSHadi Asyrafi resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID, 14496612fcaSHadi Asyrafi resp, sizeof(resp) / sizeof(resp[0])); 145c76d4239SHadi Asyrafi 146cefb37ebSTien Hock, Loh if (resp_len < 0) 147cefb37ebSTien Hock, Loh break; 148c76d4239SHadi Asyrafi 149c76d4239SHadi Asyrafi max_blocks++; 150cefb37ebSTien Hock, Loh rcv_id++; 151cefb37ebSTien Hock, Loh 152c76d4239SHadi Asyrafi if (mark_last_buffer_xfer_completed( 153c76d4239SHadi Asyrafi &completed_addr[*count]) == 0) 154c76d4239SHadi Asyrafi *count = *count + 1; 155c76d4239SHadi Asyrafi else 156c76d4239SHadi Asyrafi break; 157c76d4239SHadi Asyrafi } 158c76d4239SHadi Asyrafi 159c76d4239SHadi Asyrafi if (*count <= 0) { 160c76d4239SHadi Asyrafi if (resp_len != MBOX_NO_RESPONSE && 161c76d4239SHadi Asyrafi resp_len != MBOX_TIMEOUT && resp_len != 0) { 162cefb37ebSTien Hock, Loh mailbox_clear_response(); 163c76d4239SHadi Asyrafi return INTEL_SIP_SMC_STATUS_ERROR; 164c76d4239SHadi Asyrafi } 165c76d4239SHadi Asyrafi 166c76d4239SHadi Asyrafi *count = 0; 167c76d4239SHadi Asyrafi } 168c76d4239SHadi Asyrafi 169c76d4239SHadi Asyrafi intel_fpga_sdm_write_all(); 170c76d4239SHadi Asyrafi 171c76d4239SHadi Asyrafi if (*count > 0) 172c76d4239SHadi Asyrafi status = INTEL_SIP_SMC_STATUS_OK; 173c76d4239SHadi Asyrafi else if (*count == 0) 174c76d4239SHadi Asyrafi status = INTEL_SIP_SMC_STATUS_BUSY; 175c76d4239SHadi Asyrafi 176c76d4239SHadi Asyrafi for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 177c76d4239SHadi Asyrafi if (fpga_config_buffers[i].write_requested != 0) { 178c76d4239SHadi Asyrafi all_completed = 0; 179c76d4239SHadi Asyrafi break; 180c76d4239SHadi Asyrafi } 181c76d4239SHadi Asyrafi } 182c76d4239SHadi Asyrafi 183c76d4239SHadi Asyrafi if (all_completed == 1) 184c76d4239SHadi Asyrafi return INTEL_SIP_SMC_STATUS_OK; 185c76d4239SHadi Asyrafi 186c76d4239SHadi Asyrafi return status; 187c76d4239SHadi Asyrafi } 188c76d4239SHadi Asyrafi 189c76d4239SHadi Asyrafi int intel_fpga_config_start(uint32_t config_type) 190c76d4239SHadi Asyrafi { 191c76d4239SHadi Asyrafi uint32_t response[3]; 192c76d4239SHadi Asyrafi int status = 0; 193c76d4239SHadi Asyrafi 194cefb37ebSTien Hock, Loh mailbox_clear_response(); 195cefb37ebSTien Hock, Loh 19696612fcaSHadi Asyrafi mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0); 197cefb37ebSTien Hock, Loh 198cefb37ebSTien Hock, Loh status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0, 19996612fcaSHadi Asyrafi response, sizeof(response) / sizeof(response[0])); 200c76d4239SHadi Asyrafi 201c76d4239SHadi Asyrafi if (status < 0) 202c76d4239SHadi Asyrafi return status; 203c76d4239SHadi Asyrafi 204c76d4239SHadi Asyrafi max_blocks = response[0]; 205c76d4239SHadi Asyrafi bytes_per_block = response[1]; 206c76d4239SHadi Asyrafi 207c76d4239SHadi Asyrafi for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 208c76d4239SHadi Asyrafi fpga_config_buffers[i].size = 0; 209c76d4239SHadi Asyrafi fpga_config_buffers[i].size_written = 0; 210c76d4239SHadi Asyrafi fpga_config_buffers[i].addr = 0; 211c76d4239SHadi Asyrafi fpga_config_buffers[i].write_requested = 0; 212c76d4239SHadi Asyrafi fpga_config_buffers[i].block_number = 0; 213c76d4239SHadi Asyrafi fpga_config_buffers[i].subblocks_sent = 0; 214c76d4239SHadi Asyrafi } 215c76d4239SHadi Asyrafi 216c76d4239SHadi Asyrafi blocks_submitted = 0; 217c76d4239SHadi Asyrafi current_block = 0; 218cefb37ebSTien Hock, Loh read_block = 0; 219c76d4239SHadi Asyrafi current_buffer = 0; 220cefb37ebSTien Hock, Loh send_id = 0; 221cefb37ebSTien Hock, Loh rcv_id = 0; 222c76d4239SHadi Asyrafi 223c76d4239SHadi Asyrafi return 0; 224c76d4239SHadi Asyrafi } 225c76d4239SHadi Asyrafi 2267c58fd4eSHadi Asyrafi static bool is_fpga_config_buffer_full(void) 2277c58fd4eSHadi Asyrafi { 2287c58fd4eSHadi Asyrafi for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) 2297c58fd4eSHadi Asyrafi if (!fpga_config_buffers[i].write_requested) 2307c58fd4eSHadi Asyrafi return false; 2317c58fd4eSHadi Asyrafi return true; 2327c58fd4eSHadi Asyrafi } 2337c58fd4eSHadi Asyrafi 2347c58fd4eSHadi Asyrafi static bool is_address_in_ddr_range(uint64_t addr) 2357c58fd4eSHadi Asyrafi { 2367c58fd4eSHadi Asyrafi if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) 2377c58fd4eSHadi Asyrafi return true; 2387c58fd4eSHadi Asyrafi 2397c58fd4eSHadi Asyrafi return false; 2407c58fd4eSHadi Asyrafi } 241c76d4239SHadi Asyrafi 242c76d4239SHadi Asyrafi uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) 243c76d4239SHadi Asyrafi { 2447c58fd4eSHadi Asyrafi int i; 245c76d4239SHadi Asyrafi 2467c58fd4eSHadi Asyrafi intel_fpga_sdm_write_all(); 247c76d4239SHadi Asyrafi 2487c58fd4eSHadi Asyrafi if (!is_address_in_ddr_range(mem) || 2497c58fd4eSHadi Asyrafi !is_address_in_ddr_range(mem + size) || 2507c58fd4eSHadi Asyrafi is_fpga_config_buffer_full()) 2517c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_REJECTED; 252c76d4239SHadi Asyrafi 253c76d4239SHadi Asyrafi for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { 2547c58fd4eSHadi Asyrafi int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE; 2557c58fd4eSHadi Asyrafi 2567c58fd4eSHadi Asyrafi if (!fpga_config_buffers[j].write_requested) { 2577c58fd4eSHadi Asyrafi fpga_config_buffers[j].addr = mem; 2587c58fd4eSHadi Asyrafi fpga_config_buffers[j].size = size; 2597c58fd4eSHadi Asyrafi fpga_config_buffers[j].size_written = 0; 2607c58fd4eSHadi Asyrafi fpga_config_buffers[j].write_requested = 1; 2617c58fd4eSHadi Asyrafi fpga_config_buffers[j].block_number = 262c76d4239SHadi Asyrafi blocks_submitted++; 2637c58fd4eSHadi Asyrafi fpga_config_buffers[j].subblocks_sent = 0; 264c76d4239SHadi Asyrafi break; 265c76d4239SHadi Asyrafi } 266c76d4239SHadi Asyrafi } 267c76d4239SHadi Asyrafi 2687c58fd4eSHadi Asyrafi if (is_fpga_config_buffer_full()) 2697c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_BUSY; 270c76d4239SHadi Asyrafi 2717c58fd4eSHadi Asyrafi return INTEL_SIP_SMC_STATUS_OK; 272c76d4239SHadi Asyrafi } 273c76d4239SHadi Asyrafi 274*13d33d52SHadi Asyrafi static int is_out_of_sec_range(uint64_t reg_addr) 275*13d33d52SHadi Asyrafi { 276*13d33d52SHadi Asyrafi switch (reg_addr) { 277*13d33d52SHadi Asyrafi case(0xF8011100): /* ECCCTRL1 */ 278*13d33d52SHadi Asyrafi case(0xF8011104): /* ECCCTRL2 */ 279*13d33d52SHadi Asyrafi case(0xF8011110): /* ERRINTEN */ 280*13d33d52SHadi Asyrafi case(0xF8011114): /* ERRINTENS */ 281*13d33d52SHadi Asyrafi case(0xF8011118): /* ERRINTENR */ 282*13d33d52SHadi Asyrafi case(0xF801111C): /* INTMODE */ 283*13d33d52SHadi Asyrafi case(0xF8011120): /* INTSTAT */ 284*13d33d52SHadi Asyrafi case(0xF8011124): /* DIAGINTTEST */ 285*13d33d52SHadi Asyrafi case(0xF801112C): /* DERRADDRA */ 286*13d33d52SHadi Asyrafi case(0xFFD12028): /* SDMMCGRP_CTRL */ 287*13d33d52SHadi Asyrafi case(0xFFD12044): /* EMAC0 */ 288*13d33d52SHadi Asyrafi case(0xFFD12048): /* EMAC1 */ 289*13d33d52SHadi Asyrafi case(0xFFD1204C): /* EMAC2 */ 290*13d33d52SHadi Asyrafi case(0xFFD12090): /* ECC_INT_MASK_VALUE */ 291*13d33d52SHadi Asyrafi case(0xFFD12094): /* ECC_INT_MASK_SET */ 292*13d33d52SHadi Asyrafi case(0xFFD12098): /* ECC_INT_MASK_CLEAR */ 293*13d33d52SHadi Asyrafi case(0xFFD1209C): /* ECC_INTSTATUS_SERR */ 294*13d33d52SHadi Asyrafi case(0xFFD120A0): /* ECC_INTSTATUS_DERR */ 295*13d33d52SHadi Asyrafi case(0xFFD120C0): /* NOC_TIMEOUT */ 296*13d33d52SHadi Asyrafi case(0xFFD120C4): /* NOC_IDLEREQ_SET */ 297*13d33d52SHadi Asyrafi case(0xFFD120C8): /* NOC_IDLEREQ_CLR */ 298*13d33d52SHadi Asyrafi case(0xFFD120D0): /* NOC_IDLEACK */ 299*13d33d52SHadi Asyrafi case(0xFFD120D4): /* NOC_IDLESTATUS */ 300*13d33d52SHadi Asyrafi case(0xFFD12200): /* BOOT_SCRATCH_COLD0 */ 301*13d33d52SHadi Asyrafi case(0xFFD12204): /* BOOT_SCRATCH_COLD1 */ 302*13d33d52SHadi Asyrafi case(0xFFD12220): /* BOOT_SCRATCH_COLD8 */ 303*13d33d52SHadi Asyrafi case(0xFFD12224): /* BOOT_SCRATCH_COLD9 */ 304*13d33d52SHadi Asyrafi return 0; 305*13d33d52SHadi Asyrafi 306*13d33d52SHadi Asyrafi default: 307*13d33d52SHadi Asyrafi break; 308*13d33d52SHadi Asyrafi } 309*13d33d52SHadi Asyrafi 310*13d33d52SHadi Asyrafi return -1; 311*13d33d52SHadi Asyrafi } 312*13d33d52SHadi Asyrafi 313*13d33d52SHadi Asyrafi /* Secure register access */ 314*13d33d52SHadi Asyrafi uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) 315*13d33d52SHadi Asyrafi { 316*13d33d52SHadi Asyrafi if (is_out_of_sec_range(reg_addr)) 317*13d33d52SHadi Asyrafi return INTEL_SIP_SMC_STATUS_ERROR; 318*13d33d52SHadi Asyrafi 319*13d33d52SHadi Asyrafi *retval = mmio_read_32(reg_addr); 320*13d33d52SHadi Asyrafi 321*13d33d52SHadi Asyrafi return INTEL_SIP_SMC_STATUS_OK; 322*13d33d52SHadi Asyrafi } 323*13d33d52SHadi Asyrafi 324*13d33d52SHadi Asyrafi uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val, 325*13d33d52SHadi Asyrafi uint32_t *retval) 326*13d33d52SHadi Asyrafi { 327*13d33d52SHadi Asyrafi if (is_out_of_sec_range(reg_addr)) 328*13d33d52SHadi Asyrafi return INTEL_SIP_SMC_STATUS_ERROR; 329*13d33d52SHadi Asyrafi 330*13d33d52SHadi Asyrafi mmio_write_32(reg_addr, val); 331*13d33d52SHadi Asyrafi 332*13d33d52SHadi Asyrafi return intel_secure_reg_read(reg_addr, retval); 333*13d33d52SHadi Asyrafi } 334*13d33d52SHadi Asyrafi 335*13d33d52SHadi Asyrafi uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, 336*13d33d52SHadi Asyrafi uint32_t val, uint32_t *retval) 337*13d33d52SHadi Asyrafi { 338*13d33d52SHadi Asyrafi if (!intel_secure_reg_read(reg_addr, retval)) { 339*13d33d52SHadi Asyrafi *retval &= ~mask; 340*13d33d52SHadi Asyrafi *retval |= val; 341*13d33d52SHadi Asyrafi return intel_secure_reg_write(reg_addr, *retval, retval); 342*13d33d52SHadi Asyrafi } 343*13d33d52SHadi Asyrafi 344*13d33d52SHadi Asyrafi return INTEL_SIP_SMC_STATUS_ERROR; 345*13d33d52SHadi Asyrafi } 346*13d33d52SHadi Asyrafi 347c76d4239SHadi Asyrafi /* 348c76d4239SHadi Asyrafi * This function is responsible for handling all SiP calls from the NS world 349c76d4239SHadi Asyrafi */ 350c76d4239SHadi Asyrafi 351c76d4239SHadi Asyrafi uintptr_t sip_smc_handler(uint32_t smc_fid, 352c76d4239SHadi Asyrafi u_register_t x1, 353c76d4239SHadi Asyrafi u_register_t x2, 354c76d4239SHadi Asyrafi u_register_t x3, 355c76d4239SHadi Asyrafi u_register_t x4, 356c76d4239SHadi Asyrafi void *cookie, 357c76d4239SHadi Asyrafi void *handle, 358c76d4239SHadi Asyrafi u_register_t flags) 359c76d4239SHadi Asyrafi { 360*13d33d52SHadi Asyrafi uint32_t val = 0; 361c76d4239SHadi Asyrafi uint32_t status = INTEL_SIP_SMC_STATUS_OK; 362c76d4239SHadi Asyrafi uint32_t completed_addr[3]; 363c76d4239SHadi Asyrafi uint32_t count = 0; 364c76d4239SHadi Asyrafi 365c76d4239SHadi Asyrafi switch (smc_fid) { 366c76d4239SHadi Asyrafi case SIP_SVC_UID: 367c76d4239SHadi Asyrafi /* Return UID to the caller */ 368c76d4239SHadi Asyrafi SMC_UUID_RET(handle, intl_svc_uid); 369*13d33d52SHadi Asyrafi 370c76d4239SHadi Asyrafi case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE: 371c76d4239SHadi Asyrafi status = intel_mailbox_fpga_config_isdone(); 372c76d4239SHadi Asyrafi SMC_RET4(handle, status, 0, 0, 0); 373*13d33d52SHadi Asyrafi 374c76d4239SHadi Asyrafi case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM: 375c76d4239SHadi Asyrafi SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK, 376c76d4239SHadi Asyrafi INTEL_SIP_SMC_FPGA_CONFIG_ADDR, 377c76d4239SHadi Asyrafi INTEL_SIP_SMC_FPGA_CONFIG_SIZE - 378c76d4239SHadi Asyrafi INTEL_SIP_SMC_FPGA_CONFIG_ADDR); 379*13d33d52SHadi Asyrafi 380c76d4239SHadi Asyrafi case INTEL_SIP_SMC_FPGA_CONFIG_START: 381c76d4239SHadi Asyrafi status = intel_fpga_config_start(x1); 382c76d4239SHadi Asyrafi SMC_RET4(handle, status, 0, 0, 0); 383*13d33d52SHadi Asyrafi 384c76d4239SHadi Asyrafi case INTEL_SIP_SMC_FPGA_CONFIG_WRITE: 385c76d4239SHadi Asyrafi status = intel_fpga_config_write(x1, x2); 386c76d4239SHadi Asyrafi SMC_RET4(handle, status, 0, 0, 0); 387*13d33d52SHadi Asyrafi 388c76d4239SHadi Asyrafi case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: 389c76d4239SHadi Asyrafi status = intel_fpga_config_completed_write(completed_addr, 390c76d4239SHadi Asyrafi &count); 391c76d4239SHadi Asyrafi switch (count) { 392c76d4239SHadi Asyrafi case 1: 393c76d4239SHadi Asyrafi SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 394c76d4239SHadi Asyrafi completed_addr[0], 0, 0); 395*13d33d52SHadi Asyrafi 396c76d4239SHadi Asyrafi case 2: 397c76d4239SHadi Asyrafi SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 398c76d4239SHadi Asyrafi completed_addr[0], 399c76d4239SHadi Asyrafi completed_addr[1], 0); 400*13d33d52SHadi Asyrafi 401c76d4239SHadi Asyrafi case 3: 402c76d4239SHadi Asyrafi SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, 403c76d4239SHadi Asyrafi completed_addr[0], 404c76d4239SHadi Asyrafi completed_addr[1], 405c76d4239SHadi Asyrafi completed_addr[2]); 406*13d33d52SHadi Asyrafi 407c76d4239SHadi Asyrafi case 0: 408c76d4239SHadi Asyrafi SMC_RET4(handle, status, 0, 0, 0); 409*13d33d52SHadi Asyrafi 410c76d4239SHadi Asyrafi default: 411cefb37ebSTien Hock, Loh mailbox_clear_response(); 412c76d4239SHadi Asyrafi SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR); 413c76d4239SHadi Asyrafi } 414*13d33d52SHadi Asyrafi 415*13d33d52SHadi Asyrafi case INTEL_SIP_SMC_REG_READ: 416*13d33d52SHadi Asyrafi status = intel_secure_reg_read(x1, &val); 417*13d33d52SHadi Asyrafi SMC_RET3(handle, status, val, x1); 418*13d33d52SHadi Asyrafi 419*13d33d52SHadi Asyrafi case INTEL_SIP_SMC_REG_WRITE: 420*13d33d52SHadi Asyrafi status = intel_secure_reg_write(x1, (uint32_t)x2, &val); 421*13d33d52SHadi Asyrafi SMC_RET3(handle, status, val, x1); 422*13d33d52SHadi Asyrafi 423*13d33d52SHadi Asyrafi case INTEL_SIP_SMC_REG_UPDATE: 424*13d33d52SHadi Asyrafi status = intel_secure_reg_update(x1, (uint32_t)x2, 425*13d33d52SHadi Asyrafi (uint32_t)x3, &val); 426*13d33d52SHadi Asyrafi SMC_RET3(handle, status, val, x1); 427c76d4239SHadi Asyrafi 428c76d4239SHadi Asyrafi default: 429c76d4239SHadi Asyrafi return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, 430c76d4239SHadi Asyrafi cookie, handle, flags); 431c76d4239SHadi Asyrafi } 432c76d4239SHadi Asyrafi } 433c76d4239SHadi Asyrafi 434c76d4239SHadi Asyrafi DECLARE_RT_SVC( 435c76d4239SHadi Asyrafi socfpga_sip_svc, 436c76d4239SHadi Asyrafi OEN_SIP_START, 437c76d4239SHadi Asyrafi OEN_SIP_END, 438c76d4239SHadi Asyrafi SMC_TYPE_FAST, 439c76d4239SHadi Asyrafi NULL, 440c76d4239SHadi Asyrafi sip_smc_handler 441c76d4239SHadi Asyrafi ); 442c76d4239SHadi Asyrafi 443c76d4239SHadi Asyrafi DECLARE_RT_SVC( 444c76d4239SHadi Asyrafi socfpga_sip_svc_std, 445c76d4239SHadi Asyrafi OEN_SIP_START, 446c76d4239SHadi Asyrafi OEN_SIP_END, 447c76d4239SHadi Asyrafi SMC_TYPE_YIELD, 448c76d4239SHadi Asyrafi NULL, 449c76d4239SHadi Asyrafi sip_smc_handler 450c76d4239SHadi Asyrafi ); 451