summaryrefslogtreecommitdiffstats
path: root/sys/ia64/ia64/swtch.s
blob: 10f568e3db6b2f26192e729aead585fdb927b297 (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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
/*-
 * Copyright (c) 2000 Doug Rabson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	$FreeBSD$
 */

#include <machine/asm.h>
#include <machine/mutex.h>
#include "assym.s"

/*
 * savectx: save process context, i.e. callee-saved registers
 *
 * Arguments:
 *	in0	'struct pcb *' of the process that needs its context saved
 *
 * Return:
 *	ret0	0.  (note that for child processes, it seems
 *		like savectx() returns 1, because the return address
 *		in the PCB is set to the return address from savectx().)
 */

ENTRY(savectx, 1)
	flushrs				// push out caller's dirty regs
	mov	r3=ar.unat		// caller's value for ar.unat
	;;
	mov	ar.rsc=0		// stop the RSE after the flush
	;;
	mov	r16=ar.rnat		// read RSE's NaT collection
	mov	r17=in0
	mov	r18=ar.bspstore
	mov	r19=b0
	mov	r20=b1
	mov	r21=b2
	mov	r22=b3
	mov	r23=b4
	mov	r24=b5
	;;	
	st8.spill [r17]=r4,8 ;;		// save r4..r6 
	st8.spill [r17]=r5,8 ;;		// and accumulate NaT bits
	st8.spill [r17]=r6,8 ;;
	st8.spill [r17]=r7,8 ;;
	
	stf.spill [r17]=f2,16 ;;	// save f2..f5 with NaTVals
	stf.spill [r17]=f3,16 ;;
	stf.spill [r17]=f4,16 ;;
	stf.spill [r17]=f5,16 ;;

	st8	[r17]=r19,8 ;;		// save b0..b5
	st8	[r17]=r20,8 ;;
	st8	[r17]=r21,8 ;;
	st8	[r17]=r22,8 ;;
	st8	[r17]=r23,8 ;;
	st8	[r17]=r24,8 ;;
	
	mov	r19=ar.unat		// NaT bits for r4..r6
	mov	r20=pr
	mov	ret0=r0			// return zero

	st8	[r17]=r3,8 ;;		// save caller's ar.unat
	st8	[r17]=sp,8 ;;		// stack pointer
	st8	[r17]=r2,8 ;;		// ar.pfs
	st8	[r17]=r18,8 ;;		// ar.bspstore
	st8	[r17]=r19,8 ;;		// our NaT bits
	st8	[r17]=r16,8 ;;		// ar.rnat
	st8	[r17]=r20,8 ;;		// pr

	mov	ar.rsc=3		// turn RSE back on

	br.ret.sptk.few rp
	END(savectx)

/*
 * restorectx: restore process context, i.e. callee-saved registers
 *
 * Arguments:
 *	in0	'struct pcb *' of the process being restored
 *
 * Return:
 *	Does not return. We arrange things so that savectx appears to
 *	return a second time with a non-zero return value.
 */

ENTRY(restorectx, 1)

	add	r3=U_PCB_UNAT,in0	// point at NaT for r4..r7
	mov	ar.rsc=0 ;;		// switch off the RSE
	ld8	r16=[r3]		// load NaT for r4..r7
	;;
	mov	ar.unat=r16
	;;
	ld8.fill r4=[in0],8 ;;		// restore r4
	ld8.fill r5=[in0],8 ;;		// restore r5
	ld8.fill r6=[in0],8 ;;		// restore r6
	ld8.fill r7=[in0],8 ;;		// restore r7

	ldf.fill f2=[in0],16 ;;		// restore f2
	ldf.fill f3=[in0],16 ;;		// restore f3
	ldf.fill f4=[in0],16 ;;		// restore f4
	ldf.fill f5=[in0],16 ;;		// restore f5

	ld8	r16=[in0],8 ;;		// restore b0
	ld8	r17=[in0],8 ;;		// restore b1
	ld8	r18=[in0],8 ;;		// restore b2
	ld8	r19=[in0],8 ;;		// restore b3
	ld8	r20=[in0],8 ;;		// restore b4
	ld8	r21=[in0],8 ;;		// restore b5

	mov	b0=r16
	mov	b1=r17
	mov	b2=r18
	mov	b3=r19
	mov	b4=r20
	mov	b5=r21

	ld8	r16=[in0],8 ;;		// caller's ar.unat
	ld8	sp=[in0],8 ;;		// stack pointer
	ld8	r17=[in0],8 ;;		// ar.pfs
	ld8	r18=[in0],16 ;;		// ar.bspstore, skip ar.unat
	ld8	r19=[in0],8 ;;		// ar.rnat
	ld8	r20=[in0],8 ;;		// pr

	mov	ar.unat=r16
	mov	ar.pfs=r17
	mov	ar.bspstore=r18 ;;
	mov	ar.rnat=r19
	mov	pr=r20,0x1ffff
	mov	ret0=r18		// non-zero return
	;;
	loadrs
	mov	ar.rsc=3		// restart RSE
	invala
	;;
	br.ret.sptk.few rp
	END(restorectx)	

ENTRY(cpu_switch, 0)

	add	r16=GD_CURPROC,r13 ;;
	ld8	r17=[r16] ;; 
	add	r17=P_ADDR,r17 ;;
	ld8	r17=[r17]

	flushrs				// push out caller's dirty regs
	mov	r2=ar.pfs
	mov	r3=ar.unat		// caller's value for ar.unat
	;;
	mov	ar.rsc=0		// stop the RSE after the flush
	;;
	mov	r16=ar.rnat		// read RSE's NaT collection
	mov	r18=ar.bspstore
	mov	r19=b0
	mov	r20=b1
	mov	r21=b2
	mov	r22=b3
	mov	r23=b4
	mov	r24=b5
	;;	
	st8.spill [r17]=r4,8 ;;		// save r4..r6 
	st8.spill [r17]=r5,8 ;;		// and accumulate NaT bits
	st8.spill [r17]=r6,8 ;;
	st8.spill [r17]=r7,8 ;;
	
	stf.spill [r17]=f2,16 ;;	// save f2..f5 with NaTVals
	stf.spill [r17]=f3,16 ;;
	stf.spill [r17]=f4,16 ;;
	stf.spill [r17]=f5,16 ;;

	st8	[r17]=r19,8 ;;		// save b0..b5
	st8	[r17]=r20,8 ;;
	st8	[r17]=r21,8 ;;
	st8	[r17]=r22,8 ;;
	st8	[r17]=r23,8 ;;
	st8	[r17]=r24,8 ;;
	
	mov	r19=ar.unat		// NaT bits for r4..r6
	mov	r20=pr
	mov	ret0=r0			// return zero

	st8	[r17]=r3,8 ;;		// save caller's ar.unat
	st8	[r17]=sp,8 ;;		// stack pointer
	st8	[r17]=r2,8 ;;		// ar.pfs
	st8	[r17]=r18,8 ;;		// ar.bspstore
	st8	[r17]=r19,8 ;;		// our NaT bits
	st8	[r17]=r16,8 ;;		// ar.rnat
	st8	[r17]=r20 ;;		// pr

	mov	ar.rsc=3		// turn RSE back on

	br.call.sptk.few rp=chooseproc

	add	r14=GD_CURPROC,r13 ;;
	ld8	r15=[r14] ;;

#if 0
	cmp.ne	p6,p0=r15,ret0		// chooseproc() == curproc ?
(p6)	br.dptk.few 1f
	;;
	add	r17=P_ADDR,r15 ;;	// restore b0
	ld8	r17=[r17] ;;
	add	r17=U_PCB_B0,r17 ;;
	ld8	r17=[r17] ;;
	mov	b0=r17

	br.sptk.few 9f			// don't bother to restore
#endif

1:
	st8	[r14]=ret0		// set r13->gd_curproc
	mov	ar.k7=ret0
	mov	r4=ret0			// save from call
	;; 
	alloc	r15=ar.pfs,0,0,1,0	// create temporary output frame
	;;
	mov	out0=r4
	br.call.sptk.few rp=pmap_activate // install RIDs etc.

	add	r15=P_ADDR,r4 ;;
	ld8	r15=[r15] ;;
	add	r16=SIZEOF_USER,r15 ;;
	mov	ar.k5=r16

	add	r3=U_PCB_UNAT,r15	// point at NaT for r4..r7
	mov	ar.rsc=0 ;;		// switch off the RSE
	ld8	r16=[r3]		// load NaT for r4..r7
	;;
	mov	ar.unat=r16
	;;
	ld8.fill r4=[r15],8 ;;		// restore r4
	ld8.fill r5=[r15],8 ;;		// restore r5
	ld8.fill r6=[r15],8 ;;		// restore r6
	ld8.fill r7=[r15],8 ;;		// restore r7

	ldf.fill f2=[r15],16 ;;		// restore f2
	ldf.fill f3=[r15],16 ;;		// restore f3
	ldf.fill f4=[r15],16 ;;		// restore f4
	ldf.fill f5=[r15],16 ;;		// restore f5

	ld8	r16=[r15],8 ;;		// restore b0
	ld8	r17=[r15],8 ;;		// restore b1
	ld8	r18=[r15],8 ;;		// restore b2
	ld8	r19=[r15],8 ;;		// restore b3
	ld8	r20=[r15],8 ;;		// restore b4
	ld8	r21=[r15],8 ;;		// restore b5

	mov	b0=r16
	mov	b1=r17
	mov	b2=r18
	mov	b3=r19
	mov	b4=r20
	mov	b5=r21

	ld8	r16=[r15],8 ;;		// caller's ar.unat
	ld8	sp=[r15],8 ;;		// stack pointer
	ld8	r17=[r15],8 ;;		// ar.pfs
	ld8	r18=[r15],16 ;;		// ar.bspstore, skip ar.unat
	ld8	r19=[r15],8 ;;		// ar.rnat
	ld8	r20=[r15] ;;		// pr

	mov	ar.unat=r16
	mov	ar.pfs=r17
	mov	ar.bspstore=r18 ;;
	mov	ar.rnat=r19
	mov	pr=r20,0x1ffff
	alloc	r14=ar.pfs,0,0,0,0	// lose current frame
	;;
	loadrs
	mov	ar.rsc=3		// restart RSE
	invala
	;;
9:
	br.ret.sptk.few rp

END(cpu_switch)

/*
 * savehighfp: Save f32-f127
 *
 * Arguments:
 *	in0	array of struct ia64_fpreg
 */
ENTRY(savehighfp, 1)

	add	r14=16,in0
	;;
	stf.spill [in0]=f32,32
	stf.spill [r14]=f33,32
	;; 
	stf.spill [in0]=f34,32
	stf.spill [r14]=f35,32
	;; 
	stf.spill [in0]=f36,32
	stf.spill [r14]=f37,32
	;; 
	stf.spill [in0]=f38,32
	stf.spill [r14]=f39,32
	;; 
	stf.spill [in0]=f40,32
	stf.spill [r14]=f41,32
	;; 
	stf.spill [in0]=f42,32
	stf.spill [r14]=f43,32
	;; 
	stf.spill [in0]=f44,32
	stf.spill [r14]=f45,32
	;; 
	stf.spill [in0]=f46,32
	stf.spill [r14]=f47,32
	;; 
	stf.spill [in0]=f48,32
	stf.spill [r14]=f49,32
	;; 
	stf.spill [in0]=f50,32
	stf.spill [r14]=f51,32
	;; 
	stf.spill [in0]=f52,32
	stf.spill [r14]=f53,32
	;; 
	stf.spill [in0]=f54,32
	stf.spill [r14]=f55,32
	;; 
	stf.spill [in0]=f56,32
	stf.spill [r14]=f57,32
	;; 
	stf.spill [in0]=f58,32
	stf.spill [r14]=f59,32
	;; 
	stf.spill [in0]=f60,32
	stf.spill [r14]=f61,32
	;; 
	stf.spill [in0]=f62,32
	stf.spill [r14]=f63,32
	;; 
	stf.spill [in0]=f64,32
	stf.spill [r14]=f65,32
	;; 
	stf.spill [in0]=f66,32
	stf.spill [r14]=f67,32
	;; 
	stf.spill [in0]=f68,32
	stf.spill [r14]=f69,32
	;; 
	stf.spill [in0]=f70,32
	stf.spill [r14]=f71,32
	;; 
	stf.spill [in0]=f72,32
	stf.spill [r14]=f73,32
	;; 
	stf.spill [in0]=f74,32
	stf.spill [r14]=f75,32
	;; 
	stf.spill [in0]=f76,32
	stf.spill [r14]=f77,32
	;; 
	stf.spill [in0]=f78,32
	stf.spill [r14]=f79,32
	;; 
	stf.spill [in0]=f80,32
	stf.spill [r14]=f81,32
	;; 
	stf.spill [in0]=f82,32
	stf.spill [r14]=f83,32
	;; 
	stf.spill [in0]=f84,32
	stf.spill [r14]=f85,32
	;; 
	stf.spill [in0]=f86,32
	stf.spill [r14]=f87,32
	;; 
	stf.spill [in0]=f88,32
	stf.spill [r14]=f89,32
	;; 
	stf.spill [in0]=f90,32
	stf.spill [r14]=f91,32
	;; 
	stf.spill [in0]=f92,32
	stf.spill [r14]=f93,32
	;; 
	stf.spill [in0]=f94,32
	stf.spill [r14]=f95,32
	;; 
	stf.spill [in0]=f96,32
	stf.spill [r14]=f97,32
	;; 
	stf.spill [in0]=f98,32
	stf.spill [r14]=f99,32
	;; 
	stf.spill [in0]=f100,32
	stf.spill [r14]=f101,32
	;; 
	stf.spill [in0]=f102,32
	stf.spill [r14]=f103,32
	;; 
	stf.spill [in0]=f104,32
	stf.spill [r14]=f105,32
	;; 
	stf.spill [in0]=f106,32
	stf.spill [r14]=f107,32
	;; 
	stf.spill [in0]=f108,32
	stf.spill [r14]=f109,32
	;; 
	stf.spill [in0]=f110,32
	stf.spill [r14]=f111,32
	;; 
	stf.spill [in0]=f112,32
	stf.spill [r14]=f113,32
	;; 
	stf.spill [in0]=f114,32
	stf.spill [r14]=f115,32
	;; 
	stf.spill [in0]=f116,32
	stf.spill [r14]=f117,32
	;; 
	stf.spill [in0]=f118,32
	stf.spill [r14]=f119,32
	;; 
	stf.spill [in0]=f120,32
	stf.spill [r14]=f121,32
	;; 
	stf.spill [in0]=f122,32
	stf.spill [r14]=f123,32
	;; 
	stf.spill [in0]=f124,32
	stf.spill [r14]=f125,32
	;; 
	stf.spill [in0]=f126
	stf.spill [r14]=f127
	;; 
	br.ret.sptk.few rp

END(savehighfp)

/*
 * restorehighfp: Restore f32-f127
 *
 * Arguments:
 *	in0	array of struct ia64_fpreg
 */
ENTRY(restorehighfp, 1)
	
	add	r14=16,in0
	;;
	ldf.fill f32=[in0],32
	ldf.fill f33=[r14],32
	;; 
	ldf.fill f34=[in0],32
	ldf.fill f35=[r14],32
	;; 
	ldf.fill f36=[in0],32
	ldf.fill f37=[r14],32
	;; 
	ldf.fill f38=[in0],32
	ldf.fill f39=[r14],32
	;; 
	ldf.fill f40=[in0],32
	ldf.fill f41=[r14],32
	;; 
	ldf.fill f42=[in0],32
	ldf.fill f43=[r14],32
	;; 
	ldf.fill f44=[in0],32
	ldf.fill f45=[r14],32
	;; 
	ldf.fill f46=[in0],32
	ldf.fill f47=[r14],32
	;; 
	ldf.fill f48=[in0],32
	ldf.fill f49=[r14],32
	;; 
	ldf.fill f50=[in0],32
	ldf.fill f51=[r14],32
	;; 
	ldf.fill f52=[in0],32
	ldf.fill f53=[r14],32
	;; 
	ldf.fill f54=[in0],32
	ldf.fill f55=[r14],32
	;; 
	ldf.fill f56=[in0],32
	ldf.fill f57=[r14],32
	;; 
	ldf.fill f58=[in0],32
	ldf.fill f59=[r14],32
	;; 
	ldf.fill f60=[in0],32
	ldf.fill f61=[r14],32
	;; 
	ldf.fill f62=[in0],32
	ldf.fill f63=[r14],32
	;; 
	ldf.fill f64=[in0],32
	ldf.fill f65=[r14],32
	;; 
	ldf.fill f66=[in0],32
	ldf.fill f67=[r14],32
	;; 
	ldf.fill f68=[in0],32
	ldf.fill f69=[r14],32
	;; 
	ldf.fill f70=[in0],32
	ldf.fill f71=[r14],32
	;; 
	ldf.fill f72=[in0],32
	ldf.fill f73=[r14],32
	;; 
	ldf.fill f74=[in0],32
	ldf.fill f75=[r14],32
	;; 
	ldf.fill f76=[in0],32
	ldf.fill f77=[r14],32
	;; 
	ldf.fill f78=[in0],32
	ldf.fill f79=[r14],32
	;; 
	ldf.fill f80=[in0],32
	ldf.fill f81=[r14],32
	;; 
	ldf.fill f82=[in0],32
	ldf.fill f83=[r14],32
	;; 
	ldf.fill f84=[in0],32
	ldf.fill f85=[r14],32
	;; 
	ldf.fill f86=[in0],32
	ldf.fill f87=[r14],32
	;; 
	ldf.fill f88=[in0],32
	ldf.fill f89=[r14],32
	;; 
	ldf.fill f90=[in0],32
	ldf.fill f91=[r14],32
	;; 
	ldf.fill f92=[in0],32
	ldf.fill f93=[r14],32
	;; 
	ldf.fill f94=[in0],32
	ldf.fill f95=[r14],32
	;; 
	ldf.fill f96=[in0],32
	ldf.fill f97=[r14],32
	;; 
	ldf.fill f98=[in0],32
	ldf.fill f99=[r14],32
	;; 
	ldf.fill f100=[in0],32
	ldf.fill f101=[r14],32
	;; 
	ldf.fill f102=[in0],32
	ldf.fill f103=[r14],32
	;; 
	ldf.fill f104=[in0],32
	ldf.fill f105=[r14],32
	;; 
	ldf.fill f106=[in0],32
	ldf.fill f107=[r14],32
	;; 
	ldf.fill f108=[in0],32
	ldf.fill f109=[r14],32
	;; 
	ldf.fill f110=[in0],32
	ldf.fill f111=[r14],32
	;; 
	ldf.fill f112=[in0],32
	ldf.fill f113=[r14],32
	;; 
	ldf.fill f114=[in0],32
	ldf.fill f115=[r14],32
	;; 
	ldf.fill f116=[in0],32
	ldf.fill f117=[r14],32
	;; 
	ldf.fill f118=[in0],32
	ldf.fill f119=[r14],32
	;; 
	ldf.fill f120=[in0],32
	ldf.fill f121=[r14],32
	;; 
	ldf.fill f122=[in0],32
	ldf.fill f123=[r14],32
	;; 
	ldf.fill f124=[in0],32
	ldf.fill f125=[r14],32
	;; 
	ldf.fill f126=[in0]
	ldf.fill f127=[r14]
	;; 
	br.ret.sptk.few rp

END(restorehighfp)

/*
 * fork_trampoline()
 *
 * Arrange for a function to be invoked neatly, after a cpu_switch().
 *
 * Invokes fork_exit() passing in three arguments: a callout function, an
 * argument to the callout, and a trapframe pointer.  For child processes
 * returning from fork(2), the argument is a pointer to the child process.
 *
 * The callout function is in r4, the address to return to after executing
 * fork_exit() is in r5, and the argument is in r6.
 */
ENTRY(fork_trampoline, 0)
	alloc	r14=ar.pfs,0,0,3,0
	;;
	mov	b0=r5
	mov	out0=r4
	mov	out1=r6
	mov	out2=sp
	;;
	br.call.sptk.few b6=fork_exit

	END(fork_trampoline)

OpenPOWER on IntegriCloud