24 Commits

Author SHA1 Message Date
Travis Geiselbrecht
6a6dd56c67 AVR32 wip 2010-12-20 22:16:13 -08:00
Travis Geiselbrecht
adb27ebabc [platform][at32ap7] turn off some of the timer spew 2010-07-07 02:34:47 -07:00
Travis Geiselbrecht
99e6bd0082 [kernel] [arch] move bss clearing into C code at the start of kmain 2010-07-07 02:34:13 -07:00
Travis Geiselbrecht
6bc00a43de [arch][avr32] unstub the initial thread func 2010-07-07 02:33:42 -07:00
Travis Geiselbrecht
944c683305 [platform][at32ap7] decode and dispatch interrupts 2010-07-07 02:10:00 -07:00
Travis Geiselbrecht
ecfdc20f68 [arch][avr32] first pass at irq glue 2010-07-07 02:09:25 -07:00
Travis Geiselbrecht
5815a621d4 [platform][at32ap7] rudimentary timer and interrupt controller support 2010-07-06 19:24:24 -07:00
Travis Geiselbrecht
278734883f [platform][at32ap7] begin adding support for interrupts and clocks 2010-06-22 05:38:41 -07:00
Travis Geiselbrecht
aeae0e2623 [arch][avr32] add more generic mechanism to get to the interrupt vector 2010-06-22 05:37:53 -07:00
Travis Geiselbrecht
040239ae10 [platform][at32ap7] add register defs for interrupt controller 2010-06-22 04:50:22 -07:00
Travis Geiselbrecht
c9e55d4b70 [arch][avr32] start of support for avr32 exceptions 2010-06-16 01:43:24 -07:00
Travis Geiselbrecht
223c9e7cb7 [arch][avr32] first stab at threading support 2010-06-15 22:22:50 -07:00
Travis Geiselbrecht
0bed6ea342 [platform][at32ap7] fix up the debug routines 2010-06-15 21:47:47 -07:00
Travis Geiselbrecht
b51523a4c2 [arch][avr32] remove some of the debugging gunk from crt0.S 2010-06-15 21:47:27 -07:00
Travis Geiselbrecht
5f374106ad [arch][avr32] add cache routines 2010-06-15 21:46:58 -07:00
Travis Geiselbrecht
14918177a3 [target][ngw100] correct the load address (0x12000000 -> 0x10200000) 2010-06-15 21:14:15 -07:00
Travis Geiselbrecht
1b9468ebf9 WIP 2010-05-06 12:19:58 -07:00
Travis Geiselbrecht
aaf19ef6b3 [ngw100] u-boot loads at 0x10200000 2010-04-25 13:53:12 -07:00
Travis Geiselbrecht
7e9514af57 [at32ap7] memory base is at 0x10000000 2010-04-25 13:52:56 -07:00
Travis Geiselbrecht
10dfde3751 [arch][avr32] add support for program base != memory base 2010-04-25 13:50:19 -07:00
Travis Geiselbrecht
213c2871eb more avr32 stuffs 2010-04-25 13:16:23 -07:00
Travis Geiselbrecht
0a26a9ce8b [avr32] new toolchain path is avr32-unknown-none- 2010-04-23 15:55:07 -07:00
Travis Geiselbrecht
d934884fcd more avr32 work 2009-12-04 00:38:18 -08:00
Travis Geiselbrecht
5274c0a6c4 initial stab at avr32 support 2009-12-04 00:18:32 -08:00
36 changed files with 1972 additions and 6 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

@@ -117,6 +117,7 @@ reset:
strlt r3, [r1], #4
blt .L__copy_loop
#if 0 /* XXX do bss in kmain */
.L__do_bss:
/* clear out the bss */
ldr r0, =__bss_start
@@ -126,6 +127,7 @@ reset:
cmp r0, r1
strlt r2, [r0], #4
blt .L__bss_loop
#endif
bl kmain
b .

49
arch/avr32/arch.c Normal file
View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <arch.h>
#include <arch/avr32.h>
void arch_early_init(void)
{
TRACE_ENTRY;
printf("sr 0x%x\n", avr32_get_sr());
printf("mmucr 0x%x\n", avr32_get_mmucr());
/* set the exception base */
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;
}
void arch_init(void)
{
}
void arch_quiesce(void)
{
}

56
arch/avr32/asm.S Normal file
View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <asm.h>
/* context switch frame:
vaddr_t r0;
vaddr_t r1;
vaddr_t r2;
vaddr_t r3;
vaddr_t r4;
vaddr_t r5;
vaddr_t r6;
vaddr_t r7;
vaddr_t r8;
vaddr_t r9;
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, including SR */
mfsr r10, 0
pushm r0-r10,lr
/* save old sp */
st.w r12[0], sp
/* load new one */
mov sp, r11
/* restore state and exit */
popm r0-r10,lr
mtsr 0, r10
ret r12

54
arch/avr32/cache.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <arch.h>
#include <arch/ops.h>
#include <arch/avr32.h>
#include <arch/defines.h>
void arch_disable_cache(uint flags)
{
PANIC_UNIMPLEMENTED;
}
void arch_enable_cache(uint flags)
{
PANIC_UNIMPLEMENTED;
}
void arch_clean_cache_range(addr_t start, size_t len)
{
addr_t end = start + len;
for (start = start & ~(CACHE_LINE - 1); start < end; start += CACHE_LINE)
avr32_dcache_clean_line((void *)start);
}
void arch_clean_invalidate_cache_range(addr_t start, size_t len)
{
addr_t end = start + len;
for (start = start & ~(CACHE_LINE - 1); start < end; start += CACHE_LINE)
avr32_dcache_clean_invalidate_line((void *)start);
}

16
arch/avr32/compile.mk Normal file
View File

