Browse Source

Clean up _start() -- the one in libc doesn't zero bss correctly

... however, this one causes a reset on the first boot... then works?!
H. Peter Anvin 3 years ago
parent
commit
d6d6390bca
9 changed files with 3843 additions and 3816 deletions
  1. 1 1
      fpga/max80.sv
  2. BIN
      fpga/output_files/max80.jbc
  3. BIN
      fpga/output_files/max80.jic
  4. BIN
      fpga/output_files/max80.pof
  5. BIN
      fpga/output_files/max80.sof
  6. 3800 3800
      fw/boot.mif
  7. 29 7
      fw/head.S
  8. 12 7
      fw/max80.ld
  9. 1 1
      fw/sys.h

+ 1 - 1
fpga/max80.sv

@@ -461,7 +461,7 @@ module max80
 	.trap ( cpu_trap ),
 
 	.progaddr_reset ( 32'h0000_0000 ),
-	.progaddr_irq   ( 32'h0000_0020 ),
+	.progaddr_irq   ( 32'h0000_0040 ),
 
 	.mem_instr ( cpu_mem_instr ),
 	.mem_ready ( cpu_mem_ready ),

BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


File diff suppressed because it is too large
+ 3800 - 3800
fw/boot.mif


+ 29 - 7
fw/head.S

@@ -1,27 +1,49 @@
 #include "sys.h"
 #include "picorv32.h"
 
+#define GP_IS_ZERO 1
+	
 	// The linker ensures that section .init is first
 	.section ".init.reset","ax"
 	.globl _reset
 _reset:
-	rdtime t0		// Record timer at reset
+	rdtime s0		// Record timer at reset
+	j __start
+	.type _reset, @function
+	.size _reset, . - _reset
+
+	.section ".init","ax"
+	.globl __start
+__start:
 	li sp,STACK_TOP		// Cheaper than using la sp,___stack_top
+	not t0,zero
+	maskirq zero,t0,zero
+#if !GP_IS_ZERO
 	.option push
 	.option norelax		// Can't make gp references to set up gp...
 	la gp, __global_pointer$
 	.option pop
+#else
+	// Zero gp (linker will usually replace with the zero reg)
+	li gp,0
+#endif
 	addqxi gp,gp,0		// Set gp for interrupt code too
-	sw t0, time_zero, t1
-	j _start
-	.type _reset, @function
-	.size _reset, . - _reset
 
-	.pushsection ".sdata","a"
+	la a0,__BSS_START__
+	li a1,0
+	la a2,__BSS_LEN__
+	jal memset
+
+	sw s0, time_zero, t0
+	j main
+	.type __start, @function
+	.size __start, . - __start
+
+	.pushsection ".sbss","a"
 	.balign 4
 	.globl time_zero
 time_zero:
-	.long 0
+	.space 4
 	.type time_zero, @object
 	.size time_zero, . - time_zero
 	.popsection

+ 12 - 7
fw/max80.ld

@@ -39,6 +39,7 @@ SECTIONS
 		*(.gnu_extab*)
 		*(.exception_ranges*)
 		*crtbegin.o(*)
+		*crt0.o(*)
 	}
 
 	PROVIDE (__executable_start = _PC_RESET);
@@ -67,21 +68,28 @@ SECTIONS
 	.sdata2         : {
 		*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
 	}
-	__bss_start = .;
+
+	. = ALIGN(4);
+	__BSS_START__ = .;
+	PROVIDE (__bss_start = .);
 	.sbss : ALIGN(4) {
 		*(.dynsbss)
 		*(.sbss .sbss.* .gnu.linkonce.sb.*)
 		*(.scommon)
 	}
 	.sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
-	.bss  : {
+
+	HIDDEN($assert_zero_page = ASSERT((. <= 2048), "zero page overflow"));
+
+	.bss : {
 		*(.dynbss)
 		*(.bss .bss.* .gnu.linkonce.b.*)
 		*(COMMON)
 	}
-	__BSS_END__ = .;
 
-	HIDDEN($assert_zero_page = ASSERT((. <= 2048), "zero page overflow"));
+	. = ALIGN(4);
+	__BSS_END__ = .;
+	__BSS_LEN__ = __BSS_END__ - __BSS_START__;
 
 	__global_pointer$ = 0;
 
@@ -136,9 +144,6 @@ SECTIONS
 	}
 	.data1          : { *(.data1) }
 	_edata = .;
-	. = ALIGN(16);
-	. = ALIGN(16);
-	__BSS_END__ = .;
 	_end = .;
 
 	.stack STACK_BOTTOM : {

+ 1 - 1
fw/sys.h

@@ -26,6 +26,6 @@
 
 /* This need to match the corresponding Verilog constants */
 #define _PC_RESET	0
-#define _PC_IRQ		0x20
+#define _PC_IRQ		0x10
 
 #endif /* SYS_H */

Some files were not shown because too many files changed in this diff