sparc: fix boot MMU code

Apparently it worked by luck only on the Ultra60. Physical addresses for
openfirmware are on two cells (128 bits!) and we were passing only one
cell, of course this wouldn't go well. On the Ultra5 it ended up having
the heap point to unused space besides the RAM, so it was mostly reading
random data from there.

Change-Id: I4f9010013fe91a582e5daa83e6bf458703adba2b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2350
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2020-03-14 16:14:34 +01:00 committed by waddlesplash
parent 5f86d837c0
commit 6d929a001e

View File

@ -28,9 +28,10 @@
#define PAGE_READ_ONLY 0x0002
#define PAGE_READ_WRITE 0x0001
// NULL is actually a possible physical address...
//#define PHYSINVAL ((void *)-1)
#define PHYSINVAL NULL
// NULL is actually a possible physical address, so use -1 (which is
// misaligned, so not a valid address) as the invalid physical address.
#define PHYSINVAL ((void *)-1)
//#define PHYSINVAL NULL
//#define TRACE_MMU
#ifdef TRACE_MMU
@ -157,8 +158,8 @@ static bool
map_range(void *virtualAddress, void *physicalAddress, size_t size, uint16 mode)
{
// everything went fine, so lets mark the space as used.
int status = of_call_method(sMmuInstance, "map", 4, 0, mode, size,
virtualAddress, physicalAddress);
int status = of_call_method(sMmuInstance, "map", 5, 0, (uint64)mode, size,
virtualAddress, 0, physicalAddress);
if (status != 0) {
dprintf("map_range(base: %p, size: %" B_PRIuSIZE ") "
@ -182,12 +183,17 @@ find_allocated_ranges(void **_exceptionHandlers)
struct translation_map {
void *PhysicalAddress() {
int64_t p = data;
#if 0
// The openboot own "map?" word does not do this, so it must not
// be needed
// Sign extend
p <<= 23;
p >>= 23;
#endif
// Remove low bits
p &= 0xFFFFFFFFFFFFE000ll;
// Keep only PA[40:13]
// FIXME later CPUs have some more bits here
p &= 0x000001FFFFFFE000ll;
return (void*)p;
}
@ -219,7 +225,7 @@ find_allocated_ranges(void **_exceptionHandlers)
for (int i = 0; i < length; i++) {
struct translation_map *map = &translations[i];
bool keepRange = true;
TRACE("%i: map: %p, length %ld -> phy %p mode %d\n", i,
TRACE("%i: map: %p, length %ld -> phy %p mode %d: ", i,
map->virtual_address, map->length,
map->PhysicalAddress(), map->Mode());
@ -246,8 +252,7 @@ find_allocated_ranges(void **_exceptionHandlers)
// insert range in virtual ranges to keep
if (keepRange) {
TRACE("%i: keeping free range starting at va %p\n", i,
map->virtual_address);
TRACE("keeping\n");
if (insert_virtual_range_to_keep(map->virtual_address,
map->length) != B_OK) {
@ -255,6 +260,8 @@ find_allocated_ranges(void **_exceptionHandlers)
"(num ranges = %" B_PRIu32 ")\n",
gKernelArgs.num_virtual_allocated_ranges);
}
} else {
TRACE("dropping\n");
}
total += map->length;