Repository: incubator-mynewt-core Updated Branches: refs/heads/develop a73a65bfc -> ab16b5db1
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/hw/mcu/mips/danube/include/mcu/mips_bsp.h ---------------------------------------------------------------------- diff --git a/hw/mcu/mips/danube/include/mcu/mips_bsp.h b/hw/mcu/mips/danube/include/mcu/mips_bsp.h index 01d75f4..67c16e8 100644 --- a/hw/mcu/mips/danube/include/mcu/mips_bsp.h +++ b/hw/mcu/mips/danube/include/mcu/mips_bsp.h @@ -21,4 +21,4 @@ extern const struct hal_flash native_flash_dev; -#endif /* H_NATIVE_BSP_ */ +#endif /* H_MIPS_BSP_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/hw/mcu/mips/danube/include/mcu/mips_hal.h ---------------------------------------------------------------------- diff --git a/hw/mcu/mips/danube/include/mcu/mips_hal.h b/hw/mcu/mips/danube/include/mcu/mips_hal.h index f407e0c..74426cf 100644 --- a/hw/mcu/mips/danube/include/mcu/mips_hal.h +++ b/hw/mcu/mips/danube/include/mcu/mips_hal.h @@ -35,4 +35,4 @@ extern "C" { } #endif -#endif /* MCU_HAL_H */ +#endif /* MIPS_HAL_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/hw/mcu/mips/danube/src/hal_uart.c ---------------------------------------------------------------------- diff --git a/hw/mcu/mips/danube/src/hal_uart.c b/hw/mcu/mips/danube/src/hal_uart.c index 7509fed..9729f0c 100644 --- a/hw/mcu/mips/danube/src/hal_uart.c +++ b/hw/mcu/mips/danube/src/hal_uart.c @@ -118,7 +118,7 @@ hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, static void uart_irq_handler(int port) { - uint8_t lsr = uart_reg_read(1, CR_UART_LSR); + uint8_t lsr = uart_reg_read(port, CR_UART_LSR); if (lsr & CR_UART_LSR_RXFER) { /* receive error */ if (lsr & CR_UART_LSR_BI) { @@ -201,6 +201,9 @@ hal_uart_start_tx(int port) void hal_uart_blocking_tx(int port, uint8_t data) { + /* wait for transmit holding register to be empty */ + while(!(uart_reg_read(port, CR_UART_LSR) & CR_UART_LSR_THRE)) { + } /* write to transmit holding register */ uart_reg_write(port, CR_UART_RBR_THR_DLL, data); /* wait for transmit holding register to be empty */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/include/os/arch/mips/os/os_arch.h ---------------------------------------------------------------------- diff --git a/kernel/os/include/os/arch/mips/os/os_arch.h b/kernel/os/include/os/arch/mips/os/os_arch.h index 33afcee..91cd40e 100644 --- a/kernel/os/include/os/arch/mips/os/os_arch.h +++ b/kernel/os/include/os/arch/mips/os/os_arch.h @@ -77,4 +77,4 @@ void os_default_irq_asm(void); void os_bsp_systick_init(uint32_t os_ticks_per_sec, int prio); void os_bsp_ctx_sw(void); -#endif /* _OS_ARCH_ARM_H */ +#endif /* _OS_ARCH_MIPS_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/include/os/arch/pic32mx/os/os_arch.h ---------------------------------------------------------------------- diff --git a/kernel/os/include/os/arch/pic32mx/os/os_arch.h b/kernel/os/include/os/arch/pic32mx/os/os_arch.h new file mode 100644 index 0000000..5cd30ff --- /dev/null +++ b/kernel/os/include/os/arch/pic32mx/os/os_arch.h @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _OS_ARCH_PIC32MX_H +#define _OS_ARCH_PIC32MX_H + +#include <stdint.h> +#include <xc.h> + +// is this req'd? It seems a little odd to include up the tree +#include "mcu/pic32mx470.h" + +struct os_task; + +/* Run in priviliged or unprivileged Thread mode */ +/* only priv currently supported */ +#define OS_RUN_PRIV (0) +#define OS_RUN_UNPRIV (1) + +/* CPU status register */ +typedef uint32_t os_sr_t; +/* Stack type, aligned to a 32-bit word. */ +#define OS_STACK_PATTERN (0xdeadbeef) + +typedef uint32_t os_stack_t; +#define OS_ALIGNMENT (4) +#define OS_STACK_ALIGNMENT (8) + +#define OS_SR_IPL_BITS (0xE0) + +/* + * Stack sizes for common OS tasks + */ +#define OS_SANITY_STACK_SIZE (64) +#define OS_IDLE_STACK_SIZE (64) + +#define OS_STACK_ALIGN(__nmemb) \ + (OS_ALIGN((__nmemb), OS_STACK_ALIGNMENT)) + +/* Enter a critical section, save processor state, and block interrupts */ +#define OS_ENTER_CRITICAL(__os_sr) do {__os_sr = __builtin_get_isr_state(); \ + __builtin_disable_interrupts();} while(0) + +/* Exit a critical section, restore processor state and unblock interrupts */ +#define OS_EXIT_CRITICAL(__os_sr) __builtin_set_isr_state(__os_sr) +/* This is not the only way interrupts can be disabled */ +#define OS_IS_CRITICAL() ((__builtin_get_isr_state() & 1) == 0) +#define OS_ASSERT_CRITICAL() assert(OS_IS_CRITICAL()) + +os_stack_t *os_arch_task_stack_init(struct os_task *, os_stack_t *, int); +void timer_handler(void); +void os_arch_ctx_sw(struct os_task *); +os_sr_t os_arch_save_sr(void); +void os_arch_restore_sr(os_sr_t); +int os_arch_in_critical(void); +void os_arch_init(void); +uint32_t os_arch_start(void); +os_error_t os_arch_os_init(void); +os_error_t os_arch_os_start(void); +void os_set_env(os_stack_t *); +void os_arch_init_task_stack(os_stack_t *sf); +void os_default_irq_asm(void); + +/* External function prototypes supplied by BSP */ +void os_bsp_systick_init(uint32_t os_ticks_per_sec, int prio); +void os_bsp_ctx_sw(void); + +#endif /* _OS_ARCH_PIC32MX_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/include/os/arch/pic32mz/os/os_arch.h ---------------------------------------------------------------------- diff --git a/kernel/os/include/os/arch/pic32mz/os/os_arch.h b/kernel/os/include/os/arch/pic32mz/os/os_arch.h new file mode 100644 index 0000000..bf3017f --- /dev/null +++ b/kernel/os/include/os/arch/pic32mz/os/os_arch.h @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _OS_ARCH_PIC32MZ_H +#define _OS_ARCH_PIC32MZ_H + +#include <stdint.h> +#include <xc.h> + +// is this req'd? It seems a little odd to include up the tree +#include "mcu/pic32mz2048.h" + +struct os_task; + +/* Run in priviliged or unprivileged Thread mode */ +/* only priv currently supported */ +#define OS_RUN_PRIV (0) +#define OS_RUN_UNPRIV (1) + +/* CPU status register */ +typedef uint32_t os_sr_t; +/* Stack type, aligned to a 32-bit word. */ +#define OS_STACK_PATTERN (0xdeadbeef) + +typedef uint32_t os_stack_t; +#define OS_ALIGNMENT (4) +#define OS_STACK_ALIGNMENT (8) + +#define OS_SR_IPL_BITS (0xE0) + +/* + * Stack sizes for common OS tasks + */ +#define OS_SANITY_STACK_SIZE (64) +#define OS_IDLE_STACK_SIZE (64) + +#define OS_STACK_ALIGN(__nmemb) \ + (OS_ALIGN((__nmemb), OS_STACK_ALIGNMENT)) + +/* Enter a critical section, save processor state, and block interrupts */ +#define OS_ENTER_CRITICAL(__os_sr) do {__os_sr = __builtin_get_isr_state(); \ + __builtin_disable_interrupts();} while(0) + +/* Exit a critical section, restore processor state and unblock interrupts */ +#define OS_EXIT_CRITICAL(__os_sr) __builtin_set_isr_state(__os_sr) +/* This is not the only way interrupts can be disabled */ +#define OS_IS_CRITICAL() ((__builtin_get_isr_state() & 1) == 0) +#define OS_ASSERT_CRITICAL() assert(OS_IS_CRITICAL()) + +os_stack_t *os_arch_task_stack_init(struct os_task *, os_stack_t *, int); +void timer_handler(void); +void os_arch_ctx_sw(struct os_task *); +os_sr_t os_arch_save_sr(void); +void os_arch_restore_sr(os_sr_t); +int os_arch_in_critical(void); +void os_arch_init(void); +uint32_t os_arch_start(void); +os_error_t os_arch_os_init(void); +os_error_t os_arch_os_start(void); +void os_set_env(os_stack_t *); +void os_arch_init_task_stack(os_stack_t *sf); +void os_default_irq_asm(void); + +/* External function prototypes supplied by BSP */ +void os_bsp_systick_init(uint32_t os_ticks_per_sec, int prio); +void os_bsp_ctx_sw(void); + +#endif /* _OS_ARCH_PIC32MZ_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/mips/asm/excpt_isr.S ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/mips/asm/excpt_isr.S b/kernel/os/src/arch/mips/asm/excpt_isr.S index dded29c..ee8e4e7 100644 --- a/kernel/os/src/arch/mips/asm/excpt_isr.S +++ b/kernel/os/src/arch/mips/asm/excpt_isr.S @@ -70,9 +70,6 @@ AENT(__isr_vec_fallback) .set pop END(__isr_vec) -/* XXX: these are all pointelss, if there was a way to detect if a symbol is - defined elsewhere it could be fixed .ifdef does not seem to work for this */ - .text .weak _mips_isr_sw1 _mips_isr_sw1: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/mips/os_arch_mips.c ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/mips/os_arch_mips.c b/kernel/os/src/arch/mips/os_arch_mips.c index d1d7401..bdc9e5e 100644 --- a/kernel/os/src/arch/mips/os_arch_mips.c +++ b/kernel/os/src/arch/mips/os_arch_mips.c @@ -44,7 +44,8 @@ extern struct os_task g_idle_task; void __attribute__((interrupt, keep_interrupts_masked)) _mips_isr_hw5(void) { - mips_setcompare(mips_getcompare() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); + mips_setcompare(mips_getcompare() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / + OS_TICKS_PER_SEC)); timer_handler(); } @@ -150,9 +151,6 @@ os_arch_start(void) t = os_sched_next_task(); /* set the core timer compare register */ - /* XXX: take this magic number (for a 1ms tick from a 546MHz clock) and put - ** it in bsp or mcu somewhere - */ mips_setcompare(mips_getcount() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); /* global interrupt enable */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mx/asm/ctx.S ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mx/asm/ctx.S b/kernel/os/src/arch/pic32mx/asm/ctx.S new file mode 100644 index 0000000..e14c131 --- /dev/null +++ b/kernel/os/src/arch/pic32mx/asm/ctx.S @@ -0,0 +1,163 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <xc.h> + +#define CTX_SIZE (35*4) +#define CTX_EPC (31*4) +#define CTX_BADVADDR (32*4) +#define CTX_STATUS (33*4) +#define CTX_CAUSE (34*4) + +# note that k0 is not saved when using these macros. +# The cause register is saved but not resored. + +# saves to location k0 +.macro _gpctx_save + sw $1, 0(k0) + sw $2, 4(k0) + sw $3, 8(k0) + sw $4, 12(k0) + sw $5, 16(k0) + sw $6, 20(k0) + sw $7, 24(k0) + sw $8, 28(k0) + sw $9, 32(k0) + sw $10, 36(k0) + sw $11, 40(k0) + sw $12, 44(k0) + sw $13, 48(k0) + sw $14, 52(k0) + sw $15, 56(k0) + sw $16, 60(k0) + sw $17, 64(k0) + sw $18, 68(k0) + sw $19, 72(k0) + sw $20, 76(k0) + sw $21, 80(k0) + sw $22, 84(k0) + sw $23, 88(k0) + sw $24, 92(k0) + sw $25, 96(k0) + # k0 not saved + sw $27, 104(k0) + sw $28, 108(k0) + sw $29, 112(k0) + sw $30, 116(k0) + sw $31, 120(k0) + + # cp0 + sw ra, CTX_EPC(k0) + mfc0 $9, _CP0_BADVADDR /* PTR_MFC0? */ + sw $9, CTX_BADVADDR(k0) + mfc0 $9, _CP0_STATUS + sw $9, CTX_STATUS(k0) + mfc0 $9, _CP0_CAUSE + sw $9, CTX_CAUSE(k0) + +.endm + +# restores from location a0 + +.macro _gpctx_load + lw $1, 0(a0) + lw $2, 4(a0) + lw $3, 8(a0) + # a0 is loaded last + lw $5, 16(a0) + lw $6, 20(a0) + lw $7, 24(a0) + lw $8, 28(a0) + lw $9, 32(a0) + lw $10, 36(a0) + lw $11, 40(a0) + lw $12, 44(a0) + lw $13, 48(a0) + lw $14, 52(a0) + lw $15, 56(a0) + lw $16, 60(a0) + lw $17, 64(a0) + lw $18, 68(a0) + lw $19, 72(a0) + lw $20, 76(a0) + lw $21, 80(a0) + lw $22, 84(a0) + lw $23, 88(a0) + lw $24, 92(a0) + lw $25, 96(a0) + # restore k0 after interrupts have been disabled + lw $27, 104(a0) + lw $28, 108(a0) + # restore sp after interrupts have been disabled + lw $30, 116(a0) + lw $31, 120(a0) + + di + lw k0, CTX_EPC(a0) + mtc0 k0, _CP0_EPC + lw k0, CTX_STATUS(a0) + # STATUS here will have EXL set + mtc0 k0, _CP0_STATUS + ehb + + # restore k0 and sp as these may be overwritten by nested interrupts + lw $26, 100(a0) + lw $29, 112(a0) + # restore a0 last + lw $4, 12(a0) +.endm + +.text +.global get_global_pointer +.ent get_global_pointer +get_global_pointer: + .set noat + move v0, gp + jr ra +.end + +.text +.global isr_sw0 +.ent isr_sw0 +isr_sw0: + # context switch + .set noat + rdpgpr sp, sp + # save k0 as its not saved in ctx_switch, hardcode values for now + sw $26, ((25 * 4) - ((((CTX_SIZE - 1) / 8) + 1) * 8))(sp) + addi k0, sp, -((((CTX_SIZE - 1) / 8) + 1) * 8) + _gpctx_save # save the context + .set at + lw t0, g_current_task # get current task + beqz t0, 1f + sw k0, 0(t0) # update stored sp +1: + lw t1, g_os_run_list # get new task + sw t1, g_current_task # g_current_task = g_os_run_list + + li k0, _IFS0_CS0IF_MASK + sw k0, IFS0CLR + + lw a0, 0(t1) + .set noat + _gpctx_load # updates actual sp + wrpgpr sp, sp + + eret +.end http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mx/os_arch_pic32mx.c ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mx/os_arch_pic32mx.c b/kernel/os/src/arch/pic32mx/os_arch_pic32mx.c new file mode 100644 index 0000000..0dbddcc --- /dev/null +++ b/kernel/os/src/arch/pic32mx/os_arch_pic32mx.c @@ -0,0 +1,213 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "os/os.h" +#include "os/os_arch.h" +#include "syscfg/syscfg.h" +#include <hal/hal_bsp.h> +#include <hal/hal_os_tick.h> + +#include "os_priv.h" + +#include <string.h> + +extern void SVC_Handler(void); +extern void PendSV_Handler(void); +extern void SysTick_Handler(void); + +struct ctx { + uint32_t regs[31]; + uint32_t epc; + uint32_t badvaddr; + uint32_t status; + uint32_t cause; +}; + +/* XXX: determine how to deal with running un-privileged */ +/* only priv currently supported */ +uint32_t os_flags = OS_RUN_PRIV; + +extern struct os_task g_idle_task; + +/* core timer interrupt */ +void __attribute__((interrupt(IPL1AUTO), +vector(_CORE_TIMER_VECTOR))) isr_core_timer(void) +{ + timer_handler(); + _CP0_SET_COMPARE(_CP0_GET_COMPARE() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); + IFS0CLR = _IFS0_CTIF_MASK; +} + +/* context switch interrupt, in ctx.S */ +void __attribute__((interrupt(IPL1AUTO), +vector(_CORE_SOFTWARE_0_VECTOR))) isr_sw0(void); + +static int +os_in_isr(void) +{ + /* check the EXL bit */ + return (_CP0_GET_STATUS() & _CP0_STATUS_EXL_MASK) ? 1 : 0; +} + +void +timer_handler(void) +{ + os_time_advance(1); +} + +void +os_arch_ctx_sw(struct os_task *t) +{ + if ((os_sched_get_current_task() != 0) && (t != 0)) { + os_sched_ctx_sw_hook(t); + } + + IFS0SET = _IFS0_CS0IF_MASK; +} + +os_sr_t +os_arch_save_sr(void) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + return sr; +} + +void +os_arch_restore_sr(os_sr_t isr_ctx) +{ + OS_EXIT_CRITICAL(isr_ctx); +} + +int +os_arch_in_critical(void) +{ + return OS_IS_CRITICAL(); +} + +uint32_t get_global_pointer(void); + +/* assumes stack_top will be 8 aligned */ + +os_stack_t * +os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) +{ + os_stack_t *s = stack_top - ((((sizeof(struct ctx) - 1) / + OS_STACK_ALIGNMENT) + 1) * 2); + + struct ctx ctx; + + ctx.regs[3] = (uint32_t)t->t_arg; + ctx.regs[27] = get_global_pointer(); + ctx.regs[28] = (uint32_t)(stack_top - 4); + ctx.status = _CP0_GET_STATUS() | _CP0_STATUS_IE_MASK; + ctx.cause = _CP0_GET_CAUSE(); + ctx.epc = (uint32_t)t->t_func; + /* copy struct onto the stack */ + memcpy(s, &ctx, sizeof(ctx)); + + return (s); +} + +void +os_arch_init(void) +{ + os_init_idle_task(); +} + +os_error_t +os_arch_os_init(void) +{ + os_error_t err; + + err = OS_ERR_IN_ISR; + if (os_in_isr() == 0) { + err = OS_OK; + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + + _CP0_BIC_STATUS(_CP0_STATUS_IPL_MASK); + /* multi vector mode */ + INTCONSET = _INTCON_MVEC_MASK; + /* vector spacing 0x20 */ + _CP0_SET_INTCTL(_CP0_GET_INTCTL() | (1 << _CP0_INTCTL_VS_POSITION)); + + /* enable core timer interrupt */ + IEC0SET = _IEC0_CTIE_MASK; + /* set interrupt priority */ + IPC0CLR = _IPC0_CTIP_MASK; + IPC0SET = (1 << _IPC0_CTIP_POSITION); // priority 1 + /* set interrupt subpriority */ + IPC0CLR = _IPC0_CTIS_MASK; + IPC0SET = (0 << _IPC0_CTIS_POSITION); // subpriority 0 + + /* enable software interrupt 0 */ + IEC0SET = _IEC0_CS0IE_MASK; + /* set interrupt priority */ + IPC0CLR = _IPC0_CS0IP_MASK; + IPC0SET = (1 << _IPC0_CS0IP_POSITION); // priority 1 + /* set interrupt subpriority */ + IPC0CLR = _IPC0_CS0IS_MASK; + IPC0SET = (0 << _IPC0_CS0IS_POSITION); // subpriority 0 + + OS_EXIT_CRITICAL(sr); + + /* should be in kernel mode here */ + os_arch_init(); + } + return err; +} + +uint32_t +os_arch_start(void) +{ + struct os_task *t; + + /* Get the highest priority ready to run to set the current task */ + t = os_sched_next_task(); + + /* set the core timer compare register */ + _CP0_SET_COMPARE(_CP0_GET_COUNT() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); + + /* global interrupt enable */ + __builtin_enable_interrupts(); + + /* Mark the OS as started, right before we run our first task */ + g_os_started = 1; + + /* Perform context switch to first task */ + os_arch_ctx_sw(t); + + return (uint32_t)(t->t_arg); +} + +os_error_t +os_arch_os_start(void) +{ + os_error_t err; + + err = OS_OK; // OS_ERR_IN_ISR + if (os_in_isr() == 0) { + err = OS_OK; + /* should be in kernel mode here */ + os_arch_start(); + } + + return err; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mx/os_fault.c ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mx/os_fault.c b/kernel/os/src/arch/pic32mx/os_fault.c new file mode 100644 index 0000000..5dc952a --- /dev/null +++ b/kernel/os/src/arch/pic32mx/os_fault.c @@ -0,0 +1,122 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <console/console.h> +#include <hal/hal_system.h> +#ifdef COREDUMP_PRESENT +#include <coredump/coredump.h> +#endif +#include "os/os.h" + +#include <stdint.h> +#include <unistd.h> + +struct exception_frame { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +struct trap_frame { + struct exception_frame *ef; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t lr; /* this LR holds EXC_RETURN */ +}; + +struct coredump_regs { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t sp; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +#ifdef COREDUMP_PRESENT +static void +trap_to_coredump(struct trap_frame *tf, struct coredump_regs *regs) +{ +} +#endif + +void +__assert_func(const char *file, int line, const char *func, const char *e) +{ + int sr; + + OS_ENTER_CRITICAL(sr); + (void)sr; + console_blocking_mode(); + console_printf("Assert @ 0x%x\n", + (unsigned int)__builtin_return_address(0)); + if (hal_debugger_connected()) { + /* + * If debugger is attached, breakpoint before the trap. + */ + } + hal_system_reset(); +} + +void +os_default_irq(struct trap_frame *tf) +{ +#ifdef COREDUMP_PRESENT + struct coredump_regs regs; +#endif + + console_blocking_mode(); + console_printf("Unhandled interrupt, exception sp 0x%08lx\n", + (uint32_t)tf->ef); + console_printf(" r0:0x%08lx r1:0x%08lx r2:0x%08lx r3:0x%08lx\n", + tf->ef->r0, tf->ef->r1, tf->ef->r2, tf->ef->r3); + console_printf(" r4:0x%08lx r5:0x%08lx r6:0x%08lx r7:0x%08lx\n", + tf->r4, tf->r5, tf->r6, tf->r7); + console_printf(" r8:0x%08lx r9:0x%08lx r10:0x%08lx r11:0x%08lx\n", + tf->r8, tf->r9, tf->r10, tf->r11); + console_printf("r12:0x%08lx lr:0x%08lx pc:0x%08lx psr:0x%08lx\n", + tf->ef->r12, tf->ef->lr, tf->ef->pc, tf->ef->psr); +#ifdef COREDUMP_PRESENT + trap_to_coredump(tf, ®s); + coredump_dump(®s, sizeof(regs)); +#endif + hal_system_reset(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mz/asm/ctx.S ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mz/asm/ctx.S b/kernel/os/src/arch/pic32mz/asm/ctx.S new file mode 100644 index 0000000..0793952 --- /dev/null +++ b/kernel/os/src/arch/pic32mz/asm/ctx.S @@ -0,0 +1,163 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <xc.h> + +#define CTX_SIZE (35*4) +#define CTX_EPC (31*4) +#define CTX_BADVADDR (32*4) +#define CTX_STATUS (33*4) +#define CTX_CAUSE (34*4) + +# note that k0 is not saved when using these macros. +# The cause register is saved but not resored. + +# saves to location k0 +.macro _gpctx_save + sw $1, 0(k0) + sw $2, 4(k0) + sw $3, 8(k0) + sw $4, 12(k0) + sw $5, 16(k0) + sw $6, 20(k0) + sw $7, 24(k0) + sw $8, 28(k0) + sw $9, 32(k0) + sw $10, 36(k0) + sw $11, 40(k0) + sw $12, 44(k0) + sw $13, 48(k0) + sw $14, 52(k0) + sw $15, 56(k0) + sw $16, 60(k0) + sw $17, 64(k0) + sw $18, 68(k0) + sw $19, 72(k0) + sw $20, 76(k0) + sw $21, 80(k0) + sw $22, 84(k0) + sw $23, 88(k0) + sw $24, 92(k0) + sw $25, 96(k0) + # k0 not saved + sw $27, 104(k0) + sw $28, 108(k0) + sw $29, 112(k0) + sw $30, 116(k0) + sw $31, 120(k0) + + # cp0 + sw ra, CTX_EPC(k0) + mfc0 $9, _CP0_BADVADDR /* PTR_MFC0? */ + sw $9, CTX_BADVADDR(k0) + mfc0 $9, _CP0_STATUS + sw $9, CTX_STATUS(k0) + mfc0 $9, _CP0_CAUSE + sw $9, CTX_CAUSE(k0) + +.endm + +# restores from location a0 + +.macro _gpctx_load + lw $1, 0(a0) + lw $2, 4(a0) + lw $3, 8(a0) + # a0 is loaded last + lw $5, 16(a0) + lw $6, 20(a0) + lw $7, 24(a0) + lw $8, 28(a0) + lw $9, 32(a0) + lw $10, 36(a0) + lw $11, 40(a0) + lw $12, 44(a0) + lw $13, 48(a0) + lw $14, 52(a0) + lw $15, 56(a0) + lw $16, 60(a0) + lw $17, 64(a0) + lw $18, 68(a0) + lw $19, 72(a0) + lw $20, 76(a0) + lw $21, 80(a0) + lw $22, 84(a0) + lw $23, 88(a0) + lw $24, 92(a0) + lw $25, 96(a0) + # restore k0 after interrupts have been disabled + lw $27, 104(a0) + lw $28, 108(a0) + # restore sp after interrupts have been disabled + lw $30, 116(a0) + lw $31, 120(a0) + + di + lw k0, CTX_EPC(a0) + mtc0 k0, _CP0_EPC + lw k0, CTX_STATUS(a0) + # STATUS here will have EXL set + mtc0 k0, _CP0_STATUS + ehb + + # restore k0 and sp as these may be overwritten by nested interrupts + lw $26, 100(a0) + lw $29, 112(a0) + # restore a0 last + lw $4, 12(a0) +.endm + +.text +.global get_global_pointer +.ent get_global_pointer +get_global_pointer: + .set noat + move v0, gp + jr ra +.end + +.text +.global isr_sw0 +.ent isr_sw0 +isr_sw0: + # context switch + .set noat + rdpgpr sp, sp + # save k0 as its not saved in ctx_switch, hardcode values for now + sw $26, ((25 * 4) - ((((CTX_SIZE - 1) / 8) + 1) * 8))(sp) + addi k0, sp, -((((CTX_SIZE - 1) / 8) + 1) * 8) + _gpctx_save # save the context + .set at + lw t0, g_current_task # get current task + beqz t0, 1f + sw k0, 0(t0) # update stored sp +1: + lw t1, g_os_run_list # get new task + sw t1, g_current_task # g_current_task = g_os_run_list + + li k0, _IFS0_CS0IF_MASK + sw k0, IFS0CLR + + lw a0, 0(t1) + .set noat + _gpctx_load # updates actual sp + wrpgpr sp, sp + + eret +.end http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mz/os_arch_pic32mz.c ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mz/os_arch_pic32mz.c b/kernel/os/src/arch/pic32mz/os_arch_pic32mz.c new file mode 100644 index 0000000..0dbddcc --- /dev/null +++ b/kernel/os/src/arch/pic32mz/os_arch_pic32mz.c @@ -0,0 +1,213 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "os/os.h" +#include "os/os_arch.h" +#include "syscfg/syscfg.h" +#include <hal/hal_bsp.h> +#include <hal/hal_os_tick.h> + +#include "os_priv.h" + +#include <string.h> + +extern void SVC_Handler(void); +extern void PendSV_Handler(void); +extern void SysTick_Handler(void); + +struct ctx { + uint32_t regs[31]; + uint32_t epc; + uint32_t badvaddr; + uint32_t status; + uint32_t cause; +}; + +/* XXX: determine how to deal with running un-privileged */ +/* only priv currently supported */ +uint32_t os_flags = OS_RUN_PRIV; + +extern struct os_task g_idle_task; + +/* core timer interrupt */ +void __attribute__((interrupt(IPL1AUTO), +vector(_CORE_TIMER_VECTOR))) isr_core_timer(void) +{ + timer_handler(); + _CP0_SET_COMPARE(_CP0_GET_COMPARE() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); + IFS0CLR = _IFS0_CTIF_MASK; +} + +/* context switch interrupt, in ctx.S */ +void __attribute__((interrupt(IPL1AUTO), +vector(_CORE_SOFTWARE_0_VECTOR))) isr_sw0(void); + +static int +os_in_isr(void) +{ + /* check the EXL bit */ + return (_CP0_GET_STATUS() & _CP0_STATUS_EXL_MASK) ? 1 : 0; +} + +void +timer_handler(void) +{ + os_time_advance(1); +} + +void +os_arch_ctx_sw(struct os_task *t) +{ + if ((os_sched_get_current_task() != 0) && (t != 0)) { + os_sched_ctx_sw_hook(t); + } + + IFS0SET = _IFS0_CS0IF_MASK; +} + +os_sr_t +os_arch_save_sr(void) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + return sr; +} + +void +os_arch_restore_sr(os_sr_t isr_ctx) +{ + OS_EXIT_CRITICAL(isr_ctx); +} + +int +os_arch_in_critical(void) +{ + return OS_IS_CRITICAL(); +} + +uint32_t get_global_pointer(void); + +/* assumes stack_top will be 8 aligned */ + +os_stack_t * +os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) +{ + os_stack_t *s = stack_top - ((((sizeof(struct ctx) - 1) / + OS_STACK_ALIGNMENT) + 1) * 2); + + struct ctx ctx; + + ctx.regs[3] = (uint32_t)t->t_arg; + ctx.regs[27] = get_global_pointer(); + ctx.regs[28] = (uint32_t)(stack_top - 4); + ctx.status = _CP0_GET_STATUS() | _CP0_STATUS_IE_MASK; + ctx.cause = _CP0_GET_CAUSE(); + ctx.epc = (uint32_t)t->t_func; + /* copy struct onto the stack */ + memcpy(s, &ctx, sizeof(ctx)); + + return (s); +} + +void +os_arch_init(void) +{ + os_init_idle_task(); +} + +os_error_t +os_arch_os_init(void) +{ + os_error_t err; + + err = OS_ERR_IN_ISR; + if (os_in_isr() == 0) { + err = OS_OK; + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + + _CP0_BIC_STATUS(_CP0_STATUS_IPL_MASK); + /* multi vector mode */ + INTCONSET = _INTCON_MVEC_MASK; + /* vector spacing 0x20 */ + _CP0_SET_INTCTL(_CP0_GET_INTCTL() | (1 << _CP0_INTCTL_VS_POSITION)); + + /* enable core timer interrupt */ + IEC0SET = _IEC0_CTIE_MASK; + /* set interrupt priority */ + IPC0CLR = _IPC0_CTIP_MASK; + IPC0SET = (1 << _IPC0_CTIP_POSITION); // priority 1 + /* set interrupt subpriority */ + IPC0CLR = _IPC0_CTIS_MASK; + IPC0SET = (0 << _IPC0_CTIS_POSITION); // subpriority 0 + + /* enable software interrupt 0 */ + IEC0SET = _IEC0_CS0IE_MASK; + /* set interrupt priority */ + IPC0CLR = _IPC0_CS0IP_MASK; + IPC0SET = (1 << _IPC0_CS0IP_POSITION); // priority 1 + /* set interrupt subpriority */ + IPC0CLR = _IPC0_CS0IS_MASK; + IPC0SET = (0 << _IPC0_CS0IS_POSITION); // subpriority 0 + + OS_EXIT_CRITICAL(sr); + + /* should be in kernel mode here */ + os_arch_init(); + } + return err; +} + +uint32_t +os_arch_start(void) +{ + struct os_task *t; + + /* Get the highest priority ready to run to set the current task */ + t = os_sched_next_task(); + + /* set the core timer compare register */ + _CP0_SET_COMPARE(_CP0_GET_COUNT() + ((MYNEWT_VAL(CLOCK_FREQ) / 2) / 1000)); + + /* global interrupt enable */ + __builtin_enable_interrupts(); + + /* Mark the OS as started, right before we run our first task */ + g_os_started = 1; + + /* Perform context switch to first task */ + os_arch_ctx_sw(t); + + return (uint32_t)(t->t_arg); +} + +os_error_t +os_arch_os_start(void) +{ + os_error_t err; + + err = OS_OK; // OS_ERR_IN_ISR + if (os_in_isr() == 0) { + err = OS_OK; + /* should be in kernel mode here */ + os_arch_start(); + } + + return err; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/70bf4a85/kernel/os/src/arch/pic32mz/os_fault.c ---------------------------------------------------------------------- diff --git a/kernel/os/src/arch/pic32mz/os_fault.c b/kernel/os/src/arch/pic32mz/os_fault.c new file mode 100644 index 0000000..5dc952a --- /dev/null +++ b/kernel/os/src/arch/pic32mz/os_fault.c @@ -0,0 +1,122 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <console/console.h> +#include <hal/hal_system.h> +#ifdef COREDUMP_PRESENT +#include <coredump/coredump.h> +#endif +#include "os/os.h" + +#include <stdint.h> +#include <unistd.h> + +struct exception_frame { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +struct trap_frame { + struct exception_frame *ef; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t lr; /* this LR holds EXC_RETURN */ +}; + +struct coredump_regs { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t sp; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +#ifdef COREDUMP_PRESENT +static void +trap_to_coredump(struct trap_frame *tf, struct coredump_regs *regs) +{ +} +#endif + +void +__assert_func(const char *file, int line, const char *func, const char *e) +{ + int sr; + + OS_ENTER_CRITICAL(sr); + (void)sr; + console_blocking_mode(); + console_printf("Assert @ 0x%x\n", + (unsigned int)__builtin_return_address(0)); + if (hal_debugger_connected()) { + /* + * If debugger is attached, breakpoint before the trap. + */ + } + hal_system_reset(); +} + +void +os_default_irq(struct trap_frame *tf) +{ +#ifdef COREDUMP_PRESENT + struct coredump_regs regs; +#endif + + console_blocking_mode(); + console_printf("Unhandled interrupt, exception sp 0x%08lx\n", + (uint32_t)tf->ef); + console_printf(" r0:0x%08lx r1:0x%08lx r2:0x%08lx r3:0x%08lx\n", + tf->ef->r0, tf->ef->r1, tf->ef->r2, tf->ef->r3); + console_printf(" r4:0x%08lx r5:0x%08lx r6:0x%08lx r7:0x%08lx\n", + tf->r4, tf->r5, tf->r6, tf->r7); + console_printf(" r8:0x%08lx r9:0x%08lx r10:0x%08lx r11:0x%08lx\n", + tf->r8, tf->r9, tf->r10, tf->r11); + console_printf("r12:0x%08lx lr:0x%08lx pc:0x%08lx psr:0x%08lx\n", + tf->ef->r12, tf->ef->lr, tf->ef->pc, tf->ef->psr); +#ifdef COREDUMP_PRESENT + trap_to_coredump(tf, ®s); + coredump_dump(®s, sizeof(regs)); +#endif + hal_system_reset(); +}