sw/vec: Enable WMMU sections in linker file

Change springbok.ld to add all 6 sections. Keep a no_wmmu version for
single model tests.

Also adds a global _heap_ptr that gets reset to _sheap in crt0.

Change-Id: I6036fd9fe91dfc991bc27f43f6a6054dc1aa29a4
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b53b42..edf1a81 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,7 +32,7 @@
 
 add_subdirectory($ENV{ROOTDIR}/sw/pigweed pw)
 
-set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/springbok/springbok.ld" CACHE PATH "Linker script for springbok")
+set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/springbok/springbok_no_wmmu.ld" CACHE PATH "Linker script for springbok")
 
 set(TEST_RUNNER "${CMAKE_CURRENT_SOURCE_DIR}/scripts/test_runner.py" CACHE PATH "Test runner script path")
 
diff --git a/hello_vec/Makefile b/hello_vec/Makefile
index c006178..3b000db 100644
--- a/hello_vec/Makefile
+++ b/hello_vec/Makefile
@@ -24,7 +24,7 @@
 LDFLAGS  += -Wl,--gc-sections
 LDFLAGS  += -Wl,--print-memory-usage
 LDFLAGS  += -Wl,-Map=${BUILDDIR}/hello_vec.map
-LDFLAGS  += -T${ROOTDIR}/springbok/springbok.ld
+LDFLAGS  += -T${ROOTDIR}/springbok/springbok_no_wmmu.ld
 
 CC       := ${SHODANROOTDIR}/cache/toolchain_vp/bin/riscv32-unknown-elf-gcc
 CPP      := ${SHODANROOTDIR}/cache/toolchain_vp/bin/riscv32-unknown-elf-g++
diff --git a/springbok/crt0.S b/springbok/crt0.S
index 822fac7..21240c0 100644
--- a/springbok/crt0.S
+++ b/springbok/crt0.S
@@ -22,6 +22,8 @@
         ###############################################
         la   sp, _stack_ptr
         la   gp, _global_pointer
+        la   s0, _sheap
+        sw   s0, _heap_ptr, s1
         mv   tp, zero
         mv   t1, zero
         mv   t2, zero
diff --git a/springbok/springbok.ld b/springbok/springbok.ld
index 8b68fd1..a3ddc65 100644
--- a/springbok/springbok.ld
+++ b/springbok/springbok.ld
@@ -15,16 +15,20 @@
  */
 
 TCM_LENGTH  = DEFINED(__tcm_length__)  ? __tcm_length__  : 4M;
+WINDOW_LENGTH = 0x1000000;
 
 MEMORY
 {
-        TCM (rw) : ORIGIN = 0x34000000, LENGTH = TCM_LENGTH
+        TEXT (rx) : ORIGIN = 0x80000000, LENGTH = TCM_LENGTH
+        CONSTANT_DATA (r) : ORIGIN = 0x80000000 + WINDOW_LENGTH, LENGTH = TCM_LENGTH
+        MODEL_OUTPUT (rw) : ORIGIN = 0x80000000 + 2*WINDOW_LENGTH, LENGTH = TCM_LENGTH
+        STATIC_DATA (rw) : ORIGIN = 0x80000000 + 3*WINDOW_LENGTH, LENGTH = TCM_LENGTH
+        MODEL_INPUT (r) : ORIGIN = 0x80000000 + 4*WINDOW_LENGTH, LENGTH = TCM_LENGTH
+        TEMPORARY_DATA (rw) : ORIGIN = 0x80000000 + 5*WINDOW_LENGTH, LENGTH = TCM_LENGTH
 }
 
+HEAP_SIZE = DEFINED(HEADP_SIZE) ? HEAP_SIZE : DEFINED(__heap_size__) ? __heap_size__ : 1M;
 STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
-PROVIDE( _stack_ptr = ORIGIN(TCM) + LENGTH(TCM) - 64 );
-PROVIDE( _stack_start_sentinel = ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE );
-PROVIDE( _stack_end_sentinel = ORIGIN(TCM) + LENGTH(TCM) - 64 );
 
 ENTRY(_start)
 
@@ -36,7 +40,7 @@
                 KEEP(*(.text._start))
                 *(.text*)
                 _etext = .;
