URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ucos-ii/] [2.91/] [ucos-port/] [os_cpu_a.S] - Rev 707
Go to most recent revision | Compare with Previous | Blame | View Log
/*----------------------------------------------------------------------CHiPES Embedded RTR Systems Copyright (c) Tim Oliver 2002-2004----------------------------------------------------------------------File : os_cpu_a.SAuthor(s) : Tim Oliver, timtimoliver@yahoo.co.ukJulius Baxter, julius@opencores.org---------------------------[Description]------------------------------Start up file for OpenRISC Reference PlatformAssembly code required for ORP port of MicroC/OS-IIMacros :exception_vector name orgload32i reg conststore_contextrestore_contextInternal Routines :_reset Boot code installed at interrupt vector 0x100_start Start up sequence_OSTickISR Operating system timer tick interrupt serviceroutine_OSStartHighRdy Starts the highest priority task that isavailable to run_OSCtxSwBP_OSCtxSw Task switch_OSIntCtxSw Task switch after interrupt_UserISR Interrupt service routine template - requirescode_align Attempts to recover from memory alignmenterrorsnest_not_oneExternal Routines :_OSIntExit_OSTimeTick_OSTaskSwHookExternal variables :_OSIntNesting_OSRunning_OSPrioHighRdy_OSPrioCur_OSTCBCur_OSTCBHighRdyInterrupt Vectors Installed:0x100 _reset0x500 _OSTickISR0x600 _align0x800 _UserISR0xc00 _OSCtxSw*//*This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "spr-defs.h"#include "board.h"#define RED_ZONE_SIZE 128#define STK_FRAME_SIZE (128+RED_ZONE_SIZE)#define SPR_TTMR_LOAD (SPR_TTMR_IE | SPR_TTMR_RT | \((IN_CLK/TICKS_PER_SEC) & SPR_TTMR_PERIOD))/* function prototypes */.global OSTickISR /* internal functions */.global OSStartHighRdy.global OSCtxSwBP.global OSCtxSw.global OSIntCtxSw.global UserISR.global _align.global nest_not_one.extern OSIntExit /* external functions */.extern OSTimeTick.extern OSTaskSwHook.extern OSIntNesting /* values */.extern OSRunning.extern OSPrioHighRdy.extern OSPrioCur.extern OSTCBCur.extern OSTCBHighRdy/* Macro Definitions *//* Utility macro: Load a 32-bit constant into a register */.macro load32i reg constl.movhi \reg,hi(\const)l.ori \reg,\reg,lo(\const).endm/* Utility macro: Start code for an exception handler */.macro exception_vector namel.addi r1,r1,-STK_FRAME_SIZEl.sw 0xc(r1),r3l.movhi r3,hi(\name)l.ori r3,r3,lo(\name)l.jr r3l.nop.endm.macro unhandled_exceptionl.ori r3, r0, 1l.j 0l.nop NOP_EXIT.endm/* Utility macro: store the cpu context on the stack */.macro store_contextl.sw 0x8(r1),r2l.sw 0x10(r1),r4l.sw 0x14(r1),r5l.sw 0x18(r1),r6l.sw 0x1c(r1),r7l.sw 0x20(r1),r8l.sw 0x24(r1),r9l.sw 0x28(r1),r10l.sw 0x2c(r1),r11l.sw 0x30(r1),r12l.sw 0x34(r1),r13l.sw 0x38(r1),r14l.sw 0x3c(r1),r15l.sw 0x40(r1),r16l.sw 0x44(r1),r17l.sw 0x48(r1),r18l.sw 0x4c(r1),r19l.sw 0x50(r1),r20l.sw 0x54(r1),r21l.sw 0x58(r1),r22l.sw 0x5c(r1),r23l.sw 0x60(r1),r24l.sw 0x64(r1),r25l.sw 0x68(r1),r26l.sw 0x6c(r1),r27l.sw 0x70(r1),r28l.sw 0x74(r1),r29l.sw 0x78(r1),r30l.sw 0x7c(r1),r31.endm/* Utility macro: restore the cpu context from the stack */.macro restore_contextl.lwz r2,0x8(r1)l.lwz r3,0xc(r1)l.lwz r4,0x10(r1)l.lwz r5,0x14(r1)l.lwz r6,0x18(r1)l.lwz r7,0x1c(r1)l.lwz r8,0x20(r1)l.lwz r9,0x24(r1)l.lwz r10,0x28(r1)l.lwz r11,0x2c(r1)l.lwz r12,0x30(r1)l.lwz r13,0x34(r1)l.lwz r14,0x38(r1)l.lwz r15,0x3c(r1)l.lwz r16,0x40(r1)l.lwz r17,0x44(r1)l.lwz r18,0x48(r1)l.lwz r19,0x4c(r1)l.lwz r20,0x50(r1)l.lwz r21,0x54(r1)l.lwz r22,0x58(r1)l.lwz r23,0x5c(r1)l.lwz r24,0x60(r1)l.lwz r25,0x64(r1)l.lwz r26,0x68(r1)l.lwz r27,0x6c(r1)l.lwz r28,0x70(r1)l.lwz r29,0x74(r1)l.lwz r30,0x78(r1)l.lwz r31,0x7c(r1).endm/* actual code */.section .stack, "aw", @nobits.space STACK_SIZE_stack:/* Exception vectors */.section .vectors, "ax".org 0x100_reset:l.movhi r0,0l.addi r3,r0,SPR_SR_SMl.mtspr r0,r3,SPR_SRload32i r3,_startl.jr r3l.nop.org 0x200unhandled_exception.org 0x300unhandled_exception.org 0x400unhandled_exception.org 0x500exception_vector OSTickISR.org 0x600exception_vector _align.org 0x700unhandled_exception.org 0x800exception_vector UserISR.org 0x900unhandled_exception.org 0xa00unhandled_exception.org 0xb00unhandled_exception.org 0xc00exception_vector OSCtxSw/* Start of text section */.section .text/* _start function - called immediately after reset */_start:/* Instruction cache enable *//* Check if IC present and skip enabling otherwise */l.mfspr r24,r0,SPR_UPRl.andi r26,r24,SPR_UPR_ICPl.sfeq r26,r0l.bf .L8l.nop/* Disable IC */l.mfspr r6,r0,SPR_SRl.addi r5,r0,-1l.xori r5,r5,SPR_SR_ICEl.and r5,r6,r5l.mtspr r0,r5,SPR_SR/* Establish cache block sizeIf BS=0, 16;If BS=1, 32;r14 contain block size*/l.mfspr r24,r0,SPR_ICCFGRl.andi r26,r24,SPR_ICCFGR_CBSl.srli r28,r26,7l.ori r30,r0,16l.sll r14,r30,r28/* Establish number of cache setsr16 contains number of cache setsr28 contains log(# of cache sets)*/l.andi r26,r24,SPR_ICCFGR_NCSl.srli r28,r26,3l.ori r30,r0,1l.sll r16,r30,r28/* Invalidate IC */l.addi r6,r0,0l.sll r5,r14,r28.L7:l.mtspr r0,r6,SPR_ICBIRl.sfne r6,r5l.bf .L7l.add r6,r6,r14/* Enable IC */l.mfspr r6,r0,SPR_SRl.ori r6,r6,SPR_SR_ICEl.mtspr r0,r6,SPR_SRl.nopl.nopl.nopl.nopl.nopl.nopl.nopl.nop.L8:/* Data cache enable *//* Check if DC present and skip enabling otherwise */l.mfspr r24,r0,SPR_UPRl.andi r26,r24,SPR_UPR_DCPl.sfeq r26,r0l.bf .L10l.nop/* Disable DC */l.mfspr r6,r0,SPR_SRl.addi r5,r0,-1l.xori r5,r5,SPR_SR_DCEl.and r5,r6,r5l.mtspr r0,r5,SPR_SR/* Establish cache block sizeIf BS=0, 16;If BS=1, 32;r14 contain block size*/l.mfspr r24,r0,SPR_DCCFGRl.andi r26,r24,SPR_DCCFGR_CBSl.srli r28,r26,7l.ori r30,r0,16l.sll r14,r30,r28/* Establish number of cache setsr16 contains number of cache setsr28 contains log(# of cache sets)*/l.andi r26,r24,SPR_DCCFGR_NCSl.srli r28,r26,3l.ori r30,r0,1l.sll r16,r30,r28/* Invalidate DC */l.addi r6,r0,0l.sll r5,r14,r28.L9:l.mtspr r0,r6,SPR_DCBIRl.sfne r6,r5l.bf .L9l.add r6,r6,r14/* Enable DC */l.mfspr r6,r0,SPR_SRl.ori r6,r6,SPR_SR_DCEl.mtspr r0,r6,SPR_SR.L10:/* Clear BSS */load32i r28, ___bss_startload32i r30, __end1:l.sw (0)(r28), r0l.sfltu r28, r30l.bf 1bl.addi r28, r28, 4/* Initialise stack pointer */load32i r1,_stack-4l.addi r2,r0,-3l.and r1,r1,r2l.ori r2,r1,0load32i r3,mainl.jr r3l.addi r3,r0,0_align:l.ori r3,r0,0x600l.nop NOP_REPORTl.mfspr r3,r0,SPR_EPCR_BASEl.nop NOP_REPORTl.lwz r3,0(r3)l.nop NOP_REPORTl.mfspr r3,r0,SPR_EEAR_BASEl.nop NOP_REPORT/* Loop in place, cause simulator to exit */l.ori r3,r0,1l.j 0l.nop NOP_EXIT/*------------------------------OSCtxSw------------------------------Description :This routine switches between two different tasks.The task state of one is saved on its kernel stack.Then the state of the other is restored from its kernel stack.There maybe memory management hardware issuesFinally, we can return to the second task, via the 'return'.Includes OSIntCtxSw------------------------------Uses:------------------------------*/OSCtxSw:/* l.sys exception for now so we are in supervisor mode *//* exception - recover pc from epcr */l.mfspr r3,r0,SPR_EPCR_BASE /* save program counter that was put inexception register */l.sw 0(r1),r3l.mfspr r3,r0,SPR_ESR_BASE /* save status register that was put inexception register */l.sw 4(r1),r3store_context/* Store current stack pointer */load32i r3,OSTCBCur /* r3= &OSTCBCur */l.lwz r3,0(r3) /* r3 = &CurrentTask.OSTCBStkPtr */l.sw 0(r3),r1 /* CurrentTask.OSTCBStkPtr = SP */OSIntCtxSw:l.jal OSTaskSwHook /* call OSTaskSwHook */l.nopload32i r2,OSTCBHighRdy /* r2= &OSTCBHighRdy */l.lwz r2,0(r2)load32i r3,OSTCBCur /* r3= &OSTCBCur */l.sw 0(r3),r2 /* OSTCBCur = OSTCBHighRdy */load32i r3,OSPrioHighRdy /* r3= &OSPrioHighRdy */l.lbz r3, 0(r3)load32i r4,OSPrioCur /* r4= &OSPrioCur */l.sb 0(r4), r3 /* OSPrioCur = OSPrioHighRdy */l.lwz r1, 0(r2) /* sp = OSTCBHighRdy */l.lwz r2,0(r1) /* load context for task to be resumed */l.mtspr r0,r2,SPR_EPCR_BASEl.lwz r2,4(r1)l.mtspr r0,r2,SPR_ESR_BASErestore_contextOSCtxSwBP:l.addi r1,r1,STK_FRAME_SIZEl.rfel.nop/*------------------------------OSStartHighRdy------------------------------Description :Starts the highest priority task that is available to runOSStartHighRdy() MUST:a) Call OSTaskSwHook() then,b) Set OSRunning to TRUE,c) Switch to the HPT------------------------------Uses :------------------------------*/OSStartHighRdy:l.jal OSTaskSwHook /* call OSTaskSwHook */l.nopload32i r3,OSRunning /* r3= &OSRunning */l.ori r4,r0, 0x01 /* set OSRunning == TRUE */l.sb 0(r3), r4/* load stack pointer from next task'sTCB area */load32i r3,OSTCBHighRdy /* r3 = &OSTCBHighRdy */l.lwz r3,0(r3) /* r3 = &OS_TCB */l.lwz r1, 0(r3) /* stack is the first element */l.lwz r2,0(r1)l.mtspr r0,r2,SPR_EPCR_BASEl.lwz r2,4(r1)l.mtspr r0,r2,SPR_ESR_BASErestore_contextl.addi r1,r1,STK_FRAME_SIZEl.rfel.nop/*------------------------------OSTickISR------------------------------Description :------------------------------Uses :------------------------------*/OSTickISR:l.mfspr r3,r0,SPR_EPCR_BASE /* save program counter that was putin exception register */l.sw 0(r1),r3l.mfspr r3,r0,SPR_ESR_BASE /* save status register that was put inexception register */l.sw 4(r1),r3store_context/* either call OSIntEnter or Increment OSIntNesting *//*l.jal OSIntEnterl.nopload32i r2,OSIntNestingl.lbz r3,0(r2)*/load32i r2,OSIntNesting /* r2 &OSIntNesting */l.lbz r3,0(r2) /* r3 OSIntNesting */l.addi r3,r3,1l.sb 0(r2),r3/* if (OSIntNesting == 1) OSTCBCur->OSTCBStkPtr = sp */l.sfeqi r3,1l.bnf nest_not_onel.nopload32i r4,OSTCBCur /* set pointer to Current TCB pointer *//* r4= &OSTCBCur *//* Store current stack pointer */l.lwz r5,0(r4) /* r5 = &CurrentTask.OSTCBStkPtr */l.sw 0(r5),r1 /* CurrentTask.OSTCBStkPtr = SP */nest_not_one:/* clear interrupt */load32i r3,SPR_TTMR_LOADl.mtspr r0,r3,SPR_TTMR/* optionally re enable interrupt *//*Call OSTimeTick()*/l.jal OSTimeTickl.nop/*Call OSIntExit()*/l.jal OSIntExitl.nop/* load stack pointer from next task'sTCB area */load32i r3,OSTCBHighRdy /* r3 = &OSTCBHighRdy */l.lwz r3,0(r3) /* r3 = &OS_TCB */l.lwz r1, 0(r3) /* stack is the first element */l.lwz r2,0(r1)l.mtspr r0,r2,SPR_EPCR_BASEl.lwz r2,4(r1)l.mtspr r0,r2,SPR_ESR_BASErestore_contextl.addi r1,r1,STK_FRAME_SIZEl.rfel.nop/*------------------------------UserISR------------------------------Description :------------------------------Uses :------------------------------*/UserISR:l.mfspr r3,r0,SPR_EPCR_BASE /* save program counter that was put inexception register */l.sw 0(r1),r3l.mfspr r3,r0,SPR_ESR_BASE /* save status register that was putin exception register */l.sw 4(r1),r3store_context/* either call OSIntEnter or Increment OSIntNesting *//*l.jal _OSIntEnterl.nopload32i r2,_OSIntNestingl.lbz r3,0(r2)*/load32i r2,OSIntNesting /* r2 &OSIntNesting */l.lbz r3,0(r2) /* r3 OSIntNesting */l.addi r3,r3,1l.sb 0(r2),r3/* if (OSIntNesting == 1) OSTCBCur->OSTCBStkPtr = sp */l.sfeqi r3,1l.bnf Unest_not_onel.nopload32i r4,OSTCBCur /* set pointer to Current TCB pointer *//* r4= &OSTCBCur *//* Store current stack pointer */l.lwz r5,0(r4) /* r5 = &CurrentTask.OSTCBStkPtr */l.sw 0(r5),r1 /* CurrentTask.OSTCBStkPtr = SP */Unest_not_one:/* clear interrupt */l.mtspr r0,r0,SPR_PICSR/* optionally re enable interrupt *//*Call interrupt service routine *//*Call OSIntExit()*/l.jal OSIntExitl.nop/* load stack pointer from next task's TCB area */load32i r3,OSTCBHighRdy /* r3 = &OSTCBHighRdy */l.lwz r3,0(r3) /* r3 = &OS_TCB */l.lwz r1, 0(r3) /* stack is the first element */l.lwz r2,0(r1)l.mtspr r0,r2,SPR_EPCR_BASEl.lwz r2,4(r1)l.mtspr r0,r2,SPR_ESR_BASErestore_contextl.addi r1,r1,STK_FRAME_SIZEl.rfel.nop
Go to most recent revision | Compare with Previous | Blame | View Log
