// Copyright 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "DmaMap.h"

#include "base/Lookup.h"
#include "base/StreamSerializing.h"
#include "host-common/android_pipe_device.h"

#include <type_traits>
#include <inttypes.h>
#include <stdio.h>

#define DEBUG 0

#if DEBUG >= 1
#define D(fmt,...) fprintf(stderr, "DmaMap: %s: " fmt "\n", __func__, ##__VA_ARGS__);
#else
#define D(...) (void)0
#endif

#if DEBUG >= 2
#define DD(fmt,...) fprintf(stderr, "DmaMap: %s: " fmt "\n", __func__, ##__VA_ARGS__);
#else
#define DD(...) (void)0
#endif

#define E(fmt,...) fprintf(stderr, "DmaMap: ERROR: %s: " fmt "\n", __func__, ##__VA_ARGS__);

namespace android {

static DmaMap* sInstance = nullptr;

DmaMap* DmaMap::get() {
    return sInstance;
}

DmaMap* DmaMap::set(DmaMap* dmaMap) {
    DmaMap* result = sInstance;
    sInstance = dmaMap;
    return result;
}

void DmaMap::addBuffer(void* hwpipe,
                       uint64_t guest_paddr,
                       uint64_t bufferSize) {
    D("guest paddr 0x%llx bufferSize %llu",
      (unsigned long long)guest_paddr,
      (unsigned long long)bufferSize);
    DmaBufferInfo info;
    info.hwpipe = hwpipe;
    info.guestAddr = guest_paddr; // guest address
    info.bufferSize = bufferSize; // size of buffer
    info.currHostAddr = kNullopt; // no current host address
    android::base::AutoWriteLock lock(mLock);
    createMappingLocked(&info);
    mDmaBuffers[guest_paddr] = info;
}

void DmaMap::removeBuffer(uint64_t guest_paddr) {
    D("guest paddr 0x%llx", (unsigned long long)guest_paddr);
    android::base::AutoWriteLock lock(mLock);
    if (auto info = android::base::find(mDmaBuffers, guest_paddr)) {
        removeMappingLocked(info);
        mDmaBuffers.erase(guest_paddr);
    } else {
        E("guest addr 0x%llx not alloced!",
          (unsigned long long)guest_paddr);
    }
}

void* DmaMap::getHostAddr(uint64_t guest_paddr) {
    DD("guest paddr 0x%llx", (unsigned long long)guest_paddr);
    android::base::AutoReadLock rlock(mLock);
    if (auto info = android::base::find(mDmaBuffers, guest_paddr)) {
        if (info->currHostAddr) {
            DD("guest paddr 0x%llx -> host 0x%llx valid",
              (unsigned long long)guest_paddr,
              (unsigned long long)(*info->currHostAddr));
            return *(info->currHostAddr);
        } else {
            rlock.unlockRead();
            android::base::AutoWriteLock wlock(mLock);
            createMappingLocked(info);
            D("guest paddr 0x%llx -> host 0x%llx valid (new)",
              (unsigned long long)guest_paddr,
              (unsigned long long)*(info->currHostAddr));
            return *(info->currHostAddr);
        }
    } else {
        E("guest paddr 0x%llx not alloced!",
          (unsigned long long)guest_paddr);
        return 0;
    }
}

void DmaMap::invalidateHostMappings() {
    android::base::AutoWriteLock lock(mLock);
    for (auto& it : mDmaBuffers) {
        removeMappingLocked(&it.second);
    }
}

void DmaMap::resetHostMappings() {
    android::base::AutoWriteLock lock(mLock);
    for (auto& it : mDmaBuffers) {
        removeMappingLocked(&it.second);
    }
    mDmaBuffers.clear();
}

void* DmaMap::getPipeInstance(uint64_t guest_paddr) {
    android::base::AutoReadLock lock(mLock);
    if (auto info = android::base::find(mDmaBuffers, guest_paddr)) {
        return info->hwpipe;
    } else {
        return nullptr;
    }
}

void DmaMap::createMappingLocked(DmaBufferInfo* info) {
    info->currHostAddr = doMap(info->guestAddr, info->bufferSize);
}

void DmaMap::removeMappingLocked(DmaBufferInfo* info ) {
    if (info->currHostAddr) {
        doUnmap(*(info->currHostAddr), info->bufferSize);
        info->currHostAddr = kNullopt;
        D("guest addr 0x%llx host mapping 0x%llx removed.",
          (unsigned long long)info->guestAddr,
          (unsigned long long)info->currHostAddr);
    } else {
        D("guest addr 0x%llx has no host mapping. don't remove.",
          (unsigned long long)info->guestAddr);
    }
}

void DmaMap::save(android::base::Stream* stream) const {
    saveCollection(stream, mDmaBuffers,
                   [](android::base::Stream* stream,
                      const DmaBufferMap::value_type& v) {
        stream->putBe64(v.first); // guest paddr
        stream->putBe32(android_pipe_get_id(v.second.hwpipe));
        stream->putBe64(v.second.guestAddr); // guest addr
        stream->putBe64(v.second.bufferSize); // buffer size
        // don't save current host addr as it is invalidated.
    });
}

void DmaMap::load(android::base::Stream* stream) {
    mDmaBuffers.clear();
    loadCollection(stream, &mDmaBuffers,
                   [](android::base::Stream* stream) {
        uint64_t gpa = stream->getBe64();

        DmaBufferInfo info;
        info.hwpipe = android_pipe_lookup_by_id(stream->getBe32()),
        info.guestAddr = stream->getBe64(),
        info.bufferSize = stream->getBe64(),
        info.currHostAddr = kNullopt;
        return std::make_pair(gpa, info);
    });
}

}  // namespace android


