AVR32 wip

This commit is contained in:
Travis Geiselbrecht
2010-12-20 22:16:13 -08:00
parent adb27ebabc
commit 6a6dd56c67
14 changed files with 100 additions and 29 deletions

View File

@@ -52,7 +52,9 @@ static int app_thread_entry(void *arg)
{
const struct app_descriptor *app = (const struct app_descriptor *)arg;
TRACE_ENTRY;
app->entry(app, NULL);
TRACE_EXIT;
return 0;
}
@@ -62,5 +64,7 @@ static void start_app(const struct app_descriptor *app)
printf("starting app %s\n", app->name);
thread_resume(thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));
printf("finished starting app\n");
}

View File

@@ -26,12 +26,16 @@
static void shell_init(const struct app_descriptor *app)
{
TRACE_ENTRY;
console_init();
TRACE_EXIT;
}
static void shell_entry(const struct app_descriptor *app, void *args)
{
TRACE_ENTRY;
console_start();
TRACE_EXIT;
}
APP_START(shell)

View File

@@ -34,6 +34,8 @@ void arch_early_init(void)
avr32_set_evba((uint32_t)&avr32_exception_base);
printf("autovector offset 0x%x\n", avr32_get_interrupt_autovector_offset());
printf("mode 0x%x (%s)\n", avr32_get_mode(), avr32_mode_to_string(avr32_get_mode()));
TRACE_EXIT;
}

View File

@@ -33,16 +33,15 @@
vaddr_t r7;
vaddr_t r8;
vaddr_t r9;
vaddr_t r10;
vaddr_t r11;
vaddr_t r12;
vaddr_t sr;
vaddr_t lr;
*/
/* void avr32_context_switch(addr_t *old_sp, addr_t new_sp); */
FUNCTION(avr32_context_switch)
/* save old state */
pushm r0-r12,lr
/* save old state, including SR */
mfsr r10, 0
pushm r0-r10,lr
/* save old sp */
st.w r12[0], sp
@@ -51,6 +50,7 @@ FUNCTION(avr32_context_switch)
mov sp, r11
/* restore state and exit */
popm r0-r12,lr
icall lr
popm r0-r10,lr
mtsr 0, r10
ret r12

View File

@@ -67,17 +67,30 @@ DATA(avr32_interrupt_base)
mfsr r11, 56 // rar_int0
mfsr r12, 24 // rsr_int0
pushm r11,r12
pushm r11-r12
// convert the int0 mask to a global mask
ssrf 16
csrf 17
mov r12, sp
call avr32_irq
sub sp, -8
popm r11-r12
mtsr 24, r12 // rsr_int0
mtsr 56, r11 // rar_int0
ldmts sp++,r0-lr
rete
.align 2
FUNCTION(unhandled_exception)
stmts --sp,r0-lr
mfsr r11, 72 // rar_int0
mfsr r12, 40 // rsr_int0
pushm r11-r12
mov r12, sp
rjmp avr32_unhandled

View File

@@ -39,17 +39,28 @@ static void dump_iframe(struct avr32_iframe *iframe)
void avr32_syscall(void)
{
inc_critical_section();
printf("syscall entry\n");
printf("sr 0x%x\n", avr32_get_sr());
printf("rar_sup 0x%x\n", avr32_get_rar_sup());
printf("rsr_sup 0x%x\n", avr32_get_rsr_sup());
panic("unhandled syscall\n");
dec_critical_section();
}
void avr32_unhandled(void)
void avr32_unhandled(struct avr32_iframe *iframe)
{
inc_critical_section();
printf("rar_sup 0x%x\n", avr32_get_rar_sup());
printf("rsr_sup 0x%x\n", avr32_get_rsr_sup());
printf("rar_ex 0x%x\n", avr32_get_rar_ex());
printf("rsr_ex 0x%x\n", avr32_get_rsr_ex());
printf("sr 0x%x\n", avr32_get_sr());
printf("mode 0x%x (%s)\n", avr32_get_mode(), avr32_mode_to_string(avr32_get_mode()));
printf("unhandled exception %d\n", avr32_get_ecr());
dump_iframe(iframe);
panic("unhandled\n");
dec_critical_section();
}
void avr32_irq(struct avr32_iframe *iframe)

View File

@@ -181,6 +181,25 @@ static inline uint32_t avr32_get_interrupt_autovector_offset(void)
return (uint32_t)&avr32_interrupt_base - (uint32_t)&avr32_exception_base;
}
static inline uint avr32_get_mode(void)
{
return ((uint)avr32_get_sr() >> 22) & 0x7;
}
static const char *avr32_mode_to_string(uint mode)
{
switch (mode & 0x7) {
case 0: return "app";
case 1: return "sup";
case 2: return "int0";
case 3: return "int1";
case 4: return "int2";
case 5: return "int3";
case 6: return "exc";
case 7: return "nmi";
}
}
#if defined(__cplusplus)
}
#endif

View File

@@ -26,18 +26,12 @@
/* void arch_enable_ints(void); */
FUNCTION(arch_enable_ints)
mfsr r8, 0 /* sr */
cbr r8, 16
mtsr 0, r8 /* sr */
csrf 16
retal r12
/* void arch_disable_ints(void); */
FUNCTION(arch_disable_ints)
mfsr r8, 0 /* sr */
sbr r8, 16
mtsr 0, r8 /* sr */
ssrf 16
retal r12
/* int atomic_swap(int *ptr, int val); */

View File

