Browse Source

fw: move .sdata/.sbss into the zero page

Put .sdata/.sbss in the zero page instead of at the end of the
executable. This eliminates the need for using gp.
H. Peter Anvin 3 years ago
parent
commit
555a856ff4
4 changed files with 3566 additions and 3559 deletions
  1. 3510 3510
      fw/boot.mif
  2. 3 1
      fw/irq.c
  3. 2 3
      fw/irqasm.S
  4. 51 45
      fw/max80.ld

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


+ 3 - 1
fw/irq.c

@@ -14,7 +14,9 @@ void null_irq_handler(unsigned int vector)
 {
 {
 }
 }
 
 
-irq_handler_t __irq_handler_table[IRQ_VECTORS] =
+/* __irq_handler_table must be in .sdata so it ends up in the zero page */
+irq_handler_t __attribute__((section(".sdata")))
+__irq_handler_table[IRQ_VECTORS] =
   { [0 ... IRQ_VECTORS-1] = spurious_irq_handler };
   { [0 ... IRQ_VECTORS-1] = spurious_irq_handler };
 
 
 irq_handler_t register_irq(unsigned int vector, irq_handler_t handler,
 irq_handler_t register_irq(unsigned int vector, irq_handler_t handler,

+ 2 - 3
fw/irqasm.S

@@ -11,7 +11,6 @@ _irq:
 	
 	
 	// s10 contains the IRQ return address, s11 the mask of
 	// s10 contains the IRQ return address, s11 the mask of
 	// IRQs to be handled.
 	// IRQs to be handled.
-	lui s0, %hi(__irq_handler_table)
 	li s1, 0
 	li s1, 0
 .Lirq_loop:
 .Lirq_loop:
 	// ctz would make this more efficient...
 	// ctz would make this more efficient...
@@ -40,8 +39,8 @@ _irq:
 	srli s11,s11,1
 	srli s11,s11,1
 	addi s1,s1,1*4
 	addi s1,s1,1*4
 5:
 5:
-	add t0,s0,s1
-	lw t0,%lo(__irq_handler_table)(t0)
+	// __irq_handler_table must be in the zero page
+	lw t0,%lo(__irq_handler_table)(s1)
 	srli a0,s1,2
 	srli a0,s1,2
 	jalr t0
 	jalr t0
 	srli s11,s11,1
 	srli s11,s11,1

+ 51 - 45
fw/max80.ld

@@ -18,13 +18,13 @@ MEMORY
 
 
 SECTIONS
 SECTIONS
 {
 {
-	/* 
+	/*
 	 * Sections we do not need. This program cannot exit, so
 	 * Sections we do not need. This program cannot exit, so
 	 * fini/destructors are never needed. Exception handling
 	 * fini/destructors are never needed. Exception handling
 	 * is not supported.
 	 * is not supported.
 	 */
 	 */
 	 /DISCARD/	: {
 	 /DISCARD/	: {
-	 	*(.note.GNU-stack)
+		*(.note.GNU-stack)
 		*(.gnu_debuglink)
 		*(.gnu_debuglink)
 		*(.gnu.lto_*)
 		*(.gnu.lto_*)
 		*(.discard)
 		*(.discard)
@@ -53,42 +53,64 @@ SECTIONS
 		KEEP (*(SORT_NONE(.init.irq)))
 		KEEP (*(SORT_NONE(.init.irq)))
 	}
 	}
 
 
+	/*
+	 * Put the short data sections in the zero page.
+	 * This means .bss and .sbss aren't contiguous, but
+	 * all memory is intialized during FPGA load anyway.
+	 */
+	.sdata : ALIGN(4) {
+		__SDATA_BEGIN__ = .;
+		*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4)
+		*(.srodata.cst2) *(.srodata .srodata.*)
+		*(.sdata .sdata.* .gnu.linkonce.s.*)
+	}
+	.sbss : ALIGN(4) {
+		*(.dynsbss)
+		*(.sbss .sbss.* .gnu.linkonce.sb.*)
+		*(.scommon)
+	}
+
+	$assert_zero_page = ASSERT((. <= 2048), "zero page overflow");
+
+	__global_pointer$ = 0;
+
 	.text : ALIGN(4) {
 	.text : ALIGN(4) {
+		PROVIDE(___text = .);
 		KEEP (*(SORT_NONE(.init)))
 		KEEP (*(SORT_NONE(.init)))
 	        *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 	        *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 		*(.text.exit .text.exit.*)
 		*(.text.exit .text.exit.*)
- 		*(.text.startup .text.startup.*)
-  		*(.text.hot .text.hot.*)
-  		*(SORT(.text.sorted.*))
-  		*(.text .stub .text.* .gnu.linkonce.t.*)
-  		/* .gnu.warning sections are handled specially by elf.em.  */
-  		*(.gnu.warning)
+		*(.text.startup .text.startup.*)
+		*(.text.hot .text.hot.*)
+		*(SORT(.text.sorted.*))
+		*(.text .stub .text.* .gnu.linkonce.t.*)
+		/* .gnu.warning sections are handled specially by elf.em.  */
+		*(.gnu.warning)
 	}
 	}
 
 
 	PROVIDE (__etext = .);
 	PROVIDE (__etext = .);
- 	PROVIDE (_etext = .);
+	PROVIDE (_etext = .);
 	. = ALIGN(4);
 	. = ALIGN(4);
 	.rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
 	.rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- 	.rodata1        : { *(.rodata1) }
- 	.sdata2         : {
+	.rodata1        : { *(.rodata1) }
+	.sdata2         : {
 		*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
 		*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
- 	}
+	}
 	.sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
 	.sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
 
 
 	/* Thread Local Storage sections  */
 	/* Thread Local Storage sections  */
 	.tdata          : {
 	.tdata          : {
- 		PROVIDE_HIDDEN (__tdata_start = .);
+		PROVIDE_HIDDEN (__tdata_start = .);
 		*(.tdata .tdata.* .gnu.linkonce.td.*)
 		*(.tdata .tdata.* .gnu.linkonce.td.*)
 	}
 	}
- 	.tbss       : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- 	.preinit_array    : {
+	.tbss       : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+	.preinit_array    : {
 		PROVIDE_HIDDEN (__preinit_array_start = .);
 		PROVIDE_HIDDEN (__preinit_array_start = .);
-    		KEEP (*(.preinit_array))
-    		PROVIDE_HIDDEN (__preinit_array_end = .);
-  	}
- 	.init_array    : {
- 		PROVIDE_HIDDEN (__init_array_start = .);
- 		KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)
+		KEEP (*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+	}
+	.init_array    : {
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)
 		SORT_BY_INIT_PRIORITY(.ctors.*)))
 		SORT_BY_INIT_PRIORITY(.ctors.*)))
 		KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
 		KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
 		PROVIDE_HIDDEN (__init_array_end = .);
 		PROVIDE_HIDDEN (__init_array_end = .);