@@ -0,0 +1,16 @@
$(BUILDDIR)/%.o: %.c $(SRCDEPS)
@$(MKDIR)
@echo compiling $<
$(NOECHO)$(CC) $(CFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
$(BUILDDIR)/%.o: %.cpp $(SRCDEPS)
@$(MKDIR)
@echo compiling $<
$(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
$(BUILDDIR)/%.o: %.S $(SRCDEPS)
@$(MKDIR)
@echo compiling $<
$(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@

52
arch/avr32/crt0.S Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
.section ".text.boot"
.globl _start
_start:
lddpc sp, .Linit_stack_top_addr
rcall kmain
rjmp .
.align 2
.Linit_stack_top_addr:
.long init_stack_top
.section ".bss"
.align 2
init_stack:
.skip 1024
init_stack_top:
.section ".rodata"
.align 2
/* define the heap end as read-only data containing the end defined in the
* linker script. other archs that use dynamic memory length discovery can make
* this read-write and update it during init.
*/
.global _heap_end
_heap_end:
.int _end_of_ram

96
arch/avr32/exceptions.S Normal file
View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <asm.h>
.text
.align 9
DATA(avr32_exception_base)
rjmp unhandled_exception /* unrecoverable exception */
rjmp unhandled_exception /* tlb multiple hit */
rjmp unhandled_exception /* bus error data fetch */
rjmp unhandled_exception /* bus error instruction fetch */
rjmp unhandled_exception /* nmi */
rjmp unhandled_exception /* instrction address? */
rjmp unhandled_exception /* itlb protection */
rjmp unhandled_exception /* breakpoint */
rjmp unhandled_exception /* illegal opcode */
rjmp unhandled_exception /* unimplemented opcode */
rjmp unhandled_exception /* priviledge violation */
rjmp unhandled_exception /* floating-point */
rjmp unhandled_exception /* coprocessor absent */
rjmp unhandled_exception /* data address(read) */
rjmp unhandled_exception /* data address(write) */
rjmp unhandled_exception /* dtlb protection (read) */
rjmp unhandled_exception /* dtlb protection (write) */
rjmp unhandled_exception /* dtlb modified */
// 0x50
.skip (0x50 - (. - avr32_exception_base))
rjmp unhandled_exception /* itlb miss */
// 0x60
.skip (0x60 - (. - avr32_exception_base))
rjmp unhandled_exception /* dtlb miss(read) */
// 0x70
.skip (0x70 - (. - avr32_exception_base))
rjmp unhandled_exception /* dtlb miss(write) */
// 0x100
.skip (0x100 - (. - avr32_exception_base))
rcall avr32_syscall
rets
// 0x110 interrupt
DATA(avr32_interrupt_base)
stmts --sp,r0-lr
mfsr r11, 56 // rar_int0
mfsr r12, 24 // rsr_int0
pushm r11-r12
// convert the int0 mask to a global mask
ssrf 16
csrf 17
mov r12, sp
call avr32_irq
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

78
arch/avr32/exceptions_c.c Normal file
View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <arch.h>
#include <arch/avr32.h>
#include <kernel/thread.h>
#include <platform.h>
static void dump_iframe(struct avr32_iframe *iframe)
{
printf("iframe %p\n", iframe);
printf("\trar 0x%x, rsr 0x%x\n", iframe->rar, iframe->rsr);
printf("\tr0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", iframe->r0, iframe->r1, iframe->r2, iframe->r3);
printf("\tr4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", iframe->r4, iframe->r5, iframe->r6, iframe->r7);
printf("\tr8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", iframe->r8, iframe->r9, iframe->r10, iframe->r11);
printf("\tr12 0x%08x usp 0x%08x r14 0x%08x\n", iframe->r12, iframe->usp, iframe->r14);
hexdump(iframe, 32*4);
}
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(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)
{
inc_critical_section();
// printf("irq: 0x%x 0x%x\n", avr32_get_rar_int0(), avr32_get_rsr_int0());
// dump_iframe(iframe);
if (platform_irq(iframe) == INT_RESCHEDULE) {
thread_preempt();
}
dec_critical_section();
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2009 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __AVR32_ARCH_THREAD_H
#define __ARV32_ARCH_THREAD_H
struct arch_thread {
vaddr_t sp;
};
#endif

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ARCH_AVR32_H
#define __ARCH_AVR32_H
#include <sys/types.h>
#if defined(__cplusplus)
extern "C" {
#endif
void avr32_context_switch(vaddr_t *old_sp, vaddr_t new_sp);
struct avr32_iframe {
uint32_t rsr;
uint32_t rar;
uint32_t r14;
uint32_t usp;
uint32_t r12;
uint32_t r11;
uint32_t r10;
uint32_t r9;
uint32_t r8;
uint32_t r7;
uint32_t r6;
uint32_t r5;
uint32_t r4;
uint32_t r3;
uint32_t r2;
uint32_t r1;
uint32_t r0;
};
int platform_irq(struct avr32_iframe *iframe);
// cache routines
#define ICACHE_FLUSH 0x0
#define ICACHE_INVALIDATE 0x1
#define ICACHE_LOCK 0x2
#define ICACHE_UNLOCK 0x3
#define ICACHE_PREFETCH 0x4
#define ICACHE_FLUSH_ALL 0x0
#define ICACHE_FLUSH_UNLOCKED 0x1
#define ICACHE_FLUSH_UNLOCK_ALL 0x2
#define DCACHE_FLUSH 0x8
#define DCACHE_LOCK 0x9
#define DCACHE_UNLOCK 0xa
#define DCACHE_INVALIDATE 0xb
#define DCACHE_CLEAN 0xc
#define DCACHE_CLEAN_INVALIDATE 0xd
#define DCACHE_FLUSH_INVALIDATE_ALL 0x0
#define DCACHE_FLUSH_INVALIDATE_UNLOCKED 0x1
#define DCACHE_FLUSH_CLEAN_ALL 0x2
#define DCACHE_FLUSH_CLEAN_UNLOCKED 0x3
#define DCACHE_FLUSH_CLEAN_INVALIDATE_ALL 0x4
#define DCACHE_FLUSH_CLEAN_INVALIDATE_UNLOCKED 0x5
#define DCACHE_FLUSH_UNLOCK_ALL 0x6
static inline void avr32_icache_invalidate(void)
{
int zero = 0;
__asm__ volatile("cache %0[0], 0" :: "r"(zero) : "memory");
}
static inline void avr32_icache_invalidate_line(void *addr)
{
__asm__ volatile("cache %0[0], 1" :: "r"(addr) : "memory");
}
static inline void avr32_cache_clean(void)
{
int zero = 0;
__asm__ volatile("cache %0[2], 8" :: "r"(zero) : "memory");
}
static inline void avr32_cache_clean_invalidate(void)
{
int zero = 0;
__asm__ volatile("cache %0[4], 8" :: "r"(zero) : "memory");
}
static inline void avr32_dcache_invalidate_line(void *addr)
{
__asm__ volatile("cache %0[0], 0xb" :: "r"(addr) : "memory");
}
static inline void avr32_dcache_clean_line(void *addr)
{
__asm__ volatile("cache %0[0], 0xc" :: "r"(addr) : "memory");
}
static inline void avr32_dcache_clean_invalidate_line(void *addr)
{
__asm__ volatile("cache %0[0], 0xd" :: "r"(addr) : "memory");
}
/* system registers */
#define SR_GETPUT(name, regnum) \
static inline uint32_t avr32_get_##name(void) \
{ \
uint32_t ret; \
__asm__ volatile("mfsr %0," #regnum : "=r"(ret)); \
return ret; \
} \
\
static inline void avr32_set_##name(uint32_t val) \
{ \
__asm__ volatile("mtsr " #regnum ", %0" :: "r"(val)); \
}
SR_GETPUT(sr, 0)
SR_GETPUT(evba, 4)
SR_GETPUT(acba, 8)
SR_GETPUT(cpucr, 12)
SR_GETPUT(ecr, 16)
SR_GETPUT(rsr_sup, 20)
SR_GETPUT(rsr_int0, 24)
SR_GETPUT(rsr_int1, 28)
SR_GETPUT(rsr_int2, 32)
SR_GETPUT(rsr_int3, 36)
SR_GETPUT(rsr_ex, 40)
SR_GETPUT(rsr_nmi, 44)
SR_GETPUT(rsr_dbg, 48)
SR_GETPUT(rar_sup, 52)
SR_GETPUT(rar_int0, 56)
SR_GETPUT(rar_int1, 60)
SR_GETPUT(rar_int2, 64)
SR_GETPUT(rar_int3, 68)
SR_GETPUT(rar_ex, 72)
SR_GETPUT(rar_nmi, 76)
SR_GETPUT(rar_dbg, 80)
SR_GETPUT(config0, 256)
SR_GETPUT(config1, 260)
SR_GETPUT(count, 264)
SR_GETPUT(compare, 268)
SR_GETPUT(tlbehi, 272)
SR_GETPUT(tlbelo, 276)
SR_GETPUT(ptbr, 280)
SR_GETPUT(tlbear, 284)
SR_GETPUT(mmucr, 288)
SR_GETPUT(tlbarlo, 292)
SR_GETPUT(tlbarhi, 296)
SR_GETPUT(pccnt, 300)
SR_GETPUT(pcnt0, 304)
SR_GETPUT(pcnt1, 308)
SR_GETPUT(pccr, 312)
SR_GETPUT(bear, 316)
SR_GETPUT(sabal, 768)
SR_GETPUT(sabah, 772)
SR_GETPUT(sabd, 776)
// helpers
extern void avr32_interrupt_base;
extern void avr32_exception_base;
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
#endif

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ARCH_CPU_H
#define __ARCH_CPU_H
/* avr32 specific stuff */
#define PAGE_SIZE 4096
#define CACHE_LINE 32
#endif

170
arch/avr32/ops.S Normal file
View File

@@ -0,0 +1,170 @@
/*
* Copyright (c) 2009 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <asm.h>
.text
/* void arch_enable_ints(void); */
FUNCTION(arch_enable_ints)
csrf 16
retal r12
/* void arch_disable_ints(void); */
FUNCTION(arch_disable_ints)
ssrf 16
retal r12
/* int atomic_swap(int *ptr, int val); */
FUNCTION(atomic_swap)
#if 0
swp r2, r1, [r0]
mov r0, r2
bx lr
#endif
retal r12
/* int atomic_add(int *ptr, int val); */
FUNCTION(atomic_add)
#if 0
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_add:
ldrex r12, [r0]
add r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_add
/* save old value */
mov r0, r12
bx lr
#else
/* disable interrupts, do the add, and reenable */
mrs r2, cpsr
mov r12, r2
orr r2, r2, #(3<<6)
msr cpsr_c, r2
/* ints disabled, old cpsr state in r12 */
/* do the add, leave the previous value in r0 */
mov r3, r0
ldr r0, [r3]
add r2, r0, r1
str r2, [r3]
/* restore interrupts and exit */
msr cpsr_c, r12
bx lr
#endif
#endif
retal r12
/* int atomic_and(int *ptr, int val); */
FUNCTION(atomic_and)
#if 0
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_and:
ldrex r12, [r0]
and r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_and
/* save old value */
mov r0, r12
bx lr
#else
/* disable interrupts, do the and, and reenable */
mrs r2, cpsr
mov r12, r2
orr r2, r2, #(3<<6)
msr cpsr_c, r2
/* ints disabled, old cpsr state in r12 */
/* do the and, leave the previous value in r0 */
mov r3, r0
ldr r0, [r3]
and r2, r0, r1
str r2, [r3]
/* restore interrupts and exit */
msr cpsr_c, r12
bx lr
#endif
#endif
retal r12
/* int atomic_or(int *ptr, int val); */
FUNCTION(atomic_or)
#if 0
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_or:
ldrex r12, [r0]
orr r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_or
/* save old value */
mov r0, r12
bx lr
#else
/* disable interrupts, do the or, and reenable */
mrs r2, cpsr
mov r12, r2
orr r2, r2, #(3<<6)
msr cpsr_c, r2
/* ints disabled, old cpsr state in r12 */
/* do the or, leave the previous value in r0 */
mov r3, r0
ldr r0, [r3]
orr r2, r0, r1
str r2, [r3]
/* restore interrupts and exit */
msr cpsr_c, r12
bx lr
#endif
#endif
retal r12
/* void arch_idle(); */
FUNCTION(arch_idle)
sleep 0
retal r12
/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
FUNCTION(arch_switch_stacks_and_call)
mov sp, r11
icall r12
/* uint32_t arch_cycle_count(void); */
FUNCTION(arch_cycle_count)
retal 0

64
arch/avr32/rules.mk Normal file
View File

@@ -0,0 +1,64 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
DEFINES += \
AVR32_CPU_$(AVR32_CPU)=1
INCLUDES += \
-I$(LOCAL_DIR)/include
BOOTOBJS += \
$(LOCAL_DIR)/crt0.o
OBJS += \
$(LOCAL_DIR)/ops.o \
$(LOCAL_DIR)/thread.o \
$(LOCAL_DIR)/arch.o \
$(LOCAL_DIR)/cache.o \
$(LOCAL_DIR)/asm.o \
$(LOCAL_DIR)/exceptions.o \
$(LOCAL_DIR)/exceptions_c.o \
# $(LOCAL_DIR)/cache-ops.o \
$(LOCAL_DIR)/faults.o \
$(LOCAL_DIR)/mmu.o \
$(LOCAL_DIR)/dcc.o
# set the default toolchain and set a #define
TOOLCHAIN_PREFIX ?= avr32-unknown-none-
CFLAGS += -mcpu=ap7000
LDFLAGS += --relax
# make sure some bits were set up
MEMVARS_SET := 0
ifneq ($(MEMBASE),)
MEMVARS_SET := 1
endif
ifneq ($(MEMSIZE),)
MEMVARS_SET := 1
endif
ifeq ($(MEMVARS_SET),0)
$(error missing MEMBASE or MEMSIZE variable, please set in target rules.mk)
endif
LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -print-libgcc-file-name)
#$(info LIBGCC = $(LIBGCC))
# potentially generated files that should be cleaned out with clean make rule
GENERATED += \
$(BUILDDIR)/system-onesegment.ld \
$(BUILDDIR)/system-twosegment.ld
# rules for generating the linker scripts
PROGBASE ?= $(MEMBASE)
$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%PROGBASE%/$(PROGBASE)/" < $< > $@
$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%PROGBASE%/$(PROGBASE)/" < $< > $@

View File

@@ -0,0 +1,83 @@
OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
OUTPUT_ARCH(avr32)
ENTRY(_start)
SECTIONS
{
. = %PROGBASE%;
/* text/read-only data */
.text.boot : { *(.text.boot) }
.text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
.interp : { *(.interp) }
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
.rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
.rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
.rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
.rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
.rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init : { *(.init) } =0x9090
.plt : { *(.plt) }
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__apps_start = .;
KEEP (*(.apps))
__apps_end = .;
. = ALIGN(4);
__rodata_end = . ;
}
/* writable data */
__data_start_rom = .; /* in one segment binaries, the rom data address is on top of the ram data address */
__data_start = .;
.data : SUBALIGN(4) { *(.data .data.* .gnu.linkonce.d.*) }
__ctor_list = .;
.ctors : { *(.ctors) }
__ctor_end = .;
__dtor_list = .;
.dtors : { *(.dtors) }
__dtor_end = .;
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
__data_end = .;
/* unintialized data (in same segment as writable data) */
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss .bss.*) }
. = ALIGN(4);
_end = .;
. = %MEMBASE% + %MEMSIZE%;
_end_of_ram = .;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame) }
}

103
arch/avr32/thread.c Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2009 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#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 sr;
vaddr_t r9;
vaddr_t r8;
vaddr_t r7;
vaddr_t r6;
vaddr_t r5;
vaddr_t r4;
vaddr_t r3;
vaddr_t r2;
vaddr_t r1;
vaddr_t r0;
};
extern void avr32_context_switch(addr_t *old_sp, addr_t new_sp);
static void initial_thread_func(void) __NO_RETURN;
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);
thread_exit(ret);
}
void arch_thread_initialize(thread_t *t)
{
// create a default stack frame on the stack
vaddr_t stack_top = (vaddr_t)t->stack + t->stack_size;
struct context_switch_frame *frame = (struct context_switch_frame *)(stack_top);
frame--;
// 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. 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) 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

@@ -26,5 +26,7 @@
//#define FUNCTION(x) .global x; .type x,@function; x:
#define FUNCTION(x) .global x; x:
#define DATA(x) .global x; x:
#endif

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

@@ -40,6 +40,10 @@
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(ARCH_AVR32)
#define BYTE_ORDER BIG_ENDIAN
#endif
#if defined(__i386__) || defined(_X86_)
#define BYTE_ORDER LITTLE_ENDIAN
#endif

View File

@@ -34,8 +34,8 @@
extern void *__ctor_list;
extern void *__ctor_end;
extern int __bss_start;
extern int _end;
extern char __bss_start;
extern char _end;
static int bootstrap2(void *arg);
@@ -54,10 +54,17 @@ static void call_constructors(void)
}
}
static void clear_bss(void)
{
memset(&__bss_start, 0, &_end - &__bss_start);
}
/* called from crt0.S */
void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE;
void kmain(void)
{
clear_bss();
// get us into some sort of thread context
thread_init_early();

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

@@ -0,0 +1,9 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
ASM_STRING_OPS :=
OBJS += \
# filter out the C implementation
C_STRING_OPS := $(filter-out $(ASM_STRING_OPS),$(C_STRING_OPS))

54
platform/at32ap7/clocks.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <reg.h>
#include <platform/at32ap7.h>
#include "platform_p.h"
void platform_init_clocks(void)
{
TRACE_ENTRY;
TRACE_EXIT;
}
void platform_set_clock_enable(uint clock, bool enable)
{
uint32_t reg;
switch (CLOCK_TO_GROUP(clock)) {
case CLOCK_GROUP_CPU: reg = PM_CPUMASK; break;
case CLOCK_GROUP_HSB: reg = PM_HSBMASK; break;
case CLOCK_GROUP_PBA: reg = PM_PBAMASK; break;
case CLOCK_GROUP_PBB: reg = PM_PBBMASK; break;
default:
panic("platform_set_clock_enable: bad clock input 0x%x\n", clock);
}
if (enable) {
*REG32(reg) |= 1 << CLOCK_IN_GROUP(clock);
} else {
*REG32(reg) &= ~(1 << CLOCK_IN_GROUP(clock));
}
}

171
platform/at32ap7/debug.c Normal file
View File

@@ -0,0 +1,171 @@
/*
* Copyright (c) 2009 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdarg.h>
#include <reg.h>
#include <debug.h>
#include <printf.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#include <platform/debug.h>
#include <arch/ops.h>
#include <lib/cbuf.h>
#include <platform/at32ap7.h>
#if 0
static cbuf_t debug_buf;
static timer_t debug_timer;
#endif
static inline uint32_t uart_reg_base(int uart)
{
switch(uart) {
default:
case 0: return USART0_BASE;
case 1: return USART1_BASE;
case 2: return USART2_BASE;
case 3: return USART3_BASE;
}
}
static void write_uart_reg(int uart, int reg, unsigned char data)
{
unsigned long base;
int mul = 4;
base = uart_reg_base(uart);
*REG32(base + reg * mul) = data;
}
static unsigned int read_uart_reg(int uart, int reg)
{
unsigned long base;
int mul = 4;
base = uart_reg_base(uart);
return *REG32(base + reg * mul);
}
static int uart_init(void)
{
/* clear the tx & rx fifo and disable */
// write_uart_reg(0, UART_FCR, 0x6);
return 0;
}
int uart_putc(int port, char c )
{
while (!(read_uart_reg(port, UART_CSR) & (1<<9))) // wait for the shift register to empty
;
write_uart_reg(port, UART_THR, c);
return 0;
}
static int uart_getc(int port, bool wait) /* returns -1 if no data available */
{
if (wait) {
while (!(read_uart_reg(port, UART_CSR) & (1<<0))) // wait for data to show up in the rx fifo
;
} else {
if (!(read_uart_reg(port, UART_CSR) & (1<<0)))
return -1;
}
return read_uart_reg(port, UART_RHR);
}
void _dputc(char c)
{
if (c == '\n')
uart_putc(1, '\r');
uart_putc(1, c);
}
#if 0
static enum handler_return debug_timer_callback(timer_t *t, time_t now, void *arg)
{
signed char c;
c = uart_getc(0, false);
if (c > 0) {
cbuf_write(&debug_buf, &c, 1, false);
return INT_RESCHEDULE;
} else {
return INT_NO_RESCHEDULE;
}
}
#endif
int dgetc(char *c, bool wait)
{
#if 0
ssize_t len;
len = cbuf_read(&debug_buf, c, 1, wait);
return len;
#endif
if (wait)
thread_sleep(100);
return -1;
}
void debug_dump_regs(void)
{
PANIC_UNIMPLEMENTED;
}
void platform_halt(void)
{
dprintf(ALWAYS, "HALT: spinning forever...\n");
for(;;);
}
void debug_dump_memory_bytes(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_dump_memory_halfwords(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_dump_memory_words(void *mem, int len)
{
PANIC_UNIMPLEMENTED;
}
void debug_set_trace_level(int trace_type, int level)
{
PANIC_UNIMPLEMENTED;
}
void platform_init_debug(void)
{
#if 0
cbuf_initialize(&debug_buf, 512);
timer_set_periodic(&debug_timer, 10, &debug_timer_callback, NULL);
#endif
}

View File

@@ -0,0 +1,243 @@
#ifndef __INCLUDE_PLATFORM_AT32AP7_H
#define __INCLUDE_PLATFORM_AT32AP7_H
/* memory map */
#define SRAM_CS0_BASE (0x0)
#define SRAM_CS4_BASE (0x04000000)
#define SRAM_CS2_BASE (0x08000000)
#define SRAM_CS3_BASE (0x0c000000)
#define SRAM_CS1_BASE (0x10000000)
#define SDRAM_BASE (0x10000000)
#define SRAM_CS5_BASE (0x20000000)
#define ISRAM0_BASE (0x24000000)
#define ISRAM1_BASE (0x24004000)
#define LCDC_BASE (0xff000000)
#define DMACA_BASE (0xff200000)
#define USBA_BASE (0xff300000)
#define PBA_BASE (0xffe00000)
#define PBB_BASE (0xfff00000)
/* peripheral bases */
#define SPI0_BASE (PBA_BASE + 0x0)
#define SPI1_BASE (PBA_BASE + 0x400)
#define TWI_BASE (PBA_BASE + 0x800)
#define USART0_BASE (PBA_BASE + 0xc00)
#define USART1_BASE (PBA_BASE + 0x1000)
#define USART2_BASE (PBA_BASE + 0x1400)
#define USART3_BASE (PBA_BASE + 0x1800)
#define SSC0_BASE (PBA_BASE + 0x1c00)
#define SSC1_BASE (PBA_BASE + 0x2000)
#define SSC2_BASE (PBA_BASE + 0x2400)
#define PIOA_BASE (PBA_BASE + 0x2800)
#define PIOB_BASE (PBA_BASE + 0x2c00)
#define PIOC_BASE (PBA_BASE + 0x3000)
#define PIOD_BASE (PBA_BASE + 0x3400)
#define PIOE_BASE (PBA_BASE + 0x3800)
#define PSIF_BASE (PBA_BASE + 0x3c00)
#define PM_BASE (PBB_BASE + 0x0)
#define RTC_BASE (PBB_BASE + 0x80)
#define WDT_BASE (PBB_BASE + 0xb0)
#define EIC_BASE (PBB_BASE + 0x100)
#define INTC_BASE (PBB_BASE + 0x400)
#define HMATRIX_BASE (PBB_BASE + 0x800)
#define TC0_BASE (PBB_BASE + 0xc00)
#define TC1_BASE (PBB_BASE + 0x1000)
#define PWM_BASE (PBB_BASE + 0x1400)
#define MACB0_BASE (PBB_BASE + 0x1800)
#define MACB1_BASE (PBB_BASE + 0x1c00)
#define ABDAC_BASE (PBB_BASE + 0x2000)
#define MCI_BASE (PBB_BASE + 0x2400)
#define AC97_BASE (PBB_BASE + 0x2800)
#define ISI_BASE (PBB_BASE + 0x2c00)
#define USBA_CONFIG_BASE (PBB_BASE + 0x3000)
#define SMC_BASE (PBB_BASE + 0x3400)
#define SDRAMC_BASE (PBB_BASE + 0x3800)
#define ECC_BASE (PBB_BASE + 0x3c00)
/* interrupt vectors */
#define INT_GROUP_COUNT 64
#define INT_GROUP_SHIFT 5
#define INT_GROUP_MASK (0x3f << INT_GROUP_SHIFT)
#define INT_LINE_MASK (0x1f)
#define INT_VECTOR(group, line) (((group) << INT_GROUP_SHIFT) | (line))
#define INT_COUNT_COMPARE_MATCH INT_VECTOR(0, 0)
#define INT_PERF_COUNTER_OVERFLOW INT_VECTOR(0, 1)
#define INT_LCDC_EOF INT_VECTOR(1, 0)
#define INT_LCDC_LN INT_VECTOR(1, 1)
#define INT_LCDC_LSTLN INT_VECTOR(1, 2)
#define INT_LCDC_MER INT_VECTOR(1, 3)
#define INT_LCDC_OWR INT_VECTOR(1, 4)
#define INT_LCDC_UFLW INT_VECTOR(1, 5)
#define INT_DMACA_BLOCK INT_VECTOR(2, 0)
#define INT_DMACA_DSTT INT_VECTOR(2, 1)
#define INT_DMACA_ERR INT_VECTOR(2, 2)
#define INT_DMACA_SRCT INT_VECTOR(2, 3)
#define INT_DMACA_TFR INT_VECTOR(2, 4)
#define INT_SPI0 INT_VECTOR(3, 0)
#define INT_SPI1 INT_VECTOR(4, 0)
#define INT_TWI INT_VECTOR(5, 0)
#define INT_USART0 INT_VECTOR(6, 0)
#define INT_USART1 INT_VECTOR(7, 0)
#define INT_USART2 INT_VECTOR(8, 0)
#define INT_USART3 INT_VECTOR(9, 0)
#define INT_SSC0 INT_VECTOR(10, 0)
#define INT_SSC1 INT_VECTOR(11, 0)
#define INT_SSC2 INT_VECTOR(12, 0)
#define INT_PIOA INT_VECTOR(13, 0)
#define INT_PIOB INT_VECTOR(14, 0)
#define INT_PIOC INT_VECTOR(15, 0)
#define INT_PIOD INT_VECTOR(16, 0)
#define INT_PIOE INT_VECTOR(17, 0)
#define INT_PSIF INT_VECTOR(18, 0)
#define INT_EIC0 INT_VECTOR(19, 0)
#define INT_EIC1 INT_VECTOR(19, 1)
#define INT_EIC2 INT_VECTOR(19, 2)
#define INT_EIC3 INT_VECTOR(19, 3)
#define INT_PM INT_VECTOR(20, 0)
#define INT_RTC INT_VECTOR(21, 0)
#define INT_TC00 INT_VECTOR(22, 0)
#define INT_TC01 INT_VECTOR(22, 1)
#define INT_TC02 INT_VECTOR(22, 2)
#define INT_TC10 INT_VECTOR(23, 0)
#define INT_TC11 INT_VECTOR(23, 1)
#define INT_TC12 INT_VECTOR(23, 2)
#define INT_PWM INT_VECTOR(24, 0)
#define INT_MACB0 INT_VECTOR(25, 0)
#define INT_MACB1 INT_VECTOR(26, 0)
#define INT_ABDAC INT_VECTOR(27, 0)
#define INT_MCI INT_VECTOR(28, 0)
#define INT_AC97C INT_VECTOR(29, 0)
#define INT_ISI INT_VECTOR(30, 0)
#define INT_USBA INT_VECTOR(31, 0)
#define INT_EBI INT_VECTOR(32, 0)
/* PM block */
#define PM_MCCTRL (PM_BASE + 0x00)
#define PM_CKSEL (PM_BASE + 0x04)
#define PM_CPUMASK (PM_BASE + 0x08)
#define PM_HSBMASK (PM_BASE + 0x0c)
#define PM_PBAMASK (PM_BASE + 0x10)
#define PM_PBBMASK (PM_BASE + 0x14)
#define PM_PLL0 (PM_BASE + 0x20)
#define PM_PLL1 (PM_BASE + 0x24)
#define PM_IER (PM_BASE + 0x40)
#define PM_IDR (PM_BASE + 0x44)
#define PM_IMR (PM_BASE + 0x48)
#define PM_ISR (PM_BASE + 0x4c)
#define PM_ICR (PM_BASE + 0x50)
#define PM_GCCTRL0 (PM_BASE + 0x60)
#define PM_GCCTRL1 (PM_BASE + 0x64)
#define PM_GCCTRL2 (PM_BASE + 0x68)
#define PM_GCCTRL3 (PM_BASE + 0x6c)
#define PM_GCCTRL4 (PM_BASE + 0x70)
#define PM_GCCTRL5 (PM_BASE + 0x74)
#define PM_GCCTRL6 (PM_BASE + 0x78)
#define PM_GCCTRL7 (PM_BASE + 0x7c)
#define PM_RCAUSE (PM_BASE + 0xc0)
/* clocks */
#define _CLOCK(group, x) (((group) << 5) | (x))
#define CLOCK_TO_GROUP(clk) ((clk) >> 5)
#define CLOCK_IN_GROUP(clk) ((clk) & ((1<<5) - 1))
#define CLOCK_GROUP_CPU 0
#define CLOCK_GROUP_HSB 1
#define CLOCK_GROUP_PBA 2
#define CLOCK_GROUP_PBB 3
#define CLOCK_PICO _CLOCK(CLOCK_GROUP_CPU, 0)
#define CLOCK_EBI _CLOCK(CLOCK_GROUP_HSB, 0)
#define CLOCK_PBA _CLOCK(CLOCK_GROUP_HSB, 1)
#define CLOCK_PBB _CLOCK(CLOCK_GROUP_HSB, 2)
#define CLOCK_HRAMC _CLOCK(CLOCK_GROUP_HSB, 3)
#define CLOCK_HSB_BRIDGE _CLOCK(CLOCK_GROUP_HSB, 4)
#define CLOCK_ISI_HSB _CLOCK(CLOCK_GROUP_HSB, 5)
#define CLOCK_USB_HSB _CLOCK(CLOCK_GROUP_HSB, 6)
#define CLOCK_LCDC _CLOCK(CLOCK_GROUP_HSB, 7)
#define CLOCK_MACB0_HSB _CLOCK(CLOCK_GROUP_HSB, 8)
#define CLOCK_MACB1_HSB _CLOCK(CLOCK_GROUP_HSB, 9)
#define CLOCK_DMA _CLOCK(CLOCK_GROUP_HSB, 10)
#define CLOCK_SPI0 _CLOCK(CLOCK_GROUP_PBA, 0)
#define CLOCK_SPI1 _CLOCK(CLOCK_GROUP_PBA, 1)
#define CLOCK_TWI _CLOCK(CLOCK_GROUP_PBA, 2)
#define CLOCK_USART0 _CLOCK(CLOCK_GROUP_PBA, 3)
#define CLOCK_USART1 _CLOCK(CLOCK_GROUP_PBA, 4)
#define CLOCK_USART2 _CLOCK(CLOCK_GROUP_PBA, 5)
#define CLOCK_USART3 _CLOCK(CLOCK_GROUP_PBA, 6)
#define CLOCK_SSC0 _CLOCK(CLOCK_GROUP_PBA, 7)
#define CLOCK_SSC1 _CLOCK(CLOCK_GROUP_PBA, 8)
#define CLOCK_SSC2 _CLOCK(CLOCK_GROUP_PBA, 9)
#define CLOCK_PIOA _CLOCK(CLOCK_GROUP_PBA, 10)
#define CLOCK_PIOB _CLOCK(CLOCK_GROUP_PBA, 11)
#define CLOCK_PIOC _CLOCK(CLOCK_GROUP_PBA, 12)
#define CLOCK_PIOD _CLOCK(CLOCK_GROUP_PBA, 13)
#define CLOCK_PIOE _CLOCK(CLOCK_GROUP_PBA, 14)
#define CLOCK_PIOF _CLOCK(CLOCK_GROUP_PBA, 15)
#define CLOCK_PDC _CLOCK(CLOCK_GROUP_PBA, 16)
#define CLOCK_PM _CLOCK(CLOCK_GROUP_PBB, 0)
#define CLOCK_INTC _CLOCK(CLOCK_GROUP_PBB, 1)
#define CLOCK_HMATRIX _CLOCK(CLOCK_GROUP_PBB, 2)
#define CLOCK_TC0 _CLOCK(CLOCK_GROUP_PBB, 3)
#define CLOCK_TC1 _CLOCK(CLOCK_GROUP_PBB, 4)
#define CLOCK_PWM _CLOCK(CLOCK_GROUP_PBB, 5)
#define CLOCK_MACB0 _CLOCK(CLOCK_GROUP_PBB, 6)
#define CLOCK_MACB1 _CLOCK(CLOCK_GROUP_PBB, 7)
#define CLOCK_DAC _CLOCK(CLOCK_GROUP_PBB, 8)
#define CLOCK_MCI _CLOCK(CLOCK_GROUP_PBB, 9)
#define CLOCK_AC97C _CLOCK(CLOCK_GROUP_PBB, 10)
#define CLOCK_ISI _CLOCK(CLOCK_GROUP_PBB, 11)
#define CLOCK_USB _CLOCK(CLOCK_GROUP_PBB, 12)
#define CLOCK_SMC _CLOCK(CLOCK_GROUP_PBB, 13)
#define CLOCK_SDRAMC _CLOCK(CLOCK_GROUP_PBB, 14)
#define CLOCK_ECC _CLOCK(CLOCK_GROUP_PBB, 15)
/* UART */
#define UART_CR (0)
#define UART_MR (1)
#define UART_IER (2)
#define UART_IDR (3)
#define UART_IMR (4)
#define UART_CSR (5)
#define UART_RHR (6)
#define UART_THR (7)
#define UART_BRGR (8)
#define UART_RTOR (9)
#define UART_TTGR (10)
#define UART_FIDI (16)
#define UART_NER (17)
#define UART_IFR (19)
#define UART_MAN (20)
/* interrupt controller */
#define INTC_IPR(x) (INTC_BASE + 0x000 + ((x) * 4))
#define INTC_IRR(x) (INTC_BASE + 0x100 + ((x) * 4))
#define INTC_ICR(x) (INTC_BASE + 0x200 + ((3 - x) * 4))
/* timer */
#define TC_CCR (0x00)
#define TC_CMR (0x04)
#define TC_CV (0x10)
#define TC_RA (0x14)
#define TC_RB (0x18)
#define TC_RC (0x1c)
#define TC_SR (0x20)
#define TC_IER (0x24)
#define TC_IDR (0x28)
#define TC_IMR (0x2c)
#define TC_CCRn(n) (TC_CCR + 0x40 * (n))
#define TC_CMRn(n) (TC_CMR + 0x40 * (n))
#define TC_CVn(n) (TC_CV + 0x40 * (n))
#define TC_RAn(n) (TC_RA + 0x40 * (n))
#define TC_RBn(n) (TC_RB + 0x40 * (n))
#define TC_RCn(n) (TC_RC + 0x40 * (n))
#define TC_SRn(n) (TC_SR + 0x40 * (n))
#define TC_IERn(n) (TC_IER + 0x40 * (n))
#define TC_IDRn(n) (TC_IDR + 0x40 * (n))
#define TC_IMRn(n) (TC_IMR + 0x40 * (n))
#define TC_BCR (0xc0)
#define TC_BMR (0xc4)
#endif

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <err.h>
#include <reg.h>
#include <arch.h>
#include <arch/avr32.h>
#include <kernel/thread.h>
#include <platform/interrupts.h>
#include <platform/at32ap7.h>
#include "platform_p.h"
// XXX make this more efficient
#define INT_VECTORS (INT_GROUP_COUNT << INT_GROUP_SHIFT)
struct int_handler_struct {
int_handler handler;
void *arg;
};
static struct int_handler_struct int_handler_table[INT_VECTORS];
void platform_init_interrupts(void)
{
int i;
TRACE_ENTRY;
// enable the clock
platform_set_clock_enable(CLOCK_INTC, true);
// set the interrupt vectors to the proper offset, INT0
for (i = 0; i < INT_GROUP_COUNT; i++) {
*REG32(INTC_IPR(i)) = (0 << 30) | avr32_get_interrupt_autovector_offset();
// printf("0x%x\n", *REG32(INTC_IPR(i)));
}
TRACE_EXIT;
}
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
enter_critical_section();
int_handler_table[vector].arg = arg;
int_handler_table[vector].handler = handler;
exit_critical_section();
}
status_t mask_interrupt(unsigned int vector)
{
// XXX can't actually mask
return NO_ERROR;
}
status_t unmask_interrupt(unsigned int vector)
{
// XXX can't actually mask
return NO_ERROR;
}
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)) {
// nothing is set, must be spurious
return INT_NO_RESCHEDULE;
}
uint line = __builtin_ctz(linebits);
uint vector = INT_VECTOR(group, line);
int ret = INT_NO_RESCHEDULE;
if (likely(int_handler_table[vector].handler != NULL)) {
ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
}
return ret;
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <debug.h>
#include <platform/at32ap7.h>
#include "platform_p.h"
void platform_early_init(void)
{
TRACE_ENTRY;
platform_init_clocks();
platform_init_interrupts();
platform_init_timer();
TRACE_EXIT;
}
void platform_init(void)
{
TRACE_ENTRY;
TRACE_EXIT;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __AT32AP7_PLATFORM_P_H
#define __AT32AP7_PLATFORM_P_H
void platform_init_interrupts(void);
void platform_init_clocks(void);
void platform_set_clock_enable(uint clock, bool enable);
#endif

27
platform/at32ap7/rules.mk Normal file
View File

@@ -0,0 +1,27 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
ARCH := avr32
CPU := generic
MODULES += \
lib/cbuf
INCLUDES += \
-I$(LOCAL_DIR)/include
OBJS += \
$(LOCAL_DIR)/clocks.o \
$(LOCAL_DIR)/debug.o \
$(LOCAL_DIR)/interrupts.o \
$(LOCAL_DIR)/platform.o \
$(LOCAL_DIR)/timer.o
# $(LOCAL_DIR)/console.o \
MEMBASE := 0x10000000
MEMSIZE := 0x02000000 # 32MB
LINKER_SCRIPT += \
$(BUILDDIR)/system-onesegment.ld

133
platform/at32ap7/timer.c Normal file
View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2009-2010 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <sys/types.h>
#include <reg.h>
#include <err.h>
#include <kernel/thread.h>
#include <debug.h>
#include <platform.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include <platform/at32ap7.h>
#include "platform_p.h"
#define LOCAL_TRACE 0
#define NUM_TMR 6
#define TMR_FREQ (32768)
static time_t system_time = 0;
static time_t tick_interval;
static uint32_t ticks_per_interval;
static platform_timer_callback t_callback;
static void *callback_arg;
static inline addr_t TMR_REG_ADDR(unsigned int tmr, unsigned int reg)
{
return ((tmr >= 3) ? (TC1_BASE + reg + 0x40 * (tmr - 3)) : (TC0_BASE + reg + 0x40 * (tmr)));
}
#define TMR_REG(tmr, reg) (*REG32(TMR_REG_ADDR(tmr, reg)))
static enum handler_return os_timer_tick(void *arg)
{
uint32_t hole = TMR_REG(0, TC_SR); // gotta read the status register to clear the state
hole = hole;
system_time += tick_interval;
// printf("os_timer_tick %d\n", system_time);
if (!t_callback)
return INT_NO_RESCHEDULE;
return t_callback(callback_arg, system_time);
}
status_t platform_set_periodic_timer(platform_timer_callback callback, void *arg, time_t interval)
{
enter_critical_section();
LTRACEF("callback %p, arg %p, interval %d\n", callback, arg, interval);
t_callback = callback;
callback_arg = arg;
tick_interval = interval;
ticks_per_interval = interval * TMR_FREQ / 1000; // interval is in ms
TMR_REG(0, TC_CCR) = (1<<1); // CLKDIS
TMR_REG(0, TC_CMR) = (1<<14); // CPCTRG
TMR_REG(0, TC_RC) = interval;
TMR_REG(0, TC_IER) = (1<<4);
TMR_REG(0, TC_CCR) = (1<<0); // CLKEN
TMR_REG(0, TC_CCR) |= (1<<2); // SWTRG
register_int_handler(INT_TC00, &os_timer_tick, NULL);
unmask_interrupt(INT_TC00);
exit_critical_section();
return NO_ERROR;
}
time_t current_time(void)
{
time_t t;
uint32_t delta_ticks;
uint32_t delta_ticks2;
retry:
delta_ticks = TMR_REG(0, TC_CV);
t = system_time;
delta_ticks2 = TMR_REG(0, TC_CV);
if (delta_ticks2 < delta_ticks)
goto retry;
t += (delta_ticks2 * tick_interval) / ticks_per_interval;
return t;
}
bigtime_t current_time_hires(void)
{
return current_time() * 1000ULL;
}
void platform_init_timer(void)
{
TRACE_ENTRY;
platform_set_clock_enable(CLOCK_TC0, true);
platform_set_clock_enable(CLOCK_TC1, true);
// disable all the clocks
unsigned int i;
for (i = 0; i < NUM_TMR; i++) {
TMR_REG(i, TC_CCR) = (1<<1); // CLKDIS
TMR_REG(i, TC_IDR) = 0xf; // disable all interrupts
}
TRACE_EXIT;
}

9
project/ngw100-test.mk Normal file
View File

@@ -0,0 +1,9 @@
# top level project rules for the armemu-test project
#
LOCAL_DIR := $(GET_LOCAL_DIR)
TARGET := ngw100
MODULES += \
app/tests \
app/shell

6
scripts/do-ngw100-test Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
export PROJECT=ngw100-test
make &&
cp build-ngw100-test/lk.bin /tftproot/6300A8C0.img

0
target/ngw100/init.c Normal file
View File

15
target/ngw100/rules.mk Normal file
View File

@@ -0,0 +1,15 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
PLATFORM := at32ap7
MODULES +=
OBJS += \
$(LOCAL_DIR)/init.o
MEMSIZE := 0x02000000 # 32MB
PROGBASE := 0x10200000 # u-boot loads us here
DEFINES += \
SDRAM_SIZE=$(MEMSIZE)