AVR32 wip
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); */
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user