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