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 <ddktl/device.h> 8 #include <ddktl/protocol/platform/bus.h> 9 #include <ddktl/protocol/platform/device.h> 10 #include <fbl/unique_ptr.h> 11 #include <fbl/vector.h> 12 13 #include "device-resources.h" 14 #include "proxy-protocol.h" 15 16 namespace platform_bus { 17 18 class PlatformBus; 19 20 // This class is used for binding protocol implementation drivers. 21 // It implements the platform device protocol, and also provides access to the 22 // a subset of the platform bus protocol, and also the other protocols that are 23 // available to platform devices. 24 // Unlike platform device drivers, proto implementation drivers run in the same 25 // devhost as the platform bus driver. 26 27 class ProtocolDevice; 28 using ProtocolDeviceType = ddk::Device<ProtocolDevice, ddk::GetProtocolable>; 29 30 // This class represents a platform device attached to the platform bus. 31 // Instances of this class are created by PlatformBus at boot time when the board driver 32 // calls the platform bus protocol method pbus_device_add(). 33 34 class ProtocolDevice : public ProtocolDeviceType, 35 public ddk::PDevProtocol<ProtocolDevice, ddk::base_protocol> { 36 public: 37 // Creates a new ProtocolDevice instance. 38 // *flags* contains zero or more PDEV_ADD_* flags from the platform bus protocol. 39 static zx_status_t Create(const pbus_dev_t* pdev, zx_device_t* parent, PlatformBus* bus, 40 fbl::unique_ptr<platform_bus::ProtocolDevice>* out); 41 vid()42 inline uint32_t vid() const { return vid_; } pid()43 inline uint32_t pid() const { return pid_; } did()44 inline uint32_t did() const { return did_; } 45 46 // Device protocol implementation. 47 zx_status_t DdkGetProtocol(uint32_t proto_id, void* out); 48 void DdkRelease(); 49 50 // Platform device protocol implementation. 51 zx_status_t PDevGetMmio(uint32_t index, pdev_mmio_t* out_mmio); 52 zx_status_t PDevMapMmio(uint32_t index, uint32_t cache_policy, void** out_vaddr, 53 size_t* out_size, zx_paddr_t* out_paddr, zx::vmo* out_vmo); 54 zx_status_t PDevGetInterrupt(uint32_t index, uint32_t flags, zx::interrupt* out_irq); 55 zx_status_t PDevGetBti(uint32_t index, zx::bti* out_handle); 56 zx_status_t PDevGetSmc(uint32_t index, zx::resource* out_resource); 57 zx_status_t PDevGetDeviceInfo(pdev_device_info_t* out_info); 58 zx_status_t PDevGetBoardInfo(pdev_board_info_t* out_info); 59 zx_status_t PDevDeviceAdd(uint32_t index, const device_add_args_t* args, zx_device_t** device); 60 zx_status_t PDevGetProtocol(uint32_t proto_id, uint32_t index, void* out_protocol, 61 size_t protocol_size, size_t* protocol_actual); 62 63 // Starts the underlying devmgr device. 64 zx_status_t Start(); 65 66 private: 67 explicit ProtocolDevice(zx_device_t* parent, PlatformBus* bus, const pbus_dev_t* pdev); 68 zx_status_t Init(const pbus_dev_t* pdev); 69 70 PlatformBus* bus_; 71 char name_[ZX_DEVICE_NAME_MAX + 1]; 72 const uint32_t vid_; 73 const uint32_t pid_; 74 const uint32_t did_; 75 76 // Platform bus resources for this device. 77 DeviceResources resources_; 78 79 // Restricted subset of the platform bus protocol. 80 // We do not allow protocol devices call pbus_device_add() or pbus_protocol_device_add() 81 pbus_protocol_ops_t pbus_ops_; 82 void* pbus_ctx_; 83 }; 84 85 } // namespace platform_bus 86