#include "sys.h"
#include "sections.h"
#include "picorv32.h"

#define GP_IS_ZERO 1

	// The code in this file is sensitive to alignment, so
	// don't use compressed instructions (there are very few anyway)
	.option norvc

	// NULL pointer guard area
	// This needs to be an explicitly allocated section or the binary
	// memory initialization file ends up broken.
	//
	// This also contains a pointer to the ROM area associated
	// with this image. For a non-primary image it is patched to
	// the preferred value.
	.section ".null","a"
	.globl _NULL
_NULL:
	.space 8
	.type	_NULL, @object
	.size	_NULL, . - _NULL

	.globl __dram_checksum
__dram_checksum:
	.long 0			// Filled in post-link
	.type __dram_checksum, @object
	.size __dram_checksum, . - __dram_checksum

	.globl __rom_offset
__rom_offset:
	.long ROM_OFFSET
	.type	__rom_offset, @object
	.size	__rom_offset, . - __rom_offset

	// The linker will always assign this to _PC_RESET
	.section ".init.reset","ax"
	.globl _reset
_reset:
	.option push
	.option norvc
	.option norelax
	rdtime s0		// Record timer at reset
	lui sp,%hi(___stack_top)
	addi sp,sp,%lo(___stack_top)
	j __start
	.option pop
	.type _reset, @function
	.size _reset, . - _reset

	.section ".text.hot","ax"
	.globl __start
	.balign 4
__start:
	.option push
	.option norvc		// Weird things happen?
	.option norelax		// Can't make gp references to set up gp...

	not t0,zero
	maskirq zero,t0,zero

	// Interrupt stack
	lui t0,%hi(___irqstack_top)
	addqxi sp,t0,%lo(___irqstack_top)

	// Global pointer register (not actually used...)
#if GP_IS_ZERO
	li gp, 0
#else
	la gp, __global_pointer$
#endif

	.option pop
	addqxi gp,gp,0		// Set gp for interrupt code too

	// Clear esplink_head.magic as quickly as possible
	sw zero,esplink_head,a0

	// Clear bss
	la a0,__BSS_START__
	la a1,__BSS_END__

.L_clear_bss_loop:
	sw zero,(a0)
	sw zero,4(a0)
	sw zero,8(a0)
	sw zero,12(a0)
	sw zero,16(a0)
	sw zero,20(a0)
	sw zero,24(a0)
	sw zero,28(a0)
	addi a0,a0,32
	bltu a0,a1,.L_clear_bss_loop

	sw s0, time_zero, t0
	j main
	.type __start, @function
	.size __start, . - __start

	__sbss
	.balign 4
	.globl time_zero
time_zero:
	.space 4
	.type time_zero, @object
	.size time_zero, . - time_zero
	.popsection

	// Time stamp definition as patched in by FPGA build
	.section ".datestamp","a"
	.globl __datestamp
__datestamp:
	.space 32
	.type __datestamp, @object
	.size __datestamp, . - __datestamp

	// Stack definition
	.section ".stack","aw",@nobits
	.balign 4
	.globl __irqstack_bottom
___irqstack:
	.space IRQSTACK_SIZE
	.type ___irqstack, @object
	.size ___irqstack, IRQSTACK_SIZE

	.globl ___irqstack_top
___irqstack_top:

	.balign 4
	.globl ___stack
___stack:
	.space STACK_SIZE
	.type ___stack, @object
	.size ___stack, STACK_SIZE

	.globl ___stack_top
___stack_top:
