aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visorchipset/visorchipset.h
blob: 46dad63fa2c8729798e04b5f6a17b8a6c6ec749d (plain) (blame)
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
/* 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