/* visorchipset.h * * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * NON INFRINGEMENT. See the GNU General Public License for more * details. */ #ifndef __VISORCHIPSET_H__ #define __VISORCHIPSET_H__ #include #include "timskmod.h" #include "channel.h" #include "controlvmchannel.h" #include "parser.h" #include "procobjecttree.h" #include "vbusdeviceinfo.h" #include "vbushelper.h" /** Describes the state from the perspective of which controlvm messages have * been received for a bus or device. */ struct visorchipset_state { u32 created:1; u32 attached:1; u32 configured:1; u32 running:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ }; enum visorchipset_addresstype { /** address is guest physical, but outside of the physical memory * region that is controlled by the running OS (this is the normal * address type for Supervisor channels) */ ADDRTYPE_LOCALPHYSICAL, /** address is guest physical, and withIN the confines of the * physical memory controlled by the running OS. */ ADDRTYPE_LOCALTEST, }; enum crash_obj_type { CRASH_DEV, CRASH_BUS, }; /** Attributes for a particular Supervisor channel. */ struct visorchipset_channel_info { enum visorchipset_addresstype addr_type; HOSTADDRESS channel_addr; struct irq_info intr; u64 n_channel_bytes; uuid_le channel_type_uuid; uuid_le channel_inst_uuid; }; /** Attributes for a particular Supervisor device. * Any visorchipset client can query these attributes using * visorchipset_get_client_device_info() or * visorchipset_get_server_device_info(). */ struct visorchipset_device_info { struct list_head entry; u32 bus_no; u32 dev_no; uuid_le dev_inst_uuid; struct visorchipset_state state; struct visorchipset_channel_info chan_info; u32 reserved1; /* control_vm_id */ u64 reserved2; u32 switch_no; /* when devState.attached==1 */ u32 internal_port_no; /* when devState.attached==1 */ struct controlvm_message_header pending_msg_hdr;/* CONTROLVM_MESSAGE */ /** For private use by the bus driver */ void *bus_driver_context; }; static inline struct visorchipset_device_info *finddevice( struct list_head *list, u32 bus_no, u32 dev_no) { struct visorchipset_device_info *p; list_for_each_entry(p, list, entry) { if (p->bus_no == bus_no && p->dev_no == dev_no) return p; } return NULL; } static inline void delbusdevices(struct list_head *list, u32 bus_no) { struct visorchipset_device_info *p, *tmp; list_for_each_entry_safe(p, tmp, list, entry) { if (p->bus_no == bus_no) { list_del(&p->entry); kfree(p); } } } /** Attributes for a particular Supervisor bus. * (For a service partition acting as the server for buses/devices, there * is a 1-to-1 relationship between busses and guest partitions.) * Any visorchipset client can query these attributes using * visorchipset_get_client_bus_info() or visorchipset_get_bus_info(). */ struct visorchipset_bus_info { struct list_head entry; u32 bus_no; struct visorchipset_state state; struct visorchipset_channel_info chan_info; uuid_le partition_uuid; u64 partition_handle; u8 *name; /* UTF8 */ u8 *description; /* UTF8 */ u64 reserved1; u32 reserved2; MYPROCOBJECT *proc_object; struct { u32 server:1; /* Add new fields above. */ /* Remaining bits in this 32-bit word are unused. */ } flags; struct controlvm_message_header pending_msg_hdr;/* CONTROLVM MsgHdr */ /** For private use by the bus driver */ void *bus_driver_context; u64 dev_no; }; static inline struct visorchipset_bus_info * findbus(struct list_head *list, u32 bus_no) { struct visorchipset_bus_info *p; list_for_each_entry(p, list, entry) { if (p->bus_no == bus_no) return p; } return NULL; } /** Attributes for a particular Supervisor switch. */ struct visorchipset_switch_info { u32 switch_no; struct visorchipset_state state; uuid_le switch_type_uuid; u8 *authservice1; u8 *authservice2; u8 *authservice3; u8 *security_context; u64 reserved; u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; struct controlvm_message_header pending_msg_hdr; }; /** Attributes for a particular Supervisor external port, which is connected * to a specific switch. */ struct visorchipset_externalport_info { u32 switch_no; u32 external_port_no; struct visorchipset_state state; uuid_le network_zone_uuid; int pd_port; u8 *ip; u8 *ip_netmask; u8 *ip_broadcast; u8 *ip_network; u8 *ip_gateway; u8 *ip_dns; u64 reserved1; u32 reserved2; /* control_vm_id */ struct device dev; BOOL dev_exists; struct controlvm_message_header pending_msg_hdr; }; /** Attributes for a particular Supervisor internal port, which is how a * device connects to a particular switch. */ struct visorchipset_internalport_info { u32 switch_no; u32 internal_port_no; struct visorchipset_state state; u32 bus_no; /* valid only when state.attached == 1 */ u32 dev_no; /* valid only when state.attached == 1 */ u64 reserved1; u32 reserved2; /* CONTROLVM_ID */ struct controlvm_message_header pending_msg_hdr; MYPROCOBJECT *proc_object; }; /* These functions will be called from within visorchipset when certain * events happen. (The implementation of these functions is outside of * visorchipset.) */ struct visorchipset_busdev_notifiers { void (*bus_create)(ulong bus_no); void (*bus_destroy)(ulong bus_no); void (*device_create)(ulong bus_no, ulong dev_no); void (*device_destroy)(ulong bus_no, ulong dev_no); void (*device_pause)(ulong bus_no, ulong dev_no); void (*device_resume)(ulong bus_no, ulong dev_no); int (*get_channel_info)(uuid_le type_uuid, ulong *min_size, ulong *max_size); }; /* These functions live inside visorchipset, and will be called to indicate * responses to specific events (by code outside of visorchipset). * For now, the value for each response is simply either: * 0 = it worked * -1 = it failed */ struct visorchipset_busdev_responders { void (*bus_create)(ulong bus_no, int response); void (*bus_destroy)(ulong bus_no, int response); void (*device_create)(ulong bus_no, ulong dev_no, int response); void (*device_destroy)(ulong bus_no, ulong dev_no, int response); void (*device_pause)(ulong bus_no, ulong dev_no, int response); void (*device_resume)(ulong bus_no, ulong dev_no, int response); }; /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is * to be the server for. visorchipset will fill in , to * indicate functions the bus driver should call to indicate message * responses. */ void visorchipset_register_busdev_client( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driver_info); /** Register functions (in the bus driver) to get called by visorchipset * whenever a bus or device appears for which this service partition is * to be the client for. visorchipset will fill in , to * indicate functions the bus driver should call to indicate message * responses. */ void visorchipset_register_busdev_server( struct visorchipset_busdev_notifiers *notifiers, struct visorchipset_busdev_responders *responders, struct ultra_vbus_deviceinfo *driver_info); typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (struct controlvm_message *msg, int status); void visorchipset_device_pause_response(ulong bus_no, ulong dev_no, int response); BOOL visorchipset_get_bus_info(ulong bus_no, struct visorchipset_bus_info *bus_info); BOOL visorchipset_get_device_info(ulong bus_no, ulong dev_no, struct visorchipset_device_info *dev_info); BOOL visorchipset_set_bus_context(ulong bus_no, void *context); BOOL visorchipset_set_device_context(ulong bus_no, ulong dev_no, void *context); int visorchipset_chipset_ready(void); int visorchipset_chipset_selftest(void); int visorchipset_chipset_notready(void); void visorchipset_save_message(struct controlvm_message *msg, enum crash_obj_type type); void *visorchipset_cache_alloc(struct kmem_cache *pool, BOOL ok_to_block, char *fn, int ln); void visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln); #endif