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 <fbl/unique_ptr.h> 9 #include <fbl/vector.h> 10 11 #include "device-resources.h" 12 #include "proxy-protocol.h" 13 14 // This class, along with PlatformProxyDevice, represent a platform device. 15 // Platform devices run in separate devhosts than the platform bus driver. 16 // PlatformDevice exists in the platform bus devhost and PlatformProxyDevice 17 // exists in the platform device's devhost. PlatformProxyDevice proxys 18 // requests from the platform device via a channel, which are then 19 // handled by PlatformDevice::DdkRxrpc and then handled by relevant Rpc* methods. 20 // 21 // Resource handles passed to the proxy to allow it to access MMIOs and interrupts. 22 // This ensures if the proxy driver dies we will release their address space resources 23 // back to the kernel if necessary. 24 25 namespace platform_bus { 26 27 class PlatformBus; 28 29 class PlatformDevice; 30 using PlatformDeviceType = ddk::Device<PlatformDevice, ddk::Rxrpcable>; 31 32 // This class represents a platform device attached to the platform bus. 33 // Instances of this class are created by PlatformBus at boot time when the board driver 34 // calls the platform bus protocol method pbus_device_add(). 35 36 class PlatformDevice : public PlatformDeviceType { 37 public: 38 // Creates a new PlatformDevice instance. 39 // *flags* contains zero or more PDEV_ADD_* flags from the platform bus protocol. 40 static zx_status_t Create(const pbus_dev_t* pdev, zx_device_t* parent, PlatformBus* bus, 41 fbl::unique_ptr<platform_bus::PlatformDevice>* out); 42 vid()43 inline uint32_t vid() const { return vid_; } pid()44 inline uint32_t pid() const { return pid_; } did()45 inline uint32_t did() const { return did_; } 46 47 // Device protocol implementation. 48 void DdkRelease(); 49 zx_status_t DdkRxrpc(zx_handle_t channel); 50 51 // Starts the underlying devmgr device. 52 zx_status_t Start(); 53 54 private: 55 // *flags* contains zero or more PDEV_ADD_* flags from the platform bus protocol. 56 explicit PlatformDevice(zx_device_t* parent, PlatformBus* bus, const pbus_dev_t* pdev); 57 zx_status_t Init(const pbus_dev_t* pdev); 58 59 // Handlers for RPCs from PlatformProxy. 60 zx_status_t RpcGetMmio(const DeviceResources* dr, uint32_t index, zx_paddr_t* out_paddr, 61 size_t* out_length, zx_handle_t* out_handle, uint32_t* out_handle_count); 62 zx_status_t RpcGetInterrupt(const DeviceResources* dr, uint32_t index, uint32_t* out_irq, 63 uint32_t* out_mode, zx_handle_t* out_handle, 64 uint32_t* out_handle_count); 65 zx_status_t RpcGetBti(const DeviceResources* dr, uint32_t index, zx_handle_t* out_handle, 66 uint32_t* out_handle_count); 67 zx_status_t RpcGetSmc(const DeviceResources* dr, uint32_t index, 68 zx_handle_t* out_handle, uint32_t* out_handle_count); 69 zx_status_t RpcGetDeviceInfo(const DeviceResources* dr, pdev_device_info_t* out_info); 70 zx_status_t RpcDeviceAdd(const DeviceResources* dr, uint32_t index, uint32_t* out_device_id); 71 zx_status_t RpcGetMetadata(const DeviceResources* dr, uint32_t index, uint32_t* out_type, 72 uint8_t* buf, uint32_t buf_size, uint32_t* actual); 73 zx_status_t RpcGetProtocols(const DeviceResources* dr, uint32_t* out_protocols, 74 uint32_t* out_protocol_count); 75 zx_status_t RpcGpioConfigIn(const DeviceResources* dr, uint32_t index, uint32_t flags); 76 zx_status_t RpcGpioConfigOut(const DeviceResources* dr, uint32_t index, uint8_t initial_value); 77 zx_status_t RpcGpioSetAltFunction(const DeviceResources* dr, uint32_t index, uint64_t function); 78 zx_status_t RpcGpioRead(const DeviceResources* dr, uint32_t index, uint8_t* out_value); 79 zx_status_t RpcGpioWrite(const DeviceResources* dr, uint32_t index, uint8_t value); 80 zx_status_t RpcGpioGetInterrupt(const DeviceResources* dr, uint32_t index, uint32_t flags, 81 zx_handle_t* out_handle, uint32_t* out_handle_count); 82 zx_status_t RpcGpioReleaseInterrupt(const DeviceResources* dr, uint32_t index); 83 zx_status_t RpcGpioSetPolarity(const DeviceResources* dr, uint32_t index, uint32_t flags); 84 zx_status_t RpcI2cTransact(const DeviceResources* dr, uint32_t txid, rpc_i2c_req_t* req, 85 zx_handle_t channel); 86 zx_status_t RpcI2cGetMaxTransferSize(const DeviceResources* dr, uint32_t index, 87 size_t* out_size); 88 zx_status_t RpcClkEnable(const DeviceResources* dr, uint32_t index); 89 zx_status_t RpcClkDisable(const DeviceResources* dr, uint32_t index); 90 91 PlatformBus* bus_; 92 char name_[ZX_DEVICE_NAME_MAX + 1]; 93 const uint32_t vid_; 94 const uint32_t pid_; 95 const uint32_t did_; 96 97 // Tree of platform bus resources for this device and its children. 98 DeviceResources resource_tree_; 99 100 // Flattened list of DeviceResources, indexed by device ID. 101 // device_index_[0] returns the DeviceResources for this top level device. 102 fbl::Vector<const DeviceResources*> device_index_; 103 }; 104 105 } // namespace platform_bus 106