2 * Copyright © 2011 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 #include "ao-bringup.h"
20 #define AO_STACK_SIZE 128
22 uint8_t new_stack[512];
25 #define PUSH8(stack, val) (*((stack)--) = (val))
27 #define PUSH16(stack, val) PUSH8(stack, ((uint16_t) (val))); PUSH8(stack, ((uint16_t) (val)) >> 8)
39 LEDPORT ^= (1 << LEDOUT);
51 init_stack(void (*f) (void))
53 uint8_t *stack = new_stack + AO_STACK_SIZE - 1;
64 /* Clear register values */
69 /* SREG with interrupts enabled */
71 stack_count = stack - new_stack;
72 printf("Function is at %p. Stack[1] is %02x Stack[2] is %02x\n",
73 f, stack[1], stack[2]);
74 printf ("stack_count is %d\n", stack_count);
75 printf ("stack is %p\n", stack);
79 switch_stack(void) __attribute__((naked));
81 void show_stack(char *s, uint8_t h, uint8_t l)
83 printf ("SP at %s %02x %02x\n", s, h, l);
89 uint8_t *sp = (new_stack + stack_count);
92 // for (l = 0; l < AO_STACK_SIZE - stack_count; l++)
93 // printf ("stack[%2d] = %2x\n", l, sp[l]);
94 l = new_stack[AO_STACK_SIZE - 1];
95 h = new_stack[AO_STACK_SIZE - 2];
96 // printf ("Target return address: h %02x l %02x\n", h, l);
98 asm("push %0" : : "r" (l));
99 asm("push %0" : : "r" (h));
103 asm("push r31; push r30");
104 asm("push r29; push r28; push r27; push r26; push r25");
105 asm("push r24; push r23; push r22; push r21; push r20");
106 asm("push r19; push r18; push r17; push r16; push r15");
107 asm("push r14; push r13; push r12; push r11; push r10");
108 asm("push r9; push r8; push r7; push r6; push r5");
109 asm("push r4; push r3; push r2; push r1; push r0");
110 asm("in r0, __SREG__" "\n\t"
115 static uint8_t reg[34];
116 sp_l = (uint16_t) sp;
117 sp_h = ((uint16_t) sp) >> 8;
118 asm volatile ("out __SP_H__,%0" : : "r" (sp_h) );
119 asm volatile ("out __SP_L__,%0" : : "r" (sp_l) );
121 asm volatile ("in %0,__SP_H__" : "=&r" (sp_h));
122 asm volatile ("in %0,__SP_L__" : "=&r" (sp_l));
123 asm volatile("pop r0" "\n\t"
125 asm volatile("pop r0" "\n\t"
130 asm volatile("pop r5" "\n\t"
135 asm volatile("pop r10" "\n\t"
140 asm volatile("pop r15" "\n\t"
145 asm volatile("pop r20" "\n\t"
150 asm volatile("pop r25" "\n\t"
155 asm volatile("pop r30" "\n\t"
157 asm volatile ("in %0,__SP_H__" : "=&r" (sp_h));
158 asm volatile ("in %0,__SP_L__" : "=&r" (sp_l));
159 asm volatile ("pop %0" : "=&r" (h));
160 asm volatile ("pop %0" : "=&r" (l));
161 show_stack("before ret", sp_h, sp_l);
162 show_stack("returning to", h, l);
163 asm volatile("push %0" : : "r" (l));
164 asm volatile("push %0" : : "r" (h));
178 printf("starting\n");