/* Khavi context switcher (to be located in RAM and accessed from */
/* Uses Round robin for simplicity */
/* Table bitfields:
* First node: [Address of current linked list][Address of next linked list][registers]
* All secondary nodes: [Address of next linked list][registers]
*/
/* Should also store/reload the table if planning to implement process/thread distinction */
Start_switcher:
mov.l r2,@-r15 /* Store registers for use */
mov.l r1,@-r15
mov.l r0,@-r15
mov.l first_table,r0
mov.l @r0,r0 /* move address of current table into r0 */
add #0x7F,r0 /* Offset r0 to end of table. Needs to be tuned properly. */
mov.l @r15+,r2 /* Store r0 to table */
mov.l r2,@-r0
mov.l @r15+,r2 /* Store r1 to table */
mov.l r2,@-r0
mov.l @r15+,r2 /* Store r2 to table */
mov.l r2,@-r0
mov.l r3,@-r0 /* Store rest of registers */
mov.l r4,@-r0
mov.l r5,@-r0
mov.l r6,@-r0
mov.l r7,@-r0
mov.l r8,@-r0
mov.l r9,@-r0
mov.l r10,@-r0
mov.l r11,@-r0
mov.l r12,@-r0
mov.l r13,@-r0
mov.l r14,@-r0
mov.l r15,@-r0
stc sr,r1 /* Switch register banks */
mov.l mask,r2 /* These lines derived and modified from Linux kernel 2.6.* */
xor r2,r1
bra rest
ldc r1,sr
mask: .long 0x40000000
rest:
stc.l r1,@-r0
stc.l gbr,@-r0
stc.l vbr,@-r0
stc.l ssr,@-r0
stc.l spc,@-r0
stc.l r0_bank,@-r0
stc.l r1_bank,@-r0
stc.l r2_bank,@-r0
stc.l r3_bank,@-r0
stc.l r4_bank,@-r0
stc.l r5_bank,@-r0
stc.l r6_bank,@-r0
stc.l r7_bank,@-r0
sts.l mach,@-r0
sts.l macl,@-r0
sts.l pr,@-r0
add #-4,r0 /* Go to table to be restored */
mov.l @r0,r0
mova Start_switcher,r2
lds.l @r0+,pr /* restore system registers */
lds.l @r0+,macl
lds.l @r0+,mach
ldc.l @r0+,r7_bank
ldc.l @r0+,r6_bank
ldc.l @r0+,r5_bank
ldc.l @r0+,r4_bank
ldc.l @r0+,r3_bank
ldc.l @r0+,r2_bank
ldc.l @r0+,r1_bank
ldc.l @r0+,r0_bank
ldc.l @r0+,spc
ldc.l @r0+,ssr
ldc.l @r0+,vbr
ldc.l @r0+,gbr
ldc.l @r0+,sr
stc sr,r1 /* Switch register banks */
mov.l mask,r2 /* These lines derived and modified from Linux kernel 2.6.* */
xor r2,r1
ldc r1,sr
mov.l @r0+,r15
mov.l @r0+,r14
mov.l @r0+,r13
mov.l @r0+,r12
mov.l @r0+,r11
mov.l @r0+,r10
mov.l @r0+,r9
mov.l @r0+,r8
mov.l @r0+,r7
mov.l @r0+,r6
mov.l @r0+,r5
mov.l @r0+,r4
mov.l @r0+,r3
add #-12,r15 /* Set SP properly */
mov #8,r1 /* modify linked lists */
add r0,r1 /* Need to add call to scheduling algorithm to choose next thread/process */
mov r1,@r2
mov.l @r0+,r1
mov.l r1,@-r15
mov.l @r0+,r1
mov.l r1,@-r15
mov.l @r0+,r1
mov.l r1,@-r15
mov.l @r15+,r2
mov.l @r15+,r1
rte
mov.l @r15+,r0
first_table: .long 0x00000000 /* address of first node in linked list */