1 /* 2 * File : cpuport.c 3 * This file is part of RT-Thread RTOS 4 * COPYRIGHT (C) 2009 - 2011, RT-Thread Development Team 5 * 6 * The license and distribution terms for this file may be 7 * found in the file LICENSE in this distribution or at 8 * http://www.rt-thread.org/license/LICENSE 9 * 10 * Change Logs: 11 * Date Author Notes 12 * 2011-02-23 Bernard the first version 13 * 2012-03-03 xuzhenglim modify for rx62N 14 */ 15 #include <rthw.h> 16 #include <rtthread.h> 17 18 #include "cpuconfig.h" 19 20 #include "machine.h" 21 #include "iorx62n.h" 22 23 #define ENTER_INTERRUPT() ICU.SWINTR.BIT.SWINT = 1; 24 25 extern volatile rt_uint8_t rt_interrupt_nest; 26 27 28 /* switch flag on interrupt and thread pointer to save switch record */ 29 rt_uint32_t rt_interrupt_from_thread; 30 rt_uint32_t rt_interrupt_to_thread; 31 rt_uint32_t rt_thread_switch_interrupt_flag; 32 33 34 /* stack frame*/ 35 struct stack_frame 36 { 37 rt_uint32_t ACCLO; 38 rt_uint32_t ACCHI; 39 rt_uint32_t FPSW; 40 rt_uint32_t R1; 41 rt_uint32_t R2; 42 rt_uint32_t R3; 43 rt_uint32_t R4; 44 rt_uint32_t R5; 45 rt_uint32_t R6; 46 rt_uint32_t R7; 47 rt_uint32_t R8; 48 rt_uint32_t R9; 49 rt_uint32_t R10; 50 rt_uint32_t R11; 51 rt_uint32_t R12; 52 rt_uint32_t R13; 53 rt_uint32_t R14; 54 rt_uint32_t R15; 55 //there is not R0 register,it is special for stack pointer 56 rt_uint32_t PC; 57 rt_uint32_t PSW; 58 }; 59 60 /** 61 * Initilial the threah stack. 62 * 63 * @author LXZ (2014/11/8) 64 * 65 * @param void* tentry 66 * @param void* parameter 67 * @param rt_uint8_t* stack_addr 68 * @param void* texit 69 * 70 * @return rt_uint8_t* 71 */ 72 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, 73 rt_uint8_t *stack_addr, void *texit) 74 { 75 unsigned long *stk; 76 struct stack_frame *stack_frame; 77 unsigned long i; 78 79 stk = (unsigned long *)stack_addr; 80 *(stk) = (unsigned long)texit; 81 stack_frame = (struct stack_frame *)(stack_addr - sizeof(struct stack_frame)) ; 82 83 //Initilial all register 84 for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) 85 { 86 ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; 87 } 88 89 stack_frame->PSW = (unsigned long)0x00030000 ; /* psw */ 90 stack_frame->PC = (unsigned long)tentry; /* thread entery*/ 91 stack_frame->R1 = (unsigned long )parameter; /* r1 : parameter */ 92 stack_frame->FPSW = 0x00000100; /* fpsw */ 93 94 return(rt_uint8_t *)stack_frame; 95 } 96 97 #ifdef RT_USING_FINSH 98 extern void list_thread(void); 99 #endif 100 extern rt_thread_t rt_current_thread; 101 /** 102 * deal exception 103 * 104 * @author LXZ (2014/11/8) 105 * 106 * @param struct stack_frame* exception_contex 107 */ 108 void rt_hw_hard_fault_exception(struct stack_frame* exception_contex) 109 { 110 if (exception_contex != RT_NULL) { 111 rt_kprintf("psw: 0x%08x\n", exception_contex->PSW); 112 rt_kprintf("pc: 0x%08x\n", exception_contex->PC); 113 rt_kprintf("r0: 0x%08x\n", exception_contex->R1); 114 rt_kprintf("r0: 0x%08x\n", exception_contex->R2); 115 rt_kprintf("r0: 0x%08x\n", exception_contex->R3); 116 rt_kprintf("r0: 0x%08x\n", exception_contex->R4); 117 rt_kprintf("r0: 0x%08x\n", exception_contex->R5); 118 rt_kprintf("r0: 0x%08x\n", exception_contex->R6); 119 rt_kprintf("r0: 0x%08x\n", exception_contex->R7); 120 rt_kprintf("r0: 0x%08x\n", exception_contex->R8); 121 rt_kprintf("r0: 0x%08x\n", exception_contex->R9); 122 rt_kprintf("r0: 0x%08x\n", exception_contex->R10); 123 rt_kprintf("r0: 0x%08x\n", exception_contex->R11); 124 rt_kprintf("r0: 0x%08x\n", exception_contex->R12); 125 rt_kprintf("r0: 0x%08x\n", exception_contex->R13); 126 rt_kprintf("r0: 0x%08x\n", exception_contex->R14); 127 rt_kprintf("r0: 0x%08x\n", exception_contex->R15); 128 rt_kprintf("fpsw: 0x%08x\n", exception_contex->FPSW); 129 rt_kprintf("acchi: 0x%08x\n", exception_contex->ACCHI); 130 rt_kprintf("acclo: 0x%08x\n", exception_contex->ACCLO); 131 } 132 rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); 133 #ifdef RT_USING_FINSH 134 list_thread(); 135 #endif 136 while (1); 137 138 } 139 140 141 /** 142 * switch thread in interrupt 143 * 144 * @author LXZ (2014/11/8) 145 * 146 * @param rt_uint32_t from 147 * @param rt_uint32_t to 148 */ 149 void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to) 150 { 151 if (rt_thread_switch_interrupt_flag == 0) 152 { 153 rt_thread_switch_interrupt_flag = 1; 154 rt_interrupt_from_thread = from; 155 } 156 157 rt_interrupt_to_thread = to; 158 ENTER_INTERRUPT(); 159 } 160 /** 161 * swithc thread out the interrupt 162 * 163 * @author LXZ (2014/11/8) 164 * 165 * @param rt_uint32_t from 166 * @param rt_uint32_t to 167 */ 168 void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to) 169 { 170 if (rt_thread_switch_interrupt_flag == 0) 171 { 172 rt_thread_switch_interrupt_flag = 1; 173 rt_interrupt_from_thread = from; 174 } 175 176 rt_interrupt_to_thread = to; 177 ENTER_INTERRUPT(); 178 } 179 180 /** 181 * shut down the chip 182 * 183 * @author LXZ (2014/11/8) 184 */ 185 void rt_hw_cpu_shutdown(void) 186 { 187 rt_kprintf("shutdown...\n"); 188 189 RT_ASSERT(0); 190 } 191 /** 192 * switch to the first thread,it just call one time 193 * 194 * @author LXZ (2014/11/8) 195 * 196 * @param rt_uint32_t to 197 */ 198 void rt_hw_context_switch_to(rt_uint32_t to) 199 { 200 201 rt_interrupt_from_thread = 0; 202 rt_interrupt_to_thread = to; 203 rt_thread_switch_interrupt_flag = 1; 204 /* enable interrupt*/ 205 _IEN( _ICU_SWINT ) = 1; 206 207 /*clear the interrupt flag*/ 208 _IR( _ICU_SWINT ) = 0; 209 _IPR( _ICU_SWINT ) = MAX_SYSCALL_INTERRUPT_PRIORITY + 1; 210 211 /*touch the software interrupt*/ 212 ENTER_INTERRUPT(); 213 /*wait for first thread start up*/ 214 while(1); 215 } 216 217