📄 cpu.c
字号:
/*
; -------------------------------------------------------------------
; File: cpu.c
;
; SPARCLite-specific stuff for the uC/OS Real-time multitasking kernel
;
; Written by Brad Denniston (bradd@vpeng.com) Sept 1998
; Based on MIPS port by Phil Bunce
; -------------------------------------------------------------------
*/
#include "ucos.h"
#include "cpu.h"
#include "bsp.h"
uint debval1;
uint debval2;
uint debval3;
uint debval4;
/* REMOVE */ uint OSIntNesting = 0; /* defined in os.c */
PFV IRQVector[] =
{
0, /* 0 */
0, /* 1 */
0, /* 2 */
0, /* 3 */
0, /* 4 */
0, /* 5 */
0, /* 6 */
0, /* 7 */
0, /* 8 */
0, /* 9 */
0, /* 10 */
OSTimeTick, /* 11 */
0, /* 12 */
0, /* 13 */
0, /* 14 */
0 /* 15 */
};
/*
; -------------------------------------------------------------------
; CPUInit - set the processor up. This calls BSPInit.
; -------------------------------------------------------------------
*/
void
CPUInit()
{
int interrupt_number;
BSPInit();
/* Set up one interrupt handler for all hardware interrupts */
#if 0
for(interrupt_number = 1; interrupt_number < 16; interrupt_number++ )
{
exceptionHandler( interrupt_number + 16, IRQTrap );
}
#else
interrupt_number = 11;
exceptionHandler( interrupt_number + 16, IRQTrap );
#endif
}
/*
; -------------------------------------------------------------------
; Interrupt service routine dispatcher.
;
; This is the IRQ handler called by IRQTrap when hardware interrupts occur.
; InterruptNumber - 1 thru 15 are legal. 11 is the timer.
; Note: When this is called, higher level interrupts may occur causing nesting
;
; Return:
; 1 (any non-zero) if context switch needed
; -------------------------------------------------------------------
*/
int
CPUDispatchIRQ( uint InterruptNumber )
{
char ch;
/* increment nesting counter */
OSIntNesting++;
/* call registered interrupt handler */
if (InterruptNumber > 0 && InterruptNumber < 16 && IRQVector[InterruptNumber])
{
(*(IRQVector[InterruptNumber]))();
}
return( OSIntExit() );
} /* DispatchIRQ */
/*
; -------------------------------------------------------------------
; PFV IRQInstall - Install and enable a new Interrupt Service Routine.
;
; int IRQNum - interrupt request number
; PFV ISRFun - new interrupt handler
;
; Return:
; The old interrupt service routine address.
; -------------------------------------------------------------------
*/
PFV
IRQInstall( int IRQNumber, PFV ISRFunction )
{
PFV OldISR;
/* Sanity check */
if (IRQNumber < 1 || IRQNumber >= 15)
return((PFV)0);
/* Get old ISR function */
OldISR = IRQVector[IRQNumber];
/* Replace with new ISR function */
IRQVector[IRQNumber] = ISRFunction;
#if 0
/* Enable the interrupt */ BRAD - TBD
IRQIntEnable( IRQNumber );
#endif
return( OldISR );
} /* IRQInstall */
/*
; -------------------------------------------------------------------
; GetTbr - assembly language routine to get value of tbr
; Leafless function - no register context switch
; -------------------------------------------------------------------
*/
asm("
.text
.align 8
.global _GetTbr
_GetTbr:
retl
mov %tbr, %o0
");
/*
; -------------------------------------------------------------------
; Getfp - assembly language routine to get value of fp
; Leafless function - no register context switch
; -------------------------------------------------------------------
*/
asm("
.text
.align 8
.global _Getfp
_Getfp:
retl
mov %fp, %o0
");
/*
; -------------------------------------------------------------------
; GetPsr - assembly language routine to get value of psr
; Leafless function - no register context switch
; -------------------------------------------------------------------
*/
asm("
.text
.align 8
.global _GetPsr
_GetPsr:
retl
mov %psr, %o0
");
/*
; -------------------------------------------------------------------
; uint *BuildNewStack(uint *stk,PTV task,void *pdata)
; This will be the first register window.
; Must set %pc, %psr and %sp.
; Values of other registers does not matter.
; Put pointer to task name into the return value (%o0).
; -------------------------------------------------------------------
*/
uint *BuildNewStack(uint *stk,PTV task,void *pdata)
{
uint *frame_pointer;
frame_pointer = stk;
stk -= DEFAULT_STACK_FRAME; /* reserve space on stack for reg win */
/* (stk +35..+31) %psr, %wim, %y, %tbr */
/* use current %psr and %tbr */
*(stk + 35) = GetPsr(); /* TRAPS ENABLED */
/* %y don't care, %wim will be computed at startup */
*(stk + 32) = GetTbr();
/* (stk +31..+24) %o7..%o0 */
*(stk + 31) = (uint)task - 8; /* %o7 - Task entry point for retl */
*(stk + 30) = (uint)(stk); /* %o6 - Task stack address */
/* %o5..%o1 - don't care */
*(stk + 24) = (uint)pdata; /* %o0 - stack name into return value */
/* (stk +23..+16) %g7..%g0 */
/* %g7..%g0 - don't care */
/* (stk +8..+15) %i7..%i0 */
*(stk + 15) = 0; /* %i7 - RETURN ADDRESS??? - need task killer */
*(stk + 14) = (uint)frame_pointer; /* %i6 - use initial stack pointer */
*(stk + 8) = (uint)pdata; /* %i0 - pass pointer to task name */
/* (stk +7..+0) %l7..%l0 */
/* %l7..%l0 - don't care */
return(stk);
}
/*
; -------------------------------------------------------------------
; itoa - converts integer to a string, 32 characters max
; -------------------------------------------------------------------
*/
void
itoa (
uint value,
char *buffer,
uint base
)
{
char *pbuf, *ptmp;
char tmp[32];
char least_sig_digit;
ptmp = tmp;
if( value == 0 )
*ptmp++ = '0';
else while( value > 0 )
{
least_sig_digit = (char)(value - (value/base * base));
value = value / base;
*ptmp++ = least_sig_digit + 0x30;
}
pbuf = buffer;
while( ptmp > tmp )
*pbuf++ = *--ptmp;
*pbuf = 0;
}
/*
; -------------------------------------------------------------------
; putstr
; -------------------------------------------------------------------
*/
void
putstr( char *buf )
{
while( *buf )
putchar( *buf++ );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -