コード例 #1
0
ファイル: threadport.c プロジェクト: moslevin/Mark3C
//---------------------------------------------------------------------------
void ThreadPort_InitStack(Thread_t *pstThread_)
{
    // Initialize the stack for a Thread_t
    K_USHORT usAddr;
    K_UCHAR *pucStack;
    K_USHORT i;

    // Get the address of the thread's entry function
    usAddr = (K_USHORT)(pstThread_->pfEntryPoint);

    // Start by finding the bottom of the stack
    pucStack = (K_UCHAR*)pstThread_->pwStackTop;

    // clear the stack, and initialize it to a known-default value (easier
    // to debug when things go sour with stack corruption or overflow)
    for (i = 0; i < pstThread_->usStackSize; i++)
    {
        pstThread_->pwStack[i] = 0xFF;
    }

    // Our context starts with the entry function
    PUSH_TO_STACK(pucStack, (K_UCHAR)(usAddr & 0x00FF));
    PUSH_TO_STACK(pucStack, (K_UCHAR)((usAddr >> 8) & 0x00FF));

    // R0
    PUSH_TO_STACK(pucStack, 0x00);    // R0

    // Push status register and R1 (which is used as a constant zero)
    PUSH_TO_STACK(pucStack, 0x80);  // SR
    PUSH_TO_STACK(pucStack, 0x00);  // R1

    // Push other registers
    for (i = 2; i <= 23; i++) //R2-R23
    {
        PUSH_TO_STACK(pucStack, i);
    }

    // Assume that the argument is the only stack variable
    PUSH_TO_STACK(pucStack, (K_UCHAR)(((K_USHORT)(pstThread_->pvArg)) & 0x00FF));    //R24
    PUSH_TO_STACK(pucStack, (K_UCHAR)((((K_USHORT)(pstThread_->pvArg))>>8) & 0x00FF)); //R25

    // Push the rest of the registers in the context
    for (i = 26; i <=31; i++)
    {
        PUSH_TO_STACK(pucStack, i);
    }
    
    // Set the top o' the stack.
    pstThread_->pwStackTop = (K_UCHAR*)pucStack;

    // That's it!  the thread is ready to run now.
}
コード例 #2
0
ファイル: motif.c プロジェクト: E-LLP/QuIP
void push_nav(QSP_ARG_DECL  Gen_Win *gwp)
{
	Gen_Win *current_gwp;

	// We can push a viewer or anything!?
	//assert( GW_TYPE(NAVP_GW(np_p)) == GW_NAV_PANEL );

	if( nav_stack == NULL )
		nav_stack = new_stack();

	// We need to keep a stack of panels...
	if( (current_gwp=TOP_OF_STACK(nav_stack)) != NULL ){
		unshow_genwin(QSP_ARG  current_gwp);
	}

	PUSH_TO_STACK(nav_stack,gwp);
//fprintf(stderr,"showing associated panel %s\n",PO_NAME(NAVP_PANEL(gwp)));
	show_genwin(QSP_ARG  gwp);
}
コード例 #3
0
ファイル: threadport.c プロジェクト: moslevin/Mark3C
/*
    1) Setting up the Thread_t stacks

    Stack consists of 2 separate frames mashed together.
    a) Exception Stack Frame

    Contains the 8 registers the CPU pushes/pops to/from the stack on execution
    of an exception:

    [ XPSR ]
    [ PC   ]
    [ LR   ]
    [ R12  ]
    [ R3   ]
    [ R2   ]
    [ R1   ]
    [ R0   ]

    XPSR - Needs to be set to 0x01000000; the "T" bit (thumb) must be set for
           any Thread_t executing on an ARMv6-m processor
    PC - Should be set with the initial entry point for the Thread_t
    LR - The base link register.  We can leave this as 0, and set to 0xD on
         first context switch to tell the CPU to resume execution using the
         stack pointer held in the PSP as the regular stack.

    This is done by the CPU automagically- this format is part of the
    architecture, and there's nothing we can do to change or modify it.

    b) "Other" Register Context

    [ R11   ]
    ...
    [ R4    ]

    These are the other GP registers that need to be backed up/restored on a
    context switch, but aren't by default on a CM0 exception.  If there were
    any additional hardware registers to back up, then we'd also have to
    include them in this part of the context.

    These all need to be manually pushed to the stack on stack creation, and
    puhsed/pop as part of a normal context switch.
*/
void ThreadPort_InitStack(Thread_t *pclThread_)
{
	K_ULONG *pulStack;
	K_ULONG *pulTemp;
	K_ULONG ulAddr;
	K_USHORT i;

	// Get the entrypoint for the Thread_t
	ulAddr = (K_ULONG)(pclThread_->pfEntryPoint);

	// Get the top-of-stack pointer for the Thread_t
	pulStack = (K_ULONG*)pclThread_->pwStackTop;

	// Initialize the stack to all FF's to aid in stack depth checking
	pulTemp = (K_ULONG*)pclThread_->pwStack;
	for (i = 0; i < pclThread_->usStackSize / sizeof(K_ULONG); i++)
	{
		pulTemp[i] = 0xFFFFFFFF;
	}

	PUSH_TO_STACK(pulStack, 0);				// We need one word of padding, apparently...
	
	//-- Simulated Exception Stack Frame --
	PUSH_TO_STACK(pulStack, 0x01000000);	// XSPR
	PUSH_TO_STACK(pulStack, ulAddr);		// PC
    PUSH_TO_STACK(pulStack, 0);             // LR
	PUSH_TO_STACK(pulStack, 0x12);
	PUSH_TO_STACK(pulStack, 0x3);
    PUSH_TO_STACK(pulStack, 0x2);
	PUSH_TO_STACK(pulStack, 0x1);
	PUSH_TO_STACK(pulStack, (K_ULONG)pclThread_->pvArg);	// R0 = argument

	//-- Simulated Manually-Stacked Registers --
    PUSH_TO_STACK(pulStack, 0x11);
	PUSH_TO_STACK(pulStack, 0x10);
	PUSH_TO_STACK(pulStack, 0x09);
	PUSH_TO_STACK(pulStack, 0x08);
	PUSH_TO_STACK(pulStack, 0x07);
	PUSH_TO_STACK(pulStack, 0x06);
	PUSH_TO_STACK(pulStack, 0x05);
	PUSH_TO_STACK(pulStack, 0x04);
	pulStack++;

	pclThread_->pwStackTop = pulStack;
}