summaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visorchipset/visorchipset.h
blob: d4bf203cdfdf53e36acee078b9c89a53c445862f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/* 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