blob: ea0e8090af97b4c5c13e39a7c5eefce221976086 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <ddk/device.h>
#include <ddk/protocol/platform/device.h>
#include <ddk/protocol/platform-device-lib.h>
#include <zircon/process.h>
#include "magma_util/dlog.h"
#include "magma_util/macros.h"
#include "platform_mmio.h"
#include "zircon_platform_device.h"
#include "zircon_platform_handle.h"
#include "zircon_platform_interrupt.h"
#include "zircon_platform_mmio.h"
namespace magma {
std::unique_ptr<PlatformMmio>
ZirconPlatformDevice::CpuMapMmio(unsigned int index, PlatformMmio::CachePolicy cache_policy)
{
DLOG("CpuMapMmio index %d", index);
zx_status_t status;
mmio_buffer_t mmio_buffer;
status = pdev_map_mmio_buffer(&pdev_, index, ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio_buffer);
if (status != ZX_OK) {
DRETP(nullptr, "mapping resource failed");
}
std::unique_ptr<ZirconPlatformMmio> mmio(new ZirconPlatformMmio(mmio_buffer));
DLOG("map_mmio index %d cache_policy %d returned: 0x%x", index, static_cast<int>(cache_policy),
mmio_buffer.vmo);
return mmio;
}
std::unique_ptr<PlatformInterrupt> ZirconPlatformDevice::RegisterInterrupt(unsigned int index)
{
zx_handle_t interrupt_handle;
zx_status_t status = pdev_map_interrupt(&pdev_, index, &interrupt_handle);
if (status != ZX_OK)
return DRETP(nullptr, "register interrupt failed");
return std::make_unique<ZirconPlatformInterrupt>(zx::handle(interrupt_handle));
}
std::unique_ptr<PlatformHandle> ZirconPlatformDevice::GetBusTransactionInitiator()
{
zx_handle_t bti_handle;
zx_status_t status = pdev_get_bti(&pdev_, 0, &bti_handle);
if (status != ZX_OK)
return DRETP(nullptr, "failed to get bus transaction initiator");
return std::make_unique<ZirconPlatformHandle>(zx::handle(bti_handle));
}
std::unique_ptr<PlatformDevice> PlatformDevice::Create(void* device_handle)
{
if (!device_handle)
return DRETP(nullptr, "device_handle is null, cannot create PlatformDevice");
zx_device_t* zx_device = static_cast<zx_device_t*>(device_handle);
pdev_protocol_t pdev;
if (device_get_protocol(zx_device, ZX_PROTOCOL_PDEV, &pdev) != ZX_OK)
return DRETP(nullptr, "Failed to get protocol\n");
return std::unique_ptr<PlatformDevice>(new ZirconPlatformDevice(zx_device, pdev));
}
} // namespace magma