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
| /* 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 */
|