about summary refs log tree commit diff stats
path: root/subx/020syscalls.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-05-11 23:10:42 -0700
committerKartik Agaram <vc@akkartik.com>2019-05-11 23:11:34 -0700
commitd5d43e044d16335a3a865a8c9f5aea5cbad73360 (patch)
tree31d52d72e2a7babf378f421a4ed85242e9d76135 /subx/020syscalls.cc
parente59a74abddaf0b4f9a39432da21c6a98eae46df6 (diff)
downloadmu-d5d43e044d16335a3a865a8c9f5aea5cbad73360.tar.gz
5157
Support allocating more than 0x01000000 bytes (8MB) to a segment in the
VM.
Diffstat (limited to 'subx/020syscalls.cc')
-rw-r--r--subx/020syscalls.cc16
1 files changed, 7 insertions, 9 deletions
diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc
index 444c9fd5..eb8ebcce 100644
--- a/subx/020syscalls.cc
+++ b/subx/020syscalls.cc
@@ -111,21 +111,19 @@ void check_mode(int reg) {
 
 :(before "End Globals")
 // Very primitive/fixed/insecure mmap segments for now.
-// For now we avoid addresses with the most significant bit set; SubX doesn't
-// support unsigned comparison yet (https://github.com/akkartik/mu/issues/30)
-// Once we do, we can go up to 0xc0000000; higher addresses are reserved for
-// the Linux kernel.
-uint32_t Next_segment = 0x7c000000;
+uint32_t Segments_allocated_above = END_HEAP;
 const uint32_t SPACE_FOR_SEGMENT = 0x01000000;
 :(code)
+// always allocate multiples of the segment size
 uint32_t new_segment(uint32_t length) {
-  uint32_t result = Next_segment;
-  Mem.push_back(vma(Next_segment, Next_segment+length));
-  Next_segment -= SPACE_FOR_SEGMENT;
-  if (Next_segment <= DATA_SEGMENT) {
+  assert(length > 0);
+  uint32_t result = (Segments_allocated_above - length) & 0xff000000;
+  if (result <= START_HEAP) {
     raise << "Allocated too many segments; the VM ran out of memory. "
           << "Maybe SPACE_FOR_SEGMENT can be smaller?\n" << end();
     exit(1);
   }
+  Mem.push_back(vma(result, result+length));
+  Segments_allocated_above = result;
   return result;
 }