diff --git a/bsp/beaglebone/SConscript b/bsp/beaglebone/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..fe0ae941ae9a759ae478de901caec1c961e56af8 --- /dev/null +++ b/bsp/beaglebone/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +Import('RTT_ROOT') + +cwd = str(Dir('#')) +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/beaglebone/SConstruct b/bsp/beaglebone/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..b7c9ef221e9d7b60cd56c9f8eb30449f0ceb4210 --- /dev/null +++ b/bsp/beaglebone/SConstruct @@ -0,0 +1,29 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread-beaglebone.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/beaglebone/applications/SConscript b/bsp/beaglebone/applications/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..01eb940dfb35f92c503a78b0b49a4354590f9f3a --- /dev/null +++ b/bsp/beaglebone/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/beaglebone/applications/application.c b/bsp/beaglebone/applications/application.c new file mode 100644 index 0000000000000000000000000000000000000000..99c2991df722e947803261226778b7b249491339 --- /dev/null +++ b/bsp/beaglebone/applications/application.c @@ -0,0 +1,28 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-11-20 Bernard the first version + */ + +#include +#include +#include + +int rt_application_init() +{ + /* do component initialization */ + rt_components_init(); +#ifdef RT_USING_NEWLIB + libc_system_init(RT_CONSOLE_DEVICE_NAME); +#endif + + return 0; +} diff --git a/bsp/beaglebone/applications/board.c b/bsp/beaglebone/applications/board.c new file mode 100644 index 0000000000000000000000000000000000000000..1750dd9e172ca58eafff9d4cbe27118276b5c12a --- /dev/null +++ b/bsp/beaglebone/applications/board.c @@ -0,0 +1,171 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-11-20 Bernard the first version + */ + +#include +#include +#include + +#include "board.h" +#include + +#ifdef RT_USING_VMM +#include +static rt_uint32_t DMTIMER = 0; +#define TIMER_HW_BASE (DMTIMER) +#else +#define TIMER_HW_BASE AM33XX_DMTIMER_7_REGS +#endif + +#define DMTIMER_TCLR_AR (0x00000002u) +#define DMTIMER_TCLR_CE (0x00000040u) +#define DMTIMER_TCLR_PRE (0x00000020u) +#define DMTIMER_TCLR_ST (0x00000001u) +#define DMTIMER_IRQENABLE_SET_OVF_EN_FLAG (0x00000002u) +#define DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG (0x00000002u) + +#define CM_DPLL_CLKSEL_CLK_CLKSEL (0x00000003u) +#define CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3 (0x2u) + +#define CM_PER_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_CLKCTRL_MODULEMODE (0x00000003u) + +#define CM_PER_CLKCTRL_IDLEST (0x00030000u) +#define CM_PER_CLKCTRL_IDLEST_FUNC (0x0u) + +#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK (0x00000100u) +#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER2_GCLK (0x00004000u) +#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER7_GCLK (1<<13) + +static void rt_hw_timer_isr(int vector, void* param) +{ + rt_tick_increase(); + + DMTIMER_IRQSTATUS(TIMER_HW_BASE) = DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG; +} + +static void timer_clk_init(void) +{ + unsigned long prcm_base; + +#ifdef RT_USING_VMM + prcm_base = vmm_find_iomap("PRCM"); +#else + prcm_base = AM33XX_PRCM_REGS; +#endif + + /* software forced wakeup */ + CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2; + + /* Waiting for the L4LS clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8))) + ; + + /* Select the clock source for the Timer2 instance. */ + CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) &= ~(CM_DPLL_CLKSEL_CLK_CLKSEL); + /* 32k clock source */ + CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) |= CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3; + + while ((CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) & CM_DPLL_CLKSEL_CLK_CLKSEL) != + CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3); + + /* Writing to MODULEMODE field of CM_PER_TIMER7_CLKCTRL register. */ + CM_PER_TIMER7_CLKCTRL(prcm_base) |= CM_PER_CLKCTRL_MODULEMODE_ENABLE; + + /* Waiting for MODULEMODE field to reflect the written value. */ + while ((CM_PER_TIMER7_CLKCTRL(prcm_base) & CM_PER_CLKCTRL_MODULEMODE) != + CM_PER_CLKCTRL_MODULEMODE_ENABLE); + + /* + * Waiting for IDLEST field in CM_PER_TIMER7_CLKCTRL register + * for the module is fully functional. + */ + while ((CM_PER_TIMER7_CLKCTRL(prcm_base) & CM_PER_CLKCTRL_IDLEST) != + CM_PER_CLKCTRL_IDLEST_FUNC); + + /* Waiting for the L4LS clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK)); + /* Waiting for the TIMER7 clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER7_GCLK)); +} + +int rt_hw_timer_init(void) +{ + rt_uint32_t counter; + +#ifdef RT_USING_VMM + DMTIMER = vmm_find_iomap("TIMER7"); +#endif + + timer_clk_init(); + + /* soft reset the timer */ + DMTIMER_TIOCP_CFG(TIMER_HW_BASE) |= 1; + while ((DMTIMER_TIOCP_CFG(TIMER_HW_BASE) & 0x1) == 1) + ; + + /* calculate count */ + counter = 0xffffffff - (32768UL/RT_TICK_PER_SECOND); + + /* set initial count */ + DMTIMER_TCRR(TIMER_HW_BASE) = counter; + /* set reload count */ + DMTIMER_TLDR(TIMER_HW_BASE) = counter; + + /* set mode: auto reload */ + DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_AR; + + /* interrupt enable for match */ + DMTIMER_IRQENABLE_SET(TIMER_HW_BASE) = DMTIMER_IRQENABLE_SET_OVF_EN_FLAG; + DMTIMER_IRQSTATUS(TIMER_HW_BASE) = DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG; + + rt_hw_interrupt_install(TINT7, rt_hw_timer_isr, RT_NULL, "tick"); + rt_hw_interrupt_control(TINT7, 0, 0); + rt_hw_interrupt_umask(TINT7); + + while (DMTIMER_TWPS(TIMER_HW_BASE) != 0) + ; + + /* start timer */ + DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_ST; + + while (DMTIMER_TWPS(TIMER_HW_BASE) != 0) + ; + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_timer_init); + +/** + * This function will initialize beaglebone board + */ +void rt_hw_board_init(void) +{ + rt_components_board_init(); + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +} + +void rt_hw_cpu_reset(void) +{ + unsigned long prcm_base; + +#ifdef RT_USING_VMM + prcm_base = vmm_find_iomap("PRCM"); +#else + prcm_base = AM33XX_PRCM_REGS; +#endif + REG32(PRM_DEVICE(prcm_base)) = 0x1; + RT_ASSERT(0); +} +FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reboot the cpu); +FINSH_FUNCTION_EXPORT_ALIAS(rt_hw_cpu_reset, __cmd_reboot, reboot the cpu); diff --git a/bsp/beaglebone/applications/board.h b/bsp/beaglebone/applications/board.h new file mode 100644 index 0000000000000000000000000000000000000000..765ab962b0a295de0388682a3a163b9f98e31ded --- /dev/null +++ b/bsp/beaglebone/applications/board.h @@ -0,0 +1,32 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +#if defined(__CC_ARM) +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit) +#elif defined(__GNUC__) +extern int __bss_end; +#define HEAP_BEGIN ((void*)&__bss_end) +#endif + +#define HEAP_END (void*)0x90000000 + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/beaglebone/applications/startup.c b/bsp/beaglebone/applications/startup.c new file mode 100644 index 0000000000000000000000000000000000000000..33539aece147bdc092025ffc172a0c3a4dd3b436 --- /dev/null +++ b/bsp/beaglebone/applications/startup.c @@ -0,0 +1,68 @@ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-12-05 Bernard the first version + */ + +#include +#include + +#include + +extern int rt_application_init(void); + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* initialzie hardware interrupt */ + rt_hw_interrupt_init(); + + /* initialize board */ + rt_hw_board_init(); + /* show RT-Thread version */ + rt_show_version(); + + /* initialize memory system */ +#ifdef RT_USING_HEAP + rt_system_heap_init(HEAP_BEGIN, HEAP_END); +#endif + + /* initialize scheduler system */ + rt_system_scheduler_init(); + + /* initialize soft timer thread */ + rt_system_timer_thread_init(); + + /* initialize application */ + rt_application_init(); + + /* initialize idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int main(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* invoke rtthread_startup */ + rtthread_startup(); + + return 0; +} diff --git a/bsp/beaglebone/beaglebone_ram.lds b/bsp/beaglebone/beaglebone_ram.lds new file mode 100644 index 0000000000000000000000000000000000000000..52795e68ba3a8aae296e152dccb924aac10fee29 --- /dev/null +++ b/bsp/beaglebone/beaglebone_ram.lds @@ -0,0 +1,91 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SECTIONS +{ + . = 0x80200000; + + __text_start = .; + .text : + { + *(.vectors) + *(.text) + *(.text.*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for initialization */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + } =0 + __text_end = .; + + __rodata_start = .; + .rodata : { *(.rodata) *(.rodata.*) } + __rodata_end = .; + + . = ALIGN(4); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + __data_start = .; + . = ALIGN(4); + .data : + { + *(.data) + *(.data.*) + } + __data_end = .; + + . = ALIGN(4); + __bss_start = __data_end; + .bss : + { + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + } + . = ALIGN(4); + __bss_end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + _end = .; +} diff --git a/bsp/beaglebone/drivers/SConscript b/bsp/beaglebone/drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..a630c8a7c407f13071e80ddbae48db5b12a32046 --- /dev/null +++ b/bsp/beaglebone/drivers/SConscript @@ -0,0 +1,22 @@ +import copy +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + +# remove no need file. +if GetDepend('RT_USING_LWIP') == False: + src_need_remove = ['dm9000.c'] # need remove file list. + SrcRemove(src, src_need_remove) + +if GetDepend('RT_USING_DFS') == False: + src_need_remove = ['sd.c'] # need remove file list. + SrcRemove(src, src_need_remove) + +CPPPATH = [cwd] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/beaglebone/drivers/serial.c b/bsp/beaglebone/drivers/serial.c new file mode 100644 index 0000000000000000000000000000000000000000..3698686aab73d2739ec2e6cc17b8b69c53c1d94b --- /dev/null +++ b/bsp/beaglebone/drivers/serial.c @@ -0,0 +1,281 @@ +/* + * File : serial.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + */ + +#include +#include +#include + +#include +#include +#include "serial.h" +#include "serial_reg.h" + +struct am33xx_uart +{ + unsigned long base; + int irq; +}; + +static void am33xx_uart_isr(int irqno, void* param) +{ + rt_uint32_t iir; + struct am33xx_uart* uart; + struct rt_serial_device *serial; + + serial = (struct rt_serial_device*)param; + uart = (struct am33xx_uart *)serial->parent.user_data; + + iir = UART_IIR_REG(uart->base); + + if ((iir & (0x02 << 1)) || (iir & (0x6 << 1))) + { + rt_hw_serial_isr(serial); + } +} + +#define NOT_IMPLEMENTED() RT_ASSERT(0) + +static rt_err_t am33xx_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct am33xx_uart* uart; + unsigned long base; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + RT_ASSERT(uart); + base = uart->base; + +#define __LCR UART_LCR_REG(base) + + if (cfg->data_bits == DATA_BITS_8) + __LCR |= 3; + else + NOT_IMPLEMENTED(); + + if (cfg->stop_bits == STOP_BITS_1) + __LCR &= ~(1<<2); + else + __LCR |= (1<<2); + + if (cfg->parity == PARITY_NONE) + __LCR &= ~(1<<3); + else + __LCR |= (1<<3); + + __LCR |= (1<<7); + if (cfg->baud_rate == BAUD_RATE_115200) + { + UART_DLL_REG(base) = 26; + UART_DLH_REG(base) = 0; + } + else + { + NOT_IMPLEMENTED(); + } + __LCR &= ~(1<<7); + + UART_MDR1_REG(base) = 0; + UART_MDR2_REG(base) = 0; + +#undef __LCR + return RT_EOK; +} + +static rt_err_t am33xx_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + rt_hw_interrupt_mask(uart->irq); + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + rt_hw_interrupt_umask(uart->irq); + break; + } + + return RT_EOK; +} + +int printkc(char c) +{ + int base = 0xf9e09000; + + while (!(UART_LSR_REG(base) & 0x20)); + UART_THR_REG(base) = c; + + return 1; +} + +static int am33xx_putc(struct rt_serial_device *serial, char c) +{ + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + while (!(UART_LSR_REG(uart->base) & 0x20)); + UART_THR_REG(uart->base) = c; + + return 1; +} + +static int am33xx_getc(struct rt_serial_device *serial) +{ + int ch; + struct am33xx_uart* uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct am33xx_uart *)serial->parent.user_data; + + ch = -1; + if (UART_LSR_REG(uart->base) & 0x01) + { + ch = UART_RHR_REG(uart->base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops am33xx_uart_ops = +{ + am33xx_configure, + am33xx_control, + am33xx_putc, + am33xx_getc, +}; + +/* UART1 device driver structure */ +struct serial_ringbuffer uart1_int_rx; +struct am33xx_uart uart1 = +{ + UART1_BASE, + UART1_INT, +}; +struct rt_serial_device serial1; + +#define write_reg(base, value) *(int*)(base) = value +#define read_reg(base) *(int*)(base) + +#define PRM_PER_INTRANSLATION (1 << 20) +#define PRM_PER_POWSTATEOFF (0) +#define PRM_PER_PERMEMSTATEOFF (0) + +static void poweron_per_domain(void) +{ + unsigned long prcm_base; + unsigned long prm_state; + + prcm_base = AM33XX_PRCM_REGS; + + /* wait for ongoing translations */ + for (prm_state = PRM_PER_PWRSTST_REG(prcm_base); + prm_state & PRM_PER_INTRANSLATION; + prm_state = PRM_PER_PWRSTST_REG(prcm_base)) + ; + + /* check power state */ + if ((prm_state & 0x03) == PRM_PER_POWSTATEOFF) + /* power on PER domain */ + PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3; + + /* check per mem state */ + if ((prm_state & 0x03) == PRM_PER_PERMEMSTATEOFF) + /* power on PER domain */ + PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3 << 25; + + while (PRM_PER_PWRSTST_REG(prcm_base) & PRM_PER_INTRANSLATION) + ; +} + +static void start_uart_clk(void) +{ + unsigned long prcm_base; + + prcm_base = AM33XX_PRCM_REGS; + + /* software forced wakeup */ + CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2; + + /* Waiting for the L4LS clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8))) + ; + + /* enable uart1 */ + CM_PER_UART1_CLKCTRL_REG(prcm_base) |= 0x2; + + /* wait for uart1 clk */ + while ((CM_PER_UART1_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0) + ; + /* Waiting for the L4LS UART clock */ + while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<10))) + ; +} + +static void config_pinmux(void) +{ + unsigned long ctlm_base; + + ctlm_base = AM33XX_CTLM_REGS; + + /* make sure the pin mux is OK for uart */ + REG32(ctlm_base + 0x800 + 0x180) = 0x20; + REG32(ctlm_base + 0x800 + 0x184) = 0x00; +} + +int rt_hw_serial_init(void) +{ + struct am33xx_uart* uart; + struct serial_configure config; + + uart = &uart1; + uart->base = UART1_BASE; + + poweron_per_domain(); + start_uart_clk(); + config_pinmux(); + + config.baud_rate = BAUD_RATE_115200; + config.bit_order = BIT_ORDER_LSB; + config.data_bits = DATA_BITS_8; + config.parity = PARITY_NONE; + config.stop_bits = STOP_BITS_1; + config.invert = NRZ_NORMAL; + + serial1.ops = &am33xx_uart_ops; + serial1.int_rx = &uart1_int_rx; + serial1.config = config; + + /* enable RX interrupt */ + UART_IER_REG(uart->base) = 0x01; + /* install ISR */ + rt_hw_interrupt_install(uart->irq, am33xx_uart_isr, &serial1, "uart1"); + rt_hw_interrupt_control(uart->irq, 0, 0); + rt_hw_interrupt_mask(uart->irq); + + /* register UART1 device */ + rt_hw_serial_register(&serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + uart); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_serial_init); + diff --git a/bsp/beaglebone/drivers/serial.h b/bsp/beaglebone/drivers/serial.h new file mode 100644 index 0000000000000000000000000000000000000000..15f7f2c3996166aa6696401c4ccb238e5af70a7e --- /dev/null +++ b/bsp/beaglebone/drivers/serial.h @@ -0,0 +1,20 @@ +/* + * File : serial.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard the first version + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + +int rt_hw_serial_init(void); + +#endif diff --git a/bsp/beaglebone/drivers/serial_reg.h b/bsp/beaglebone/drivers/serial_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..cb984631f8232aea5fb36185732c01b6e1df9838 --- /dev/null +++ b/bsp/beaglebone/drivers/serial_reg.h @@ -0,0 +1,109 @@ +#ifndef SERIAL_REG_H +#define SERIAL_REG_H + +/** @brief Base addresses of UART memory mapped registers */ +#define UART0_BASE (0x44E09000) +#define UART1_BASE (0x48022000) +#define UART2_BASE (0x48024000) +#define UART3_BASE (0x481A6000) +#define UART4_BASE (0x481A8000) +#define UART5_BASE (0x481AA000) + +/* UART registers */ +#define UART_DLL(base) (base + 0x0) +#define UART_RHR(base) (base + 0x0) +#define UART_THR(base) (base + 0x0) +#define UART_DLH(base) (base + 0x4) +#define UART_IER(base) (base + 0x4) +#define UART_EFR(base) (base + 0x8) +#define UART_FCR(base) (base + 0x8) +#define UART_IIR(base) (base + 0x8) +#define UART_LCR(base) (base + 0xC) +#define UART_MCR(base) (base + 0x10) +#define UART_XON1_ADDR1(base) (base + 0x10) +#define UART_LSR(base) (base + 0x14) +#define UART_XON2_ADDR2(base) (base + 0x14) +#define UART_MSR(base) (base + 0x18) +#define UART_TCR(base) (base + 0x18) +#define UART_XOFF1(base) (base + 0x18) +#define UART_SPR(base) (base + 0x1C) +#define UART_TLR(base) (base + 0x1C) +#define UART_XOFF2(base) (base + 0x1C) +#define UART_MDR1(base) (base + 0x20) +#define UART_MDR2(base) (base + 0x24) +#define UART_SFLSR(base) (base + 0x28) +#define UART_TXFLL(base) (base + 0x28) +#define UART_RESUME(base) (base + 0x2C) +#define UART_TXFLH(base) (base + 0x2C) +#define UART_RXFLL(base) (base + 0x30) +#define UART_SFREGL(base) (base + 0x30) +#define UART_RXFLH(base) (base + 0x34) +#define UART_SFREGH(base) (base + 0x34) +#define UART_BLR(base) (base + 0x38) +#define UART_UASR(base) (base + 0x38) +#define UART_ACREG(base) (base + 0x3C) +#define UART_SCR(base) (base + 0x40) +#define UART_SSR(base) (base + 0x44) +#define UART_EBLR(base) (base + 0x48) +#define UART_MVR(base) (base + 0x50) +#define UART_SYSC(base) (base + 0x54) +#define UART_SYSS(base) (base + 0x58) +#define UART_WER(base) (base + 0x5C) +#define UART_CFPS(base) (base + 0x60) +#define UART_RXFIFO_LVL(base) (base + 0x64) +#define UART_TXFIFO_LVL(base) (base + 0x68) +#define UART_IER2(base) (base + 0x6C) +#define UART_ISR2(base) (base + 0x70) +#define UART_FREQ_SEL(base) (base + 0x74) +#define UART_MDR3(base) (base + 0x80) +#define UART_TX_DMA_THRESHOLD(base) (base + 0x84) + +#define UART_DLL_REG(base) REG16(UART_DLL(base)) +#define UART_RHR_REG(base) REG16(UART_RHR(base)) +#define UART_THR_REG(base) REG16(UART_THR(base)) +#define UART_DLH_REG(base) REG16(UART_DLH(base)) +#define UART_IER_REG(base) REG16(UART_IER(base)) +#define UART_EFR_REG(base) REG16(UART_EFR(base)) +#define UART_FCR_REG(base) REG16(UART_FCR(base)) +#define UART_IIR_REG(base) REG16(UART_IIR(base)) +#define UART_LCR_REG(base) REG16(UART_LCR(base)) +#define UART_MCR_REG(base) REG16(UART_MCR(base)) +#define UART_XON1_ADDR1_REG(base) REG16(UART_XON1_ADDR1(base)) +#define UART_LSR_REG(base) REG16(UART_LSR(base)) +#define UART_XON2_ADDR2_REG(base) REG16(UART_XON2_ADDR2(base)) +#define UART_MSR_REG(base) REG16(UART_MSR(base)) +#define UART_TCR_REG(base) REG16(UART_TCR(base)) +#define UART_XOFF1_REG(base) REG16(UART_XOFF1(base)) +#define UART_SPR_REG(base) REG16(UART_SPR(base)) +#define UART_TLR_REG(base) REG16(UART_TLR(base)) +#define UART_XOFF2_REG(base) REG16(UART_XOFF2(base)) +#define UART_MDR1_REG(base) REG16(UART_MDR1(base)) +#define UART_MDR2_REG(base) REG16(UART_MDR2(base)) +#define UART_SFLSR_REG(base) REG16(UART_SFLSR(base)) +#define UART_TXFLL_REG(base) REG16(UART_TXFLL(base)) +#define UART_RESUME_REG(base) REG16(UART_RESUME(base)) +#define UART_TXFLH_REG(base) REG16(UART_TXFLH(base)) +#define UART_RXFLL_REG(base) REG16(UART_RXFLL(base)) +#define UART_SFREGL_REG(base) REG16(UART_SFREGL(base)) +#define UART_RXFLH_REG(base) REG16(UART_RXFLH(base)) +#define UART_SFREGH_REG(base) REG16(UART_SFREGH(base)) +#define UART_BLR_REG(base) REG16(UART_BLR(base)) +#define UART_UASR_REG(base) REG16(UART_UASR(base)) +#define UART_ACREG_REG(base) REG16(UART_ACREG(base)) +#define UART_SCR_REG(base) REG16(UART_SCR(base)) +#define UART_SSR_REG(base) REG16(UART_SSR(base)) +#define UART_EBLR_REG(base) REG16(UART_EBLR(base)) +#define UART_MVR_REG(base) REG16(UART_MVR(base)) +#define UART_SYSC_REG(base) REG16(UART_SYSC(base)) +#define UART_SYSS_REG(base) REG16(UART_SYSS(base)) +#define UART_WER_REG(base) REG16(UART_WER(base)) +#define UART_CFPS_REG(base) REG16(UART_CFPS(base)) +#define UART_RXFIFO_LVL_REG(base) REG16(UART_RXFIFO_LVL(base)) +#define UART_TXFIFO_LVL_REG(base) REG16(UART_TXFIFO_LVL(base)) +#define UART_IER2_REG(base) REG16(UART_IER2(base)) +#define UART_ISR2_REG(base) REG16(UART_ISR2(base)) +#define UART_FREQ_SEL_REG(base) REG16(UART_FREQ_SEL(base)) +#define UART_MDR3_REG(base) REG16(UART_MDR3(base)) +#define UART_TX_DMA_THRESHOLD_REG(base) REG16(UART_TX_DMA_THRESHOLD(base)) + +#endif /* end of include guard: SERIAL_REG_H */ diff --git a/bsp/beaglebone/rtconfig.h b/bsp/beaglebone/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..27992c84cd73d79f09dc65931b66a4d44809db8b --- /dev/null +++ b/bsp/beaglebone/rtconfig.h @@ -0,0 +1,147 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +// + +// +#define RT_NAME_MAX 6 +// +#define RT_ALIGN_SIZE 4 +// +// 8 +// 32 +// 256 +// +#define RT_THREAD_PRIORITY_MAX 32 +// +#define RT_TICK_PER_SECOND 1000 +// +#define IDLE_THREAD_STACK_SIZE 512 +//
+#define RT_DEBUG +//#define RT_DEBUG_SCHEDULER 1 +// +// #define RT_THREAD_DEBUG +// +//#define RT_USING_OVERFLOW_CHECK +//
+ +// +#define RT_USING_HOOK +//
+// #define RT_USING_TIMER_SOFT +// +#define RT_TIMER_THREAD_PRIO 4 +// +#define RT_TIMER_THREAD_STACK_SIZE 512 +// +#define RT_TIMER_TICK_PER_SECOND 10 +//
+ +//
+// +#define RT_USING_SEMAPHORE +// +#define RT_USING_MUTEX +// +#define RT_USING_EVENT +// +#define RT_USING_MAILBOX +// +#define RT_USING_MESSAGEQUEUE +//
+ +//
+// +#define RT_USING_MEMPOOL +// +// #define RT_USING_MEMHEAP +// +#define RT_USING_HEAP +// +// #define RT_USING_MEMHEAP_AS_HEAP +// +#define RT_USING_SMALL_MEM +// +// #define RT_USING_SLAB +//
+ +//
+#define RT_USING_DEVICE +// +#define RT_USING_DEVICE_IPC +// +#define RT_USING_SERIAL +// +#define RT_UART_RX_BUFFER_SIZE 64 +// +#define RT_USING_INTERRUPT_INFO +//
+ +//
+#define RT_USING_CONSOLE +// +#define RT_CONSOLEBUF_SIZE 128 +// +#define RT_CONSOLE_DEVICE_NAME "uart1" +//
+ +// +#define RT_USING_COMPONENTS_INIT +//
+#define RT_USING_FINSH +// +#define FINSH_USING_MSH +// +//#define FINSH_USING_MSH_DEFAULT +// +#define FINSH_USING_SYMTAB +// +#define FINSH_USING_DESCRIPTION +// +#define FINSH_THREAD_STACK_SIZE 4096 +//
+ +//
+// +//#define RT_USING_NEWLIB +// +#define RT_USING_PTHREADS +//
+ +//
+// #define RT_USING_DFS +// +// #define DFS_USING_WORKDIR +// +#define DFS_FILESYSTEMS_MAX 2 +// +#define DFS_FD_MAX 4 +// +#define RT_USING_DFS_ELMFAT +// +// 1 +// 2 +// +#define RT_DFS_ELM_USE_LFN 1 +// +#define RT_DFS_ELM_MAX_LFN 64 +// +// #define RT_USING_DFS_YAFFS2 +// +// #define RT_USING_DFS_UFFS +// +// #define RT_USING_DFS_DEVFS +// +// #define RT_USING_DFS_NFS +// +#define RT_NFS_HOST_EXPORT "192.168.1.5:/" +//
+ +//
+ +#define __rt_ffs __builtin_ffs + +#endif + diff --git a/bsp/beaglebone/rtconfig.py b/bsp/beaglebone/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..3c7f228d86e61995d059f24f52dfbf2575e8da72 --- /dev/null +++ b/bsp/beaglebone/rtconfig.py @@ -0,0 +1,103 @@ +import os + +# toolchains options +ARCH='arm' +CPU='am335x' +CROSS_TOOL='gcc' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'C:\Program Files (x86)\CodeSourcery\Sourcery_CodeBench_Lite_for_ARM_EABI\bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil' +elif CROSS_TOOL == 'iar': + print '================ERROR============================' + print 'Not support IAR yet!' + print '=================================================' + exit(0) + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'release' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -Wall -march=armv7-a -mtune=cortex-a8'+\ + ' -ftree-vectorize -ffast-math -mfpu=vfpv3-d16 -mfloat-abi=softfp' + #DEVICE = ' ' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-beaglebone.map,-cref,-u,Reset_Handler -T beaglebone_ram.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -Wall' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2 -Wall' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\ + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + CXX = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --device DARMP' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-beaglebone.map --scatter beaglebone_ram.sct' + + CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' + + EXEC_PATH += '/arm/bin40/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = ' --cpu DARMP' + + CFLAGS = '' + AFLAGS = '' + LFLAGS = ' --config beaglebone_ram.icf' + + EXEC_PATH += '/arm/bin/' + RT_USING_MINILIBC = False + POST_ACTION = '' diff --git a/bsp/beaglebone/uboot_cmd.txt b/bsp/beaglebone/uboot_cmd.txt new file mode 100644 index 0000000000000000000000000000000000000000..8f849c5730166941b83a6e0b49bf268a80e4b57c --- /dev/null +++ b/bsp/beaglebone/uboot_cmd.txt @@ -0,0 +1,3 @@ +mmcinfo +fatload mmc 0 0x80200000 rtthread.bin +go 0x80200000 diff --git a/libcpu/arm/am335x/SConscript b/libcpu/arm/am335x/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..2ad51b573e9fb738f85c3c91aebd2e9319d2d60d --- /dev/null +++ b/libcpu/arm/am335x/SConscript @@ -0,0 +1,17 @@ +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') +elif rtconfig.PLATFORM == 'gcc': + src += Glob('*_gcc.S') +elif rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +group = DefineGroup('AM1808', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/am335x/am33xx.h b/libcpu/arm/am335x/am33xx.h new file mode 100644 index 0000000000000000000000000000000000000000..86ed82750a98f00c3ba521e5c941331801f54dea --- /dev/null +++ b/libcpu/arm/am335x/am33xx.h @@ -0,0 +1,333 @@ +#ifndef __AM33XX_H__ +#define __AM33XX_H__ + +#define REG32(x) (*((volatile unsigned int *)(x))) +#define REG16(x) (*((volatile unsigned short *)(x))) + +/** Cache Line size in ARM Cortex-A8. */ +#define AM33XX_CACHELINE_SIZE (64) + +/** @brief Base address of AINTC memory mapped registers */ +#define AM33XX_AINTC_REGS (0x48200000) + + +/** @brief Base addresses of control module registers */ +#define AM33XX_CTLM_REGS (0x44e10000) + +/** @brief Base addresses of USB memory mapped registers */ +#define AM33XX_USB_0_BASE (0x47401400) +#define AM33XX_USB_1_BASE (0x47401C00) +/** @brief Base addresses of SPI memory mapped registers */ +#define AM33XX_SPI_0_REGS (0x48030000) +#define AM33XX_SPI_1_REGS (0x481A0000) + +/** @brief Base addresses of GPIO memory mapped registers */ +#define AM33XX_GPIO_0_REGS (0x44E07000) +#define AM33XX_GPIO_1_REGS (0x4804C000) +#define AM33XX_GPIO_2_REGS (0x481AC000) +#define AM33XX_GPIO_3_REGS (0x481AE000) + +/** @brief Base addresses of DMTIMER memory mapped registers */ +#define AM33XX_DMTIMER_0_REGS (0x44E05000) +#define AM33XX_DMTIMER_1_REGS (0x44E31000) +#define AM33XX_DMTIMER_2_REGS (0x48040000) +#define AM33XX_DMTIMER_3_REGS (0x48042000) +#define AM33XX_DMTIMER_4_REGS (0x48044000) +#define AM33XX_DMTIMER_5_REGS (0x48046000) +#define AM33XX_DMTIMER_6_REGS (0x48048000) +#define AM33XX_DMTIMER_7_REGS (0x4804A000) + +/** @brief Base address of MMC memory mapped registers */ +#define AM33XX_MMCHS_0_REGS (0x48060000) +#define AM33XX_MMCHS_1_REGS (0x481D8000) +#define AM33XX_MMCHS_2_REGS (0x47810000) + +/** @brief Base address of GPMC memory mapped registers */ +#define AM33XX_GPMC_0_REGS (0x50000000) + +/** @brief Base address of GPMC memory mapped registers */ +#define AM33XX_ELM_0_REGS (0x48080000) + +/** @brief Base address of I2C memory mapped registers */ +#define AM33XX_I2C_0_REGS (0x44E0B000) +#define AM33XX_I2C_1_REGS (0x4802A000) +#define AM33XX_I2C_2_REGS (0x4819C000) + +/** @brief Base address of WDT memory mapped registers */ +#define AM33XX_WDT_0_REGS (0x44E33000) +#define AM33XX_WDT_1_REGS (0x44E35000) + +/** @brief Base address of WDT memory mapped registers */ +#define AM33XX_CPSW_SS_REGS (0x4A100000) +#define AM33XX_CPSW_MDIO_REGS (0x4A101000) +#define AM33XX_CPSW_WR_REGS (0x4A101200) +#define AM33XX_CPSW_CPDMA_REGS (0x4A100800) +#define AM33XX_CPSW_ALE_REGS (0x4A100D00) +#define AM33XX_CPSW_STAT_REGS (0x4A100900) +#define AM33XX_CPSW_PORT_0_REGS (0x4A100100) +#define AM33XX_CPSW_PORT_1_REGS (0x4A100200) +#define AM33XX_CPSW_SLIVER_1_REGS (0x4A100D80) +#define AM33XX_CPSW_PORT_2_REGS (0x4A100300) +#define AM33XX_CPSW_SLIVER_2_REGS (0x4A100DC0) +#define AM33XX_CPSW_CPPI_RAM_REGS (0x4A102000) + +/** @brief Base address of McASP memory mapped registers */ +#define AM33XX_MCASP_1_CTRL_REGS (0x4803C000) +#define AM33XX_MCASP_1_FIFO_REGS (AM33XX_MCASP_1_CTRL_REGS + 0x1000) +#define AM33XX_MCASP_1_DATA_REGS (0x46400000) + +/** @brief Base address of EMIF memory mapped registers */ +#define AM33XX_EMIF_0_REGS (0x4C000000) + +/** @brief Base addresses of RTC memory mapped registers */ +#define AM33XX_RTC_0_REGS (0x44E3E000) + +#define CM_PER(base) ((base) + 0) +#define CM_PER_L4LS_CLKSTCTRL(base) (CM_PER(base) + 0) +#define CM_PER_UART1_CLKCTRL(base) (CM_PER(base) + 0x06C) +#define CM_WKUP(base) ((base) + 0x400) +#define CM_DPLL(base) ((base) + 0x500) +#define CM_MPU(base) ((base) + 0x600) +#define CM_DEVICE(base) ((base) + 0x700) +#define CM_RTC(base) ((base) + 0x800) +#define CM_GFX(base) ((base) + 0x900) +#define CM_CEFUSE(base) ((base) + 0xA00) +#define OCP_AM33XXKET_RAM(base) ((base) + 0xB00) +#define PRM_PER(base) ((base) + 0xC00) +#define PRM_PER_PWRSTST(base) (PRM_PER(base) + 0x008) +#define PRM_PER_PWRSTCTRL(base) (PRM_PER(base) + 0x00C) +#define PRM_WKUP(base) ((base) + 0xD00) +#define PRM_MPU(base) ((base) + 0xE00) +#define PRM_DEVICE(base) ((base) + 0xF00) +#define PRM_RTC(base) ((base) + 0x1000) +#define PRM_GFX(base) ((base) + 0x1100) +#define PRM_CEFUSE(base) ((base) + 0x1200) + +/** @brief Base addresses of PRCM memory mapped registers */ +#define AM33XX_PRCM_REGS (0x44E00000) +#define AM33XX_CM_PER_REGS CM_PER(AM33XX_PRCM_REGS) +#define AM33XX_CM_WKUP_REGS CM_WKUP(AM33XX_PRCM_REGS) +#define AM33XX_CM_DPLL_REGS CM_DPLL(AM33XX_PRCM_REGS) +#define AM33XX_CM_MPU_REGS CM_MPU(AM33XX_PRCM_REGS) +#define AM33XX_CM_DEVICE_REGS CM_DEVICE(AM33XX_PRCM_REGS) +#define AM33XX_CM_RTC_REGS CM_RTC(AM33XX_PRCM_REGS) +#define AM33XX_CM_GFX_REGS CM_GFX(AM33XX_PRCM_REGS) +#define AM33XX_CM_CEFUSE_REGS CM_CEFUSE(AM33XX_PRCM_REGS) +#define AM33XX_OCP_AM33XXKET_RAM_REGS OCP_AM33XXKET_RAM(AM33XX_PRCM_REGS) +#define AM33XX_PRM_PER_REGS PRM_PER(AM33XX_PRCM_REGS) +#define AM33XX_PRM_WKUP_REGS PRM_WKUP(AM33XX_PRCM_REGS) +#define AM33XX_PRM_MPU_REGS PRM_MPU(AM33XX_PRCM_REGS) +#define AM33XX_PRM_DEVICE_REGS PRM_DEVICE(AM33XX_PRCM_REGS) +#define AM33XX_PRM_RTC_REGS PRM_RTC(AM33XX_PRCM_REGS) +#define AM33XX_PRM_GFX_REGS PRM_GFX(AM33XX_PRCM_REGS) +#define AM33XX_PRM_CEFUSE_REGS PRM_CEFUSE(AM33XX_PRCM_REGS) + +/** @brief Base address of control module memory mapped registers */ +#define AM33XX_CONTROL_REGS (0x44E10000) + + +/** @brief Base address of Channel controller memory mapped registers */ +#define AM33XX_EDMA30CC_0_REGS (0x49000000) + +/** @brief Base address of DCAN module memory mapped registers */ +#define AM33XX_DCAN_0_REGS (0x481CC000) +#define AM33XX_DCAN_1_REGS (0x481D0000) + +/******************************************************************************\ +* Parameterizable Configuration:- These are fed directly from the RTL +* parameters for the given AM33XX +\******************************************************************************/ +#define TPCC_MUX(n) 0xF90 + ((n) * 4) + + +#define AM33XX_LCDC_0_REGS 0x4830E000 + +#define AM33XX_ADC_TSC_0_REGS 0x44E0D000 + +/** @brief Base addresses of PWMSS memory mapped registers. */ + +#define AM33XX_PWMSS0_REGS (0x48300000) +#define AM33XX_PWMSS1_REGS (0x48302000) +#define AM33XX_PWMSS2_REGS (0x48304000) + +#define AM33XX_ECAP_REGS (0x00000100) +#define AM33XX_EQEP_REGS (0x00000180) +#define AM33XX_EPWM_REGS (0x00000200) + +#define AM33XX_ECAP_0_REGS (AM33XX_PWMSS0_REGS + AM33XX_ECAP_REGS) +#define AM33XX_ECAP_1_REGS (AM33XX_PWMSS1_REGS + AM33XX_ECAP_REGS) +#define AM33XX_ECAP_2_REGS (AM33XX_PWMSS2_REGS + AM33XX_ECAP_REGS) + +#define AM33XX_EQEP_0_REGS (AM33XX_PWMSS0_REGS + AM33XX_EQEP_REGS) +#define AM33XX_EQEP_1_REGS (AM33XX_PWMSS1_REGS + AM33XX_EQEP_REGS) +#define AM33XX_EQEP_2_REGS (AM33XX_PWMSS2_REGS + AM33XX_EQEP_REGS) + +#define AM33XX_EPWM_0_REGS (AM33XX_PWMSS0_REGS + AM33XX_EPWM_REGS) +#define AM33XX_EPWM_1_REGS (AM33XX_PWMSS1_REGS + AM33XX_EPWM_REGS) +#define AM33XX_EPWM_2_REGS (AM33XX_PWMSS2_REGS + AM33XX_EPWM_REGS) + +#define AM33XX_EPWM_MODULE_FREQ 100 + +/* PRCM registers */ +#define CM_PER_L4LS_CLKSTCTRL_REG(base) REG32((base) + 0x0) +#define CM_PER_UART1_CLKCTRL_REG(base) REG32(CM_PER_UART1_CLKCTRL(base)) + +#define CM_PER_TIMER7_CLKCTRL(base) REG32((base) + 0x7C) +#define CM_PER_TIMER2_CLKCTRL(base) REG32((base) + 0x80) + +#define PRM_PER_PWRSTST_REG(base) REG32(PRM_PER_PWRSTST(base)) +#define PRM_PER_PWRSTCTRL_REG(base) REG32(PRM_PER_PWRSTCTRL(base)) + +#define CM_DPLL_CLKSEL_TIMER7_CLK(base) REG32(CM_DPLL(base) + 0x4) +#define CM_DPLL_CLKSEL_TIMER2_CLK(base) REG32(CM_DPLL(base) + 0x8) + +/* timer registers */ +#define DMTIMER_TIDR(base) REG32(base + 0x0) +#define DMTIMER_TIOCP_CFG(base) REG32(base + 0x10) +#define DMTIMER_IRQ_EOI(base) REG32(base + 0x20) +#define DMTIMER_IRQSTATUS_RAW(base) REG32(base + 0x24) +#define DMTIMER_IRQSTATUS(base) REG32(base + 0x28) +#define DMTIMER_IRQENABLE_SET(base) REG32(base + 0x2C) +#define DMTIMER_IRQENABLE_CLR(base) REG32(base + 0x30) +#define DMTIMER_IRQWAKEEN(base) REG32(base + 0x34) +#define DMTIMER_TCLR(base) REG32(base + 0x38) +#define DMTIMER_TCRR(base) REG32(base + 0x3C) +#define DMTIMER_TLDR(base) REG32(base + 0x40) +#define DMTIMER_TTGR(base) REG32(base + 0x44) +#define DMTIMER_TWPS(base) REG32(base + 0x48) +#define DMTIMER_TMAR(base) REG32(base + 0x4C) +#define DMTIMER_TCAR(base, n) REG32(base + 0x50 + (((n) - 1) * 8)) +#define DMTIMER_TSICR(base) REG32(base + 0x54) + +#define EMU_INT 0 +#define COMMTX_INT 1 +#define COMMRX_INT 2 +#define BENCH_INT 3 +#define ELM_IRQ_INT 4 +#define NMI_INT 7 +#define L3DEBUG_INT 9 +#define L3APP_INT 10 +#define PRCM_INT 11 +#define EDMACOMP_INT 12 +#define EDMAMPERR_INT 13 +#define EDMAERR_INT 14 +#define ADC_TSC_GEN_INT 16 +#define USBSS_INT 17 +#define USB_INT0 18 +#define USB_INT1 19 +#define PRU_ICSS_EVTOUT0_INT 20 +#define PRU_ICSS_EVTOUT1_INT 21 +#define PRU_ICSS_EVTOUT2_INT 22 +#define PRU_ICSS_EVTOUT3_INT 23 +#define PRU_ICSS_EVTOUT4_INT 24 +#define PRU_ICSS_EVTOUT5_INT 25 +#define PRU_ICSS_EVTOUT6_INT 26 +#define PRU_ICSS_EVTOUT7_INT 27 +#define MMCSD1_INT 28 +#define MMCSD2_INT 29 +#define I2C2_INT 30 +#define ECAP0_INT 31 +#define GPIO_INT2A 32 +#define GPIO_INT2B 33 +#define USBWAKEUP_INT 34 +#define LCDC_INT 36 +#define GFX_INT 37 +#define EPWM2_INT 39 +#define CPSW_RXTHR0_INT 40 +#define CPSW_RX_INT0 41 +#define CPSW_TX_INT0 42 +#define CPSW_MISC0_INT 43 +#define UART3_INT 44 +#define UART4_INT 45 +#define UART5_INT 46 +#define ECAP1_INT 47 +#define DCAN0_INT0 52 +#define DCAN0_INT1 53 +#define DCAN0_PARITY 54 +#define DCAN1_INT0 55 +#define DCAN1_INT1 56 +#define DCAN1_PARITY 57 +#define EPWM0_TZINT 58 +#define EPWM1_TZINT 59 +#define EPWM2_TZINT 60 +#define ECAP2_INT 61 +#define GPIO_INT3A 62 +#define GPIO_INT3B 63 +#define MMCSD0_INT 64 +#define MCSPI0_INT 65 +#define TINT0 66 +#define TINT1_1MS 67 +#define TINT2 68 +#define TINT3 69 +#define I2C0_INT 70 +#define I2C1_INT 71 +#define UART0_INT 72 +#define UART1_INT 73 +#define UART2_INT 74 +#define RTC_INT 75 +#define RTC_ALARM_INT 76 +#define MB_INT0 77 +#define M3_TXEV 78 +#define EQEP0_INT 79 +#define MACTX_INT0 80 +#define MCARX_INT0 81 +#define MCATX_INT1 82 +#define MCARX_INT1 83 +#define EPWM0_INT 86 +#define EPWM1_INT 87 +#define EQEP1_INT 88 +#define EQEP2_INT 89 +#define DMA_INTR_PIN2 90 +#define WDT1_INT 91 +#define TINT4 92 +#define TINT5 93 +#define TINT6 94 +#define TINT7 95 +#define GPIO_INT0A 96 +#define GPIO_INT0B 97 +#define GPIO_INT1A 98 +#define GPIO_INT1B 99 +#define GPMC_INT 100 +#define DDRERR0 101 +#define TCERR_INT0 112 +#define TCERR_INT1 113 +#define TCERR_INT2 114 +#define ADC_TSC_PEN_INT 115 +#define SMRFLX_MPU 120 +#define SMRFLX_CORE 121 +#define DMA_INTR_PIN0 123 +#define DMA_INTR_PIN1 124 +#define MCSPI1_INT 125 + +struct rt_hw_register +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; + unsigned long ORIG_r0; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define ABORTMODE 0x17 +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#endif diff --git a/libcpu/arm/am335x/context_gcc.S b/libcpu/arm/am335x/context_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..a49ce0862d788df65306fba3e9f98e019d932ba1 --- /dev/null +++ b/libcpu/arm/am335x/context_gcc.S @@ -0,0 +1,102 @@ +/* + * File : context.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid if + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr_c, r0 + bx lr + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + orrne r4, r4, #0x20 @ it's thumb code + + stmfd sp!, {r4} @ push cpsr + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task cpsr to spsr + msr spsr_cxsf, r4 + +_do_switch: + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task spsr + msr spsr_cxsf, r4 + + bic r4, r4, #0x20 @ must be ARM mode + msr cpsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r3, [r2] + ldr r2, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + str r0, [r2] +_reswitch: + ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [r2] + bx lr diff --git a/libcpu/arm/am335x/cp15_gcc.S b/libcpu/arm/am335x/cp15_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..1f8e685e21c1d892853e0c96c464ce8172567bf3 --- /dev/null +++ b/libcpu/arm/am335x/cp15_gcc.S @@ -0,0 +1,145 @@ +/* + * File : cp15_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * http://www.rt-thread.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.globl rt_cpu_vector_set_base +rt_cpu_vector_set_base: + mcr p15, #0, r0, c12, c0, #0 + dsb + bx lr + +.globl rt_cpu_vector_get_base +rt_cpu_vector_get_base: + mrc p15, #0, r0, c12, c0, #0 + bx lr + +.globl rt_cpu_get_sctlr +rt_cpu_get_sctlr: + mrc p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_dcache_enable +rt_cpu_dcache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_icache_enable +rt_cpu_icache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +_FLD_MAX_WAY: + .word 0x3ff +_FLD_MAX_IDX: + .word 0x7ff + +.globl rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + push {r4-r11} + dmb + mrc p15, #1, r0, c0, c0, #1 @ read clid register + ands r3, r0, #0x7000000 @ get level of coherency + mov r3, r3, lsr #23 + beq finished + mov r10, #0 +loop1: + add r2, r10, r10, lsr #1 + mov r1, r0, lsr r2 + and r1, r1, #7 + cmp r1, #2 + blt skip + mcr p15, #2, r10, c0, c0, #0 + isb + mrc p15, #1, r1, c0, c0, #0 + and r2, r1, #7 + add r2, r2, #4 + ldr r4, _FLD_MAX_WAY + ands r4, r4, r1, lsr #3 + clz r5, r4 + ldr r7, _FLD_MAX_IDX + ands r7, r7, r1, lsr #13 +loop2: + mov r9, r4 +loop3: + orr r11, r10, r9, lsl r5 + orr r11, r11, r7, lsl r2 + mcr p15, #0, r11, c7, c14, #2 + subs r9, r9, #1 + bge loop3 + subs r7, r7, #1 + bge loop2 +skip: + add r10, r10, #2 + cmp r3, r10 + bgt loop1 + +finished: + dsb + isb + pop {r4-r11} + bx lr + +.globl rt_cpu_dcache_disable +rt_cpu_dcache_disable: + push {r4-r11, lr} + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bl rt_cpu_dcache_clean_flush + pop {r4-r11, lr} + bx lr + +.globl rt_cpu_icache_disable +rt_cpu_icache_disable: + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_mmu_disable +rt_cpu_mmu_disable: + mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #1 + mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit + dsb + bx lr + +.globl rt_cpu_mmu_enable +rt_cpu_mmu_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x001 + mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit + dsb + bx lr + +.globl rt_cpu_tlb_set +rt_cpu_tlb_set: + mcr p15, #0, r0, c2, c0, #0 + dmb + bx lr diff --git a/libcpu/arm/am335x/cpu.c b/libcpu/arm/am335x/cpu.c new file mode 100644 index 0000000000000000000000000000000000000000..e67983eed078c59b745d5cad975c0aabeff793c2 --- /dev/null +++ b/libcpu/arm/am335x/cpu.c @@ -0,0 +1,165 @@ +/* + * File : cpu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#include +#include +#include "am33xx.h" + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +#define ICACHE_MASK (rt_uint32_t)(1 << 12) +#define DCACHE_MASK (rt_uint32_t)(1 << 2) + +#if defined(__CC_ARM) +rt_inline rt_uint32_t cp15_rd(void) +{ + rt_uint32_t i; + + __asm + { + mrc p15, 0, i, c1, c0, 0 + } + + return i; +} + +rt_inline void cache_enable(rt_uint32_t bit) +{ + rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, bit + mcr p15, 0, value, c1, c0, 0 + } +} + +rt_inline void cache_disable(rt_uint32_t bit) +{ + rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, bit + mcr p15, 0, value, c1, c0, 0 + } +} +#elif defined(__GNUC__) +rt_inline rt_uint32_t cp15_rd(void) +{ + rt_uint32_t i; + + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + return i; +} + +rt_inline void cache_enable(rt_uint32_t bit) +{ + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); +} + +rt_inline void cache_disable(rt_uint32_t bit) +{ + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); +} +#endif + +/** + * enable I-Cache + * + */ +void rt_hw_cpu_icache_enable() +{ + cache_enable(ICACHE_MASK); +} + +/** + * disable I-Cache + * + */ +void rt_hw_cpu_icache_disable() +{ + cache_disable(ICACHE_MASK); +} + +/** + * return the status of I-Cache + * + */ +rt_base_t rt_hw_cpu_icache_status() +{ + return (cp15_rd() & ICACHE_MASK); +} + +/** + * enable D-Cache + * + */ +void rt_hw_cpu_dcache_enable() +{ + cache_enable(DCACHE_MASK); +} + +/** + * disable D-Cache + * + */ +void rt_hw_cpu_dcache_disable() +{ + cache_disable(DCACHE_MASK); +} + +/** + * return the status of D-Cache + * + */ +rt_base_t rt_hw_cpu_dcache_status() +{ + return (cp15_rd() & DCACHE_MASK); +} + +/** + * shutdown CPU + * + */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/libcpu/arm/am335x/interrupt.c b/libcpu/arm/am335x/interrupt.c new file mode 100644 index 0000000000000000000000000000000000000000..081bdd6b41612a9c2b14d14e7e1f02c2d56e6765 --- /dev/null +++ b/libcpu/arm/am335x/interrupt.c @@ -0,0 +1,205 @@ +/* + * File : interrupt.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + */ + +#include +#include + +#include "am33xx.h" +#include "interrupt.h" + +#define AINTC_BASE AM33XX_AINTC_REGS + +#define MAX_HANDLERS 128 + +extern volatile rt_uint8_t rt_interrupt_nest; + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +void rt_dump_aintc(void) +{ + int k; + rt_kprintf("active irq %d", INTC_SIR_IRQ(AINTC_BASE)); + rt_kprintf("\n--- hw mask ---\n"); + for (k = 0; k < 4; k++) + { + rt_kprintf("0x%08x, ", INTC_MIR(AINTC_BASE, k)); + } + rt_kprintf("\n--- hw itr ---\n"); + for (k = 0; k < 4; k++) + { + rt_kprintf("0x%08x, ", INTC_ITR(AINTC_BASE, k)); + } + rt_kprintf("\n"); +} + +const unsigned int AM335X_VECTOR_BASE = 0x4030FC00; +extern void rt_cpu_vector_set_base(unsigned int addr); +extern int system_vectors; + +static void rt_hw_vector_init(void) +{ + unsigned int *dest = (unsigned int *)AM335X_VECTOR_BASE; + unsigned int *src = (unsigned int *)&system_vectors; + + rt_memcpy(dest, src, 16 * 4); + rt_cpu_vector_set_base(AM335X_VECTOR_BASE); +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + /* initialize vector table */ + rt_hw_vector_init(); + + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + INTC_MIR_SET(AINTC_BASE, vector >> 0x05) = 0x1 << (vector & 0x1f); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + INTC_MIR_CLEAR(AINTC_BASE, vector >> 0x05) = 0x1 << (vector & 0x1f); +} + +/** + * This function will control the interrupt attribute. + * @param vector the interrupt number + */ +void rt_hw_interrupt_control(int vector, int priority, int route) +{ + int fiq; + + if (route == 0) + fiq = 0; + else + fiq = 1; + + INTC_ILR(AINTC_BASE, vector) = ((priority << 0x02) & 0x1FC) | fiq ; +} + +int rt_hw_interrupt_get_active(int fiq_irq) +{ + int ir; + if (fiq_irq == INT_FIQ) + { + ir = INTC_SIR_FIQ(AINTC_BASE) & 0x7f; + } + else + { + ir = INTC_SIR_IRQ(AINTC_BASE) & 0x7f; + } + + return ir; +} + +void rt_hw_interrupt_ack(int fiq_irq) +{ + if (fiq_irq == INT_FIQ) + { + /* new FIQ generation */ + INTC_CONTROL(AINTC_BASE) |= 0x02; + } + else + { + /* new IRQ generation */ + INTC_CONTROL(AINTC_BASE) |= 0x01; + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +/** + * This function will trigger an interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_trigger(int vector) +{ + INTC_ISR_SET(AINTC_BASE, vector>>5) = 1 << (vector & 0x1f); +} + +void rt_hw_interrupt_clear(int vector) +{ + INTC_ISR_CLEAR(AINTC_BASE, vector>>5) = 1 << (vector & 0x1f); +} + +void rt_dump_isr_table(void) +{ + int idx; + for(idx = 0; idx < MAX_HANDLERS; idx++) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_kprintf("nr:%4d, name: %*.s, handler: 0x%p, param: 0x%08x\r\n", + idx, RT_NAME_MAX, isr_table[idx].name, + isr_table[idx].handler, isr_table[idx].param); +#else + rt_kprintf("nr:%4d, handler: 0x%p, param: 0x%08x\r\n", + idx, isr_table[idx].handler, isr_table[idx].param); +#endif + } +} +/*@}*/ diff --git a/libcpu/arm/am335x/interrupt.h b/libcpu/arm/am335x/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..d81f1c81ae38f4f2b48c8780a070fdefd178f446 --- /dev/null +++ b/libcpu/arm/am335x/interrupt.h @@ -0,0 +1,50 @@ +/* + * File : interrupt.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +#define INTC_REVISION(hw_base) REG32((hw_base) + 0x0) +#define INTC_SYSCONFIG(hw_base) REG32((hw_base) + 0x10) +#define INTC_SYSSTATUS(hw_base) REG32((hw_base) + 0x14) +#define INTC_SIR_IRQ(hw_base) REG32((hw_base) + 0x40) +#define INTC_SIR_FIQ(hw_base) REG32((hw_base) + 0x44) +#define INTC_CONTROL(hw_base) REG32((hw_base) + 0x48) +#define INTC_PROTECTION(hw_base) REG32((hw_base) + 0x4c) +#define INTC_IDLE(hw_base) REG32((hw_base) + 0x50) +#define INTC_IRQ_PRIORITY(hw_base) REG32((hw_base) + 0x60) +#define INTC_FIQ_PRIORITY(hw_base) REG32((hw_base) + 0x64) +#define INTC_THRESHOLD(hw_base) REG32((hw_base) + 0x68) +#define INTC_SICR(hw_base) REG32((hw_base) + 0x6c) +#define INTC_SCR(hw_base, n) REG32((hw_base) + 0x70 + ((n) * 0x04)) +#define INTC_ITR(hw_base, n) REG32((hw_base) + 0x80 + ((n) * 0x20)) +#define INTC_MIR(hw_base, n) REG32((hw_base) + 0x84 + ((n) * 0x20)) +#define INTC_MIR_CLEAR(hw_base, n) REG32((hw_base) + 0x88 + ((n) * 0x20)) +#define INTC_MIR_SET(hw_base, n) REG32((hw_base) + 0x8c + ((n) * 0x20)) +#define INTC_ISR_SET(hw_base, n) REG32((hw_base) + 0x90 + ((n) * 0x20)) +#define INTC_ISR_CLEAR(hw_base, n) REG32((hw_base) + 0x94 + ((n) * 0x20)) +#define INTC_PENDING_IRQ(hw_base, n) REG32((hw_base) + 0x98 + ((n) * 0x20)) +#define INTC_PENDING_FIQ(hw_base, n) REG32((hw_base) + 0x9c + ((n) * 0x20)) +#define INTC_ILR(hw_base, n) REG32((hw_base) + 0x100 + ((n) * 0x04)) + +void rt_hw_interrupt_control(int vector, int priority, int route); +int rt_hw_interrupt_get_active(int fiq_irq); +void rt_hw_interrupt_ack(int fiq_irq); +void rt_hw_interrupt_trigger(int vector); +void rt_hw_interrupt_clear(int vector); + +#endif diff --git a/libcpu/arm/am335x/mmu.c b/libcpu/arm/am335x/mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..46f2d6afd7e247a3df8360d5030bb5f8064144bd --- /dev/null +++ b/libcpu/arm/am335x/mmu.c @@ -0,0 +1,457 @@ +/* + * File : mmu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + */ + +#include +#include "am33xx.h" + +#define DESC_SEC (0x2|(1<<4)) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */ +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */ +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */ + +#ifdef __CC_ARM +void mmu_setttbase(rt_uint32_t i) +{ + register rt_uint32_t value; + + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ + value = 0; + __asm + { + mcr p15, 0, value, c8, c7, 0 + } + + value = 0x55555555; + __asm + { + mcr p15, 0, value, c3, c0, 0 + mcr p15, 0, i, c2, c0, 0 + } +} + +void mmu_set_domain(rt_uint32_t i) +{ + __asm + { + mcr p15,0, i, c3, c0, 0 + } +} + +void mmu_enable() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, #0x01 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_disable() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, #0x01 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_enable_icache() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, #0x1000 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_enable_dcache() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, #0x04 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_disable_icache() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, #0x1000 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_disable_dcache() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, #0x04 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_enable_alignfault() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + orr value, value, #0x02 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_disable_alignfault() +{ + register rt_uint32_t value; + + __asm + { + mrc p15, 0, value, c1, c0, 0 + bic value, value, #0x02 + mcr p15, 0, value, c1, c0, 0 + } +} + +void mmu_clean_invalidated_cache_index(int index) +{ + __asm + { + mcr p15, 0, index, c7, c14, 2 + } +} + +void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~0x1f; + + while(ptr < buffer + size) + { + __asm + { + MCR p15, 0, ptr, c7, c14, 1 + } + ptr += 32; + } +} + +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~0x1f; + + while (ptr < buffer + size) + { + __asm + { + MCR p15, 0, ptr, c7, c10, 1 + } + ptr += 32; + } +} + +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~0x1f; + + while (ptr < buffer + size) + { + __asm + { + MCR p15, 0, ptr, c7, c6, 1 + } + ptr += 32; + } +} + +void mmu_invalidate_tlb() +{ + register rt_uint32_t value; + + value = 0; + __asm + { + mcr p15, 0, value, c8, c7, 0 + } +} + +void mmu_invalidate_icache() +{ + register rt_uint32_t value; + + value = 0; + + __asm + { + mcr p15, 0, value, c7, c5, 0 + } +} + +#elif defined(__GNUC__) +void mmu_setttbase(register rt_uint32_t i) +{ + register rt_uint32_t value; + + /* Invalidates all TLBs.Domain access is selected as + * client by configuring domain access register, + * in that case access controlled by permission value + * set by page table entry + */ + value = 0; + asm ("mcr p15, 0, %0, c8, c7, 0"::"r"(value)); + + value = 0x55555555; + asm ("mcr p15, 0, %0, c3, c0, 0"::"r"(value)); + asm ("mcr p15, 0, %0, c2, c0, 0"::"r"(i)); +} + +void mmu_set_domain(register rt_uint32_t i) +{ + asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); +} + +void mmu_enable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= 0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_icache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_dcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disable_alignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_clean_invalidated_cache_index(int index) +{ + asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); +} + +void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~0x1f; + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr)); + ptr += 32; + } +} + +void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size) +{ + unsigned int ptr; + + ptr = buffer & ~0x1f; + + while (ptr < buffer + size) + { + asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr)); + ptr += 32; + } +} + +void mmu_invalidate_tlb() +{ + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); +} + +void mmu_invalidate_icache() +{ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); +} +#endif + +/* level1 page table */ +static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024))); +void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i,nSec; + pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20); + nSec=(vaddrEnd>>20)-(vaddrStart>>20); + for(i=0;i<=nSec;i++) + { + *pTT = attr |(((paddrStart>>20)+i)<<20); + pTT++; + } +} + +void rt_hw_mmu_init(void) +{ + /* disable I/D cache */ + mmu_disable_dcache(); + mmu_disable_icache(); + mmu_disable(); + mmu_invalidate_tlb(); + + /* set page table */ + mmu_setmtt(0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB); /* None cached for 4G memory */ + mmu_setmtt(0xC0000000, 0xC8000000-1, 0xC0000000, RW_CB); /* 128M cached DDR memory */ + mmu_setmtt(0xD0000000, 0xD8000000-1, 0xC0000000, RW_NCNB); /* 128M none-cached DDR memory */ + mmu_setmtt(0x80000000, 0x80020000-1, 0x80000000, RW_CB); /* 128k OnChip memory */ + + /* set MMU table address */ + mmu_setttbase((rt_uint32_t)_page_table); + + /* enables MMU */ + mmu_enable(); + + /* enable Instruction Cache */ + mmu_enable_icache(); + + /* enable Data Cache */ + mmu_enable_dcache(); +} + diff --git a/libcpu/arm/am335x/stack.c b/libcpu/arm/am335x/stack.c new file mode 100644 index 0000000000000000000000000000000000000000..e46f34f7cd775fd579318f450e949e69a72b07e2 --- /dev/null +++ b/libcpu/arm/am335x/stack.c @@ -0,0 +1,65 @@ +/* + * File : stack.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + */ +#include +#include "am33xx.h" + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + stk = (rt_uint32_t*)stack_addr; + *(stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0; /* r12 */ + *(--stk) = 0; /* r11 */ + *(--stk) = 0; /* r10 */ + *(--stk) = 0; /* r9 */ + *(--stk) = 0; /* r8 */ + *(--stk) = 0; /* r7 */ + *(--stk) = 0; /* r6 */ + *(--stk) = 0; /* r5 */ + *(--stk) = 0; /* r4 */ + *(--stk) = 0; /* r3 */ + *(--stk) = 0; /* r2 */ + *(--stk) = 0; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/libcpu/arm/am335x/start_gcc.S b/libcpu/arm/am335x/start_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..6d9ec8be2561be18955c95b77e306d1ef0049c40 --- /dev/null +++ b/libcpu/arm/am335x/start_gcc.S @@ -0,0 +1,245 @@ +/* + * File : start_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.equ UND_Stack_Size, 0x00000000 +.equ SVC_Stack_Size, 0x00000100 +.equ ABT_Stack_Size, 0x00000000 +.equ FIQ_Stack_Size, 0x00000000 +.equ IRQ_Stack_Size, 0x00000100 +.equ USR_Stack_Size, 0x00000100 + +#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + FIQ_Stack_Size + IRQ_Stack_Size) + +/* stack */ +.globl stack_start +.globl stack_top + +stack_start: +.rept ISR_Stack_Size +.long 0 +.endr +stack_top: + +/* reset entry */ +.globl _reset +_reset: + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 + + /* setup stack */ + bl stack_setup + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* call C++ constructors of global objects */ + ldr r0, =__ctors_start__ + ldr r1, =__ctors_end__ + +ctor_loop: + cmp r0, r1 + beq ctor_end + ldr r2, [r0], #4 + stmfd sp!, {r0-r1} + mov lr, pc + bx r2 + ldmfd sp!, {r0-r1} + b ctor_loop +ctor_end: + + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup +_rtthread_startup: + .word rtthread_startup + +stack_setup: + ldr r0, =stack_top + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #UND_Stack_Size + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #FIQ_Stack_Size + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #IRQ_Stack_Size + + @ Enter Supervisor Mode and set its Stack Pointer + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #SVC_Stack_Size + + @ Enter User Mode and set its Stack Pointer + mov sp, r0 + sub sl, sp, #USR_Stack_Size + bx lr + +/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ + .align 5 +.globl vector_undef +vector_undef: + sub sp, sp, #72 + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + add r8, sp, #60 + stmdb r8, {sp, lr} @/* Calling SP, LR */ + str lr, [r8, #0] @/* Save calling PC */ + mrs r6, spsr + str r6, [r8, #4] @/* Save CPSR */ + str r0, [r8, #8] @/* Save OLD_R0 */ + mov r0, sp + + bl rt_hw_trap_udef + + .align 5 +.globl vector_swi +vector_swi: + bl rt_hw_trap_swi + + .align 5 +.globl vector_pabt +vector_pabt: + bl rt_hw_trap_pabt + + .align 5 +.globl vector_dabt +vector_dabt: + sub sp, sp, #72 + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + add r8, sp, #60 + stmdb r8, {sp, lr} @/* Calling SP, LR */ + str lr, [r8, #0] @/* Save calling PC */ + mrs r6, spsr + str r6, [r8, #4] @/* Save CPSR */ + str r0, [r8, #8] @/* Save OLD_R0 */ + mov r0, sp + + bl rt_hw_trap_dabt + + .align 5 +.globl vector_resv +vector_resv: + b . + + .align 5 +.globl vector_fiq +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc,lr,#4 + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + +.globl rt_current_thread +.globl vmm_thread +.globl vmm_virq_check + +.globl vector_irq +vector_irq: + stmfd sp!, {r0-r12,lr} + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + @ if rt_thread_switch_interrupt_flag set, jump to + @ rt_hw_context_switch_interrupt_do and don't return + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + mov r1, #0 @ clear flag + str r1, [r0] + + ldmfd sp!, {r0-r12,lr}@ reload saved registers + stmfd sp, {r0-r2} @ save r0-r2 + + mrs r0, spsr @ get cpsr of interrupt thread + + sub r1, sp, #4*3 + sub r2, lr, #4 @ save old task's pc to r2 + + @ switch to SVC mode with no interrupt + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread + stmfd sp!, {r1-r3} @ push old task's r0-r2 + stmfd sp!, {r0} @ push old task's cpsr + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] @ get new task's stack pointer + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr diff --git a/libcpu/arm/am335x/trap.c b/libcpu/arm/am335x/trap.c new file mode 100644 index 0000000000000000000000000000000000000000..925ec564341d48335ec13a2a31dc1dd200b567a0 --- /dev/null +++ b/libcpu/arm/am335x/trap.c @@ -0,0 +1,182 @@ +/* + * File : trap.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard first version + */ + +#include +#include + +#include "am33xx.h" +#include "interrupt.h" + +/** + * @addtogroup AM33XX + */ +/*@{*/ + +extern struct rt_thread *rt_current_thread; +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ + +void rt_hw_show_register (struct rt_hw_register *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + +/** + * When ARM7TDMI comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_udef(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("undefined instruction\n"); + rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("software interrupt\n"); + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("prefetch abort\n"); + rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("data abort\n"); + rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq() +{ + void *param; + unsigned long ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_active(INT_IRQ); + if (ir == 127) + { + /* new IRQ generation */ + rt_hw_interrupt_ack(INT_IRQ); + ir = rt_hw_interrupt_get_active(INT_IRQ); + if (ir == 127) + { + /* still spurious interrupt, get out */ + /*rt_kprintf("still spurious interrupt\n");*/ + return; + } + /*rt_kprintf("new IRQ: %d\n", ir);*/ + } + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + param = isr_table[ir].param; + + /* turn to interrupt service routine */ + if (isr_func != RT_NULL) + isr_func(ir, param); + + /* new IRQ generation */ + rt_hw_interrupt_ack(INT_IRQ); +} + +void rt_hw_trap_fiq() +{ + void *param; + unsigned long ir; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + ir = rt_hw_interrupt_get_active(INT_FIQ); + + /* get interrupt service routine */ + isr_func = isr_table[ir].handler; + param = isr_table[ir].param; + + /* turn to interrupt service routine */ + isr_func(ir, param); + + /* new FIQ generation */ + rt_hw_interrupt_ack(INT_FIQ); +} + +/*@}*/ diff --git a/libcpu/arm/am335x/vector_gcc.S b/libcpu/arm/am335x/vector_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..4a44a7395cbbf15e4fe45d39183c3bdc1fe3b072 --- /dev/null +++ b/libcpu/arm/am335x/vector_gcc.S @@ -0,0 +1,65 @@ +/* + * File : vector_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .vectors, "ax" +.code 32 + +.globl system_vectors +system_vectors: + ldr pc, _vector_reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +.globl _reset +.globl vector_undef +.globl vector_swi +.globl vector_pabt +.globl vector_dabt +.globl vector_resv +.globl vector_irq +.globl vector_fiq + +_vector_reset: + .word _reset +_vector_undef: + .word vector_undef +_vector_swi: + .word vector_swi +_vector_pabt: + .word vector_pabt +_vector_dabt: + .word vector_dabt +_vector_resv: + .word vector_resv +_vector_irq: + .word vector_irq +_vector_fiq: + .word vector_fiq + +.balignl 16,0xdeadbeef