diff options
-rw-r--r-- | sim/ppc/core.c | 43 | ||||
-rw-r--r-- | sim/ppc/system.c | 14 |
2 files changed, 42 insertions, 15 deletions
diff --git a/sim/ppc/core.c b/sim/ppc/core.c index 5e8479f..9c47a6c 100644 --- a/sim/ppc/core.c +++ b/sim/ppc/core.c @@ -312,24 +312,47 @@ core_stack_size(core *memory) INLINE_CORE void core_add_data(core *memory, unsigned_word incr) { - memory->data_upper_bound += incr; - if (memory->data_upper_bound > memory->data_high_water) { - malloc_core_memory(memory, memory->data_high_water, incr, - device_is_readable | device_is_writeable); - memory->data_high_water = memory->data_upper_bound; + unsigned_word new_upper_bound = memory->data_upper_bound + incr; + if (new_upper_bound > memory->data_high_water) { + if (memory->data_upper_bound >= memory->data_high_water) + /* all the memory is new */ + malloc_core_memory(memory, + memory->data_upper_bound, + incr, + device_is_readable | device_is_writeable); + else + /* some of the memory was already allocated, only need to add + missing bit */ + malloc_core_memory(memory, + memory->data_high_water, + new_upper_bound - memory->data_high_water, + device_is_readable | device_is_writeable); + memory->data_high_water = new_upper_bound; } + memory->data_upper_bound = new_upper_bound; } INLINE_CORE void core_add_stack(core *memory, unsigned_word incr) { - memory->stack_lower_bound -= incr; - if (memory->stack_lower_bound < memory->stack_low_water) { - malloc_core_memory(memory, memory->stack_lower_bound, incr, - device_is_readable | device_is_writeable); - memory->stack_low_water = memory->stack_lower_bound; + unsigned_word new_lower_bound = memory->stack_lower_bound - incr; + if (new_lower_bound < memory->stack_low_water) { + if (memory->stack_lower_bound <= memory->stack_low_water) + /* all the memory is new */ + malloc_core_memory(memory, + new_lower_bound, + incr, + device_is_readable | device_is_writeable); + else + /* allocate only the extra bit */ + malloc_core_memory(memory, + new_lower_bound, + memory->stack_low_water - new_lower_bound, + device_is_readable | device_is_writeable); + memory->stack_low_water = new_lower_bound; } + memory->stack_lower_bound = new_lower_bound; } diff --git a/sim/ppc/system.c b/sim/ppc/system.c index ca62b27..c032688 100644 --- a/sim/ppc/system.c +++ b/sim/ppc/system.c @@ -169,13 +169,17 @@ system_call(cpu *processor, # error "SYS_break" #endif { - unsigned_word new_sbrk = ALIGN_PAGE(cpu_registers(processor)->gpr[3]); - unsigned_word old_sbrk = core_data_upper_bound(cpu_core(processor)); - signed_word delta = new_sbrk - old_sbrk; + /* pretend to extend the heap so that it reaches addresss + new_break while in truth, if growth is needed grow it by a + page aligned amount */ + unsigned_word new_break = ALIGN_8(cpu_registers(processor)->gpr[3]); + unsigned_word old_break = core_data_upper_bound(cpu_core(processor)); + signed_word delta = new_break - old_break; if (delta > 0) - core_add_data(cpu_core(processor), delta); + core_add_data(cpu_core(processor), + ALIGN_PAGE(new_break) - old_break); cpu_registers(processor)->gpr[0] = 0; - cpu_registers(processor)->gpr[3] = new_sbrk; + cpu_registers(processor)->gpr[3] = new_break; break; } |