Many files include qemu/log.h without needing it. Remove the superfluous include statements. Signed-off-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20210328054833.2351597-1-thuth@redhat.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
		
			
				
	
	
		
			177 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2018, Impinj, Inc.
 | 
						|
 *
 | 
						|
 * Chipidea USB block emulation code
 | 
						|
 *
 | 
						|
 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
 | 
						|
 *
 | 
						|
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | 
						|
 * See the COPYING file in the top-level directory.
 | 
						|
 */
 | 
						|
 | 
						|
#include "qemu/osdep.h"
 | 
						|
#include "hw/usb/hcd-ehci.h"
 | 
						|
#include "hw/usb/chipidea.h"
 | 
						|
#include "qemu/module.h"
 | 
						|
 | 
						|
enum {
 | 
						|
    CHIPIDEA_USBx_DCIVERSION   = 0x000,
 | 
						|
    CHIPIDEA_USBx_DCCPARAMS    = 0x004,
 | 
						|
    CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
 | 
						|
};
 | 
						|
 | 
						|
static uint64_t chipidea_read(void *opaque, hwaddr offset,
 | 
						|
                               unsigned size)
 | 
						|
{
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void chipidea_write(void *opaque, hwaddr offset,
 | 
						|
                            uint64_t value, unsigned size)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static const struct MemoryRegionOps chipidea_ops = {
 | 
						|
    .read = chipidea_read,
 | 
						|
    .write = chipidea_write,
 | 
						|
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
						|
    .impl = {
 | 
						|
        /*
 | 
						|
         * Our device would not work correctly if the guest was doing
 | 
						|
         * unaligned access. This might not be a limitation on the
 | 
						|
         * real device but in practice there is no reason for a guest
 | 
						|
         * to access this device unaligned.
 | 
						|
         */
 | 
						|
        .min_access_size = 4,
 | 
						|
        .max_access_size = 4,
 | 
						|
        .unaligned = false,
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
 | 
						|
                                 unsigned size)
 | 
						|
{
 | 
						|
    switch (offset) {
 | 
						|
    case CHIPIDEA_USBx_DCIVERSION:
 | 
						|
        return 0x1;
 | 
						|
    case CHIPIDEA_USBx_DCCPARAMS:
 | 
						|
        /*
 | 
						|
         * Real hardware (at least i.MX7) will also report the
 | 
						|
         * controller as "Device Capable" (and 8 supported endpoints),
 | 
						|
         * but there doesn't seem to be much point in doing so, since
 | 
						|
         * we don't emulate that part.
 | 
						|
         */
 | 
						|
        return CHIPIDEA_USBx_DCCPARAMS_HC;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void chipidea_dc_write(void *opaque, hwaddr offset,
 | 
						|
                              uint64_t value, unsigned size)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static const struct MemoryRegionOps chipidea_dc_ops = {
 | 
						|
    .read = chipidea_dc_read,
 | 
						|
    .write = chipidea_dc_write,
 | 
						|
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
						|
    .impl = {
 | 
						|
        /*
 | 
						|
         * Our device would not work correctly if the guest was doing
 | 
						|
         * unaligned access. This might not be a limitation on the real
 | 
						|
         * device but in practice there is no reason for a guest to access
 | 
						|
         * this device unaligned.
 | 
						|
         */
 | 
						|
        .min_access_size = 4,
 | 
						|
        .max_access_size = 4,
 | 
						|
        .unaligned = false,
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
static void chipidea_init(Object *obj)
 | 
						|
{
 | 
						|
    EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
 | 
						|
    ChipideaState *ci = CHIPIDEA(obj);
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
 | 
						|
        const struct {
 | 
						|
            const char *name;
 | 
						|
            hwaddr offset;
 | 
						|
            uint64_t size;
 | 
						|
            const struct MemoryRegionOps *ops;
 | 
						|
        } regions[ARRAY_SIZE(ci->iomem)] = {
 | 
						|
            /*
 | 
						|
             * Registers located between offsets 0x000 and 0xFC
 | 
						|
             */
 | 
						|
            {
 | 
						|
                .name   = TYPE_CHIPIDEA ".misc",
 | 
						|
                .offset = 0x000,
 | 
						|
                .size   = 0x100,
 | 
						|
                .ops    = &chipidea_ops,
 | 
						|
            },
 | 
						|
            /*
 | 
						|
             * Registers located between offsets 0x1A4 and 0x1DC
 | 
						|
             */
 | 
						|
            {
 | 
						|
                .name   = TYPE_CHIPIDEA ".endpoints",
 | 
						|
                .offset = 0x1A4,
 | 
						|
                .size   = 0x1DC - 0x1A4 + 4,
 | 
						|
                .ops    = &chipidea_ops,
 | 
						|
            },
 | 
						|
            /*
 | 
						|
             * USB_x_DCIVERSION and USB_x_DCCPARAMS
 | 
						|
             */
 | 
						|
            {
 | 
						|
                .name   = TYPE_CHIPIDEA ".dc",
 | 
						|
                .offset = 0x120,
 | 
						|
                .size   = 8,
 | 
						|
                .ops    = &chipidea_dc_ops,
 | 
						|
            },
 | 
						|
        };
 | 
						|
 | 
						|
        memory_region_init_io(&ci->iomem[i],
 | 
						|
                              obj,
 | 
						|
                              regions[i].ops,
 | 
						|
                              ci,
 | 
						|
                              regions[i].name,
 | 
						|
                              regions[i].size);
 | 
						|
 | 
						|
        memory_region_add_subregion(&ehci->mem,
 | 
						|
                                    regions[i].offset,
 | 
						|
                                    &ci->iomem[i]);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void chipidea_class_init(ObjectClass *klass, void *data)
 | 
						|
{
 | 
						|
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
						|
    SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Offsets used were taken from i.MX7Dual Applications Processor
 | 
						|
     * Reference Manual, Rev 0.1, p. 3177, Table 11-59
 | 
						|
     */
 | 
						|
    sec->capsbase   = 0x100;
 | 
						|
    sec->opregbase  = 0x140;
 | 
						|
    sec->portnr     = 1;
 | 
						|
 | 
						|
    set_bit(DEVICE_CATEGORY_USB, dc->categories);
 | 
						|
    dc->desc = "Chipidea USB Module";
 | 
						|
}
 | 
						|
 | 
						|
static const TypeInfo chipidea_info = {
 | 
						|
    .name          = TYPE_CHIPIDEA,
 | 
						|
    .parent        = TYPE_SYS_BUS_EHCI,
 | 
						|
    .instance_size = sizeof(ChipideaState),
 | 
						|
    .instance_init = chipidea_init,
 | 
						|
    .class_init    = chipidea_class_init,
 | 
						|
};
 | 
						|
 | 
						|
static void chipidea_register_type(void)
 | 
						|
{
 | 
						|
    type_register_static(&chipidea_info);
 | 
						|
}
 | 
						|
type_init(chipidea_register_type)
 |