110859Sandreas.sandberg@arm.com/*
210859Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited
310859Sandreas.sandberg@arm.com * All rights reserved
410859Sandreas.sandberg@arm.com *
510859Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610859Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710859Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810859Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910859Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010859Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110859Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210859Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310859Sandreas.sandberg@arm.com *
1410859Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1510859Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1610859Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1710859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1810859Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1910859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2010859Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2110859Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2210859Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2310859Sandreas.sandberg@arm.com * this software without specific prior written permission.
2410859Sandreas.sandberg@arm.com *
2510859Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610859Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710859Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810859Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910859Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010859Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110859Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210859Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310859Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410859Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510859Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610859Sandreas.sandberg@arm.com *
3710859Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3810859Sandreas.sandberg@arm.com */
3910859Sandreas.sandberg@arm.com
4010859Sandreas.sandberg@arm.com#ifndef __CPU_KVM_DEVICE_HH__
4110859Sandreas.sandberg@arm.com#define __CPU_KVM_DEVICE_HH__
4210859Sandreas.sandberg@arm.com
4310859Sandreas.sandberg@arm.com#include <cstdint>
4410859Sandreas.sandberg@arm.com
4510859Sandreas.sandberg@arm.com/**
4610859Sandreas.sandberg@arm.com * KVM device wrapper
4710859Sandreas.sandberg@arm.com *
4810859Sandreas.sandberg@arm.com * This is a wrapper around a device emulated by KVM. Such devices can
4910859Sandreas.sandberg@arm.com * be created using KvmVM::createDevice() API. They are typically used
5010859Sandreas.sandberg@arm.com * for in-kernel interrupt controllers and similar devices.
5110859Sandreas.sandberg@arm.com *
5210859Sandreas.sandberg@arm.com * Each device has a device-specific set of attributes which are
5310859Sandreas.sandberg@arm.com * mapped into groups. The available attributes are described in the
5410859Sandreas.sandberg@arm.com * device's documentation in the kernel source tree
5510859Sandreas.sandberg@arm.com * (Documentation/virtual/kvm/devices/). Each attribute can be
5610859Sandreas.sandberg@arm.com * accessed with the getAttr() and setAttr() access methods. The
5710859Sandreas.sandberg@arm.com * presence of an attribute can be queried using the hasAttr() method.
5810859Sandreas.sandberg@arm.com */
5910859Sandreas.sandberg@arm.comclass KvmDevice
6010859Sandreas.sandberg@arm.com{
6110859Sandreas.sandberg@arm.com  public:
6210859Sandreas.sandberg@arm.com    KvmDevice(int fd);
6310859Sandreas.sandberg@arm.com    virtual ~KvmDevice();
6410859Sandreas.sandberg@arm.com
6510859Sandreas.sandberg@arm.com  public:
6610859Sandreas.sandberg@arm.com    /**
6710859Sandreas.sandberg@arm.com     * Get the value of an attribute
6810859Sandreas.sandberg@arm.com     *
6910859Sandreas.sandberg@arm.com     * See KVM's documentation, and specifically the device-specific
7010859Sandreas.sandberg@arm.com     * documentation, for available attributes and attribute groups.
7110859Sandreas.sandberg@arm.com     *
7210859Sandreas.sandberg@arm.com     * @param group Attribute group
7310859Sandreas.sandberg@arm.com     * @param attr Attribute ID within group
7410859Sandreas.sandberg@arm.com     * @return Attribute value
7510859Sandreas.sandberg@arm.com     */
7610859Sandreas.sandberg@arm.com    template<typename T>
7710859Sandreas.sandberg@arm.com    T getAttr(uint32_t group, uint64_t attr) const {
7810859Sandreas.sandberg@arm.com        T data;
7910859Sandreas.sandberg@arm.com        getAttrPtr(group, attr, &data);
8010859Sandreas.sandberg@arm.com        return data;
8110859Sandreas.sandberg@arm.com    }
8210859Sandreas.sandberg@arm.com
8310859Sandreas.sandberg@arm.com    /**
8410859Sandreas.sandberg@arm.com     * Get the value of an attribute
8510859Sandreas.sandberg@arm.com     *
8610859Sandreas.sandberg@arm.com     * See KVM's documentation, and specifically the device-specific
8710859Sandreas.sandberg@arm.com     * documentation, for available attributes and attribute groups.
8810859Sandreas.sandberg@arm.com     *
8910859Sandreas.sandberg@arm.com     * @param group Attribute group
9010859Sandreas.sandberg@arm.com     * @param attr Attribute ID within group
9110859Sandreas.sandberg@arm.com     * @return Attribute value
9210859Sandreas.sandberg@arm.com     */
9310859Sandreas.sandberg@arm.com    template<typename T>
9410859Sandreas.sandberg@arm.com    void setAttr(uint32_t group, uint64_t attr, const T &data) const {
9510859Sandreas.sandberg@arm.com        setAttrPtr(group, attr, &data);
9610859Sandreas.sandberg@arm.com    }
9710859Sandreas.sandberg@arm.com
9810859Sandreas.sandberg@arm.com    void getAttrPtr(uint32_t group, uint64_t attr, void *data) const;
9910859Sandreas.sandberg@arm.com    void setAttrPtr(uint32_t group, uint64_t attr, const void *data) const;
10010859Sandreas.sandberg@arm.com
10110859Sandreas.sandberg@arm.com    /**
10210859Sandreas.sandberg@arm.com     * Check if a device attribute is valid
10310859Sandreas.sandberg@arm.com     *
10410859Sandreas.sandberg@arm.com     * See KVM's documentation, and specifically the device-specific
10510859Sandreas.sandberg@arm.com     * documentation, for available attributes and attribute groups.
10610859Sandreas.sandberg@arm.com     *
10710859Sandreas.sandberg@arm.com     * @param group Attribute group
10810859Sandreas.sandberg@arm.com     * @param attr Attribute ID within group
10910859Sandreas.sandberg@arm.com     * @return true if attribute is valid, false otherwise.
11010859Sandreas.sandberg@arm.com     */
11110859Sandreas.sandberg@arm.com    bool hasAttr(uint32_t group, uint64_t attr) const;
11210859Sandreas.sandberg@arm.com
11310859Sandreas.sandberg@arm.com  protected:
11410859Sandreas.sandberg@arm.com    int ioctl(int request, long p1) const;
11510859Sandreas.sandberg@arm.com    int ioctl(int request, void *p1) const {
11610859Sandreas.sandberg@arm.com        return ioctl(request, (long)p1);
11710859Sandreas.sandberg@arm.com    }
11810859Sandreas.sandberg@arm.com    int ioctl(int request) const {
11910859Sandreas.sandberg@arm.com        return ioctl(request, 0L);
12010859Sandreas.sandberg@arm.com    }
12110859Sandreas.sandberg@arm.com
12210859Sandreas.sandberg@arm.com  private:
12310859Sandreas.sandberg@arm.com    int fd;
12410859Sandreas.sandberg@arm.com};
12510859Sandreas.sandberg@arm.com
12610859Sandreas.sandberg@arm.com#endif // __CPU_KVM_DEVICE_HH__
127