-        } > TCM
+        } > TEXT
 
         .rodata :
         {
@@ -44,14 +48,14 @@
                 _srodata = .;
                 *(.rodata*)
                 _erodata = .;
-        } > TCM
+        } > CONSTANT_DATA
 
         .preinit_array :
         {
                 PROVIDE(__preinit_array_start = .);
                 KEEP(*(.preinit_array))
                 PROVIDE(__preinit_array_end = .);
-        } > TCM
+        } > CONSTANT_DATA
 
         .init_array :
         {
@@ -59,7 +63,7 @@
                 KEEP(*(SORT(.init_array.*)))
                 KEEP(*(.init_array))
                 PROVIDE(__init_array_end = .);
-        } > TCM
+        } > CONSTANT_DATA
 
         .fini_array :
         {
@@ -67,7 +71,15 @@
                 KEEP(*(SORT(.fini_array.*)))
                 KEEP(*(.fini_array))
                 PROVIDE(__fini_array_end = .);
-        } > TCM
+        } > CONSTANT_DATA
+
+        .model_output :
+        {
+                . = ALIGN(64);
+                _smodel_output = .;
+                *(.model_output*)
+                _emodel_output = .;
+        } > MODEL_OUTPUT
 
         .data :
         {
@@ -76,7 +88,7 @@
                 _sdata = .;
                 *(.data*)
                 _edata = .;
-        } > TCM
+        } > STATIC_DATA
 
         .bss (NOLOAD) :
         {
@@ -85,24 +97,28 @@
                 *(.bss*)
                 *(COMMON)
                 _ebss = .;
-        } > TCM
+        } > TEMPORARY_DATA
 
         .heap (NOLOAD) :
         {
                 . = ALIGN(64);
                 _sheap = .;
-                . = ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE - 63;
+                . = . + HEAP_SIZE;
                 . = ALIGN(64);
                 _eheap = .;
-        } > TCM
+        } > TEMPORARY_DATA
 
-        .stack ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE (NOLOAD) :
+        .stack (NOLOAD) :
         {
                 _sstack = .;
+                PROVIDE(_stack_start_sentinel = .);
                 . = . + STACK_SIZE;
+                PROVIDE(_stack_ptr = .);
+                PROVIDE(_stack_end_sentinel = .);
                 . = ALIGN(64);
+                . = . + 64;
                 _estack = .;
-        } > TCM
+        } > TEMPORARY_DATA
 
         _end = .;
 }
diff --git a/springbok/springbok_gloss.cpp b/springbok/springbok_gloss.cpp
index 0f55e64..8f83415 100644
--- a/springbok/springbok_gloss.cpp
+++ b/springbok/springbok_gloss.cpp
@@ -20,18 +20,23 @@
 
 #include <springbok_intrinsics.h>
 
-void* __dso_handle = (void*) &__dso_handle;
+void *__dso_handle = reinterpret_cast<void *>(&__dso_handle);
+
+char *_heap_ptr;  // Set to _sheap in crt0.S
 
 extern "C" void *_sbrk(int nbytes) {
   extern char _sheap, _eheap;
-  static char *_heap_ptr = &_sheap;
 
   if ((nbytes < 0) ||
       (_heap_ptr + nbytes > &_eheap)) {
-    springbok_simprint(SPRINGBOK_SIMPRINT_ERROR, "_sbrk failed to allocate memory. Number of bytes requested:", nbytes);
-    springbok_simprint(SPRINGBOK_SIMPRINT_ERROR, "Number of unallocated bytes remaining:", static_cast<int32_t>(&_eheap - _heap_ptr));
+    springbok_simprint(
+        SPRINGBOK_SIMPRINT_ERROR,
+        "_sbrk failed to allocate memory. Number of bytes requested:", nbytes);
+    springbok_simprint(SPRINGBOK_SIMPRINT_ERROR,
+                       "Number of unallocated bytes remaining:",
+                       static_cast<int32_t>(&_eheap - _heap_ptr));
     errno = ENOMEM;
-    return (void *)-1;
+    return reinterpret_cast<void *>(-1);
   }
 
   void *base = _heap_ptr;
@@ -67,7 +72,8 @@
   }
 
   const int buffer_num   = (file == STDOUT_FILENO)? 0 : 1;
