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 16namespace platform_bus { 17 18class 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 27class ProtocolDevice; 28using 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 34class ProtocolDevice : public ProtocolDeviceType, public ddk::PlatformDevProtocol<ProtocolDevice> { 35public: 36 // Creates a new ProtocolDevice instance. 37 // *flags* contains zero or more PDEV_ADD_* flags from the platform bus protocol. 38 static zx_status_t Create(const pbus_dev_t* pdev, zx_device_t* parent, PlatformBus* bus, 39 fbl::unique_ptr<platform_bus::ProtocolDevice>* out); 40 41 inline uint32_t vid() const { return vid_; } 42 inline uint32_t pid() const { return pid_; } 43 inline uint32_t did() const { return did_; } 44 45 // Device protocol implementation. 46 zx_status_t DdkGetProtocol(uint32_t proto_id, void* out); 47 void DdkRelease(); 48 49 // Platform device protocol implementation. 50 zx_status_t GetMmio(uint32_t index, pdev_mmio_t* out_mmio); 51 zx_status_t MapMmio(uint32_t index, uint32_t cache_policy, void** out_vaddr, size_t* out_size, 52 zx_paddr_t* out_paddr, zx_handle_t* out_handle); 53 zx_status_t MapInterrupt(uint32_t index, uint32_t flags, zx_handle_t* out_handle); 54 zx_status_t GetBti(uint32_t index, zx_handle_t* out_handle); 55 zx_status_t GetDeviceInfo(pdev_device_info_t* out_info); 56 zx_status_t GetBoardInfo(pdev_board_info_t* out_info); 57 zx_status_t DeviceAdd(uint32_t index, device_add_args_t* args, zx_device_t** out); 58 zx_status_t GetProtocol(uint32_t proto_id, uint32_t index, void* out_protocol); 59 60 // Starts the underlying devmgr device. 61 zx_status_t Start(); 62 63private: 64 explicit ProtocolDevice(zx_device_t* parent, PlatformBus* bus, const pbus_dev_t* pdev); 65 zx_status_t Init(const pbus_dev_t* pdev); 66 67 PlatformBus* bus_; 68 char name_[ZX_DEVICE_NAME_MAX + 1]; 69 const uint32_t vid_; 70 const uint32_t pid_; 71 const uint32_t did_; 72 73 // Platform bus resources for this device. 74 DeviceResources resources_; 75 76 // Restricted subset of the platform bus protocol. 77 // We do not allow protocol devices call pbus_device_add() or pbus_protocol_device_add() 78 platform_bus_protocol_ops_t pbus_ops_; 79 void* pbus_ctx_; 80}; 81 82} // namespace platform_bus 83