@@ -106,42 +128,26 @@ SECTIONS
 		SORT(CONSTRUCTORS)
 		SORT(CONSTRUCTORS)
 	}
 	}
 	.data1          : { *(.data1) }
 	.data1          : { *(.data1) }
-  /* We want the small data sections together, so single-instruction offsets
-     can access them all, and initialized data all before uninitialized, so
-     we can shorten the on-disk segment size.  */
-	.sdata          :  {
- 		__SDATA_BEGIN__ = .;
- 		*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4)
-		*(.srodata.cst2) *(.srodata .srodata.*)
- 		*(.sdata .sdata.* .gnu.linkonce.s.*)
- 	}
- 	_edata = .;
+	_edata = .;
 	. = ALIGN(16);
 	. = ALIGN(16);
- 	__bss_start = .;
- 	.sbss           : {
-		*(.dynsbss)
-    		*(.sbss .sbss.* .gnu.linkonce.sb.*)
-    		*(.scommon)
-  	}
+	__bss_start = .;
 	.bss            : {
 	.bss            : {
 		*(.dynbss)
 		*(.dynbss)
- 		*(.bss .bss.* .gnu.linkonce.b.*)
-  		*(COMMON)
+		*(.bss .bss.* .gnu.linkonce.b.*)
+		*(COMMON)
    /* Align here to ensure that the .bss section occupies space up to
    /* Align here to ensure that the .bss section occupies space up to
       _end.  Align after .bss to ensure correct alignment even if the
       _end.  Align after .bss to ensure correct alignment even if the
       .bss section disappears because there are no input sections.
       .bss section disappears because there are no input sections.
       FIXME: Why do we need it? When there is no .bss section, we do not
       FIXME: Why do we need it? When there is no .bss section, we do not
       pad the .data section.  */
       pad the .data section.  */
- 		. = ALIGN(16);
+		. = ALIGN(16);
 	}
 	}
- 	. = SEGMENT_START("ldata-segment", .);
- 	. = ALIGN(16);
+	. = SEGMENT_START("ldata-segment", .);
+	. = ALIGN(16);
 	__BSS_END__ = .;
 	__BSS_END__ = .;
+	_end = .;
 
 
 	.stack STACK_BOTTOM : {
 	.stack STACK_BOTTOM : {
 		KEEP (*(.stack))
 		KEEP (*(.stack))
 	}
 	}
- 	__global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
-                            MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
- 	_end = .;
 }
 }

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