-  const int buffer_level = (file == STDOUT_FILENO)? SPRINGBOK_SIMPRINT_INFO : SPRINGBOK_SIMPRINT_ERROR;
+  const int buffer_level = (file == STDOUT_FILENO) ? SPRINGBOK_SIMPRINT_INFO
+                                                   : SPRINGBOK_SIMPRINT_ERROR;
 
   int bytes_read = 0;
   char c;
@@ -78,7 +84,8 @@
 
     if ((c == '\n') || (c == '\0')) {
       _write_line_buffer[buffer_num][len] = '\0';
-      springbok_simprint(buffer_level, _write_line_buffer[buffer_num], buffer_num);
+      springbok_simprint(buffer_level, _write_line_buffer[buffer_num],
+                         buffer_num);
       len = 0;
     } else {
       _write_line_buffer[buffer_num][len] = c;
@@ -86,7 +93,8 @@
 
       if (len == 255) {
         _write_line_buffer[buffer_num][len] = '\0';
-        springbok_simprint(buffer_level, _write_line_buffer[buffer_num], buffer_num);
+        springbok_simprint(buffer_level, _write_line_buffer[buffer_num],
+                           buffer_num);
         len = 0;
       }
     }
@@ -139,6 +147,6 @@
   free(p);
 }
 
-extern "C" void operator delete(void *p, unsigned long c) noexcept {
+extern "C" void operator delete(void *p, uint32_t c) noexcept {
   operator delete(p);
 }
diff --git a/springbok/springbok_no_wmmu.ld b/springbok/springbok_no_wmmu.ld
new file mode 100644
index 0000000..2f6a194
--- /dev/null
+++ b/springbok/springbok_no_wmmu.ld
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+TCM_LENGTH  = DEFINED(__tcm_length__)  ? __tcm_length__  : 4M;
+
+MEMORY
+{
+        TCM (rw) : ORIGIN = 0x34000000, LENGTH = TCM_LENGTH
+}
+
+STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
+PROVIDE( _stack_ptr = ORIGIN(TCM) + LENGTH(TCM) - 64 );
+PROVIDE( _stack_start_sentinel = ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE );
+PROVIDE( _stack_end_sentinel = ORIGIN(TCM) + LENGTH(TCM) - 64 );
+
+ENTRY(_start)
+
+SECTIONS
+{
+        .text :
+        {
+                _stext = .;
+                KEEP(*(.text._start))
+                *(.text*)
+                _etext = .;
+        } > TCM
+
+        .rodata :
+        {
+                . = ALIGN(64);
+                _srodata = .;
+                *(.rodata*)
+                _erodata = .;
+        } > TCM
+
+        .preinit_array :
+        {
+                PROVIDE(__preinit_array_start = .);
+                KEEP(*(.preinit_array))
+                PROVIDE(__preinit_array_end = .);
+        } > TCM
+
+        .init_array :
+        {
+                PROVIDE(__init_array_start = .);
+                KEEP(*(SORT(.init_array.*)))
+                KEEP(*(.init_array))
+                PROVIDE(__init_array_end = .);
+        } > TCM
+
+        .fini_array :
+        {
+                PROVIDE(__fini_array_start = .);
+                KEEP(*(SORT(.fini_array.*)))
+                KEEP(*(.fini_array))
+                PROVIDE(__fini_array_end = .);
+        } > TCM
+
+
+        .model_output :
+        {
+                . = ALIGN(64);
+                _smodel_output = .;
+                *(.model_output*)
+                _emodel_output = .;
+        } > TCM
+
+        .data :
+        {
+                . = ALIGN(64);
+                _global_pointer = . + 0x800;
+                _sdata = .;
+                *(.data*)
+                _edata = .;
+        } > TCM
+
+        .bss (NOLOAD) :
+        {
+                . = ALIGN(64);
+                _sbss = .;
+                *(.bss*)
+                *(COMMON)
+                _ebss = .;
+        } > TCM
+
+        .heap (NOLOAD) :
+        {
+                . = ALIGN(64);
+                _sheap = .;
+                . = ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE - 63;
+                . = ALIGN(64);
+                _eheap = .;
+        } > TCM
+
+        .stack ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE (NOLOAD) :
+        {
+                _sstack = .;
+                . = . + STACK_SIZE;
+                . = ALIGN(64);
+                _estack = .;
+        } > TCM
+
+        _end = .;
+}