summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/score/cpu/avr/ChangeLog5
-rw-r--r--cpukit/score/cpu/avr/cpu.c82
-rw-r--r--cpukit/score/cpu/avr/cpu_asm.S137
-rw-r--r--cpukit/score/cpu/avr/rtems/score/cpu.h2
4 files changed, 111 insertions, 115 deletions
diff --git a/cpukit/score/cpu/avr/ChangeLog b/cpukit/score/cpu/avr/ChangeLog
index 67ecd4c344..81dce75db4 100644
--- a/cpukit/score/cpu/avr/ChangeLog
+++ b/cpukit/score/cpu/avr/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-11 Josh Switnicki <josh.switnicki@utoronto.ca>
+
+ * cpu.c, cpu_asm.S, rtems/score/cpu.h: Fix bug in
+ _CPU_Context_Initialize.
+
2009-08-05 Josh Switnicki <josh.switnicki@utoronto.ca>
* Makefile.am: added AVR specific Header files to score/cpu/avr/avr.
diff --git a/cpukit/score/cpu/avr/cpu.c b/cpukit/score/cpu/avr/cpu.c
index c4ec993eb3..5833deea12 100644
--- a/cpukit/score/cpu/avr/cpu.c
+++ b/cpukit/score/cpu/avr/cpu.c
@@ -30,8 +30,7 @@
*/
void _CPU_Initialize(void)
{
- printk( "AVR CPU Initialize\n" );
-
+
/*
* If there is not an easy way to initialize the FP context
* during Context_Initialize, then it is usually easier to
@@ -44,82 +43,6 @@ void _CPU_Initialize(void)
/*PAGE
*
- * _CPU_Context_Initialize
- *
- * This kernel routine initializes the basic non-FP context area associated
- * with each thread.
- *
- * Input parameters:
- * the_context - pointer to the context area
- * stack_base - address of memory for the SPARC
- * size - size in bytes of the stack area
- * new_level - interrupt level for this context area
- * entry_point - the starting execution point for this this context
- * is_fp - TRUE if this context is associated with an FP thread
- *
- * Output parameters: NONE
- */
-
-void _CPU_Context_Initialize(
- Context_Control *the_context,
- uint32_t *stack_base,
- uint32_t size,
- uint32_t new_level,
- void *entry_point,
- bool is_fp
-)
-{
- uint16_t stack;
- uint16_t start;
- uint8_t *tmp_sp;
- uint8_t start_low;
- uint8_t start_high;
-
- /* calc stack high end */
- stack = (uint16_t) (stack_base) + (uint16_t) (size);
- /* calc stack pointer initial value */
- the_context->stack_pointer = (stack - 18);
- /* put the entry point on the stack */
- start = (uint16_t) entry_point;
- start_low = start & 0xff;
- start_high = start >> 8;
- tmp_sp = (uint8_t *) (stack+1);
- tmp_sp[0] = start_high;
- tmp_sp[1] = start_low;
-
- if (new_level) the_context->status = 0x00; //interrupts are enabled
- else the_context->status = 0x80; //interrupts are disabled
-
- /*
- * JOEL: Why if I comment out these three lines does ticker not run?
- */
-#if 1
- printk( "tmp_sp=0x%04x ", ((uint16_t)tmp_sp) );
- printk("the_context = 0x%x\n", the_context);
- printk("entry = 0x%x\n", entry_point);
-#endif
-#if 0
- printk("sp = 0x%x\n\n",stack);
-
- { int i; uint8_t *p;
- p = (uint8_t *)(stack - 18);
- for( i=0 ; i<=20 ; i+=8 ) {
- printk( "0x%04x ", ((uint16_t)&p[i]) );
- printk(
- "0x%02x 0x%02x 0x%02x 0x%02x ",
- p[i + 0], p[i + 1], p[i + 2], p[i + 3]
- );
- printk(
- "0x%02x 0x%02x 0x%02x 0x%02x\n",
- p[i + 4], p[i + 5], p[i + 6], p[i + 7]
- );
- }
- }
-#endif
-}
-
-/*PAGE
- *
* _CPU_ISR_Get_level
*
* NO_CPU Specific Information:
@@ -132,8 +55,9 @@ uint32_t _CPU_ISR_Get_level( void )
/*
* This routine returns the current interrupt level.
*/
+ if((SREG & 0x80))return 1;
+ else return 0;
- return 0;
}
/*PAGE
diff --git a/cpukit/score/cpu/avr/cpu_asm.S b/cpukit/score/cpu/avr/cpu_asm.S
index 39c0d3ddd3..5f69b5fc07 100644
--- a/cpukit/score/cpu/avr/cpu_asm.S
+++ b/cpukit/score/cpu/avr/cpu_asm.S
@@ -208,11 +208,21 @@ SYM(_CPU_Context_restore_fp):
PUBLIC(_CPU_Context_switch)
SYM(_CPU_Context_switch):
- mov r26, r24 /* r26,r27 is X or current context */
+ mov r26, r24 /*r26,r27 is X*/
mov r27, r25
- mov r24, r22 /* r24,r25 is heir context */
+ mov r24, r22
mov r25, r23
/*save registers*/
+#if 1
+/*if this section is removed there is a problem.*/
+/*debug section start*/
+ pop r22
+ pop r23
+ push r22
+ push r23
+/*debug section end*/
+#endif
+
push r2
push r3
push r4
@@ -229,36 +239,42 @@ SYM(_CPU_Context_switch):
push r15
push r16
push r17
+
push r28
push r29
+
/*load sreg*/
- lds r23,0x5F /*load sreg*/
+ lds r23,0x5f /*load sreg*/
/*disable interrupts*/
cli
/*load stack pointer*/
- lds r22,0x5D /*spl*/
- lds r21,0x5E /*sph*/
- /*save sp to context struct*/
+ lds r22,0x5d /*spl*/
+ lds r21,0x5e /*sph*/
+ /*save sreg and sp to context struct*/
+
/*save low then high byte --- verify this delete when verified*/
st X+, r22
st X+, r21
- /*save sreg and sp to context struct*/
st X, r23
-
PUBLIC(_CPU_Context_restore)
SYM(_CPU_Context_restore):
mov r26,r24 /* R26/27 are X */
mov r27,r25
+
/*restore stack pointer*/
ld r25, X+
ld r24, X+
- sts 0x5E, r24 /*sph*/
- sts 0x5D, r25 /*spl*/
+ sts 0x5E,r24 /*sph*/
+ sts 0x5D ,r25 /*spl*/
/*restore registers from stack*/
+
+
pop r29
pop r28
+
+
pop r17
pop r16
pop r15
@@ -275,41 +291,92 @@ SYM(_CPU_Context_restore):
pop r4
pop r3
pop r2
- /*restore status register*/
- ld r23, X
- sts 0x5f,r23 /*sreg*/
+
+ /*restore sreg*/
+ ld r25, X
+ sts 0x5f,r25 /*sreg*/
+ pop r30
+ pop r31
+ IJMP
ret
-/*
- * _CPU_Context_restore
+/*PAGE
*
- * This routine is generally used only to restart self in an
- * efficient manner. It may simply be a label in _CPU_Context_switch.
+ * _CPU_Context_Initialize
*
- * NOTE: May be unnecessary to reload some registers.
+ * This kernel routine initializes the basic non-FP context area associated
+ * with each thread.
*
- * NO_CPU Specific Information:
+ * Input parameters:
+ * the_context - pointer to the context area
+ * stack_base - address of memory for the SPARC
+ * size - size in bytes of the stack area
+ * new_level - interrupt level for this context area
+ * entry_point - the starting execution point for this this context
+ * is_fp - TRUE if this context is associated with an FP thread
*
- * XXX document implementation including references if appropriate
-
-
-void _CPU_Context_restore(
- Context_Control *new_context
-)
-{
- printk( "AVR _CPU_Context_restore\n" );
-}
-*/
-/*
- PUBLIC(_CPU_Context_restore)
+ * the_context is in r25,r24
+ * entry point is in r13,r12
+ * stack base is in r23, r22
+ * size is in r21, r20, r19,r18
+ * newleve is in r14,r15, r16, 17
+ *
+ *
+ * Output parameters: NONE
+ */
-SYM(_CPU_Context_restore):
- //call printk("AVR _CPU_Context_restore\n")
- ret
+ PUBLIC(_CPU_Context_Initialize)
+SYM(_CPU_Context_Initialize):
+ //save caller saved regs
+ PUSH R10
+ PUSH R11
+ PUSH R12
+ PUSH R13
+ PUSH R14
+ PUSH R15
+ PUSH R16
+ PUSH R17
+ PUSH R28
+ PUSH R29
+ //calculate new stack pointer
+ ADD R22, R18
+ ADC R23, R19
+ MOV R26, R22
+ MOV R27, R23
+ //Initialize stack with entry point
+ ST -X, R13
+ ST -X, R12
+ //store new stack pointer in context control
+ SBIW R26, 0X13 /*subtract 33 to account for registers*/
+ MOV R28, R24
+ MOV R29, R25
+ STD Y+1, R27 //save stack pointer high to context control
+ ST Y, R26 //save stack pointer low to context control
+ //set interrupt level in new context
+ LDI R18, 0 //set sreg in new context to zero
+ STD Y+2, R18 //interrupts not enabled
+ MOV R18, R14
+ CPI R18, 0
+ BRNE NEW_LEVEL_ZERO
+ LDI R18, 0X80 //set sreg in new context to 0x80
+ STD Y+2, R18 //interupts enabled
+NEW_LEVEL_ZERO:
+ //restore caller saved regs
+ POP R29
+ POP R28
+ POP R17
+ POP R16
+ POP R15
+ POP R14
+ POP R13
+ POP R12
+ POP R11
+ POP R10
+ RET
+
-*/
/* void __ISR_Handler()
*
diff --git a/cpukit/score/cpu/avr/rtems/score/cpu.h b/cpukit/score/cpu/avr/rtems/score/cpu.h
index d23d3b3555..26b0f2795c 100644
--- a/cpukit/score/cpu/avr/rtems/score/cpu.h
+++ b/cpukit/score/cpu/avr/rtems/score/cpu.h
@@ -762,7 +762,7 @@ uint32_t _CPU_ISR_Get_level( void );
*/
#define _CPU_Context_Restart_self( _the_context ) \
- _CPU_Context_restore( (_the_context) );
+ _CPU_Context_restore( _the_context );
/*
* The purpose of this macro is to allow the initial pointer into