blob: d4bf203cdfdf53e36acee078b9c89a53c445862f [file] [log] [blame]
/* visorchipset.h
*
* Copyright © 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 "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.
*/
typedef struct {
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. */
} VISORCHIPSET_STATE;
typedef enum {
/** 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,
} VISORCHIPSET_ADDRESSTYPE;
typedef enum {
CRASH_dev,
CRASH_bus,
} CRASH_OBJ_TYPE;
/** Attributes for a particular Supervisor channel.
*/
typedef struct {
VISORCHIPSET_ADDRESSTYPE addrType;
HOSTADDRESS channelAddr;
struct InterruptInfo intr;
U64 nChannelBytes;
GUID channelTypeGuid;
GUID channelInstGuid;
} VISORCHIPSET_CHANNEL_INFO;
/** 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().
*/
typedef struct {
struct list_head entry;
U32 busNo;
U32 devNo;
GUID devInstGuid;
VISORCHIPSET_STATE state;
VISORCHIPSET_CHANNEL_INFO chanInfo;
U32 Reserved1; /* CONTROLVM_ID */
U64 Reserved2;
U32 switchNo; /* when devState.attached==1 */
U32 internalPortNo; /* when devState.attached==1 */
CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM_MESSAGE */
/** For private use by the bus driver */
void *bus_driver_context;
} VISORCHIPSET_DEVICE_INFO;
static inline VISORCHIPSET_DEVICE_INFO *
finddevice(struct list_head *list, U32 busNo, U32 devNo)
{
VISORCHIPSET_DEVICE_INFO *p;
list_for_each_entry(p, list, entry) {
if (p->busNo == busNo && p->devNo == devNo)
return p;
}
return NULL;
}
static inline void delbusdevices(struct list_head *list, U32 busNo)
{
VISORCHIPSET_DEVICE_INFO *p;
list_for_each_entry(p, list, entry) {
if (p->busNo == busNo) {
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().
*/
typedef struct {
struct list_head entry;
U32 busNo;
VISORCHIPSET_STATE state;
VISORCHIPSET_CHANNEL_INFO chanInfo;
GUID partitionGuid;
U64 partitionHandle;
U8 *name; /* UTF8 */
U8 *description; /* UTF8 */
U64 Reserved1;
U32 Reserved2;
MYPROCOBJECT *procObject;
struct {
U32 server:1;
/* Add new fields above. */
/* Remaining bits in this 32-bit word are unused. */
} flags;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM MsgHdr */
/** For private use by the bus driver */
void *bus_driver_context;
U64 devNo;
} VISORCHIPSET_BUS_INFO;
static inline VISORCHIPSET_BUS_INFO *
findbus(struct list_head *list, U32 busNo)
{
VISORCHIPSET_BUS_INFO *p;
list_for_each_entry(p, list, entry) {
if (p->busNo == busNo)
return p;
}
return NULL;
}
/** Attributes for a particular Supervisor switch.
*/
typedef struct {
U32 switchNo;
VISORCHIPSET_STATE state;
GUID switchTypeGuid;
U8 *authService1;
U8 *authService2;
U8 *authService3;
U8 *securityContext;
U64 Reserved;
U32 Reserved2; /* CONTROLVM_ID */
struct device dev;
BOOL dev_exists;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
} VISORCHIPSET_SWITCH_INFO;
/** Attributes for a particular Supervisor external port, which is connected
* to a specific switch.
*/
typedef struct {
U32 switchNo;
U32 externalPortNo;
VISORCHIPSET_STATE state;
GUID networkZoneGuid;
int pdPort;
U8 *ip;
U8 *ipNetmask;
U8 *ipBroadcast;
U8 *ipNetwork;
U8 *ipGateway;
U8 *ipDNS;
U64 Reserved1;
U32 Reserved2; /* CONTROLVM_ID */
struct device dev;
BOOL dev_exists;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
} VISORCHIPSET_EXTERNALPORT_INFO;
/** Attributes for a particular Supervisor internal port, which is how a
* device connects to a particular switch.
*/
typedef struct {
U32 switchNo;
U32 internalPortNo;
VISORCHIPSET_STATE state;
U32 busNo; /* valid only when state.attached == 1 */
U32 devNo; /* valid only when state.attached == 1 */
U64 Reserved1;
U32 Reserved2; /* CONTROLVM_ID */
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
MYPROCOBJECT *procObject;
} VISORCHIPSET_INTERNALPORT_INFO;
/* These functions will be called from within visorchipset when certain
* events happen. (The implementation of these functions is outside of
* visorchipset.)
*/
typedef struct {
void (*bus_create)(ulong busNo);
void (*bus_destroy)(ulong busNo);
void (*device_create)(ulong busNo, ulong devNo);
void (*device_destroy)(ulong busNo, ulong devNo);
void (*device_pause)(ulong busNo, ulong devNo);
void (*device_resume)(ulong busNo, ulong devNo);
int (*get_channel_info)(GUID typeGuid, ulong *minSize,
ulong *maxSize);
} VISORCHIPSET_BUSDEV_NOTIFIERS;
/* 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
*/
typedef struct {
void (*bus_create)(ulong busNo, int response);
void (*bus_destroy)(ulong busNo, int response);
void (*device_create)(ulong busNo, ulong devNo, int response);
void (*device_destroy)(ulong busNo, ulong devNo, int response);
void (*device_pause)(ulong busNo, ulong devNo, int response);
void (*device_resume)(ulong busNo, ulong devNo, int response);
} VISORCHIPSET_BUSDEV_RESPONDERS;
/** 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(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
VISORCHIPSET_BUSDEV_RESPONDERS *responders,
ULTRA_VBUS_DEVICEINFO *driverInfo);
/** 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(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
VISORCHIPSET_BUSDEV_RESPONDERS *responders,
ULTRA_VBUS_DEVICEINFO *driverInfo);
typedef void (*SPARREPORTEVENT_COMPLETE_FUNC) (CONTROLVM_MESSAGE *msg,
int status);
void visorchipset_device_pause_response(ulong busNo, ulong devNo, int response);
BOOL visorchipset_get_bus_info(ulong busNo, VISORCHIPSET_BUS_INFO *busInfo);
BOOL visorchipset_get_device_info(ulong busNo, ulong devNo,
VISORCHIPSET_DEVICE_INFO *devInfo);
BOOL visorchipset_get_switch_info(ulong switchNo,
VISORCHIPSET_SWITCH_INFO *switchInfo);
BOOL visorchipset_get_externalport_info(ulong switchNo, ulong externalPortNo,
VISORCHIPSET_EXTERNALPORT_INFO
*externalPortInfo);
BOOL visorchipset_set_bus_context(ulong busNo, void *context);
BOOL visorchipset_set_device_context(ulong busNo, ulong devNo, void *context);
int visorchipset_chipset_ready(void);
int visorchipset_chipset_selftest(void);
int visorchipset_chipset_notready(void);
void visorchipset_controlvm_respond_reportEvent(CONTROLVM_MESSAGE *msg,
void *payload);
void visorchipset_save_message(CONTROLVM_MESSAGE *msg, 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);
#if defined(TRANSMITFILE_DEBUG) || defined(DEBUG)
#define DBG_GETFILE_PAYLOAD(msg, controlvm_header) \
LOGINF(msg, \
(ulong)controlvm_header.PayloadVmOffset, \
(ulong)controlvm_header.PayloadMaxBytes)
#define DBG_GETFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__)
#define DBG_PUTFILE(fmt, ...) LOGINF(fmt, ##__VA_ARGS__)
#else
#define DBG_GETFILE_PAYLOAD(msg, controlvm_header)
#define DBG_GETFILE(fmt, ...)
#define DBG_PUTFILE(fmt, ...)
#endif
#endif