| /* 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 <linux/uuid.h> |
| |
| #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 <responders>, 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 <responders>, 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 |