parent
ea26beda5f
commit
78354caede
@ -0,0 +1,175 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* Run in FLASH */
|
||||||
|
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 16k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 6k
|
||||||
|
|
||||||
|
/* Run in RAM */
|
||||||
|
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 4k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20001000, LENGTH = 2K
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 1K;
|
||||||
|
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ilalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _ilm_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ialign :
|
||||||
|
{
|
||||||
|
PROVIDE( _ilm = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.fini)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE (etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . ); /*0X2000,0340*/
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
} >ram AT>ram
|
||||||
|
}
|
@ -0,0 +1,175 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* Run in FLASH */
|
||||||
|
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 32k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 10k
|
||||||
|
|
||||||
|
/* Run in RAM */
|
||||||
|
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 7k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20001C00, LENGTH = 3K
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 1K;
|
||||||
|
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ilalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _ilm_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ialign :
|
||||||
|
{
|
||||||
|
PROVIDE( _ilm = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.fini)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE (etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . ); /*0X2000,0340*/
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
} >ram AT>ram
|
||||||
|
}
|
@ -0,0 +1,175 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* Run in FLASH */
|
||||||
|
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 64k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 20k
|
||||||
|
|
||||||
|
/* Run in RAM */
|
||||||
|
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 15k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20003C00, LENGTH = 5K
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||||
|
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ilalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _ilm_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ialign :
|
||||||
|
{
|
||||||
|
PROVIDE( _ilm = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.fini)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE (etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . ); /*0X2000,0340*/
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
} >ram AT>ram
|
||||||
|
}
|
@ -0,0 +1,175 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
ENTRY( _start )
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* Run in FLASH */
|
||||||
|
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K
|
||||||
|
|
||||||
|
/* Run in RAM */
|
||||||
|
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||||
|
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ilalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _ilm_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ialign :
|
||||||
|
{
|
||||||
|
PROVIDE( _ilm = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.fini)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE (etext = .);/*0x80022c8*/
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _eilm = . );
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800);
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . ); /*0X2000,0340*/
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
} >ram AT>ram
|
||||||
|
}
|
@ -0,0 +1,286 @@
|
|||||||
|
// See LICENSE for license details
|
||||||
|
|
||||||
|
#ifndef ENTRY_S
|
||||||
|
#define ENTRY_S
|
||||||
|
|
||||||
|
#include "riscv_encoding.h"
|
||||||
|
#include "riscv_bits.h"
|
||||||
|
#include "n200_eclic.h"
|
||||||
|
#include "n200_timer.h"
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
# Disable Interrupt
|
||||||
|
#
|
||||||
|
.macro DISABLE_MIE
|
||||||
|
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
#Save caller registers
|
||||||
|
.macro SAVE_CONTEXT
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
#if (__riscv_flen==64 )
|
||||||
|
addi sp, sp, -20*REGBYTES - 20*FPREGBYTES
|
||||||
|
#else
|
||||||
|
addi sp, sp, -20*REGBYTES
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
addi sp, sp, -20*REGBYTES
|
||||||
|
#endif
|
||||||
|
STORE x1, 0*REGBYTES(sp)
|
||||||
|
STORE x4, 1*REGBYTES(sp)
|
||||||
|
STORE x5, 2*REGBYTES(sp)
|
||||||
|
STORE x6, 3*REGBYTES(sp)
|
||||||
|
STORE x7, 4*REGBYTES(sp)
|
||||||
|
STORE x10, 5*REGBYTES(sp)
|
||||||
|
STORE x11, 6*REGBYTES(sp)
|
||||||
|
STORE x12, 7*REGBYTES(sp)
|
||||||
|
STORE x13, 8*REGBYTES(sp)
|
||||||
|
STORE x14, 9*REGBYTES(sp)
|
||||||
|
STORE x15, 10*REGBYTES(sp)
|
||||||
|
#ifndef __riscv_32e
|
||||||
|
STORE x16, 11*REGBYTES(sp)
|
||||||
|
STORE x17, 12*REGBYTES(sp)
|
||||||
|
STORE x28, 13*REGBYTES(sp)
|
||||||
|
STORE x29, 14*REGBYTES(sp)
|
||||||
|
STORE x30, 15*REGBYTES(sp)
|
||||||
|
STORE x31, 16*REGBYTES(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
#if (__riscv_flen == 64)
|
||||||
|
FPSTORE f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
|
||||||
|
FPSTORE f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
#restore caller registers
|
||||||
|
.macro RESTORE_CONTEXT
|
||||||
|
LOAD x1, 0*REGBYTES(sp)
|
||||||
|
LOAD x4, 1*REGBYTES(sp)
|
||||||
|
LOAD x5, 2*REGBYTES(sp)
|
||||||
|
LOAD x6, 3*REGBYTES(sp)
|
||||||
|
LOAD x7, 4*REGBYTES(sp)
|
||||||
|
LOAD x10, 5*REGBYTES(sp)
|
||||||
|
LOAD x11, 6*REGBYTES(sp)
|
||||||
|
LOAD x12, 7*REGBYTES(sp)
|
||||||
|
LOAD x13, 8*REGBYTES(sp)
|
||||||
|
LOAD x14, 9*REGBYTES(sp)
|
||||||
|
LOAD x15, 10*REGBYTES(sp)
|
||||||
|
#ifndef __riscv_32e
|
||||||
|
LOAD x16, 11*REGBYTES(sp)
|
||||||
|
LOAD x17, 12*REGBYTES(sp)
|
||||||
|
LOAD x28, 13*REGBYTES(sp)
|
||||||
|
LOAD x29, 14*REGBYTES(sp)
|
||||||
|
LOAD x30, 15*REGBYTES(sp)
|
||||||
|
LOAD x31, 16*REGBYTES(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
#if (__riscv_flen==64)
|
||||||
|
/* Restore fp caller registers */
|
||||||
|
FPLOAD f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
|
||||||
|
FPLOAD f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
#if(__riscv_flen == 64 )
|
||||||
|
addi sp, sp, 20*REGBYTES + 20*FPREGBYTES
|
||||||
|
#else
|
||||||
|
addi sp, sp, 20*REGBYTES
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// De-allocate the stack space
|
||||||
|
addi sp, sp, 20*REGBYTES
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
#restore caller registers
|
||||||
|
.macro RESTORE_CONTEXT_EXCPT_X5
|
||||||
|
LOAD x1, 0*REGBYTES(sp)
|
||||||
|
LOAD x6, 2*REGBYTES(sp)
|
||||||
|
LOAD x7, 3*REGBYTES(sp)
|
||||||
|
LOAD x10, 4*REGBYTES(sp)
|
||||||
|
LOAD x11, 5*REGBYTES(sp)
|
||||||
|
LOAD x12, 6*REGBYTES(sp)
|
||||||
|
LOAD x13, 7*REGBYTES(sp)
|
||||||
|
LOAD x14, 8*REGBYTES(sp)
|
||||||
|
LOAD x15, 9*REGBYTES(sp)
|
||||||
|
#ifndef __riscv_32e
|
||||||
|
LOAD x16, 10*REGBYTES(sp)
|
||||||
|
LOAD x17, 11*REGBYTES(sp)
|
||||||
|
LOAD x28, 12*REGBYTES(sp)
|
||||||
|
LOAD x29, 13*REGBYTES(sp)
|
||||||
|
LOAD x30, 14*REGBYTES(sp)
|
||||||
|
LOAD x31, 15*REGBYTES(sp)
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
#restore caller registers
|
||||||
|
.macro RESTORE_CONTEXT_ONLY_X5
|
||||||
|
LOAD x5, 1*REGBYTES(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
# Save the mepc and mstatus
|
||||||
|
#
|
||||||
|
.macro SAVE_EPC_STATUS
|
||||||
|
csrr x5, CSR_MEPC
|
||||||
|
STORE x5, 16*REGBYTES(sp)
|
||||||
|
csrr x5, CSR_MSTATUS
|
||||||
|
STORE x5, 17*REGBYTES(sp)
|
||||||
|
csrr x5, CSR_MSUBM
|
||||||
|
STORE x5, 18*REGBYTES(sp)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
# Restore the mepc and mstatus
|
||||||
|
#
|
||||||
|
.macro RESTORE_EPC_STATUS
|
||||||
|
LOAD x5, 16*REGBYTES(sp)
|
||||||
|
csrw CSR_MEPC, x5
|
||||||
|
LOAD x5, 17*REGBYTES(sp)
|
||||||
|
csrw CSR_MSTATUS, x5
|
||||||
|
LOAD x5, 18*REGBYTES(sp)
|
||||||
|
csrw CSR_MSUBM, x5
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
// Trap entry point
|
||||||
|
//
|
||||||
|
.section .text.trap
|
||||||
|
.align 6// In CLIC mode, the trap entry must be 64bytes aligned
|
||||||
|
.global trap_entry
|
||||||
|
.weak trap_entry
|
||||||
|
trap_entry:
|
||||||
|
// Allocate the stack space
|
||||||
|
// addi sp, sp, -19*REGBYTES
|
||||||
|
|
||||||
|
// Save the caller saving registers (context)
|
||||||
|
SAVE_CONTEXT
|
||||||
|
// Save the MEPC/Mstatus/Msubm reg
|
||||||
|
SAVE_EPC_STATUS
|
||||||
|
|
||||||
|
// Set the function argument
|
||||||
|
csrr a0, mcause
|
||||||
|
mv a1, sp
|
||||||
|
// Call the function
|
||||||
|
call handle_trap
|
||||||
|
|
||||||
|
// Restore the MEPC/Mstatus/Msubm reg
|
||||||
|
RESTORE_EPC_STATUS
|
||||||
|
// Restore the caller saving registers (context)
|
||||||
|
RESTORE_CONTEXT
|
||||||
|
|
||||||
|
// De-allocate the stack space
|
||||||
|
// addi sp, sp, 19*REGBYTES
|
||||||
|
// Return to regular code
|
||||||
|
mret
|
||||||
|
|
||||||
|
|
||||||
|
###############################################
|
||||||
|
###############################################
|
||||||
|
// IRQ entry point
|
||||||
|
//
|
||||||
|
.section .text.irq
|
||||||
|
.align 2
|
||||||
|
.global irq_entry
|
||||||
|
.weak irq_entry
|
||||||
|
irq_entry: // -------------> This label will be set to MTVT2 register
|
||||||
|
// Allocate the stack space
|
||||||
|
|
||||||
|
|
||||||
|
SAVE_CONTEXT// Save 16 regs
|
||||||
|
|
||||||
|
//------This special CSR read operation, which is actually use mcause as operand to directly store it to memory
|
||||||
|
csrrwi x0, CSR_PUSHMCAUSE, 17
|
||||||
|
//------This special CSR read operation, which is actually use mepc as operand to directly store it to memory
|
||||||
|
csrrwi x0, CSR_PUSHMEPC, 18
|
||||||
|
//------This special CSR read operation, which is actually use Msubm as operand to directly store it to memory
|
||||||
|
csrrwi x0, CSR_PUSHMSUBM, 19
|
||||||
|
|
||||||
|
service_loop:
|
||||||
|
//------This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest
|
||||||
|
// ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and
|
||||||
|
// update the link register
|
||||||
|
csrrw ra, CSR_JALMNXTI, ra
|
||||||
|
|
||||||
|
//RESTORE_CONTEXT_EXCPT_X5
|
||||||
|
|
||||||
|
#---- Critical section with interrupts disabled -----------------------
|
||||||
|
DISABLE_MIE # Disable interrupts
|
||||||
|
|
||||||
|
LOAD x5, 19*REGBYTES(sp)
|
||||||
|
csrw CSR_MSUBM, x5
|
||||||
|
LOAD x5, 18*REGBYTES(sp)
|
||||||
|
csrw CSR_MEPC, x5
|
||||||
|
LOAD x5, 17*REGBYTES(sp)
|
||||||
|
csrw CSR_MCAUSE, x5
|
||||||
|
|
||||||
|
|
||||||
|
RESTORE_CONTEXT
|
||||||
|
|
||||||
|
|
||||||
|
// Return to regular code
|
||||||
|
mret
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,32 @@
|
|||||||
|
//See LICENSE for license details.
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "riscv_encoding.h"
|
||||||
|
#include "n200_func.h"
|
||||||
|
|
||||||
|
__attribute__((weak)) uintptr_t handle_nmi()
|
||||||
|
{
|
||||||
|
write(1, "nmi\n", 5);
|
||||||
|
_exit(1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((weak)) uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp)
|
||||||
|
{
|
||||||
|
if((mcause & 0xFFF) == 0xFFF) {
|
||||||
|
handle_nmi();
|
||||||
|
}
|
||||||
|
write(1, "trap\n", 5);
|
||||||
|
//printf("In trap handler, the mcause is %d\n", mcause);
|
||||||
|
//printf("In trap handler, the mepc is 0x%x\n", read_csr(mepc));
|
||||||
|
//printf("In trap handler, the mtval is 0x%x\n", read_csr(mbadaddr));
|
||||||
|
_exit(mcause);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
//See LICENSE for license details.
|
||||||
|
#include <gd32vf103.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "riscv_encoding.h"
|
||||||
|
#include "n200_func.h"
|
||||||
|
|
||||||
|
extern uint32_t disable_mcycle_minstret();
|
||||||
|
void _init()
|
||||||
|
{
|
||||||
|
SystemInit();
|
||||||
|
|
||||||
|
//ECLIC init
|
||||||
|
eclic_init(ECLIC_NUM_INTERRUPTS);
|
||||||
|
eclic_mode_enable();
|
||||||
|
|
||||||
|
//printf("After ECLIC mode enabled, the mtvec value is %x \n\n\r", read_csr(mtvec));
|
||||||
|
|
||||||
|
// // It must be NOTED:
|
||||||
|
// // * In the RISC-V arch, if user mode and PMP supported, then by default if PMP is not configured
|
||||||
|
// // with valid entries, then user mode cannot access any memory, and cannot execute any instructions.
|
||||||
|
// // * So if switch to user-mode and still want to continue, then you must configure PMP first
|
||||||
|
//pmp_open_all_space();
|
||||||
|
//switch_m2u_mode();
|
||||||
|
|
||||||
|
/* Before enter into main, add the cycle/instret disable by default to save power,
|
||||||
|
only use them when needed to measure the cycle/instret */
|
||||||
|
disable_mcycle_minstret();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fini()
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,258 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#include "riscv_encoding.h"
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
|
||||||
|
.weak eclic_msip_handler
|
||||||
|
.weak eclic_mtip_handler
|
||||||
|
.weak eclic_bwei_handler
|
||||||
|
.weak eclic_pmovi_handler
|
||||||
|
.weak WWDGT_IRQHandler
|
||||||
|
.weak LVD_IRQHandler
|
||||||
|
.weak TAMPER_IRQHandler
|
||||||
|
.weak RTC_IRQHandler
|
||||||
|
.weak FMC_IRQHandler
|
||||||
|
.weak RCU_IRQHandler
|
||||||
|
.weak EXTI0_IRQHandler
|
||||||
|
.weak EXTI1_IRQHandler
|
||||||
|
.weak EXTI2_IRQHandler
|
||||||
|
.weak EXTI3_IRQHandler
|
||||||
|
.weak EXTI4_IRQHandler
|
||||||
|
.weak DMA0_Channel0_IRQHandler
|
||||||
|
.weak DMA0_Channel1_IRQHandler
|
||||||
|
.weak DMA0_Channel2_IRQHandler
|
||||||
|
.weak DMA0_Channel3_IRQHandler
|
||||||
|
.weak DMA0_Channel4_IRQHandler
|
||||||
|
.weak DMA0_Channel5_IRQHandler
|
||||||
|
.weak DMA0_Channel6_IRQHandler
|
||||||
|
.weak ADC0_1_IRQHandler
|
||||||
|
.weak CAN0_TX_IRQHandler
|
||||||
|
.weak CAN0_RX0_IRQHandler
|
||||||
|
.weak CAN0_RX1_IRQHandler
|
||||||
|
.weak CAN0_EWMC_IRQHandler
|
||||||
|
.weak EXTI5_9_IRQHandler
|
||||||
|
.weak TIMER0_BRK_IRQHandler
|
||||||
|
.weak TIMER0_UP_IRQHandler
|
||||||
|
.weak TIMER0_TRG_CMT_IRQHandler
|
||||||
|
.weak TIMER0_Channel_IRQHandler
|
||||||
|
.weak TIMER1_IRQHandler
|
||||||
|
.weak TIMER2_IRQHandler
|
||||||
|
.weak TIMER3_IRQHandler
|
||||||
|
.weak I2C0_EV_IRQHandler
|
||||||
|
.weak I2C0_ER_IRQHandler
|
||||||
|
.weak I2C1_EV_IRQHandler
|
||||||
|
.weak I2C1_ER_IRQHandler
|
||||||
|
.weak SPI0_IRQHandler
|
||||||
|
.weak SPI1_IRQHandler
|
||||||
|
.weak USART0_IRQHandler
|
||||||
|
.weak USART1_IRQHandler
|
||||||
|
.weak USART2_IRQHandler
|
||||||
|
.weak EXTI10_15_IRQHandler
|
||||||
|
.weak RTC_Alarm_IRQHandler
|
||||||
|
.weak USBFS_WKUP_IRQHandler
|
||||||
|
.weak EXMC_IRQHandler
|
||||||
|
.weak TIMER4_IRQHandler
|
||||||
|
.weak SPI2_IRQHandler
|
||||||
|
.weak UART3_IRQHandler
|
||||||
|
.weak UART4_IRQHandler
|
||||||
|
.weak TIMER5_IRQHandler
|
||||||
|
.weak TIMER6_IRQHandler
|
||||||
|
.weak DMA1_Channel0_IRQHandler
|
||||||
|
.weak DMA1_Channel1_IRQHandler
|
||||||
|
.weak DMA1_Channel2_IRQHandler
|
||||||
|
.weak DMA1_Channel3_IRQHandler
|
||||||
|
.weak DMA1_Channel4_IRQHandler
|
||||||
|
.weak CAN1_TX_IRQHandler
|
||||||
|
.weak CAN1_RX0_IRQHandler
|
||||||
|
.weak CAN1_RX1_IRQHandler
|
||||||
|
.weak CAN1_EWMC_IRQHandler
|
||||||
|
.weak USBFS_IRQHandler
|
||||||
|
|
||||||
|
vector_base:
|
||||||
|
j _start
|
||||||
|
.align 2
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word eclic_msip_handler
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word eclic_mtip_handler
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word eclic_bwei_handler
|
||||||
|
.word eclic_pmovi_handler
|
||||||
|
.word WWDGT_IRQHandler
|
||||||
|
.word LVD_IRQHandler
|
||||||
|
.word TAMPER_IRQHandler
|
||||||
|
.word RTC_IRQHandler
|
||||||
|
.word FMC_IRQHandler
|
||||||
|
.word RCU_IRQHandler
|
||||||
|
.word EXTI0_IRQHandler
|
||||||
|
.word EXTI1_IRQHandler
|
||||||
|
.word EXTI2_IRQHandler
|
||||||
|
.word EXTI3_IRQHandler
|
||||||
|
.word EXTI4_IRQHandler
|
||||||
|
.word DMA0_Channel0_IRQHandler
|
||||||
|
.word DMA0_Channel1_IRQHandler
|
||||||
|
.word DMA0_Channel2_IRQHandler
|
||||||
|
.word DMA0_Channel3_IRQHandler
|
||||||
|
.word DMA0_Channel4_IRQHandler
|
||||||
|
.word DMA0_Channel5_IRQHandler
|
||||||
|
.word DMA0_Channel6_IRQHandler
|
||||||
|
.word ADC0_1_IRQHandler
|
||||||
|
.word CAN0_TX_IRQHandler
|
||||||
|
.word CAN0_RX0_IRQHandler
|
||||||
|
.word CAN0_RX1_IRQHandler
|
||||||
|
.word CAN0_EWMC_IRQHandler
|
||||||
|
.word EXTI5_9_IRQHandler
|
||||||
|
.word TIMER0_BRK_IRQHandler
|
||||||
|
.word TIMER0_UP_IRQHandler
|
||||||
|
.word TIMER0_TRG_CMT_IRQHandler
|
||||||
|
.word TIMER0_Channel_IRQHandler
|
||||||
|
.word TIMER1_IRQHandler
|
||||||
|
.word TIMER2_IRQHandler
|
||||||
|
.word TIMER3_IRQHandler
|
||||||
|
.word I2C0_EV_IRQHandler
|
||||||
|
.word I2C0_ER_IRQHandler
|
||||||
|
.word I2C1_EV_IRQHandler
|
||||||
|
.word I2C1_ER_IRQHandler
|
||||||
|
.word SPI0_IRQHandler
|
||||||
|
.word SPI1_IRQHandler
|
||||||
|
.word USART0_IRQHandler
|
||||||
|
.word USART1_IRQHandler
|
||||||
|
.word USART2_IRQHandler
|
||||||
|
.word EXTI10_15_IRQHandler
|
||||||
|
.word RTC_Alarm_IRQHandler
|
||||||
|
.word USBFS_WKUP_IRQHandler
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word EXMC_IRQHandler
|
||||||
|
.word 0
|
||||||
|
.word TIMER4_IRQHandler
|
||||||
|
.word SPI2_IRQHandler
|
||||||
|
.word UART3_IRQHandler
|
||||||
|
.word UART4_IRQHandler
|
||||||
|
.word TIMER5_IRQHandler
|
||||||
|
.word TIMER6_IRQHandler
|
||||||
|
.word DMA1_Channel0_IRQHandler
|
||||||
|
.word DMA1_Channel1_IRQHandler
|
||||||
|
.word DMA1_Channel2_IRQHandler
|
||||||
|
.word DMA1_Channel3_IRQHandler
|
||||||
|
.word DMA1_Channel4_IRQHandler
|
||||||
|
.word 0
|
||||||
|
.word 0
|
||||||
|
.word CAN1_TX_IRQHandler
|
||||||
|
.word CAN1_RX0_IRQHandler
|
||||||
|
.word CAN1_RX1_IRQHandler
|
||||||
|
.word CAN1_EWMC_IRQHandler
|
||||||
|
.word USBFS_IRQHandler
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
.type _start,@function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||||
|
/* Jump to logical address first to ensure correct operation of RAM region */
|
||||||
|
la a0, _start
|
||||||
|
li a1, 1
|
||||||
|
slli a1, a1, 29
|
||||||
|
bleu a1, a0, _start0800
|
||||||
|
srli a1, a1, 2
|
||||||
|
bleu a1, a0, _start0800
|
||||||
|
la a0, _start0800
|
||||||
|
add a0, a0, a1
|
||||||
|
jr a0
|
||||||
|
|
||||||
|
_start0800:
|
||||||
|
|
||||||
|
/* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */
|
||||||
|
li t0, 0x200
|
||||||
|
csrs CSR_MMISC_CTL, t0
|
||||||
|
|
||||||
|
/* Intial the mtvt*/
|
||||||
|
la t0, vector_base
|
||||||
|
csrw CSR_MTVT, t0
|
||||||
|
|
||||||
|
/* Intial the mtvt2 and enable it*/
|
||||||
|
la t0, irq_entry
|
||||||
|
csrw CSR_MTVT2, t0
|
||||||
|
csrs CSR_MTVT2, 0x1
|
||||||
|
|
||||||
|
/* Intial the CSR MTVEC for the Trap ane NMI base addr*/
|
||||||
|
la t0, trap_entry
|
||||||
|
csrw CSR_MTVEC, t0
|
||||||
|
|
||||||
|
#ifdef __riscv_flen
|
||||||
|
/* Enable FPU */
|
||||||
|
li t0, MSTATUS_FS
|
||||||
|
csrs mstatus, t0
|
||||||
|
csrw fcsr, x0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
la gp, __global_pointer$
|
||||||
|
.option pop
|
||||||
|
la sp, _sp
|
||||||
|
|
||||||
|
/* Load data section */
|
||||||
|
la a0, _data_lma
|
||||||
|
la a1, _data
|
||||||
|
la a2, _edata
|
||||||
|
bgeu a1, a2, 2f
|
||||||
|
1:
|
||||||
|
lw t0, (a0)
|
||||||
|
sw t0, (a1)
|
||||||
|
addi a0, a0, 4
|
||||||
|
addi a1, a1, 4
|
||||||
|
bltu a1, a2, 1b
|
||||||
|
2:
|
||||||
|
/* Clear bss section */
|
||||||
|
la a0, __bss_start
|
||||||
|
la a1, _end
|
||||||
|
bgeu a0, a1, 2f
|
||||||
|
1:
|
||||||
|
sw zero, (a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
bltu a0, a1, 1b
|
||||||
|
2:
|
||||||
|
/*enable mcycle_minstret*/
|
||||||
|
csrci CSR_MCOUNTINHIBIT, 0x5
|
||||||
|
/* Call global constructors */
|
||||||
|
// la a0, __libc_fini_array
|
||||||
|
// call atexit
|
||||||
|
// call __libc_init_array
|
||||||
|
call _init
|
||||||
|
|
||||||
|
/* argc = argv = 0 */
|
||||||
|
li a0, 0
|
||||||
|
li a1, 0
|
||||||
|
call main
|
||||||
|
// tail exit
|
||||||
|
|
||||||
|
1:
|
||||||
|
j 1b
|
||||||
|
|
||||||
|
.global disable_mcycle_minstret
|
||||||
|
disable_mcycle_minstret:
|
||||||
|
csrsi CSR_MCOUNTINHIBIT, 0x5
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global enable_mcycle_minstret
|
||||||
|
enable_mcycle_minstret:
|
||||||
|
csrci CSR_MCOUNTINHIBIT, 0x5
|
||||||
|
ret
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
int __wrap_printf(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
// You can implement your own printf to reduce the code size, because the printf is really a big function
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "stub.h"
|
||||||
|
|
||||||
|
|
||||||
|
void _exit(int code)
|
||||||
|
{
|
||||||
|
const char message[] = "\nProgram has exited with code:";
|
||||||
|
|
||||||
|
write(STDERR_FILENO, message, sizeof(message) - 1);
|
||||||
|
write_hex(STDERR_FILENO, code);
|
||||||
|
write(STDERR_FILENO, "\n", 1);
|
||||||
|
|
||||||
|
for (;;);
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "stub.h"
|
||||||
|
|
||||||
|
int _close(int fd)
|
||||||
|
{
|
||||||
|
return _stub(EBADF);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "stub.h"
|
||||||
|
|
||||||
|
int _fstat(int fd, struct stat* st)
|
||||||
|
{
|
||||||
|
if (isatty(fd)) {
|
||||||
|
st->st_mode = S_IFCHR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _stub(EBADF);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int _isatty(int fd)
|
||||||
|
{
|
||||||
|
if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "stub.h"
|
||||||
|
|
||||||
|
off_t _lseek(int fd, off_t ptr, int dir)
|
||||||
|
{
|
||||||
|
if (isatty(fd))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _stub(EBADF);
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "stub.h"
|
||||||
|
|
||||||
|
ssize_t _read(int fd, void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
return _stub(EBADF);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *_sbrk(ptrdiff_t incr)
|
||||||
|
{
|
||||||
|
extern char _end[];
|
||||||
|
extern char _heap_end[];
|
||||||
|
static char *curbrk = _end;
|
||||||
|
|
||||||
|
if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))
|
||||||
|
return NULL - 1;
|
||||||
|
|
||||||
|
curbrk += incr;
|
||||||
|
return curbrk - incr;
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
#ifndef _NUCLEI_SYS_STUB_H
|
||||||
|
#define _NUCLEI_SYS_STUB_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void write_hex(int fd, unsigned long int hex);
|
||||||
|
|
||||||
|
static inline int _stub(int err)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _NUCLEI_SYS_STUB_H */
|
@ -0,0 +1,47 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <gd32vf103.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "stub.h"
|
||||||
|
#include "gd32vf103.h"
|
||||||
|
|
||||||
|
typedef unsigned int size_t;
|
||||||
|
|
||||||
|
extern int _put_char(int ch) __attribute__((weak));
|
||||||
|
|
||||||
|
ssize_t _write(int fd, const void* ptr, size_t len) {
|
||||||
|
const uint8_t * current = (const uint8_t *) ptr;
|
||||||
|
|
||||||
|
// if (isatty(fd))
|
||||||
|
{
|
||||||
|
for (size_t jj = 0; jj < len; jj++) {
|
||||||
|
_put_char(current[jj]);
|
||||||
|
|
||||||
|
if (current[jj] == '\n') {
|
||||||
|
_put_char('\r');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _stub(EBADF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int puts(const char* string) {
|
||||||
|
return _write(0, (const void *) string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
int _put_char(int ch)
|
||||||
|
{
|
||||||
|
usart_data_transmit(USART0, (uint8_t) ch );
|
||||||
|
while (usart_flag_get(USART0, USART_FLAG_TBE)== RESET){
|
||||||
|
}
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
/* See LICENSE of license details. */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void write_hex(int fd, unsigned long int hex)
|
||||||
|
{
|
||||||
|
uint8_t ii;
|
||||||
|
uint8_t jj;
|
||||||
|
char towrite;
|
||||||
|
write(fd , "0x", 2);
|
||||||
|
for (ii = sizeof(unsigned long int) * 2 ; ii > 0; ii--) {
|
||||||
|
jj = ii - 1;
|
||||||
|
uint8_t digit = ((hex & (0xF << (jj*4))) >> (jj*4));
|
||||||
|
towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA));
|
||||||
|
write(fd, &towrite, 1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue