From d4a57a313137bad9cf9fb899d13b4034bd9d2468 Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Mon, 2 Aug 2004 03:05:09 +0000 Subject: [PATCH] G5 support: handle the case where the OpenFirmware memory array uses 64 bits for the phys address, but only 32 for the virtual address. --- sys/boot/ofw/common/main.c | 34 +++++++++----- sys/boot/ofw/libofw/libofw.h | 9 +++- sys/boot/ofw/libofw/ofw_memory.c | 76 ++++++++++++++++++++++++-------- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c index ada7a1f903d5..23850ebdcc5f 100644 --- a/sys/boot/ofw/common/main.c +++ b/sys/boot/ofw/common/main.c @@ -42,6 +42,7 @@ extern char bootprog_date[]; extern char bootprog_maker[]; phandle_t chosen; +u_int32_t acells; static char bootargs[128]; @@ -60,31 +61,40 @@ init_heap(void) setheap(base, (void *)((int)base + HEAP_SIZE)); } -uint32_t +uint64_t memsize(void) { ihandle_t meminstance; phandle_t memory; struct ofw_reg reg[4]; + struct ofw_reg2 reg2[8]; int i; - int sz, memsz; + u_int64_t sz, memsz; OF_getprop(chosen, "memory", &meminstance, sizeof(meminstance)); memory = OF_instance_to_package(meminstance); - sz = OF_getprop(memory, "reg", ®, sizeof(reg)); + if (acells == 1) { + sz = OF_getprop(memory, "reg", ®, sizeof(reg)); + sz /= sizeof(struct ofw_reg); - sz /= sizeof(struct ofw_reg); + for (i = 0, memsz = 0; i < sz; i++) + memsz += reg[i].size; + } else if (acells == 2) { + sz = OF_getprop(memory, "reg", ®2, sizeof(reg2)); + sz /= sizeof(struct ofw_reg2); + + for (i = 0, memsz = 0; i < sz; i++) + memsz += reg2[i].size; + } - for (i = 0, memsz = 0; i < sz; i++) - memsz += reg[i].size; - return (memsz); } int main(int (*openfirm)(void *)) { + phandle_t root; int i; char bootpath[64]; char *ch; @@ -96,8 +106,12 @@ main(int (*openfirm)(void *)) */ OF_init(openfirm); + root = OF_finddevice("/"); chosen = OF_finddevice("/chosen"); + acells = 1; + OF_getprop(root, "#address-cells", &acells, sizeof(acells)); + /* * Set up console. */ @@ -125,7 +139,7 @@ main(int (*openfirm)(void *)) printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); - printf("Memory: %dKB\n", memsize() / 1024); + printf("Memory: %lldKB\n", memsize() / 1024); OF_getprop(chosen, "bootpath", bootpath, 64); ch = index(bootpath, ':'); @@ -142,7 +156,7 @@ main(int (*openfirm)(void *)) bargc = 0; parse(&bargc, &bargv, bootargs); if (bargc == 1) - env_setenv("currdev", EV_VOLATILE, bargv[0], ofw_setcurrdev, + env_setenv("currdev", EV_VOLATILE, bargv[0], ofw_setcurrdev, env_nounset); else env_setenv("currdev", EV_VOLATILE, bootpath, @@ -180,6 +194,6 @@ int command_memmap(int argc, char **argv) { - ofw_memmap(); + ofw_memmap(acells); return (CMD_OK); } diff --git a/sys/boot/ofw/libofw/libofw.h b/sys/boot/ofw/libofw/libofw.h index 9440a2e511bd..f3a2d8c05423 100644 --- a/sys/boot/ofw/libofw/libofw.h +++ b/sys/boot/ofw/libofw/libofw.h @@ -50,7 +50,7 @@ ssize_t ofw_readin(const int fd, vm_offset_t dest, const size_t len); extern int ofw_boot(void); extern int ofw_autoload(void); -void ofw_memmap(void); +void ofw_memmap(int); void *ofw_alloc_heap(unsigned int); void ofw_release_heap(void); @@ -70,4 +70,11 @@ struct ofw_reg cell_t size; }; +struct ofw_reg2 +{ + cell_t base_hi; + cell_t base_lo; + cell_t size; +}; + extern int (*openfirmware)(void *); diff --git a/sys/boot/ofw/libofw/ofw_memory.c b/sys/boot/ofw/libofw/ofw_memory.c index c23ab8e94b08..5239fa2be8ee 100644 --- a/sys/boot/ofw/libofw/ofw_memory.c +++ b/sys/boot/ofw/libofw/ofw_memory.c @@ -45,34 +45,74 @@ struct ofw_mapping { int mode; }; +struct ofw_mapping2 { + vm_offset_t va; + int len; + vm_offset_t pa_hi; + vm_offset_t pa_lo; + int mode; +}; + void -ofw_memmap(void) +ofw_memmap(int acells) { - phandle_t mmup; - int nmapping, i; - struct ofw_mapping mappings[256]; - - mmup = OF_instance_to_package(mmu); - - bzero(mappings, sizeof(mappings)); - - nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings)); + struct ofw_mapping *mapptr; + struct ofw_mapping2 *mapptr2; + phandle_t mmup; + int nmapping, i; + u_char mappings[256 * sizeof(struct ofw_mapping2)]; + char lbuf[80]; + + mmup = OF_instance_to_package(mmu); + + bzero(mappings, sizeof(mappings)); + + nmapping = OF_getprop(mmup, "translations", mappings, sizeof(mappings)); if (nmapping == -1) { printf("Could not get memory map (%d)\n", nmapping); return; } - nmapping /= sizeof(struct ofw_mapping); - printf("%17s %17s %8s %6s\n", "Virtual Range", "Physical Range", - "#Pages", "Mode"); + pager_open(); + if (acells == 1) { + nmapping /= sizeof(struct ofw_mapping); + mapptr = (struct ofw_mapping *) mappings; - for (i = 0; i < nmapping; i++) { - printf("%08x-%08x %08x-%08x %8d %6x\n", mappings[i].pa, - mappings[i].pa + mappings[i].len, mappings[i].va, - mappings[i].va + mappings[i].len, mappings[i].len / 0x1000, - mappings[i].mode); + printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range", + "Physical Range", "#Pages", "Mode"); + + for (i = 0; i < nmapping; i++) { + sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n", + mapptr[i].va, + mapptr[i].va + mapptr[i].len, + mapptr[i].pa, + mapptr[i].pa + mapptr[i].len, + mapptr[i].len / 0x1000, + mapptr[i].mode); + if (pager_output(lbuf)) + break; + } + } else { + nmapping /= sizeof(struct ofw_mapping2); + mapptr2 = (struct ofw_mapping2 *) mappings; + + printf("%17s\t%17s\t%8s\t%6s\n", "Virtual Range", + "Physical Range", "#Pages", "Mode"); + + for (i = 0; i < nmapping; i++) { + sprintf(lbuf, "%08x-%08x\t%08x-%08x\t%8d\t%6x\n", + mapptr2[i].va, + mapptr2[i].va + mapptr2[i].len, + mapptr2[i].pa_lo, + mapptr2[i].pa_lo + mapptr2[i].len, + mapptr2[i].len / 0x1000, + mapptr2[i].mode); + if (pager_output(lbuf)) + break; + } } + pager_close(); } void *