qemu/include/hw/fdt_generic_util.h
<<
>>
Prefs
   1#ifndef FDT_GENERIC_UTIL_H
   2#define FDT_GENERIC_UTIL_H
   3
   4#include "qemu-common.h"
   5#include "fdt_generic.h"
   6#include "exec/memory.h"
   7#include "qom/object.h"
   8
   9/* create a fdt_generic machine. the top level cpu irqs are required for
  10 * systems instantiating interrupt devices. The client is responsible for
  11 * destroying the returned FDTMachineInfo (using fdt_init_destroy_fdti)
  12 */
  13
  14FDTMachineInfo *fdt_generic_create_machine(void *fdt, qemu_irq *cpu_irq);
  15
  16/* get an irq for a device. The interrupt parent of a device is idenitified
  17 * and the specified irq (by the interrupts device-tree property) is retrieved
  18 */
  19
  20qemu_irq *fdt_get_irq(FDTMachineInfo *fdti, char *node_path, int irq_idx,
  21                      bool *map_mode);
  22
  23/* same as above, but poulates err with non-zero if something goes wrong, and
  24 * populates info with a human readable string giving some basic information
  25 * about the interrupt connection found (or not found). Both arguments are
  26 * optional (i.e. can be NULL)
  27 */
  28
  29qemu_irq *fdt_get_irq_info(FDTMachineInfo *fdti, char *node_path, int irq_idx,
  30                           char * info, bool *map_mode);
  31
  32#define TYPE_FDT_GENERIC_INTC "fdt-generic-intc"
  33
  34#define FDT_GENERIC_INTC_CLASS(klass) \
  35     OBJECT_CLASS_CHECK(FDTGenericIntcClass, (klass), TYPE_FDT_GENERIC_INTC)
  36#define FDT_GENERIC_INTC_GET_CLASS(obj) \
  37    OBJECT_GET_CLASS(FDTGenericIntcClass, (obj), TYPE_FDT_GENERIC_INTC)
  38#define FDT_GENERIC_INTC(obj) \
  39     INTERFACE_CHECK(FDTGenericIntc, (obj), TYPE_FDT_GENERIC_INTC)
  40
  41typedef struct FDTGenericIntc {
  42    /*< private >*/
  43    Object parent_obj;
  44} FDTGenericIntc;
  45
  46typedef struct FDTGenericIntcClass {
  47    /*< private >*/
  48    InterfaceClass parent_class;
  49
  50    /*< public >*/
  51    /**
  52     * get irq - Based on the FDT generic interrupt binding for this device
  53     * grab the irq(s) for the given interrupt cells description. In some device
  54     * tree bindings (E.G. ARM GIC with its PPI) a single interrupt cell-tuple
  55     * can describe more than one connection. So populates an array with all
  56     * relevant IRQs.
  57     *
  58     * @obj - interrupt controller to get irqs input for ("interrupt-parent")
  59     * @irqs - array to populate with irqs (must be >= @max length
  60     * @cells - interrupt cells values. Must be >= ncells length
  61     * @ncells - number of cells in @cells
  62     * @max - maximum number of irqs to return
  63     * @errp - Error condition
  64     *
  65     * @returns the number of interrupts populated in irqs. Undefined on error
  66     * (use errp for error checking). If it is valid for the interrupt
  67     * controller binding to specify no (or a disabled) connections it may
  68     * return 0 as a non-error.
  69     */
  70
  71    int (*get_irq)(FDTGenericIntc *obj, qemu_irq *irqs, uint32_t *cells,
  72                   int ncells, int max, Error **errp);
  73
  74    /**
  75     * auto_parent. An interrupt controller often infers its own interrupt
  76     * parent (usually a CPU or CPU cluster. This function allows an interrupt
  77     * controller to implement its own auto-connections. Is called if an
  78     * interrupt controller itself (detected via "interrupt-controller") has no
  79     * "interrupt-parent" node.
  80     *
  81     * @obj - Interrupt controller top attempt autoconnection
  82     * @errp - Error condition
  83     *
  84     * FIXME: More arguments need to be added for partial descriptions
  85     */
  86
  87    void (*auto_parent)(FDTGenericIntc *obj, Error **errp);
  88
  89} FDTGenericIntcClass;
  90
  91#define TYPE_FDT_GENERIC_MMAP "fdt-generic-mmap"
  92
  93#define FDT_GENERIC_MMAP_CLASS(klass) \
  94     OBJECT_CLASS_CHECK(FDTGenericMMapClass, (klass), TYPE_FDT_GENERIC_MMAP)
  95#define FDT_GENERIC_MMAP_GET_CLASS(obj) \
  96    OBJECT_GET_CLASS(FDTGenericMMapClass, (obj), TYPE_FDT_GENERIC_MMAP)
  97#define FDT_GENERIC_MMAP(obj) \
  98     INTERFACE_CHECK(FDTGenericMMap, (obj), TYPE_FDT_GENERIC_MMAP)
  99
 100typedef struct FDTGenericMMap {
 101    /*< private >*/
 102    Object parent_obj;
 103} FDTGenericMMap;
 104
 105/* The number of "things" in the tuple. Not to be confused with the cell length
 106 * of the tuple (which is variable based on content
 107 */
 108
 109#define FDT_GENERIC_REG_TUPLE_LENGTH 4
 110
 111typedef struct FDTGenericRegPropInfo {
 112    int n;
 113    union {
 114        struct {
 115            uint64_t *a;
 116            uint64_t *s;
 117            uint64_t *b;
 118            uint64_t *p;
 119        };
 120        uint64_t *x[FDT_GENERIC_REG_TUPLE_LENGTH];
 121    };
 122    Object **parents;
 123} FDTGenericRegPropInfo;
 124
 125typedef struct FDTGenericMMapClass {
 126    /*< private >*/
 127    InterfaceClass parent_class;
 128
 129    /*< public >*/
 130    bool (*parse_reg)(FDTGenericMMap *obj, FDTGenericRegPropInfo info,
 131                      Error **errp);
 132} FDTGenericMMapClass;
 133
 134#define TYPE_FDT_GENERIC_GPIO "fdt-generic-gpio"
 135
 136#define FDT_GENERIC_GPIO_CLASS(klass) \
 137     OBJECT_CLASS_CHECK(FDTGenericGPIOClass, (klass), TYPE_FDT_GENERIC_GPIO)
 138#define FDT_GENERIC_GPIO_GET_CLASS(obj) \
 139    OBJECT_GET_CLASS(FDTGenericGPIOClass, (obj), TYPE_FDT_GENERIC_GPIO)
 140#define FDT_GENERIC_GPIO(obj) \
 141     INTERFACE_CHECK(FDTGenericGPIO, (obj), TYPE_FDT_GENERIC_GPIO)
 142
 143typedef struct FDTGenericGPIO {
 144    /*< private >*/
 145    Object parent_obj;
 146} FDTGenericGPIO;
 147
 148typedef struct FDTGenericGPIOConnection {
 149    const char *name;
 150    uint16_t fdt_index;
 151    uint16_t range;
 152} FDTGenericGPIOConnection;
 153
 154typedef struct FDTGenericGPIONameSet {
 155    const char *propname;
 156    const char *cells_propname;
 157    const char *names_propname;
 158} FDTGenericGPIONameSet;
 159
 160typedef struct FDTGenericGPIOSet {
 161    const FDTGenericGPIONameSet *names;
 162    const FDTGenericGPIOConnection *gpios;
 163} FDTGenericGPIOSet;
 164
 165static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_power_gpio = {
 166    .propname = "power-gpios",
 167    .cells_propname = "#gpio-cells",
 168    .names_propname = "power-gpio-names",
 169};
 170
 171static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_reset_gpio = {
 172    .propname = "reset-gpios",
 173    .cells_propname = "#gpio-cells",
 174    .names_propname = "reset-gpio-names",
 175};
 176
 177static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_resets = {
 178    .propname = "resets",
 179    .cells_propname = "#reset-cells",
 180    .names_propname = "reset-names",
 181};
 182
 183static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_gpio = {
 184    .propname = "gpios",
 185    .cells_propname = "#gpio-cells",
 186    .names_propname = "gpio-names",
 187};
 188
 189static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_clock = {
 190    .propname = "clocks",
 191    .cells_propname = "#clock-cells",
 192    .names_propname = "clock-names",
 193};
 194
 195static const FDTGenericGPIONameSet fdt_generic_gpio_name_set_interrupts = {
 196    .propname = "interrupts-extended",
 197    .cells_propname = "#interrupt-cells",
 198    .names_propname = "interrupt-names",
 199};
 200
 201static const FDTGenericGPIOSet default_gpio_sets [] = {
 202    { .names = &fdt_generic_gpio_name_set_gpio },
 203    {
 204      .names = &fdt_generic_gpio_name_set_reset_gpio,
 205      .gpios = (FDTGenericGPIOConnection[]) {
 206        { .name = "rst_cntrl", .fdt_index = 0, .range = 6 },
 207      },
 208    },
 209    {
 210      .names = &fdt_generic_gpio_name_set_resets,
 211      .gpios = (FDTGenericGPIOConnection[]) {
 212        { .name = "rst_cntrl", .fdt_index = 0, .range = 6 },
 213      },
 214    },
 215    {
 216      .names = &fdt_generic_gpio_name_set_power_gpio,
 217      .gpios = (FDTGenericGPIOConnection[]) {
 218        { .name = "pwr_cntrl", .fdt_index = 0, .range = 1 },
 219      },
 220    },
 221    { .names = &fdt_generic_gpio_name_set_clock },
 222    { .names = &fdt_generic_gpio_name_set_interrupts },
 223    { },
 224};
 225
 226typedef struct FDTGenericGPIOClass {
 227    /*< private >*/
 228    InterfaceClass parent_class;
 229
 230    /*< public >*/
 231    /**
 232     * Unfortunately, FDT GPIOs aren't named. This allows a device to define
 233     * a mapping between a QEMU named GPIO and the FDT GPIO lists. Client GPIOs
 234     * name the GPIOs in the fdt 'gpios' property. E.G. An entry in this list
 235     * with .name = "foo' and fdt_index = 0 would associated the first element
 236     * in the gpios list with named gpio 'foo' on the device.
 237     *
 238     * controller_gpios is the same but for for gpio controllers. E.g. with the
 239     * example above, gpio "foo" would bt the first gpio defined for the device.
 240     */
 241
 242    const FDTGenericGPIOSet *controller_gpios;
 243    const FDTGenericGPIOSet *client_gpios;
 244} FDTGenericGPIOClass;
 245
 246#define TYPE_FDT_GENERIC_PROPS "fdt-generic-props"
 247
 248#define FDT_GENERIC_PROPS_CLASS(klass) \
 249     OBJECT_CLASS_CHECK(FDTGenericPropsClass, (klass), \
 250                        TYPE_FDT_GENERIC_PROPS)
 251#define FDT_GENERIC_PROPS_GET_CLASS(obj) \
 252    OBJECT_GET_CLASS(FDTGenericPropsClass, (obj), \
 253                     TYPE_FDT_GENERIC_PROPS)
 254
 255typedef struct FDTGenericPropsClass {
 256    /*< private >*/
 257    InterfaceClass parent_class;
 258
 259    /*< public >*/
 260    void (*set_props)(Object *obj, Error **errp);
 261} FDTGenericPropsClass;
 262
 263#endif /* FDT_GENERIC_UTIL_H */
 264