mirror of
https://github.com/t-crest/rtems.git
synced 2025-11-16 12:34:47 +00:00
Implemented clock ISR.
Fixed _CPU_Context_Initialize, _CPU_Context_Switch and _CPU_Context_Restore (stack and shadow stack management). Fixed linker missing symbols.
This commit is contained in:
@@ -23,14 +23,7 @@
|
||||
#include <bsp.h>
|
||||
|
||||
void Clock_exit( void );
|
||||
rtems_isr Clock_isr( rtems_vector_number vector );
|
||||
|
||||
/*
|
||||
* The interrupt vector number associated with the clock tick device
|
||||
* driver.
|
||||
*/
|
||||
|
||||
#define CLOCK_VECTOR 4
|
||||
rtems_isr Clock_isr( rtems_vector_number vector )__attribute__((naked));
|
||||
|
||||
/*
|
||||
* Clock_driver_ticks is a monotonically increasing counter of the
|
||||
@@ -64,22 +57,248 @@ rtems_isr_entry Old_ticker;
|
||||
|
||||
void Clock_exit( void );
|
||||
|
||||
void set_cpu_cycles (u64 time_warp)
|
||||
{
|
||||
|
||||
__PATMOS_RTC_WR_CYCLE_LOW((unsigned int)time_warp);
|
||||
__PATMOS_RTC_WR_CYCLE_UP((unsigned int)(time_warp >> 32));
|
||||
|
||||
}
|
||||
|
||||
u64 get_cpu_cycles(void)
|
||||
{
|
||||
unsigned int u;
|
||||
unsigned int l;
|
||||
|
||||
__PATMOS_RTC_RD_CYCLE_LOW(l);
|
||||
__PATMOS_RTC_RD_CYCLE_UP(u);
|
||||
|
||||
return (((u64)u) << 32) | l;
|
||||
}
|
||||
|
||||
u64 get_cpu_time(void)
|
||||
{
|
||||
unsigned int u;
|
||||
unsigned int l;
|
||||
|
||||
__PATMOS_RTC_RD_TIME_LOW(l);
|
||||
__PATMOS_RTC_RD_TIME_UP(u);
|
||||
|
||||
return (((u64)u) << 32) | l;
|
||||
}
|
||||
|
||||
uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
||||
{
|
||||
uint32_t usecs;
|
||||
|
||||
usecs = get_cpu_time() - Clock_driver_ticks*rtems_configuration_get_microseconds_per_tick();
|
||||
|
||||
return usecs * 1000;
|
||||
}
|
||||
|
||||
#define Clock_driver_nanoseconds_since_last_tick \
|
||||
bsp_clock_nanoseconds_since_last_tick
|
||||
|
||||
/*
|
||||
* Isr Handler
|
||||
* Clock_isr
|
||||
*
|
||||
* This is the clock tick interrupt handler.
|
||||
*
|
||||
* Input parameters:
|
||||
* vector - vector number
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* Return values: NONE
|
||||
*/
|
||||
|
||||
rtems_isr Clock_isr(
|
||||
rtems_vector_number vector
|
||||
)
|
||||
{
|
||||
/*
|
||||
* bump the number of clock driver ticks since initialization
|
||||
*
|
||||
* determine if it is time to announce the passing of tick as configured
|
||||
* to RTEMS through the rtems_clock_tick directive
|
||||
*
|
||||
* perform any timer dependent tasks
|
||||
*/
|
||||
/*
|
||||
* save general-purpose registers to the shadow stack
|
||||
* copy the current stack to memory and save the stack size to the shadow stack
|
||||
* save special-purpose registers to the shadow stack
|
||||
* reset r0 and update function return address base and offset registers r30 and r31
|
||||
*/
|
||||
asm volatile("sub $r29 = $r29, %0 \n\t" // offset shadow stack pointer
|
||||
"swm [ $r29 + %1 ] = $r0 \n\t" //save r0
|
||||
"swm [ $r29 + %2 ] = $r1 \n\t" //save r1
|
||||
"swm [ $r29 + %3 ] = $r2 \n\t" //save r2
|
||||
"swm [ $r29 + %4 ] = $r3 \n\t" //save r3
|
||||
"swm [ $r29 + %5 ] = $r4 \n\t" //save r4
|
||||
"swm [ $r29 + %6 ] = $r5 \n\t" //save r5
|
||||
"swm [ $r29 + %7 ] = $r6 \n\t" //save r6
|
||||
"swm [ $r29 + %8 ] = $r7 \n\t" //save r7
|
||||
"swm [ $r29 + %9 ] = $r8 \n\t" //save r8
|
||||
"swm [ $r29 + %10 ] = $r9 \n\t" //save r9
|
||||
"swm [ $r29 + %11 ] = $r10 \n\t" //save r10
|
||||
"swm [ $r29 + %12 ] = $r11 \n\t" //save r11
|
||||
"swm [ $r29 + %13 ] = $r12 \n\t" //save r12
|
||||
"swm [ $r29 + %14 ] = $r13 \n\t" //save r13
|
||||
"swm [ $r29 + %15 ] = $r14 \n\t" //save r14
|
||||
"swm [ $r29 + %16 ] = $r15 \n\t" //save r15
|
||||
"swm [ $r29 + %17 ] = $r16 \n\t" //save r16
|
||||
"swm [ $r29 + %18 ] = $r17 \n\t" //save r17
|
||||
"swm [ $r29 + %19 ] = $r18 \n\t" //save r18
|
||||
"swm [ $r29 + %20 ] = $r19 \n\t" //save r19
|
||||
"swm [ $r29 + %21 ] = $r20 \n\t" //save r20
|
||||
"swm [ $r29 + %22 ] = $r21 \n\t" //save r21
|
||||
"swm [ $r29 + %23 ] = $r22 \n\t" //save r22
|
||||
"swm [ $r29 + %24 ] = $r23 \n\t" //save r23
|
||||
"swm [ $r29 + %25 ] = $r24 \n\t" //save r24
|
||||
"swm [ $r29 + %26 ] = $r25 \n\t" //save r25
|
||||
"swm [ $r29 + %27 ] = $r26 \n\t" //save r26
|
||||
"swm [ $r29 + %28 ] = $r27 \n\t" //save r27
|
||||
"swm [ $r29 + %29 ] = $r28 \n\t" //save r28
|
||||
"swm [ $r29 + %30 ] = $r29 \n\t" //save r29
|
||||
"swm [ $r29 + %31 ] = $r30 \n\t" //save r30
|
||||
"swm [ $r29 + %32 ] = $r31 \n\t" //save r31
|
||||
"mfs $r5 = $s5 \n\t"
|
||||
"mfs $r6 = $s6 \n\t"
|
||||
"sub $r2 = $r5, $r6 \n\t" // get stack size
|
||||
"sspill $r2 \n\t"
|
||||
"swm [ $r29 + %33 ] = $r2 \n\t" //save stack size to memory
|
||||
"mfs $r1 = $s0 \n\t" //move s0 to r1
|
||||
"swm [ $r29 + %34 ] = $r1 \n\t" //save s0
|
||||
"mfs $r1 = $s1 \n\t" //move s1 to r1
|
||||
"swm [ $r29 + %35 ] = $r1 \n\t" //save s1
|
||||
"mfs $r1 = $s2 \n\t" //move s2 to r1
|
||||
"swm [ $r29 + %36 ] = $r1 \n\t" //save s2
|
||||
"mfs $r1 = $s3 \n\t" //move s3 to r1
|
||||
"swm [ $r29 + %37 ] = $r1 \n\t" //save s3
|
||||
"mfs $r1 = $s4 \n\t" //move s4 to r1
|
||||
"swm [ $r29 + %38 ] = $r1 \n\t" //save s4
|
||||
"mfs $r1 = $s5 \n\t" //move s5 to r1
|
||||
"swm [ $r29 + %39 ] = $r1 \n\t" //save s5
|
||||
"mfs $r1 = $s6 \n\t" //move s6 to r1
|
||||
"swm [ $r29 + %40 ] = $r1 \n\t" //save s6
|
||||
"mfs $r1 = $s7 \n\t" //move s7 to r1
|
||||
"swm [ $r29 + %41 ] = $r1 \n\t" //save s7
|
||||
"mfs $r1 = $s8 \n\t" //move s8 to r1
|
||||
"swm [ $r29 + %42 ] = $r1 \n\t" //save s8
|
||||
"mfs $r1 = $s9 \n\t" //move s9 to r1
|
||||
"swm [ $r29 + %43 ] = $r1 \n\t" //save s9
|
||||
"mfs $r1 = $s10 \n\t" //move s10 to r1
|
||||
"swm [ $r29 + %44 ] = $r1 \n\t" //save s10
|
||||
"mfs $r1 = $s11 \n\t" //move s11 to r1
|
||||
"swm [ $r29 + %45 ] = $r1 \n\t" //save s11
|
||||
"mfs $r1 = $s12 \n\t" //move s12 to r1
|
||||
"swm [ $r29 + %46 ] = $r1 \n\t" //save s12
|
||||
"mfs $r1 = $s13 \n\t" //move s13 to r1
|
||||
"swm [ $r29 + %47 ] = $r1 \n\t" //save s13
|
||||
"mfs $r1 = $s14 \n\t" //move s14 to r1
|
||||
"swm [ $r29 + %48 ] = $r1 \n\t" //save s14
|
||||
"mfs $r1 = $s15 \n\t" //move s15 to r1
|
||||
"swm [ $r29 + %49 ] = $r1 \n\t" //save s15
|
||||
"and $r0 = $r0, 0\n\t" //reset r0
|
||||
"li $r30 = Clock_isr\n\t" //set return address
|
||||
"li $r31 = restore_context\n\t"
|
||||
: : "i" (CONTEXT_OFFSET), "i" (r0_OFFSET), "i" (r1_OFFSET),"i" (r2_OFFSET), "i" (r3_OFFSET),
|
||||
"i" (r4_OFFSET), "i" (r5_OFFSET), "i" (r6_OFFSET), "i" (r7_OFFSET), "i" (r8_OFFSET),
|
||||
"i" (r9_OFFSET), "i" (r10_OFFSET), "i" (r11_OFFSET), "i" (r12_OFFSET), "i" (r13_OFFSET),
|
||||
"i" (r14_OFFSET), "i" (r15_OFFSET), "i" (r16_OFFSET), "i" (r17_OFFSET), "i" (r18_OFFSET),
|
||||
"i" (r19_OFFSET), "i" (r20_OFFSET), "i" (r21_OFFSET), "i" (r22_OFFSET), "i" (r23_OFFSET),
|
||||
"i" (r24_OFFSET), "i" (r25_OFFSET), "i" (r26_OFFSET), "i" (r27_OFFSET), "i" (r28_OFFSET),
|
||||
"i" (r29_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET), "i" (ssize_OFFSET), "i" (s0_OFFSET),
|
||||
"i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET), "i" (s4_OFFSET), "i" (s5_OFFSET),
|
||||
"i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET), "i" (s9_OFFSET), "i" (s10_OFFSET),
|
||||
"i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
/*
|
||||
* Accurate count of ISRs
|
||||
*/
|
||||
Clock_driver_ticks += 1;
|
||||
|
||||
__PATMOS_RTC_WR_INTERVAL(rtems_configuration_get_microseconds_per_tick() * PATMOS_FREQ_MHZ);
|
||||
|
||||
rtems_clock_tick();
|
||||
|
||||
/*
|
||||
* load general-purpose registers from the shadow stack
|
||||
* load special-purpose registers from the shadow stack cache
|
||||
*/
|
||||
asm volatile("restore_context: \n\t"
|
||||
"lwc $r0 = [ $r29 + %0 ] \n\t" //load r0
|
||||
"lwc $r2 = [ $r29 + %1 ] \n\t" //load r2
|
||||
"lwc $r3 = [ $r29 + %2 ] \n\t" //load r3
|
||||
"lwc $r4 = [ $r29 + %3 ] \n\t" //load r4
|
||||
"lwc $r5 = [ $r29 + %4 ] \n\t" //load r5
|
||||
"lwc $r6 = [ $r29 + %5 ] \n\t" //load r6
|
||||
"lwc $r7 = [ $r29 + %6 ] \n\t" //load r7
|
||||
"lwc $r8 = [ $r29 + %7 ] \n\t" //load r8
|
||||
"lwc $r9 = [ $r29 + %8 ] \n\t" //load r9
|
||||
"lwc $r10 = [ $r29 + %9 ] \n\t" //load r10
|
||||
"lwc $r11 = [ $r29 + %10 ] \n\t" //load r11
|
||||
"lwc $r12 = [ $r29 + %11 ] \n\t" //load r12
|
||||
"lwc $r13 = [ $r29 + %12 ] \n\t" //load r13
|
||||
"lwc $r14 = [ $r29 + %13 ] \n\t" //load r14
|
||||
"lwc $r15 = [ $r29 + %14 ] \n\t" //load r15
|
||||
"lwc $r16 = [ $r29 + %15 ] \n\t" //load r16
|
||||
"lwc $r17 = [ $r29 + %16 ] \n\t" //load r17
|
||||
"lwc $r18 = [ $r29 + %17 ] \n\t" //load r18
|
||||
"lwc $r19 = [ $r29 + %18 ] \n\t" //load r19
|
||||
"lwc $r20 = [ $r29 + %19 ] \n\t" //load r20
|
||||
"lwc $r21 = [ $r29 + %20 ] \n\t" //load r21
|
||||
"lwc $r22 = [ $r29 + %21 ] \n\t" //load r22
|
||||
"lwc $r23 = [ $r29 + %22 ] \n\t" //load r23
|
||||
"lwc $r24 = [ $r29 + %23 ] \n\t" //load r24
|
||||
"lwc $r25 = [ $r29 + %24 ] \n\t" //load r25
|
||||
"lwc $r26 = [ $r29 + %25 ] \n\t" //load r26
|
||||
"lwc $r27 = [ $r29 + %26 ] \n\t" //load r27
|
||||
"lwc $r28 = [ $r29 + %27 ] \n\t" //load r28
|
||||
"lwc $r30 = [ $r29 + %28 ] \n\t" //load r30
|
||||
"lwc $r31 = [ $r29 + %29 ] \n\t" //load r31
|
||||
"lwc $r1 = [ $r29 + %30 ] \n\t nop \n\t" //load s0
|
||||
"mts $s0 = $r1 \n\t" //move r1 to s0
|
||||
"lwc $r1 = [ $r29 + %31 ] \n\t nop \n\t" //load s1
|
||||
"mts $s1 = $r1 \n\t" //move r1 to s1
|
||||
"lwc $r1 = [ $r29 + %32 ] \n\t nop \n\t" //load s2
|
||||
"mts $s2 = $r1 \n\t" //move r1 to s2
|
||||
"lwc $r1 = [ $r29 + %33 ] \n\t nop \n\t" //load s3
|
||||
"mts $s3 = $r1 \n\t" //move r1 to s3
|
||||
"lwc $r1 = [ $r29 + %34 ] \n\t nop \n\t" //load s4
|
||||
"mts $s4 = $r1 \n\t" //move r1 to s4
|
||||
"lwc $r1 = [ $r29 + %35 ] \n\t nop \n\t" //load s5
|
||||
"mts $s5 = $r1 \n\t" //move r1 to s5
|
||||
"lwc $r1 = [ $r29 + %36 ] \n\t nop \n\t" //load s6
|
||||
"mts $s6 = $r1 \n\t" //move r1 to s6
|
||||
"lwc $r1 = [ $r29 + %37 ] \n\t nop \n\t" //load s7
|
||||
"mts $s7 = $r1 \n\t" //move r1 to s7
|
||||
"lwc $r1 = [ $r29 + %38 ] \n\t nop \n\t" //load s8
|
||||
"mts $s8 = $r1 \n\t" //move r1 to s8
|
||||
"lwc $r1 = [ $r29 + %39 ] \n\t nop \n\t" //load s10
|
||||
"mts $s10 = $r1 \n\t" //move r1 to s10
|
||||
"lwc $r1 = [ $r29 + %40 ] \n\t nop \n\t" //load s11
|
||||
"mts $s11 = $r1 \n\t" //move r1 to s11
|
||||
"lwc $r1 = [ $r29 + %41 ] \n\t nop \n\t" //load s12
|
||||
"mts $s12 = $r1 \n\t" //move r1 to s12
|
||||
"lwc $r1 = [ $r29 + %42 ] \n\t nop \n\t" //load s13
|
||||
"mts $s13 = $r1 \n\t" //move r1 to s13
|
||||
"lwc $r1 = [ $r29 + %43 ] \n\t nop \n\t" //load s14
|
||||
"mts $s14 = $r1 \n\t" //move r1 to s14
|
||||
"lwc $r1 = [ $r29 + %44 ] \n\t nop \n\t" //load s15
|
||||
"mts $s15 = $r1 \n\t" //move r1 to s15
|
||||
"lwm $r1 = [ $r29 + %45 ] \n\t nop \n\t" //load ssize
|
||||
"sens $r1 \n\t" //ensure the stack size in the stack cache
|
||||
"lwc $r1 = [ $r29 + %46 ] \n\t nop \n\t" //load s9
|
||||
"mts $s9 = $r1 \n\t" //move r1 to s9
|
||||
"lwc $r1 = [ $r29 + %47 ] \n\t" //load r1
|
||||
"ret $r1, $r0 \n\t" //return to s9 (r1 still has s9 due to lwc cycle delay slot)
|
||||
"lwc $r29 = [ $r29 + %48 ] \n\t nop \n\t" //load r29
|
||||
"add $r29 = $r29, %49 \n\t" // reset shadow stack pointer
|
||||
: : "i" (r0_OFFSET), "i" (r2_OFFSET), "i" (r3_OFFSET), "i" (r4_OFFSET), "i" (r5_OFFSET),
|
||||
"i" (r6_OFFSET), "i" (r7_OFFSET), "i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET),
|
||||
"i" (r11_OFFSET), "i" (r12_OFFSET), "i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET),
|
||||
"i" (r16_OFFSET), "i" (r17_OFFSET), "i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET),
|
||||
"i" (r21_OFFSET), "i" (r22_OFFSET), "i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET),
|
||||
"i" (r26_OFFSET), "i" (r27_OFFSET), "i" (r28_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET),
|
||||
"i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET), "i" (s4_OFFSET),
|
||||
"i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET), "i" (s10_OFFSET),
|
||||
"i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET), "i" (s15_OFFSET),
|
||||
"i" (ssize_OFFSET), "i" (s9_OFFSET), "i" (r1_OFFSET), "i" (r29_OFFSET), "i" (CONTEXT_OFFSET));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -100,11 +319,15 @@ void Install_clock(
|
||||
Clock_driver_ticks = 0;
|
||||
Clock_isrs = rtems_configuration_get_microseconds_per_tick() / 1000;
|
||||
|
||||
/*
|
||||
* Hardware specific initialize goes here
|
||||
*/
|
||||
__PATMOS_RTC_WR_ISR((uint32_t)clock_isr);
|
||||
|
||||
/* XXX */
|
||||
#if defined(Clock_driver_nanoseconds_since_last_tick)
|
||||
rtems_clock_set_nanoseconds_extension(
|
||||
Clock_driver_nanoseconds_since_last_tick
|
||||
);
|
||||
#endif
|
||||
|
||||
__PATMOS_RTC_WR_INTERVAL(rtems_configuration_get_microseconds_per_tick() * PATMOS_FREQ_MHZ);
|
||||
|
||||
/*
|
||||
* Schedule the clock cleanup routine to execute if the application exits.
|
||||
@@ -138,10 +361,6 @@ rtems_device_driver Clock_initialize(
|
||||
{
|
||||
Install_clock( Clock_isr );
|
||||
|
||||
/*
|
||||
* make major/minor avail to others such as shared memory driver
|
||||
*/
|
||||
|
||||
rtems_clock_major = major;
|
||||
rtems_clock_minor = minor;
|
||||
|
||||
|
||||
@@ -30,9 +30,6 @@ extern "C" {
|
||||
/* PATMOS CPU variant: PASIM */
|
||||
#define PASIM 1
|
||||
|
||||
#define STDOUT_FILENO 0 /* standard output file descriptor */
|
||||
#define STDERR_FILENO 1 /* standard error file descriptor */
|
||||
|
||||
/* Constants */
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,24 +22,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define PASIM_SHADOW_STACK_BASE 0x4000
|
||||
#define PASIM_STACK_CACHE_BASE 0x3000
|
||||
*/
|
||||
#define PASIM_SHADOW_STACK_BASE 0x4000000
|
||||
#define PASIM_STACK_CACHE_BASE 0x3000000
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
extern char _iomap_base; /* linker symbol giving the base address of the IO map address range */
|
||||
|
||||
#define _IODEV __attribute__((address_space(1)))
|
||||
|
||||
typedef _IODEV unsigned int volatile * const _iodev_ptr_t;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
extern char _uart_status_base; /* linker symbol giving the address of the UART status register */
|
||||
/*
|
||||
* UART Management
|
||||
*/
|
||||
|
||||
extern char _uart_data_base; /* linker symbol giving the address of the UART data register */
|
||||
extern char _iomap_base; /* linker symbol giving the base address of the IO map address range */
|
||||
|
||||
extern char _uart_base; /* linker symbol giving the address of the UART */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -52,8 +51,15 @@ extern char _uart_data_base; /* linker symbol giving the address of the UART dat
|
||||
#define __PATMOS_UART_PAE 4 /* Bit mask for the parity-error bit (PAE) */
|
||||
#define __PATMOS_UART_TFL 8 /* Bit mask for the transmit-flush bit (TFL) */
|
||||
|
||||
#define __PATMOS_UART_STATUS_ADDR (&_uart_status_base) /* Address to access the status register of the UART coming with Patmos */
|
||||
#define __PATMOS_UART_DATA_ADDR (&_uart_data_base) /* Address to access the data register of the UART coming with Patmos */
|
||||
/*
|
||||
* Address to access the status register of the UART coming with Patmos
|
||||
*/
|
||||
#define __PATMOS_UART_STATUS_ADDR (&_uart_base + 0x00)
|
||||
|
||||
/*
|
||||
* Address to access the data register of the UART coming with Patmos
|
||||
*/
|
||||
#define __PATMOS_UART_DATA_ADDR (&_uart_base + 0x04)
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
@@ -73,6 +79,69 @@ extern char _uart_data_base; /* linker symbol giving the address of the UART dat
|
||||
/* Macro to write the UART's data register */
|
||||
#define __PATMOS_UART_WR_DATA(data) *((_iodev_ptr_t)__PATMOS_UART_DATA_ADDR) = data;
|
||||
|
||||
/*
|
||||
* End of UART Management
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* RTC Management
|
||||
*/
|
||||
|
||||
extern char _timer_base; /* linker symbol giving the address of the RTC */
|
||||
|
||||
#define PATMOS_FREQ_MHZ 74
|
||||
#define PATMOS_FREQ_HZ ( PATMOS_FREQ_MHZ * 1000000U)
|
||||
|
||||
/* Address to access the cycle counter low register of the RTC */
|
||||
#define __PATMOS_RTC_CYCLE_LOW_ADDR (&_timer_base + 0x00)
|
||||
|
||||
/* Address to access the cycle counter up register of the RTC */
|
||||
#define __PATMOS_RTC_CYCLE_UP_ADDR (&_timer_base + 0x04)
|
||||
|
||||
/* Address to access the time in microseconds low register of the RTC */
|
||||
#define __PATMOS_RTC_TIME_LOW_ADDR (&_timer_base + 0x08)
|
||||
|
||||
/* Address to access the time in microseconds up register of the RTC */
|
||||
#define __PATMOS_RTC_TIME_UP_ADDR (&_timer_base + 0x0C)
|
||||
|
||||
/* Address to access the interrupt interval register of the RTC */
|
||||
#define __PATMOS_RTC_INTERVAL_ADDR (&_timer_base + 0x10)
|
||||
|
||||
/* Address to access the ISR address register of the RTC */
|
||||
#define __PATMOS_RTC_ISR_ADDR (&_timer_base + 0x14)
|
||||
|
||||
/* Macro to read the RTC's cycle counter low register of the RTC */
|
||||
#define __PATMOS_RTC_RD_CYCLE_LOW(res) res = *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_LOW_ADDR);
|
||||
|
||||
/* Macro to read the RTC's cycle counter up register of the RTC */
|
||||
#define __PATMOS_RTC_RD_CYCLE_UP(res) res = *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_UP_ADDR);
|
||||
|
||||
/* Macro to read the RTC's time in microseconds low register of the RTC */
|
||||
#define __PATMOS_RTC_RD_TIME_LOW(res) res = *((_iodev_ptr_t)__PATMOS_RTC_TIME_LOW_ADDR);
|
||||
|
||||
/* Macro to read the RTC's time in microseconds up register of the RTC */
|
||||
#define __PATMOS_RTC_RD_TIME_UP(res) res = *((_iodev_ptr_t)__PATMOS_RTC_TIME_UP_ADDR);
|
||||
|
||||
/* Macro to read the RTC's interrupt interval register */
|
||||
#define __PATMOS_RTC_RD_INTERVAL(interval) interval = *((_iodev_ptr_t)__PATMOS_RTC_INTERVAL_ADDR);
|
||||
|
||||
/* Macro to write the RTC's cycle counter low register */
|
||||
#define __PATMOS_RTC_WR_CYCLE_LOW(val) *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_LOW_ADDR) = val;
|
||||
|
||||
/* Macro to write the RTC's cycle counter up register */
|
||||
#define __PATMOS_RTC_WR_CYCLE_UP(val) *((_iodev_ptr_t)__PATMOS_RTC_CYCLE_UP_ADDR) = val;
|
||||
|
||||
/* Macro to write the RTC's interrupt interval register */
|
||||
#define __PATMOS_RTC_WR_INTERVAL(interval) *((_iodev_ptr_t)__PATMOS_RTC_INTERVAL_ADDR) = interval;
|
||||
|
||||
/* Macro to write the RTC's ISR address register */
|
||||
#define __PATMOS_RTC_WR_ISR(address) *((_iodev_ptr_t)__PATMOS_RTC_ISR_ADDR) = address;
|
||||
|
||||
/*
|
||||
* End of RTC Management
|
||||
*/
|
||||
|
||||
#endif /* !ASM */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -21,8 +21,10 @@ declare i32 @_close_r(%struct._reent* nocapture %ptr, i32 %fd) nounwind
|
||||
declare i32 @boot_card(i32 %argc, i8** nocapture %argv, i8** nocapture %envp) nounwind
|
||||
declare i32 @getdents(i32 %dd_fd, i32 %dd_buf, i32 %dd_len) nounwind
|
||||
declare i32 @_rename_r(%struct._reent* nocapture %ptr, i32 %old, i32 %new) nounwind
|
||||
declare i32 @rtems_clock_set_nanoseconds_extension(i32 ()* nocapture %routine) nounwind
|
||||
declare i32 @rtems_clock_tick() nounwind
|
||||
|
||||
@llvm.used = appending global [17 x i8*] [
|
||||
@llvm.used = appending global [19 x i8*] [
|
||||
i8* bitcast (i32 (i8*)* @rtems_termios_write to i8*),
|
||||
i8* bitcast (i32 (i8*, i32, i32)* @rtems_io_register_name to i8*),
|
||||
i8* bitcast (void ()* @libc_init to i8*),
|
||||
@@ -39,7 +41,9 @@ i8* bitcast (i32 (%struct._reent*, i32, i32, i32)* @_lseek_r to i8*),
|
||||
i8* bitcast (i32 (%struct._reent*, i32)* @_close_r to i8*),
|
||||
i8* bitcast (i32 (i32, i8**, i8**)* @boot_card to i8*),
|
||||
i8* bitcast (i32 (i32, i32, i32)* @getdents to i8*),
|
||||
i8* bitcast (i32 (%struct._reent*, i32, i32)* @_rename_r to i8*)
|
||||
i8* bitcast (i32 (%struct._reent*, i32, i32)* @_rename_r to i8*),
|
||||
i8* bitcast (i32 (i32()*)* @rtems_clock_set_nanoseconds_extension to i8*),
|
||||
i8* bitcast (i32 ()* @rtems_clock_tick to i8*)
|
||||
], section "llvm.metadata"
|
||||
|
||||
; End of libsyms.ll
|
||||
@@ -49,7 +49,7 @@ void _CPU_Initialize(void)
|
||||
|
||||
uint32_t _CPU_ISR_Get_level( void )
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -71,11 +71,11 @@ uint32_t _CPU_ISR_Get_level( void )
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
uint32_t vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
uint32_t vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -96,11 +96,11 @@ void _CPU_ISR_install_raw_handler(
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
uint32_t vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
uint32_t vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -122,338 +122,321 @@ void _CPU_ISR_install_vector(
|
||||
*/
|
||||
|
||||
void _CPU_Context_Initialize(
|
||||
Context_Control *the_context ,
|
||||
uint32_t *stack_base ,
|
||||
uint32_t size ,
|
||||
uint32_t new_level ,
|
||||
void *entry_point ,
|
||||
uint32_t *shadow_stack_base
|
||||
)
|
||||
Context_Control *the_context ,
|
||||
uint32_t *stack_base ,
|
||||
uint32_t size ,
|
||||
uint32_t new_level ,
|
||||
void *entry_point ,
|
||||
uint32_t *shadow_stack_base
|
||||
)
|
||||
{
|
||||
|
||||
/* set the shadow stack pointer */
|
||||
the_context->r29 = (uint32_t)shadow_stack_base;
|
||||
|
||||
/* set the stack pointer and spill pointer */
|
||||
the_context->s5 = (uint32_t)stack_base;
|
||||
the_context->s6 = (uint32_t)stack_base;
|
||||
|
||||
/* set the return address */
|
||||
the_context->r30 = (uint32_t)entry_point;
|
||||
uint32_t stack_high; /* highest "stack aligned" address */
|
||||
|
||||
/* set the stack size */
|
||||
the_context->ssize = 0;
|
||||
/*
|
||||
* On CPUs with stacks which grow down (i.e. PATMOS), we build the stack
|
||||
* based on the stack_high address.
|
||||
*/
|
||||
|
||||
stack_high = ((uint32_t)(stack_base) + size);
|
||||
stack_high &= ~(CPU_STACK_ALIGNMENT - 1);
|
||||
|
||||
/* set the shadow stack pointer */
|
||||
the_context->r29 = (uint32_t)shadow_stack_base;
|
||||
|
||||
/* set the stack pointer and spill pointer */
|
||||
the_context->s5 = stack_high;
|
||||
the_context->s6 = stack_high;
|
||||
|
||||
/* set the return address */
|
||||
the_context->r30 = (uint32_t)entry_point;
|
||||
|
||||
/* set the stack size */
|
||||
the_context->ssize = 0;
|
||||
}
|
||||
|
||||
void _CPU_Context_switch(
|
||||
Context_Control *run ,
|
||||
Context_Control *heir
|
||||
)
|
||||
Context_Control *run ,
|
||||
Context_Control *heir
|
||||
)
|
||||
{
|
||||
volatile unsigned int aux;
|
||||
|
||||
aux = (unsigned int) run;
|
||||
aux = aux + (unsigned int) heir;
|
||||
|
||||
/*
|
||||
* save general-purpose registers (skip r0 which is always 0)
|
||||
* address of the previous task is passed as function argument in register r3
|
||||
*/
|
||||
asm volatile("swm [ $r3 + %0 ] = $r1 \n\t" //save r1
|
||||
"swm [ $r3 + %1 ] = $r2 \n\t" //save r2
|
||||
"swm [ $r3 + %2 ] = $r3 \n\t" //save r3
|
||||
"swm [ $r3 + %3 ] = $r4 \n\t" //save r4
|
||||
"swm [ $r3 + %4 ] = $r5 \n\t" //save r5
|
||||
"swm [ $r3 + %5 ] = $r6 \n\t" //save r6
|
||||
"swm [ $r3 + %6 ] = $r7 \n\t" //save r7
|
||||
"swm [ $r3 + %7 ] = $r8 \n\t" //save r8
|
||||
"swm [ $r3 + %8 ] = $r9 \n\t" //save r9
|
||||
"swm [ $r3 + %9 ] = $r10 \n\t" //save r10
|
||||
"swm [ $r3 + %10 ] = $r11 \n\t" //save r11
|
||||
"swm [ $r3 + %11 ] = $r12 \n\t" //save r12
|
||||
"swm [ $r3 + %12 ] = $r13 \n\t" //save r13
|
||||
"swm [ $r3 + %13 ] = $r14 \n\t" //save r14
|
||||
"swm [ $r3 + %14 ] = $r15 \n\t" //save r15
|
||||
"swm [ $r3 + %15 ] = $r16 \n\t" //save r16
|
||||
"swm [ $r3 + %16 ] = $r17 \n\t" //save r17
|
||||
"swm [ $r3 + %17 ] = $r18 \n\t" //save r18
|
||||
"swm [ $r3 + %18 ] = $r19 \n\t" //save r19
|
||||
"swm [ $r3 + %19 ] = $r20 \n\t" //save r20
|
||||
"swm [ $r3 + %20 ] = $r21 \n\t" //save r21
|
||||
"swm [ $r3 + %21 ] = $r22 \n\t" //save r22
|
||||
"swm [ $r3 + %22 ] = $r23 \n\t" //save r23
|
||||
"swm [ $r3 + %23 ] = $r24 \n\t" //save r24
|
||||
"swm [ $r3 + %24 ] = $r25 \n\t" //save r25
|
||||
"swm [ $r3 + %25 ] = $r26 \n\t" //save r26
|
||||
"swm [ $r3 + %26 ] = $r27 \n\t" //save r27
|
||||
"swm [ $r3 + %27 ] = $r28 \n\t" //save r28
|
||||
"swm [ $r3 + %28 ] = $r29 \n\t" //save r29
|
||||
"swm [ $r3 + %29 ] = $r30 \n\t" //save r30
|
||||
"swm [ $r3 + %30 ] = $r31 \n\t" //save r31
|
||||
: : "i" (r1_OFFSET),"i" (r2_OFFSET), "i" (r3_OFFSET), "i" (r4_OFFSET), "i" (r5_OFFSET),
|
||||
"i" (r6_OFFSET), "i" (r7_OFFSET), "i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET),
|
||||
"i" (r11_OFFSET), "i" (r12_OFFSET), "i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET),
|
||||
"i" (r16_OFFSET), "i" (r17_OFFSET), "i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET),
|
||||
"i" (r21_OFFSET), "i" (r22_OFFSET), "i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET),
|
||||
"i" (r26_OFFSET), "i" (r27_OFFSET), "i" (r28_OFFSET), "i" (r29_OFFSET), "i" (r30_OFFSET),
|
||||
"i" (r31_OFFSET));
|
||||
asm volatile("swm [ %0 + %1 ] = $r1 \n\t" //save r1
|
||||
"swm [ %0 + %2 ] = $r2 \n\t" //save r2
|
||||
"swm [ %0 + %3 ] = $r3 \n\t" //save r3
|
||||
"swm [ %0 + %4 ] = $r4 \n\t" //save r4
|
||||
"swm [ %0 + %5 ] = $r5 \n\t" //save r5
|
||||
"swm [ %0 + %6 ] = $r6 \n\t" //save r6
|
||||
"swm [ %0 + %7 ] = $r7 \n\t" //save r7
|
||||
"swm [ %0 + %8 ] = $r8 \n\t" //save r8
|
||||
"swm [ %0 + %9 ] = $r9 \n\t" //save r9
|
||||
"swm [ %0 + %10 ] = $r10 \n\t" //save r10
|
||||
"swm [ %0 + %11 ] = $r11 \n\t" //save r11
|
||||
"swm [ %0 + %12 ] = $r12 \n\t" //save r12
|
||||
"swm [ %0 + %13 ] = $r13 \n\t" //save r13
|
||||
"swm [ %0 + %14 ] = $r14 \n\t" //save r14
|
||||
"swm [ %0 + %15 ] = $r15 \n\t" //save r15
|
||||
"swm [ %0 + %16 ] = $r16 \n\t" //save r16
|
||||
"swm [ %0 + %17 ] = $r17 \n\t" //save r17
|
||||
"swm [ %0 + %18 ] = $r18 \n\t" //save r18
|
||||
"swm [ %0 + %19 ] = $r19 \n\t" //save r19
|
||||
"swm [ %0 + %20 ] = $r20 \n\t" //save r20
|
||||
"swm [ %0 + %21 ] = $r21 \n\t" //save r21
|
||||
"swm [ %0 + %22 ] = $r22 \n\t" //save r22
|
||||
"swm [ %0 + %23 ] = $r23 \n\t" //save r23
|
||||
"swm [ %0 + %24 ] = $r24 \n\t" //save r24
|
||||
"swm [ %0 + %25 ] = $r25 \n\t" //save r25
|
||||
"swm [ %0 + %26 ] = $r26 \n\t" //save r26
|
||||
"swm [ %0 + %27 ] = $r27 \n\t" //save r27
|
||||
"swm [ %0 + %28 ] = $r28 \n\t" //save r28
|
||||
"swm [ %0 + %29 ] = $r29 \n\t" //save r29
|
||||
"swm [ %0 + %30 ] = $r30 \n\t" //save r30
|
||||
"swm [ %0 + %31 ] = $r31 \n\t" //save r31
|
||||
: : "r" (run), "i" (r1_OFFSET),"i" (r2_OFFSET), "i" (r3_OFFSET), "i" (r4_OFFSET),
|
||||
"i" (r5_OFFSET), "i" (r6_OFFSET), "i" (r7_OFFSET), "i" (r8_OFFSET), "i" (r9_OFFSET),
|
||||
"i" (r10_OFFSET), "i" (r11_OFFSET), "i" (r12_OFFSET), "i" (r13_OFFSET), "i" (r14_OFFSET),
|
||||
"i" (r15_OFFSET), "i" (r16_OFFSET), "i" (r17_OFFSET), "i" (r18_OFFSET), "i" (r19_OFFSET),
|
||||
"i" (r20_OFFSET), "i" (r21_OFFSET), "i" (r22_OFFSET), "i" (r23_OFFSET), "i" (r24_OFFSET),
|
||||
"i" (r25_OFFSET), "i" (r26_OFFSET), "i" (r27_OFFSET), "i" (r28_OFFSET), "i" (r29_OFFSET),
|
||||
"i" (r30_OFFSET), "i" (r31_OFFSET));
|
||||
|
||||
/*
|
||||
* copy the current stack to memory and save the stack size to the Context_Control struct in memory
|
||||
*/
|
||||
asm volatile("mfs $r5 = $s5 \n\t"
|
||||
"mfs $r6 = $s6 \n\t"
|
||||
"sub $r2 = $r5, $r6 \n\t" // get stack size
|
||||
"sspill $r2 \n\t"
|
||||
"swm [ $r3 + %0 ] = $r2 \n\t" //save stack size to memory
|
||||
: : "i" (ssize_OFFSET));
|
||||
|
||||
"mfs $r6 = $s6 \n\t"
|
||||
"sub $r2 = $r5, $r6 \n\t" // get stack size
|
||||
"sspill $r2 \n\t"
|
||||
"swm [ %0 + %1 ] = $r2 \n\t" //save stack size to memory
|
||||
: : "r" (run), "i" (ssize_OFFSET));
|
||||
|
||||
/*
|
||||
* save special-purpose registers
|
||||
* use r1 as intermediate register to save special-purpose registers (no instruction to do it directly)
|
||||
*/
|
||||
asm volatile("mfs $r1 = $s0 \n\t" //move s0 to r1
|
||||
"swm [ $r3 + %0 ] = $r1 \n\t" //save s0
|
||||
"mfs $r1 = $s1 \n\t" //move s1 to r1
|
||||
"swm [ $r3 + %1 ] = $r1 \n\t" //save s1
|
||||
"mfs $r1 = $s2 \n\t" //move s2 to r1
|
||||
"swm [ $r3 + %2 ] = $r1 \n\t" //save s2
|
||||
"mfs $r1 = $s3 \n\t" //move s3 to r1
|
||||
"swm [ $r3 + %3 ] = $r1 \n\t" //save s3
|
||||
"mfs $r1 = $s4 \n\t" //move s4 to r1
|
||||
"swm [ $r3 + %4 ] = $r1 \n\t" //save s4
|
||||
"mfs $r1 = $s5 \n\t" //move s5 to r1
|
||||
"swm [ $r3 + %5 ] = $r1 \n\t" //save s5
|
||||
"mfs $r1 = $s6 \n\t" //move s6 to r1
|
||||
"swm [ $r3 + %6 ] = $r1 \n\t" //save s6
|
||||
"mfs $r1 = $s7 \n\t" //move s7 to r1
|
||||
"swm [ $r3 + %7 ] = $r1 \n\t" //save s7
|
||||
"mfs $r1 = $s8 \n\t" //move s8 to r1
|
||||
"swm [ $r3 + %8 ] = $r1 \n\t" //save s8
|
||||
"mfs $r1 = $s9 \n\t" //move s9 to r1
|
||||
"swm [ $r3 + %9 ] = $r1 \n\t" //save s9
|
||||
"mfs $r1 = $s10 \n\t" //move s10 to r1
|
||||
"swm [ $r3 + %10 ] = $r1 \n\t" //save s10
|
||||
"mfs $r1 = $s11 \n\t" //move s11 to r1
|
||||
"swm [ $r3 + %11 ] = $r1 \n\t" //save s11
|
||||
"mfs $r1 = $s12 \n\t" //move s12 to r1
|
||||
"swm [ $r3 + %12 ] = $r1 \n\t" //save s12
|
||||
"mfs $r1 = $s13 \n\t" //move s13 to r1
|
||||
"swm [ $r3 + %13 ] = $r1 \n\t" //save s13
|
||||
"mfs $r1 = $s14 \n\t" //move s14 to r1
|
||||
"swm [ $r3 + %14 ] = $r1 \n\t" //save s14
|
||||
"mfs $r1 = $s15 \n\t" //move s15 to r1
|
||||
"swm [ $r3 + %15 ] = $r1 \n\t" //save s15
|
||||
: : "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET),
|
||||
"i" (s4_OFFSET), "i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET),
|
||||
"i" (s8_OFFSET), "i" (s9_OFFSET), "i" (s10_OFFSET),"i" (s11_OFFSET),
|
||||
"i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
asm volatile("mfs $r1 = $s0 \n\t" //move s0 to r1
|
||||
"swm [ %0 + %1 ] = $r1 \n\t" //save s0
|
||||
"mfs $r1 = $s1 \n\t" //move s1 to r1
|
||||
"swm [ %0 + %2 ] = $r1 \n\t" //save s1
|
||||
"mfs $r1 = $s2 \n\t" //move s2 to r1
|
||||
"swm [ %0 + %3 ] = $r1 \n\t" //save s2
|
||||
"mfs $r1 = $s3 \n\t" //move s3 to r1
|
||||
"swm [ %0 + %4 ] = $r1 \n\t" //save s3
|
||||
"mfs $r1 = $s4 \n\t" //move s4 to r1
|
||||
"swm [ %0 + %5 ] = $r1 \n\t" //save s4
|
||||
"mfs $r1 = $s5 \n\t" //move s5 to r1
|
||||
"swm [ %0 + %6 ] = $r1 \n\t" //save s5
|
||||
"mfs $r1 = $s6 \n\t" //move s6 to r1
|
||||
"swm [ %0 + %7 ] = $r1 \n\t" //save s6
|
||||
"mfs $r1 = $s7 \n\t" //move s7 to r1
|
||||
"swm [ %0 + %8 ] = $r1 \n\t" //save s7
|
||||
"mfs $r1 = $s8 \n\t" //move s8 to r1
|
||||
"swm [ %0 + %9 ] = $r1 \n\t" //save s8
|
||||
"mfs $r1 = $s9 \n\t" //move s9 to r1
|
||||
"swm [ %0 + %10 ] = $r1 \n\t" //save s9
|
||||
"mfs $r1 = $s10 \n\t" //move s10 to r1
|
||||
"swm [ %0 + %11 ] = $r1 \n\t" //save s10
|
||||
"mfs $r1 = $s11 \n\t" //move s11 to r1
|
||||
"swm [ %0 + %12 ] = $r1 \n\t" //save s11
|
||||
"mfs $r1 = $s12 \n\t" //move s12 to r1
|
||||
"swm [ %0 + %13 ] = $r1 \n\t" //save s12
|
||||
"mfs $r1 = $s13 \n\t" //move s13 to r1
|
||||
"swm [ %0 + %14 ] = $r1 \n\t" //save s13
|
||||
"mfs $r1 = $s14 \n\t" //move s14 to r1
|
||||
"swm [ %0 + %15 ] = $r1 \n\t" //save s14
|
||||
"mfs $r1 = $s15 \n\t" //move s15 to r1
|
||||
"swm [ %0 + %16 ] = $r1 \n\t" //save s15
|
||||
: : "r" (run), "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET),
|
||||
"i" (s4_OFFSET), "i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET),
|
||||
"i" (s9_OFFSET), "i" (s10_OFFSET),"i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET),
|
||||
"i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
/*
|
||||
* load general-purpose registers (skip r0 which is always 0)
|
||||
* address of the current task is passed as function argument in register r4
|
||||
* r4 is the last register to be loaded so that the memory address of the current task is not lost
|
||||
* r1 will be used as auxiliary register, so it is not loaded yet
|
||||
*/
|
||||
asm volatile("lwc $r2 = [ $r4 + %0 ] \n\t" //load r2
|
||||
"lwc $r3 = [ $r4 + %1 ] \n\t" //load r3
|
||||
"lwc $r5 = [ $r4 + %2 ] \n\t" //load r5
|
||||
"lwc $r6 = [ $r4 + %3 ] \n\t" //load r6
|
||||
"lwc $r7 = [ $r4 + %4 ] \n\t" //load r7
|
||||
"lwc $r8 = [ $r4 + %5 ] \n\t" //load r8
|
||||
"lwc $r9 = [ $r4 + %6 ] \n\t" //load r9
|
||||
"lwc $r10 = [ $r4 + %7 ] \n\t" //load r10
|
||||
"lwc $r11 = [ $r4 + %8 ] \n\t" //load r11
|
||||
"lwc $r12 = [ $r4 + %9 ] \n\t" //load r12
|
||||
"lwc $r13 = [ $r4 + %10 ] \n\t" //load r13
|
||||
"lwc $r14 = [ $r4 + %11 ] \n\t" //load r14
|
||||
"lwc $r15 = [ $r4 + %12 ] \n\t" //load r15
|
||||
"lwc $r16 = [ $r4 + %13 ] \n\t" //load r16
|
||||
"lwc $r17 = [ $r4 + %14 ] \n\t" //load r17
|
||||
"lwc $r18 = [ $r4 + %15 ] \n\t" //load r18
|
||||
"lwc $r19 = [ $r4 + %16 ] \n\t" //load r19
|
||||
"lwc $r20 = [ $r4 + %17 ] \n\t" //load r20
|
||||
"lwc $r21 = [ $r4 + %18 ] \n\t" //load r21
|
||||
"lwc $r22 = [ $r4 + %19 ] \n\t" //load r22
|
||||
"lwc $r23 = [ $r4 + %20 ] \n\t" //load r23
|
||||
"lwc $r24 = [ $r4 + %21 ] \n\t" //load r24
|
||||
"lwc $r25 = [ $r4 + %22 ] \n\t" //load r25
|
||||
"lwc $r26 = [ $r4 + %23 ] \n\t" //load r26
|
||||
"lwc $r27 = [ $r4 + %24 ] \n\t" //load r27
|
||||
"lwc $r28 = [ $r4 + %25 ] \n\t" //load r28
|
||||
"lwc $r29 = [ $r4 + %26 ] \n\t" //load r29
|
||||
"lwc $r30 = [ $r4 + %27 ] \n\t" //load r30
|
||||
"lwc $r31 = [ $r4 + %28 ] \n\t" //load r31
|
||||
: : "i" (r2_OFFSET), "i" (r3_OFFSET), "i" (r5_OFFSET), "i" (r6_OFFSET), "i" (r7_OFFSET),
|
||||
"i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET), "i" (r11_OFFSET), "i" (r12_OFFSET),
|
||||
"i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET), "i" (r16_OFFSET), "i" (r17_OFFSET),
|
||||
"i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET), "i" (r21_OFFSET), "i" (r22_OFFSET),
|
||||
"i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET), "i" (r26_OFFSET), "i" (r27_OFFSET),
|
||||
"i" (r28_OFFSET), "i" (r29_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET));
|
||||
asm volatile("lwc $r2 = [ %0 + %1 ] \n\t" //load r2
|
||||
"lwc $r3 = [ %0 + %2 ] \n\t" //load r3
|
||||
"lwc $r5 = [ %0 + %3 ] \n\t" //load r5
|
||||
"lwc $r6 = [ %0 + %4 ] \n\t" //load r6
|
||||
"lwc $r7 = [ %0 + %5 ] \n\t" //load r7
|
||||
"lwc $r8 = [ %0 + %6 ] \n\t" //load r8
|
||||
"lwc $r9 = [ %0 + %7 ] \n\t" //load r9
|
||||
"lwc $r10 = [ %0 + %8 ] \n\t" //load r10
|
||||
"lwc $r11 = [ %0 + %9 ] \n\t" //load r11
|
||||
"lwc $r12 = [ %0 + %10 ] \n\t" //load r12
|
||||
"lwc $r13 = [ %0 + %11 ] \n\t" //load r13
|
||||
"lwc $r14 = [ %0 + %12 ] \n\t" //load r14
|
||||
"lwc $r15 = [ %0 + %13 ] \n\t" //load r15
|
||||
"lwc $r16 = [ %0 + %14 ] \n\t" //load r16
|
||||
"lwc $r17 = [ %0 + %15 ] \n\t" //load r17
|
||||
"lwc $r18 = [ %0 + %16 ] \n\t" //load r18
|
||||
"lwc $r19 = [ %0 + %17 ] \n\t" //load r19
|
||||
"lwc $r20 = [ %0 + %18 ] \n\t" //load r20
|
||||
"lwc $r21 = [ %0 + %19 ] \n\t" //load r21
|
||||
"lwc $r22 = [ %0 + %20 ] \n\t" //load r22
|
||||
"lwc $r23 = [ %0 + %21 ] \n\t" //load r23
|
||||
"lwc $r24 = [ %0 + %22 ] \n\t" //load r24
|
||||
"lwc $r25 = [ %0 + %23 ] \n\t" //load r25
|
||||
"lwc $r26 = [ %0 + %24 ] \n\t" //load r26
|
||||
"lwc $r27 = [ %0 + %25 ] \n\t" //load r27
|
||||
"lwc $r28 = [ %0 + %26 ] \n\t" //load r28
|
||||
"lwc $r29 = [ %0 + %27 ] \n\t" //load r29
|
||||
"lwc $r30 = [ %0 + %28 ] \n\t" //load r30
|
||||
"lwc $r31 = [ %0 + %29 ] \n\t" //load r31
|
||||
: : "r" (heir), "i" (r2_OFFSET), "i" (r3_OFFSET), "i" (r5_OFFSET), "i" (r6_OFFSET),
|
||||
"i" (r7_OFFSET), "i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET), "i" (r11_OFFSET),
|
||||
"i" (r12_OFFSET), "i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET), "i" (r16_OFFSET),
|
||||
"i" (r17_OFFSET), "i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET), "i" (r21_OFFSET),
|
||||
"i" (r22_OFFSET), "i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET), "i" (r26_OFFSET),
|
||||
"i" (r27_OFFSET), "i" (r28_OFFSET), "i" (r29_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET));
|
||||
|
||||
asm volatile("lwm $r1 = [ $r4 + %0 ] \n\t" //load ssize
|
||||
"sens $r1 \n\t" //ensure the stack size in the stack cache
|
||||
: : "i" (ssize_OFFSET));
|
||||
|
||||
/*
|
||||
* load special-purpose registers
|
||||
* use r1 as intermediate register to load special-purpose registers (no instruction to do it directly)
|
||||
*/
|
||||
asm volatile("lwc $r1 = [ $r4 + %0 ] \n\t" //load s0
|
||||
"mts $s0 = $r1 \n\t" //move r1 to s0
|
||||
"lwc $r1 = [ $r4 + %1 ] \n\t" //load s1
|
||||
"mts $s1 = $r1 \n\t" //move r1 to s1
|
||||
"lwc $r1 = [ $r4 + %2 ] \n\t" //load s2
|
||||
"mts $s2 = $r1 \n\t" //move r1 to s2
|
||||
"lwc $r1 = [ $r4 + %3 ] \n\t" //load s3
|
||||
"mts $s3 = $r1 \n\t" //move r1 to s3
|
||||
"lwc $r1 = [ $r4 + %4 ] \n\t" //load s4
|
||||
"mts $s4 = $r1 \n\t" //move r1 to s4
|
||||
"lwc $r1 = [ $r4 + %5 ] \n\t" //load s5
|
||||
"mts $s5 = $r1 \n\t" //move r1 to s5
|
||||
"lwc $r1 = [ $r4 + %6 ] \n\t" //load s6
|
||||
"mts $s6 = $r1 \n\t" //move r1 to s6
|
||||
"lwc $r1 = [ $r4 + %7 ] \n\t" //load s7
|
||||
"mts $s7 = $r1 \n\t" //move r1 to s7
|
||||
"lwc $r1 = [ $r4 + %8 ] \n\t" //load s8
|
||||
"mts $s8 = $r1 \n\t" //move r1 to s8
|
||||
"lwc $r1 = [ $r4 + %9 ] \n\t" //load s9
|
||||
"mts $s9 = $r1 \n\t" //move r1 to s9
|
||||
"lwc $r1 = [ $r4 + %10 ] \n\t" //load s10
|
||||
"mts $s10 = $r1 \n\t" //move r1 to s10
|
||||
"lwc $r1 = [ $r4 + %11 ] \n\t" //load s11
|
||||
"mts $s11 = $r1 \n\t" //move r1 to s11
|
||||
"lwc $r1 = [ $r4 + %12 ] \n\t" //load s12
|
||||
"mts $s12 = $r1 \n\t" //move r1 to s12
|
||||
"lwc $r1 = [ $r4 + %13 ] \n\t" //load s13
|
||||
"mts $s13 = $r1 \n\t" //move r1 to s13
|
||||
"lwc $r1 = [ $r4 + %14 ] \n\t" //load s14
|
||||
"mts $s14 = $r1 \n\t" //move r1 to s14
|
||||
"lwc $r1 = [ $r4 + %15 ] \n\t" //load s15
|
||||
"mts $s15 = $r1 \n\t" //move r1 to s15
|
||||
: : "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET), "i" (s4_OFFSET),
|
||||
"i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET), "i" (s9_OFFSET),
|
||||
"i" (s10_OFFSET), "i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET),
|
||||
"i" (s15_OFFSET));
|
||||
|
||||
/*
|
||||
* restore the thread's stack into the stack cache
|
||||
* use r1 to store the size of the thread's stack
|
||||
* use r2 and r3 as intermediate registers to load special-purpose registers (no instruction to do it directly)
|
||||
*/
|
||||
asm volatile(//"mfs $r2 = $s6 \n\t" //store the stack cache's top pointer in auxiliary register r2
|
||||
//"mfs $r3 = $s5 \n\t" //store the stack cache's bottom pointer in auxiliary register r3
|
||||
//"sub $r1 = $r2, $r3 \n\t" //store the size of the thread's stack
|
||||
//"mts $s6 = $r3 \n\t" //make stack cache's bottom and top pointers equal to each other
|
||||
//"sens $r1 \n\t" //restores the thread's stack into the stack cache
|
||||
//"mts $s6 = $r2 \n\t" //restore the stack cache's top pointer from auxiliary register r2
|
||||
"lwc $r1 = [ $r4 + %0 ] \n\t" //load r1
|
||||
"lwc $r4 = [ $r4 + %1 ] \n\t" //load r4
|
||||
: : "i" (r1_OFFSET), "i" (r4_OFFSET));
|
||||
|
||||
asm volatile("lwc $r1 = [ %0 + %1 ] \n\t nop \n\t" //load s0
|
||||
"mts $s0 = $r1 \n\t" //move r1 to s0
|
||||
"lwc $r1 = [ %0 + %2 ] \n\t nop \n\t" //load s1
|
||||
"mts $s1 = $r1 \n\t" //move r1 to s1
|
||||
"lwc $r1 = [ %0 + %3 ] \n\t nop \n\t" //load s2
|
||||
"mts $s2 = $r1 \n\t" //move r1 to s2
|
||||
"lwc $r1 = [ %0 + %4 ] \n\t nop \n\t" //load s3
|
||||
"mts $s3 = $r1 \n\t" //move r1 to s3
|
||||
"lwc $r1 = [ %0 + %5 ] \n\t nop \n\t" //load s4
|
||||
"mts $s4 = $r1 \n\t" //move r1 to s4
|
||||
"lwc $r1 = [ %0 + %6 ] \n\t nop \n\t" //load s5
|
||||
"mts $s5 = $r1 \n\t" //move r1 to s5
|
||||
"lwc $r1 = [ %0 + %7 ] \n\t nop \n\t" //load s6
|
||||
"mts $s6 = $r1 \n\t" //move r1 to s6
|
||||
"lwc $r1 = [ %0 + %8 ] \n\t nop \n\t" //load s7
|
||||
"mts $s7 = $r1 \n\t" //move r1 to s7
|
||||
"lwc $r1 = [ %0 + %9 ] \n\t nop \n\t" //load s8
|
||||
"mts $s8 = $r1 \n\t" //move r1 to s8
|
||||
"lwc $r1 = [ %0 + %10 ] \n\t nop \n\t" //load s9
|
||||
"mts $s9 = $r1 \n\t" //move r1 to s9
|
||||
"lwc $r1 = [ %0 + %11 ] \n\t nop \n\t" //load s10
|
||||
"mts $s10 = $r1 \n\t" //move r1 to s10
|
||||
"lwc $r1 = [ %0 + %12 ] \n\t nop \n\t" //load s11
|
||||
"mts $s11 = $r1 \n\t" //move r1 to s11
|
||||
"lwc $r1 = [ %0 + %13 ] \n\t nop \n\t" //load s12
|
||||
"mts $s12 = $r1 \n\t" //move r1 to s12
|
||||
"lwc $r1 = [ %0 + %14 ] \n\t nop \n\t" //load s13
|
||||
"mts $s13 = $r1 \n\t" //move r1 to s13
|
||||
"lwc $r1 = [ %0 + %15 ] \n\t nop \n\t" //load s14
|
||||
"mts $s14 = $r1 \n\t" //move r1 to s14
|
||||
"lwc $r1 = [ %0 + %16 ] \n\t nop \n\t" //load s15
|
||||
"mts $s15 = $r1 \n\t" //move r1 to s15
|
||||
: : "r" (heir), "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET),
|
||||
"i" (s4_OFFSET), "i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET),
|
||||
"i" (s9_OFFSET), "i" (s10_OFFSET), "i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET),
|
||||
"i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
asm volatile("lwm $r1 = [ %0 + %1 ] \n\t nop \n\t" //load ssize
|
||||
"sens $r1 \n\t" //ensure the stack size in the stack cache
|
||||
"lwc $r1 = [ %0 + %2 ] \n\t" //load r1
|
||||
"lwc $r4 = [ %0 + %3 ] \n\t" //load r4
|
||||
: : "r" (heir), "i" (ssize_OFFSET), "i" (r1_OFFSET), "i" (r4_OFFSET));
|
||||
|
||||
}
|
||||
|
||||
void _CPU_Context_restore(
|
||||
Context_Control *new_context
|
||||
)
|
||||
Context_Control *new_context
|
||||
)
|
||||
{
|
||||
volatile unsigned int aux;
|
||||
|
||||
aux = (unsigned int) new_context + 1;
|
||||
|
||||
/*
|
||||
* load general-purpose registers (skip r0 which is always 0)
|
||||
* address of the current task is passed as function argument in register r3
|
||||
* r3 is the last register to be loaded so that the memory address of the current task is not lost
|
||||
* r1 will be used as auxiliary register, so it is not loaded yet
|
||||
*/
|
||||
asm volatile("lwc $r2 = [ $r3 + %0 ] \n\t" //load r2
|
||||
"lwc $r4 = [ $r3 + %1 ] \n\t" //load r4
|
||||
"lwc $r5 = [ $r3 + %2 ] \n\t" //load r5
|
||||
"lwc $r6 = [ $r3 + %3 ] \n\t" //load r6
|
||||
"lwc $r7 = [ $r3 + %4 ] \n\t" //load r7
|
||||
"lwc $r8 = [ $r3 + %5 ] \n\t" //load r8
|
||||
"lwc $r9 = [ $r3 + %6 ] \n\t" //load r9
|
||||
"lwc $r10 = [ $r3 + %7 ] \n\t" //load r10
|
||||
"lwc $r11 = [ $r3 + %8 ] \n\t" //load r11
|
||||
"lwc $r12 = [ $r3 + %9 ] \n\t" //load r12
|
||||
"lwc $r13 = [ $r3 + %10 ] \n\t" //load r13
|
||||
"lwc $r14 = [ $r3 + %11 ] \n\t" //load r14
|
||||
"lwc $r15 = [ $r3 + %12 ] \n\t" //load r15
|
||||
"lwc $r16 = [ $r3 + %13 ] \n\t" //load r16
|
||||
"lwc $r17 = [ $r3 + %14 ] \n\t" //load r17
|
||||
"lwc $r18 = [ $r3 + %15 ] \n\t" //load r18
|
||||
"lwc $r19 = [ $r3 + %16 ] \n\t" //load r19
|
||||
"lwc $r20 = [ $r3 + %17 ] \n\t" //load r20
|
||||
"lwc $r21 = [ $r3 + %18 ] \n\t" //load r21
|
||||
"lwc $r22 = [ $r3 + %19 ] \n\t" //load r22
|
||||
"lwc $r23 = [ $r3 + %20 ] \n\t" //load r23
|
||||
"lwc $r24 = [ $r3 + %21 ] \n\t" //load r24
|
||||
"lwc $r25 = [ $r3 + %22 ] \n\t" //load r25
|
||||
"lwc $r26 = [ $r3 + %23 ] \n\t" //load r26
|
||||
"lwc $r27 = [ $r3 + %24 ] \n\t" //load r27
|
||||
"lwc $r28 = [ $r3 + %25 ] \n\t" //load r28
|
||||
"lwc $r29 = [ $r3 + %26 ] \n\t" //load r29
|
||||
"lwc $r30 = [ $r3 + %27 ] \n\t" //load r30
|
||||
"lwc $r31 = [ $r3 + %28 ] \n\t" //load r31
|
||||
: : "i" (r2_OFFSET), "i" (r4_OFFSET), "i" (r5_OFFSET), "i" (r6_OFFSET), "i" (r7_OFFSET),
|
||||
"i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET), "i" (r11_OFFSET), "i" (r12_OFFSET),
|
||||
"i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET), "i" (r16_OFFSET), "i" (r17_OFFSET),
|
||||
"i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET), "i" (r21_OFFSET), "i" (r22_OFFSET),
|
||||
"i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET), "i" (r26_OFFSET), "i" (r27_OFFSET),
|
||||
"i" (r28_OFFSET), "i" (r29_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET));
|
||||
|
||||
asm volatile("lwm $r1 = [ $r3 + %0 ] \n\t" //load ssize
|
||||
"sens $r1 \n\t" //ensure the stack size in the stack cache
|
||||
: : "i" (ssize_OFFSET));
|
||||
asm volatile("lwc $r2 = [ %0 + %1 ] \n\t" //load r2
|
||||
"lwc $r4 = [ %0 + %2 ] \n\t" //load r4
|
||||
"lwc $r5 = [ %0 + %3 ] \n\t" //load r5
|
||||
"lwc $r6 = [ %0 + %4 ] \n\t" //load r6
|
||||
"lwc $r7 = [ %0 + %5 ] \n\t" //load r7
|
||||
"lwc $r8 = [ %0 + %6 ] \n\t" //load r8
|
||||
"lwc $r9 = [ %0 + %7 ] \n\t" //load r9
|
||||
"lwc $r10 = [ %0 + %8 ] \n\t" //load r10
|
||||
"lwc $r11 = [ %0 + %9 ] \n\t" //load r11
|
||||
"lwc $r12 = [ %0 + %10 ] \n\t" //load r12
|
||||
"lwc $r13 = [ %0 + %11 ] \n\t" //load r13
|
||||
"lwc $r14 = [ %0 + %12 ] \n\t" //load r14
|
||||
"lwc $r15 = [ %0 + %13 ] \n\t" //load r15
|
||||
"lwc $r16 = [ %0 + %14 ] \n\t" //load r16
|
||||
"lwc $r17 = [ %0 + %15 ] \n\t" //load r17
|
||||
"lwc $r18 = [ %0 + %16 ] \n\t" //load r18
|
||||
"lwc $r19 = [ %0 + %17 ] \n\t" //load r19
|
||||
"lwc $r20 = [ %0 + %18 ] \n\t" //load r20
|
||||
"lwc $r21 = [ %0 + %19 ] \n\t" //load r21
|
||||
"lwc $r22 = [ %0 + %20 ] \n\t" //load r22
|
||||
"lwc $r23 = [ %0 + %21 ] \n\t" //load r23
|
||||
"lwc $r24 = [ %0 + %22 ] \n\t" //load r24
|
||||
"lwc $r25 = [ %0 + %23 ] \n\t" //load r25
|
||||
"lwc $r26 = [ %0 + %24 ] \n\t" //load r26
|
||||
"lwc $r27 = [ %0 + %25 ] \n\t" //load r27
|
||||
"lwc $r28 = [ %0 + %26 ] \n\t" //load r28
|
||||
"lwc $r29 = [ %0 + %27 ] \n\t" //load r29
|
||||
"lwc $r30 = [ %0 + %28 ] \n\t" //load r30
|
||||
"lwc $r31 = [ %0 + %29 ] \n\t" //load r31
|
||||
: : "r" (new_context), "i" (r2_OFFSET), "i" (r4_OFFSET), "i" (r5_OFFSET), "i" (r6_OFFSET),
|
||||
"i" (r7_OFFSET), "i" (r8_OFFSET), "i" (r9_OFFSET), "i" (r10_OFFSET), "i" (r11_OFFSET),
|
||||
"i" (r12_OFFSET), "i" (r13_OFFSET), "i" (r14_OFFSET), "i" (r15_OFFSET), "i" (r16_OFFSET),
|
||||
"i" (r17_OFFSET), "i" (r18_OFFSET), "i" (r19_OFFSET), "i" (r20_OFFSET), "i" (r21_OFFSET),
|
||||
"i" (r22_OFFSET), "i" (r23_OFFSET), "i" (r24_OFFSET), "i" (r25_OFFSET), "i" (r26_OFFSET),
|
||||
"i" (r27_OFFSET), "i" (r28_OFFSET), "i" (r29_OFFSET), "i" (r30_OFFSET), "i" (r31_OFFSET));
|
||||
|
||||
/*
|
||||
* load special-purpose registers
|
||||
* load special-purpose registers
|
||||
* use r1 as intermediate register to load special-purpose registers (no instruction to do it directly)
|
||||
*/
|
||||
asm volatile("lwc $r1 = [ $r3 + %0 ] \n\t" //load s0
|
||||
"mts $s0 = $r1 \n\t" //move r1 to s0
|
||||
"lwc $r1 = [ $r3 + %1 ] \n\t" //load s1
|
||||
"mts $s1 = $r1 \n\t" //move r1 to s1
|
||||
"lwc $r1 = [ $r3 + %2 ] \n\t" //load s2
|
||||
"mts $s2 = $r1 \n\t" //move r1 to s2
|
||||
"lwc $r1 = [ $r3 + %3 ] \n\t" //load s3
|
||||
"mts $s3 = $r1 \n\t" //move r1 to s3
|
||||
"lwc $r1 = [ $r3 + %4 ] \n\t" //load s4
|
||||
"mts $s4 = $r1 \n\t" //move r1 to s4
|
||||
"lwc $r1 = [ $r3 + %5 ] \n\t" //load s5
|
||||
"mts $s5 = $r1 \n\t" //move r1 to s5
|
||||
"lwc $r1 = [ $r3 + %6 ] \n\t" //load s6
|
||||
"mts $s6 = $r1 \n\t" //move r1 to s6
|
||||
"lwc $r1 = [ $r3 + %7 ] \n\t" //load s7
|
||||
"mts $s7 = $r1 \n\t" //move r1 to s7
|
||||
"lwc $r1 = [ $r3 + %8 ] \n\t" //load s8
|
||||
"mts $s8 = $r1 \n\t" //move r1 to s8
|
||||
"lwc $r1 = [ $r3 + %9 ] \n\t" //load s9
|
||||
"mts $s9 = $r1 \n\t" //move r1 to s9
|
||||
"lwc $r1 = [ $r3 + %10 ] \n\t" //load s10
|
||||
"mts $s10 = $r1 \n\t" //move r1 to s10
|
||||
"lwc $r1 = [ $r3 + %11 ] \n\t" //load s11
|
||||
"mts $s11 = $r1 \n\t" //move r1 to s11
|
||||
"lwc $r1 = [ $r3 + %12 ] \n\t" //load s12
|
||||
"mts $s12 = $r1 \n\t" //move r1 to s12
|
||||
"lwc $r1 = [ $r3 + %13 ] \n\t" //load s13
|
||||
"mts $s13 = $r1 \n\t" //move r1 to s13
|
||||
"lwc $r1 = [ $r3 + %14 ] \n\t" //load s14
|
||||
"mts $s14 = $r1 \n\t" //move r1 to s14
|
||||
"lwc $r1 = [ $r3 + %15 ] \n\t" //load s15
|
||||
"mts $s15 = $r1 \n\t" //move r1 to s15
|
||||
: : "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET), "i" (s4_OFFSET),
|
||||
"i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET), "i" (s9_OFFSET),
|
||||
"i" (s10_OFFSET), "i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET), "i" (s14_OFFSET),
|
||||
"i" (s15_OFFSET));
|
||||
|
||||
/*
|
||||
* restore r1 and r3
|
||||
*/
|
||||
asm volatile("lwc $r1 = [ $r3 + %0 ] \n\t" //load r1
|
||||
"lwc $r3 = [ $r3 + %1 ] \n\t" //load r3
|
||||
: : "i" (r1_OFFSET), "i" (r3_OFFSET));
|
||||
asm volatile("lwc $r1 = [ %0 + %1 ] \n\t nop \n\t" //load s0
|
||||
"mts $s0 = $r1 \n\t" //move r1 to s0
|
||||
"lwc $r1 = [ %0 + %2 ] \n\t nop \n\t" //load s1
|
||||
"mts $s1 = $r1 \n\t" //move r1 to s1
|
||||
"lwc $r1 = [ %0 + %3 ] \n\t nop \n\t" //load s2
|
||||
"mts $s2 = $r1 \n\t" //move r1 to s2
|
||||
"lwc $r1 = [ %0 + %4 ] \n\t nop \n\t" //load s3
|
||||
"mts $s3 = $r1 \n\t" //move r1 to s3
|
||||
"lwc $r1 = [ %0 + %5 ] \n\t nop \n\t" //load s4
|
||||
"mts $s4 = $r1 \n\t" //move r1 to s4
|
||||
"lwc $r1 = [ %0 + %6 ] \n\t nop \n\t" //load s5
|
||||
"mts $s5 = $r1 \n\t" //move r1 to s5
|
||||
"lwc $r1 = [ %0 + %7 ] \n\t nop \n\t" //load s6
|
||||
"mts $s6 = $r1 \n\t" //move r1 to s6
|
||||
"lwc $r1 = [ %0 + %8 ] \n\t nop \n\t" //load s7
|
||||
"mts $s7 = $r1 \n\t" //move r1 to s7
|
||||
"lwc $r1 = [ %0 + %9 ] \n\t nop \n\t" //load s8
|
||||
"mts $s8 = $r1 \n\t" //move r1 to s8
|
||||
"lwc $r1 = [ %0 + %10 ] \n\t nop \n\t" //load s9
|
||||
"mts $s9 = $r1 \n\t" //move r1 to s9
|
||||
"lwc $r1 = [ %0 + %11 ] \n\t nop \n\t" //load s10
|
||||
"mts $s10 = $r1 \n\t" //move r1 to s10
|
||||
"lwc $r1 = [ %0 + %12 ] \n\t nop \n\t" //load s11
|
||||
"mts $s11 = $r1 \n\t" //move r1 to s11
|
||||
"lwc $r1 = [ %0 + %13 ] \n\t nop \n\t" //load s12
|
||||
"mts $s12 = $r1 \n\t" //move r1 to s12
|
||||
"lwc $r1 = [ %0 + %14 ] \n\t nop \n\t" //load s13
|
||||
"mts $s13 = $r1 \n\t" //move r1 to s13
|
||||
"lwc $r1 = [ %0 + %15 ] \n\t nop \n\t" //load s14
|
||||
"mts $s14 = $r1 \n\t" //move r1 to s14
|
||||
"lwc $r1 = [ %0 + %16 ] \n\t nop \n\t" //load s15
|
||||
"mts $s15 = $r1 \n\t" //move r1 to s15
|
||||
: : "r" (new_context), "i" (s0_OFFSET), "i" (s1_OFFSET), "i" (s2_OFFSET), "i" (s3_OFFSET),
|
||||
"i" (s4_OFFSET), "i" (s5_OFFSET), "i" (s6_OFFSET), "i" (s7_OFFSET), "i" (s8_OFFSET),
|
||||
"i" (s9_OFFSET), "i" (s10_OFFSET), "i" (s11_OFFSET), "i" (s12_OFFSET), "i" (s13_OFFSET),
|
||||
"i" (s14_OFFSET), "i" (s15_OFFSET));
|
||||
|
||||
asm volatile("lwm $r1 = [ %0 + %1 ] \n\t nop \n\t" //load ssize
|
||||
"sens $r1 \n\t" //ensure the stack size in the stack cache
|
||||
"lwc $r1 = [ %0 + %2 ] \n\t" //load r1
|
||||
"lwc $r3 = [ %0 + %3 ] \n\t" //load r3
|
||||
: : "r" (new_context), "i" (ssize_OFFSET), "i" (r1_OFFSET), "i" (r3_OFFSET));
|
||||
|
||||
}
|
||||
|
||||
void abort_trap()
|
||||
|
||||
@@ -335,12 +335,16 @@ typedef struct {
|
||||
|
||||
#define ssize_OFFSET 47
|
||||
|
||||
#define r0_OFFSET 48
|
||||
|
||||
/*
|
||||
* context control size (in number of bytes)
|
||||
*/
|
||||
|
||||
#define CONTEXT_CONTROL_SIZE 192
|
||||
|
||||
#define CONTEXT_OFFSET 200
|
||||
|
||||
/**
|
||||
*
|
||||
* This macro returns the stack pointer associated with _context.
|
||||
@@ -541,7 +545,7 @@ SCORE_EXTERN volatile uint32_t _CPU_ISR_Dispatch_disable;
|
||||
* NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
|
||||
*/
|
||||
|
||||
#define CPU_STACK_ALIGNMENT 0
|
||||
#define CPU_STACK_ALIGNMENT 16
|
||||
|
||||
#ifndef ASM
|
||||
|
||||
|
||||
Reference in New Issue
Block a user