1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <ddk/protocol/platform-device-lib.h> 8 #include <ddk/protocol/platform/device.h> 9 #include <ddktl/device.h> 10 #include <ddktl/protocol/empty-protocol.h> 11 #include <fbl/function.h> 12 #include <fbl/intrusive_double_list.h> 13 #include <fbl/mutex.h> 14 #include <fbl/unique_ptr.h> 15 #include <fuchsia/hardware/tee/c/fidl.h> 16 #include <zircon/thread_annotations.h> 17 18 #include "optee-message.h" 19 #include "optee-smc.h" 20 #include "shared-memory.h" 21 22 namespace optee { 23 24 class OpteeClient; 25 26 class OpteeController; 27 using OpteeControllerBase = ddk::Device<OpteeController, ddk::Openable, ddk::Unbindable>; 28 using OpteeControllerProtocol = ddk::EmptyProtocol<ZX_PROTOCOL_TEE>; 29 class OpteeController : public OpteeControllerBase, 30 public OpteeControllerProtocol { 31 public: 32 using RpcHandler = fbl::Function<zx_status_t(const RpcFunctionArgs&, RpcFunctionResult*)>; 33 OpteeController(zx_device_t * parent)34 explicit OpteeController(zx_device_t* parent) 35 : OpteeControllerBase(parent) {} 36 37 OpteeController(const OpteeController&) = delete; 38 OpteeController& operator=(const OpteeController&) = delete; 39 40 zx_status_t Bind(); 41 42 zx_status_t DdkOpen(zx_device_t** out_dev, uint32_t flags); 43 void DdkUnbind(); 44 void DdkRelease(); 45 46 // Client FIDL commands 47 zx_status_t GetOsInfo(fidl_txn_t* txn) const; 48 49 void RemoveClient(OpteeClient* client); 50 51 uint32_t CallWithMessage(const Message& message, RpcHandler rpc_handler); 52 driver_pool()53 SharedMemoryManager::DriverMemoryPool* driver_pool() const { 54 return shared_memory_manager_->driver_pool(); 55 } 56 client_pool()57 SharedMemoryManager::ClientMemoryPool* client_pool() const { 58 return shared_memory_manager_->client_pool(); 59 } 60 61 private: 62 zx_status_t ValidateApiUid() const; 63 zx_status_t ValidateApiRevision() const; 64 zx_status_t GetOsRevision(); 65 zx_status_t ExchangeCapabilities(); 66 void AddClient(OpteeClient* client); 67 void CloseClients(); 68 zx_status_t InitializeSharedMemory(); 69 zx_status_t DiscoverSharedMemoryConfig(zx_paddr_t* out_start_addr, size_t* out_size); 70 71 pdev_protocol_t pdev_proto_ = {}; 72 // TODO(rjascani): Eventually, the secure_monitor_ object should be an owned resource object 73 // created and provided to us by our parent. For now, we're simply stashing a copy of the 74 // root resource so that we can make zx_smc_calls. We can make that switch when we can properly 75 // craft a resource object dedicated only to secure monitor calls targetting the Trusted OS. 76 zx_handle_t secure_monitor_ = ZX_HANDLE_INVALID; 77 uint32_t secure_world_capabilities_ = 0; 78 fuchsia_hardware_tee_OsRevision os_revision_ = {}; 79 fbl::Mutex clients_lock_; 80 fbl::DoublyLinkedList<OpteeClient*> clients_ TA_GUARDED(clients_lock_); 81 fbl::unique_ptr<SharedMemoryManager> shared_memory_manager_; 82 }; 83 84 } // namespace optee 85