On 01/01/2019 21:21, Mark Cave-Ayland wrote:
Currently the /memory node reg property is set to a single range encompassing the entire physical RAM of the machine. This seems to cause issues with Solaris when booting on QEMU SS-10 and SS-20 machines whereby having just a single entry causes the top of physical memory to be calculated incorrectly and triggers a panic on boot.
Instead copy the behaviour of OBP which is to divide the reg property into a set of ranges representing the physical SIMM arrangement in the machine, which fixes the error and allows Solaris to boot under the QEMU SS-10 and SS-20 machines.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
arch/sparc32/boot.h | 2 +- arch/sparc32/lib.c | 14 +++++++++----- arch/sparc32/openbios.c | 6 +++++- 3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/arch/sparc32/boot.h b/arch/sparc32/boot.h index e372acc..366e0f6 100644 --- a/arch/sparc32/boot.h +++ b/arch/sparc32/boot.h @@ -33,5 +33,5 @@ extern struct linux_mlist_v0 *ptphys; extern struct linux_mlist_v0 *ptmap; extern struct linux_mlist_v0 *ptavail;
-void ob_init_mmu(void); +void ob_init_mmu(uint32_t simm_size); void init_mmu_swift(void); diff --git a/arch/sparc32/lib.c b/arch/sparc32/lib.c index e88c0bf..727929c 100644 --- a/arch/sparc32/lib.c +++ b/arch/sparc32/lib.c @@ -294,12 +294,13 @@ static void ignore_dfault_addr(void) }
void -ob_init_mmu(void) +ob_init_mmu(uint32_t simm_size) { ucell *memreg; ucell *virtreg; phys_addr_t virtregsize; ofmem_t *ofmem = ofmem_arch_get_private();
int i, c;
/* Find the phandles for the /memory and /virtual-memory nodes */ push_str("/memory");
@@ -315,14 +316,17 @@ ob_init_mmu(void) ofmem_register(s_phandle_memory, s_phandle_mmu);
/* Setup /memory:reg (totphys) property */
- memreg = malloc(3 * sizeof(ucell));
- ofmem_arch_encode_physaddr(memreg, 0); /* physical base */
- memreg[2] = (ucell)ofmem->ramsize; /* size */
c = ofmem->ramsize / simm_size;
memreg = malloc(3 * c * sizeof(ucell));
for (i = 0; i < c; i++) {
ofmem_arch_encode_physaddr(&memreg[i * 3], simm_size * i); /* physical base */
memreg[i * 3 + 2] = simm_size; /* size */
}
push_str("/memory"); fword("find-device"); PUSH(pointer2cell(memreg));
- PUSH(3 * sizeof(ucell));
- PUSH(3 * c * sizeof(ucell)); push_str("reg"); PUSH_ph(s_phandle_memory); fword("encode-property");
diff --git a/arch/sparc32/openbios.c b/arch/sparc32/openbios.c index 3ec8fd7..17a6550 100644 --- a/arch/sparc32/openbios.c +++ b/arch/sparc32/openbios.c @@ -42,6 +42,7 @@ struct hwdef { unsigned long aux1_offset, aux2_offset; uint64_t dma_base, esp_base, le_base; uint64_t tcx_base;
- uint32_t simm_size; int intr_ncpu; int mid_offset; int machine_id_low, machine_id_high;
@@ -65,6 +66,7 @@ static const struct hwdef hwdefs[] = { .dma_base = 0x78400000, .esp_base = 0x78800000, .le_base = 0x78c00000,
.simm_size = 0x2000000, .mid_offset = 0, .machine_id_low = 32, .machine_id_high = 63,
@@ -86,6 +88,7 @@ static const struct hwdef hwdefs[] = { .dma_base = 0xef0400000ULL, .esp_base = 0xef0800000ULL, .le_base = 0xef0c00000ULL,
.simm_size = 0x4000000, .mid_offset = 8, .machine_id_low = 64, .machine_id_high = 65,
@@ -107,6 +110,7 @@ static const struct hwdef hwdefs[] = { .dma_base = 0xef0081000ULL, .esp_base = 0xef0080000ULL, .le_base = 0xef0060000ULL,
.simm_size = 0x4000000, .mid_offset = 8, .machine_id_low = 66, .machine_id_high = 66,
@@ -874,7 +878,7 @@ arch_init( void )
openbios_init(); modules_init();
ob_init_mmu();
ob_init_mmu(hwdef->simm_size); ob_init_iommu(hwdef->iommu_base); bind_func("(sparc32-dma-alloc)", dma_alloc);
Seems good in testing here, so I've pushed this to OpenBIOS master (with a slight rewording of the subject line).
ATB,
Mark.