112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * QuickThreads -- Threads-building toolkit.
312027Sjungma@eit.uni-kl.de * Copyright (c) 1993 by David Keppel
412027Sjungma@eit.uni-kl.de *
512027Sjungma@eit.uni-kl.de * Permission to use, copy, modify and distribute this software and
612027Sjungma@eit.uni-kl.de * its documentation for any purpose and without fee is hereby
712027Sjungma@eit.uni-kl.de * granted, provided that the above copyright notice and this notice
812027Sjungma@eit.uni-kl.de * appear in all copies.  This software is provided as a
912027Sjungma@eit.uni-kl.de * proof-of-concept and for demonstration purposes; there is no
1012027Sjungma@eit.uni-kl.de * representation about the suitability of this software for any
1112027Sjungma@eit.uni-kl.de * purpose.
1212027Sjungma@eit.uni-kl.de */
1312027Sjungma@eit.uni-kl.de
1412027Sjungma@eit.uni-kl.de#ifndef QUICKTHREADS_KSR1_H
1512027Sjungma@eit.uni-kl.de#define QUICKTHREADS_KSR1_H
1612027Sjungma@eit.uni-kl.de
1712027Sjungma@eit.uni-kl.de/*
1812027Sjungma@eit.uni-kl.de   Stack layout:
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de   Registers are saved in strictly low to high order, FPU regs first
2112027Sjungma@eit.uni-kl.de   (only if qt_block is called), CEU regs second, IPU regs next, with no
2212027Sjungma@eit.uni-kl.de   padding between the groups.
2312027Sjungma@eit.uni-kl.de
2412027Sjungma@eit.uni-kl.de   Callee-save:  f16..f63; c15..c30; i12..i30.
2512027Sjungma@eit.uni-kl.de   Args passed in i2..i5.
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de   Note: c31 is a private data pointer.  It is not changed on thread
2812027Sjungma@eit.uni-kl.de   swaps with the assumption that it represents per-processor rather
2912027Sjungma@eit.uni-kl.de   than per-thread state.
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.de   Note: i31 is an instruction count register that is updated by the
3212027Sjungma@eit.uni-kl.de   context switch routines.  Like c31, it is not changed on context
3312027Sjungma@eit.uni-kl.de   switches.
3412027Sjungma@eit.uni-kl.de
3512027Sjungma@eit.uni-kl.de   This is what we want on startup:
3612027Sjungma@eit.uni-kl.de
3712027Sjungma@eit.uni-kl.de
3812027Sjungma@eit.uni-kl.de   +------		<-- BOS: Bottom of stack (grows down)
3912027Sjungma@eit.uni-kl.de   | 80 (128 - 48) bytes of padding to a 128-byte boundary
4012027Sjungma@eit.uni-kl.de   +---
4112027Sjungma@eit.uni-kl.de   | only
4212027Sjungma@eit.uni-kl.de   | userf
4312027Sjungma@eit.uni-kl.de   | t
4412027Sjungma@eit.uni-kl.de   | u
4512027Sjungma@eit.uni-kl.de   | qt_start$TXT
4612027Sjungma@eit.uni-kl.de   | (empty)     	<-- qt.sp
4712027Sjungma@eit.uni-kl.de   +------		<-- (BOS - 128)
4812027Sjungma@eit.uni-kl.de
4912027Sjungma@eit.uni-kl.de   This is why we want this on startup:
5012027Sjungma@eit.uni-kl.de
5112027Sjungma@eit.uni-kl.de   A thread begins running when the restore procedure switches thread stacks
5212027Sjungma@eit.uni-kl.de   and pops a return address off of the top of the new stack (see below
5312027Sjungma@eit.uni-kl.de   for the reason why we explicitly store qt_start$TXT).  The
5412027Sjungma@eit.uni-kl.de   block procedure pushes two jump addresses on a thread's stack before
5512027Sjungma@eit.uni-kl.de   it switches stacks.  The first is the return address for the block
5612027Sjungma@eit.uni-kl.de   procedure, and the second is a restore address.  The return address
5712027Sjungma@eit.uni-kl.de   is used to jump back to the thread that has been switched to;  the
5812027Sjungma@eit.uni-kl.de   restore address is a jump within the block code to restore the registers.
5912027Sjungma@eit.uni-kl.de   Normally, this is just a jump to the next address.  However, on thread
6012027Sjungma@eit.uni-kl.de   startup, this is a jump to qt_start$TXT.  (The block procedure stores
6112027Sjungma@eit.uni-kl.de   the restore address at an offset of 8 bytes from the top of the stack,
6212027Sjungma@eit.uni-kl.de   which is also the offset at which qt_start$TXT is stored on the stacks
6312027Sjungma@eit.uni-kl.de   of new threads.  Hence, when the block procedure switches to a new
6412027Sjungma@eit.uni-kl.de   thread stack, it will initially jump to qt_start$TXT; thereafter,
6512027Sjungma@eit.uni-kl.de   it jumps to the restore code.)
6612027Sjungma@eit.uni-kl.de
6712027Sjungma@eit.uni-kl.de   qt_start$TXT, after it has read the initial data on the new thread's
6812027Sjungma@eit.uni-kl.de   stack and placed it in registers, pops the initial stack frame
6912027Sjungma@eit.uni-kl.de   and gives the thread the entire stack to use for execution.
7012027Sjungma@eit.uni-kl.de
7112027Sjungma@eit.uni-kl.de   The KSR runtime system has an unusual treatment of pointers to
7212027Sjungma@eit.uni-kl.de   functions.  From C, taking the `name' of a function yields a
7312027Sjungma@eit.uni-kl.de   pointer to a _constant block_ and *not* the address of the
7412027Sjungma@eit.uni-kl.de   function.  The zero'th entry in the constant block is a pointer to
7512027Sjungma@eit.uni-kl.de   the function.
7612027Sjungma@eit.uni-kl.de
7712027Sjungma@eit.uni-kl.de   We have to be careful: the restore procedure expects a return
7812027Sjungma@eit.uni-kl.de   address on the top of the stack (pointed to by qt.sp).  This is not
7912027Sjungma@eit.uni-kl.de   a problem when restoring a thread that has run before, since the
8012027Sjungma@eit.uni-kl.de   block routine would have stored the return address on top of the
8112027Sjungma@eit.uni-kl.de   stack.  However, when ``faking up'' a thread start (bootstrapping a
8212027Sjungma@eit.uni-kl.de   thread stack frame), the top of the stack needs to contain a
8312027Sjungma@eit.uni-kl.de   pointer to the code that will start the thread running.
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.de   The pointer to the startup code is *not* `qt_start'.  It is the
8612027Sjungma@eit.uni-kl.de   word *pointed to* by `qt_start'.  Thus, we dereference `qt_start',
8712027Sjungma@eit.uni-kl.de   see QUICKTHREADS_ARGS_MD below.
8812027Sjungma@eit.uni-kl.de
8912027Sjungma@eit.uni-kl.de   On varargs startup (still unimplemented):
9012027Sjungma@eit.uni-kl.de
9112027Sjungma@eit.uni-kl.de   | padding to 128 byte boundary
9212027Sjungma@eit.uni-kl.de   | varargs		<-- padded to a 128-byte-boundary
9312027Sjungma@eit.uni-kl.de   +---
9412027Sjungma@eit.uni-kl.de   | caller's frame, 16 bytes
9512027Sjungma@eit.uni-kl.de   | 80 bytes of padding (frame padded to a 128-byte boundary)
9612027Sjungma@eit.uni-kl.de   +---
9712027Sjungma@eit.uni-kl.de   | cleanup
9812027Sjungma@eit.uni-kl.de   | vuserf
9912027Sjungma@eit.uni-kl.de   | startup
10012027Sjungma@eit.uni-kl.de   | t
10112027Sjungma@eit.uni-kl.de   +---
10212027Sjungma@eit.uni-kl.de   | qt_start		<-- qt.sp
10312027Sjungma@eit.uni-kl.de   +---
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.de   Of a suspended thread:
10612027Sjungma@eit.uni-kl.de
10712027Sjungma@eit.uni-kl.de   +---
10812027Sjungma@eit.uni-kl.de   | caller's frame, 16 bytes
10912027Sjungma@eit.uni-kl.de   | fpu registers 47 regs * 8 bytes/reg 376 bytes
11012027Sjungma@eit.uni-kl.de   | ceu registers 16 regs * 8 bytes/reg 128 bytes
11112027Sjungma@eit.uni-kl.de   | ipu registers 19 regs * 8 bytes/reg 152 bytes
11212027Sjungma@eit.uni-kl.de   |  :
11312027Sjungma@eit.uni-kl.de   | 80 bytes of padding
11412027Sjungma@eit.uni-kl.de   |  :
11512027Sjungma@eit.uni-kl.de   | qt_restore		<-- qt.sp
11612027Sjungma@eit.uni-kl.de   +---
11712027Sjungma@eit.uni-kl.de
11812027Sjungma@eit.uni-kl.de   */
11912027Sjungma@eit.uni-kl.de
12012027Sjungma@eit.uni-kl.de
12112027Sjungma@eit.uni-kl.de#define QUICKTHREADS_STKALIGN	128
12212027Sjungma@eit.uni-kl.de#define QUICKTHREADS_GROW_DOWN
12312027Sjungma@eit.uni-kl.detypedef unsigned long qt_word_t;
12412027Sjungma@eit.uni-kl.de
12512027Sjungma@eit.uni-kl.de#define QUICKTHREADS_STKBASE	QUICKTHREADS_STKALIGN
12612027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VSTKBASE	QUICKTHREADS_STKBASE
12712027Sjungma@eit.uni-kl.de
12812027Sjungma@eit.uni-kl.deextern void qt_start(void);
12912027Sjungma@eit.uni-kl.de/*
13012027Sjungma@eit.uni-kl.de * See the discussion above for what indexing into a procedure ptr
13112027Sjungma@eit.uni-kl.de * does for us (it's lovely, though, isn't it?).
13212027Sjungma@eit.uni-kl.de *
13312027Sjungma@eit.uni-kl.de * This assumes that the address of a procedure's code is the
13412027Sjungma@eit.uni-kl.de * first word in a procedure's constant block.  That's how the manual
13512027Sjungma@eit.uni-kl.de * says it will be arranged.
13612027Sjungma@eit.uni-kl.de */
13712027Sjungma@eit.uni-kl.de#define QUICKTHREADS_ARGS_MD(sp)	(QUICKTHREADS_SPUT (sp, 1, ((qt_word_t *)qt_start)[0]))
13812027Sjungma@eit.uni-kl.de
13912027Sjungma@eit.uni-kl.de/*
14012027Sjungma@eit.uni-kl.de * The *index* (positive offset) of where to put each value.
14112027Sjungma@eit.uni-kl.de * See the picture of the stack above that explains the offsets.
14212027Sjungma@eit.uni-kl.de */
14312027Sjungma@eit.uni-kl.de#define QUICKTHREADS_ONLY_INDEX	(5)
14412027Sjungma@eit.uni-kl.de#define QUICKTHREADS_USER_INDEX	(4)
14512027Sjungma@eit.uni-kl.de#define QUICKTHREADS_ARGT_INDEX	(3)
14612027Sjungma@eit.uni-kl.de#define QUICKTHREADS_ARGU_INDEX	(2)
14712027Sjungma@eit.uni-kl.de
14812027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS_DEFAULT
14912027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS(sp, nb, vargs, pt, startup, vuserf, cleanup) \
15012027Sjungma@eit.uni-kl.de      (qt_vargs (sp, nbytes, &vargs, pt, startup, vuserf, cleanup))
15112027Sjungma@eit.uni-kl.de
15212027Sjungma@eit.uni-kl.de
15312027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
15412027Sjungma@eit.uni-kl.de  ((qt_t *)(((char *)(sp)) - 4*8 - QUICKTHREADS_STKROUNDUP(vabytes)))
15512027Sjungma@eit.uni-kl.de
15612027Sjungma@eit.uni-kl.deextern void qt_vstart(void);
15712027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS_MD1(sp)	(QUICKTHREADS_SPUT (sp, 0, ((qt_word_t *)qt_vstart)[0]))
15812027Sjungma@eit.uni-kl.de
15912027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VCLEANUP_INDEX	(4)
16012027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VUSERF_INDEX		(3)
16112027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VSTARTUP_INDEX	(2)
16212027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGT_INDEX		(1)
16312027Sjungma@eit.uni-kl.de
16412027Sjungma@eit.uni-kl.de#endif /* def QUICKTHREADS_KSR1_H */
165