@@ -23,15 +23,14 @@
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <compiler.h>
#include <debug.h>
#include <kernel/thread.h>
#include <arch/avr32.h>
struct context_switch_frame {
vaddr_t lr;
vaddr_t r12;
vaddr_t r11;
vaddr_t r10;
vaddr_t sr;
vaddr_t r9;
vaddr_t r8;
vaddr_t r7;
@@ -52,11 +51,13 @@ static void initial_thread_func(void)
int ret;
printf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
printf("initial mode 0x%x\n", avr32_get_mode());
// dump_thread(current_thread);
/* exit the implicit critical section we're within */
exit_critical_section();
printf("actually calling\n");
ret = current_thread->entry(current_thread->arg);
printf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);
@@ -75,18 +76,28 @@ void arch_thread_initialize(thread_t *t)
// fill it in
memset(frame, 0, sizeof(*frame));
frame->lr = (vaddr_t)&initial_thread_func;
// set the initial SR for supervisor mode, global interrupt mask
frame->sr = (1<<22)|(1<<16);
// set the stack pointer
t->arch.sp = (vaddr_t)frame;
printf("finished initializing thread stack: thread %p, sp 0x%x\n", t, t->arch.sp);
printf("finished initializing thread stack: thread %p, sp 0x%x. stack 0x%x-0x%x\n", t, t->arch.sp, t->stack, stack_top);
hexdump((void *)t->arch.sp, 64);
}
void arch_context_switch(thread_t *oldthread, thread_t *newthread)
{
printf("arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
hexdump(newthread->arch.sp, 64);
printf("arch_context_switch: old %p (%s) sp %p, new %p (%s) sp %p\n",
oldthread, oldthread->name, (void *)oldthread->arch.sp,
newthread, newthread->name, (void *)newthread->arch.sp);
// printf("sr 0x%x\n", avr32_get_sr());
hexdump(newthread->arch.sp, 128);
// hexdump(__GET_FRAME(0), 128);
// printf("before mode 0x%x\n", avr32_get_mode());
avr32_context_switch(&oldthread->arch.sp, newthread->arch.sp);
// printf("after mode 0x%x\n", avr32_get_mode());
// printf("after sr 0x%x\n", avr32_get_sr());
}

View File

@@ -41,6 +41,7 @@
#define __WEAK __attribute__((weak))
#define __GNU_INLINE __attribute__((gnu_inline))
#define __GET_CALLER(x) __builtin_return_address(0)
#define __GET_FRAME(x) __builtin_frame_address(0)
/* look for gcc 3.0 and above */
#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 0)

View File

@@ -74,6 +74,7 @@ static void insert_in_run_queue_head(thread_t *t)
ASSERT(t->state == THREAD_READY);
ASSERT(!list_in_list(&t->queue_node));
ASSERT(in_critical_section());
ASSERT(t->priority >= LOWEST_PRIORITY && t->priority <= HIGHEST_PRIORITY);
#endif
list_add_head(&run_queue[t->priority], &t->queue_node);
@@ -87,6 +88,7 @@ static void insert_in_run_queue_tail(thread_t *t)
ASSERT(t->state == THREAD_READY);
ASSERT(!list_in_list(&t->queue_node));
ASSERT(in_critical_section());
ASSERT(t->priority >= LOWEST_PRIORITY && t->priority <= HIGHEST_PRIORITY);
#endif
list_add_tail(&run_queue[t->priority], &t->queue_node);
@@ -120,6 +122,7 @@ thread_t *thread_create(const char *name, thread_start_routine entry, void *arg,
/* create the stack */
t->stack = malloc(stack_size);
if (!t->stack) {
free(t);
return NULL;
@@ -226,7 +229,7 @@ void thread_resched(void)
thread_t *oldthread;
thread_t *newthread;
// dprintf("thread_resched: current %p: ", current_thread);
// printf("thread_resched: current %p: \n", current_thread);
// dump_thread(current_thread);
#if THREAD_CHECKS
@@ -248,11 +251,14 @@ void thread_resched(void)
#endif
int next_queue = HIGHEST_PRIORITY - __builtin_clz(run_queue_bitmap) - (32 - NUM_PRIORITIES);
//dprintf(SPEW, "bitmap 0x%x, next %d\n", run_queue_bitmap, next_queue);
// dprintf(SPEW, "bitmap 0x%x, next %d\n", run_queue_bitmap, next_queue);
newthread = list_remove_head_type(&run_queue[next_queue], thread_t, queue_node);
#if THREAD_CHECKS
if (newthread == 0) {
printf("about to be fucked: run_queue_bitmap 0x%x, next_queue %d\n", run_queue_bitmap, next_queue);
}
ASSERT(newthread);
#endif
@@ -269,7 +275,7 @@ void thread_resched(void)
}
#endif
// dprintf("newthread: ");
// printf("newthread: %p\n", newthread);
// dump_thread(newthread);
newthread->state = THREAD_RUNNING;

View File

@@ -182,7 +182,7 @@ static enum handler_return timer_tick(void *arg, time_t now)
bool periodic = timer->periodic_time > 0;
// TRACEF("timer %p firing callback %p, arg %p\n", timer, timer->callback, timer->arg);
TRACEF("timer %p firing callback %p, arg %p\n", timer, timer->callback, timer->arg);
if (timer->callback(timer, now, timer->arg) == INT_RESCHEDULE)
ret = INT_RESCHEDULE;

View File

@@ -124,7 +124,11 @@ int dgetc(char *c, bool wait)
len = cbuf_read(&debug_buf, c, 1, wait);
return len;
#endif
return 0;
if (wait)
thread_sleep(100);
return -1;
}
void debug_dump_regs(void)

View File

@@ -82,6 +82,8 @@ status_t unmask_interrupt(unsigned int vector)
int platform_irq(struct avr32_iframe *iframe)
{
// printf("int sr 0x%x\n", avr32_get_sr());
uint group = *REG32(INTC_ICR(0)) & 0x3f;
uint linebits = *REG32(INTC_IRR(group));
if (unlikely(linebits == 0)) {