aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc/ofw
diff options
context:
space:
mode:
authorNathan Whitehorn <nwhitehorn@FreeBSD.org>2011-06-02 17:43:17 +0000
committerNathan Whitehorn <nwhitehorn@FreeBSD.org>2011-06-02 17:43:17 +0000
commit48174c14b552af1d45b1fa074b2d3ba1e3c47dfb (patch)
tree4d97de756412c70db93239d087fe1fbd83582914 /sys/powerpc/ofw
parent17763042e4fd3df8b6476726c2623e53346bf174 (diff)
downloadsrc-48174c14b552af1d45b1fa074b2d3ba1e3c47dfb.tar.gz
src-48174c14b552af1d45b1fa074b2d3ba1e3c47dfb.zip
Temporarily back out those parts of r222613 related to parsing the memory
map. They cause non-understood boot failures on some Apple machines with more than 2 GB of RAM (like my work desktop).
Notes
Notes: svn path=/head/; revision=222622
Diffstat (limited to 'sys/powerpc/ofw')
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c169
1 files changed, 25 insertions, 144 deletions
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index f60243044bcf..2f1e770941dc 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -60,15 +60,18 @@ __FBSDID("$FreeBSD$");
#include <machine/platform.h>
#include <machine/ofw_machdep.h>
-static struct mem_region OFmem[PHYS_AVAIL_SZ], OFavail[PHYS_AVAIL_SZ];
-static struct mem_region OFfree[PHYS_AVAIL_SZ];
+#define OFMEM_REGIONS 32
+static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
+static struct mem_region OFfree[OFMEM_REGIONS + 3];
+static int nOFmem;
extern register_t ofmsr[5];
+int ofwcall(void *);
extern void *openfirmware_entry;
static void *fdt;
int ofw_real_mode;
-int ofwcall(void *);
+int ofw_32bit_mode_entry(void *);
static void ofw_quiesce(void);
static int openfirmware(void *args);
@@ -132,32 +135,11 @@ memr_merge(struct mem_region *from, struct mem_region *to)
to->mr_size = end - to->mr_start;
}
-/*
- * Quick sort callout for comparing memory regions.
- */
-static int mr_cmp(const void *a, const void *b);
-
-static int
-mr_cmp(const void *a, const void *b)
-{
- const struct mem_region *regiona;
- const struct mem_region *regionb;
-
- regiona = a;
- regionb = b;
- if (regiona->mr_start < regionb->mr_start)
- return (-1);
- else if (regiona->mr_start > regionb->mr_start)
- return (1);
- else
- return (0);
-}
-
static int
parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
{
cell_t address_cells, size_cells;
- cell_t OFmem[4 * PHYS_AVAIL_SZ];
+ cell_t OFmem[4*(OFMEM_REGIONS + 1)];
int sz, i, j;
int apple_hack_mode;
phandle_t phandle;
@@ -194,7 +176,7 @@ parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
* Get memory.
*/
if ((node == -1) || (sz = OF_getprop(node, prop,
- OFmem, sizeof(OFmem[0]) * 4 * PHYS_AVAIL_SZ)) <= 0)
+ OFmem, sizeof(OFmem[0]) * 4 * OFMEM_REGIONS)) <= 0)
panic("Physical memory map not found");
i = 0;
@@ -244,7 +226,7 @@ parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
#ifdef __powerpc64__
if (apple_hack_mode) {
/* Add in regions above 4 GB to the available list */
- struct mem_region himem[PHYS_AVAIL_SZ];
+ struct mem_region himem[OFMEM_REGIONS];
int hisz;
hisz = parse_ofw_memory(node, "reg", himem);
@@ -262,81 +244,6 @@ parse_ofw_memory(phandle_t node, const char *prop, struct mem_region *output)
return (sz);
}
-static int
-parse_drconf_memory(int *msz, int *asz, struct mem_region *ofmem,
- struct mem_region *ofavail)
-{
- phandle_t phandle;
- vm_offset_t base;
- int i, idx, len, lasz, lmsz, res;
- uint32_t lmb_size[2];
- unsigned long *dmem, flags;
-
- lmsz = *msz;
- lasz = *asz;
-
- phandle = OF_finddevice("/ibm,dynamic-reconfiguration-memory");
- if (phandle == -1)
- /* No drconf node, return. */
- return (0);
-
- res = OF_getprop(phandle, "ibm,lmb-size", lmb_size, sizeof(lmb_size));
- if (res == -1)
- return (0);
-
- /* Parse the /ibm,dynamic-memory.
- The first position gives the # of entries. The next two words
- reflect the address of the memory block. The next four words are
- the DRC index, reserved, list index and flags.
- (see PAPR C.6.6.2 ibm,dynamic-reconfiguration-memory)
-
- #el Addr DRC-idx res list-idx flags
- -------------------------------------------------
- | 4 | 8 | 4 | 4 | 4 | 4 |....
- -------------------------------------------------
- */
-
- len = OF_getproplen(phandle, "ibm,dynamic-memory");
- if (len > 0) {
-
- /* We have to use a variable length array on the stack
- since we have very limited stack space.
- */
- cell_t arr[len/sizeof(cell_t)];
-
- res = OF_getprop(phandle, "ibm,dynamic-memory", &arr,
- sizeof(arr));
- if (res == -1)
- return (0);
-
- /* Number of elements */
- idx = arr[0];
-
- /* First address. */
- dmem = (void*)&arr[1];
-
- for (i = 0; i < idx; i++) {
- base = *dmem;
- dmem += 2;
- flags = *dmem;
- /* Use region only if available and not reserved. */
- if ((flags & 0x8) && !(flags & 0x80)) {
- ofmem[lmsz].mr_start = base;
- ofmem[lmsz].mr_size = (vm_size_t)lmb_size[1];
- ofavail[lasz].mr_start = base;
- ofavail[lasz].mr_size = (vm_size_t)lmb_size[1];
- lmsz++;
- lasz++;
- }
- dmem++;
- }
- }
-
- *msz = lmsz;
- *asz = lasz;
-
- return (1);
-}
/*
* This is called during powerpc_init, before the system is really initialized.
* It shall provide the total and the available regions of RAM.
@@ -349,62 +256,31 @@ ofw_mem_regions(struct mem_region **memp, int *memsz,
struct mem_region **availp, int *availsz)
{
phandle_t phandle;
- vm_offset_t maxphysaddr;
int asz, msz, fsz;
- int i, j, res;
+ int i, j;
int still_merging;
- char name[31];
asz = msz = 0;
/*
- * Get memory from all the /memory nodes.
+ * Get memory.
*/
- for (phandle = OF_child(OF_peer(0)); phandle != 0;
- phandle = OF_peer(phandle)) {
- if (OF_getprop(phandle, "name", name, sizeof(name)) <= 0)
- continue;
- if (strncmp(name, "memory", sizeof(name)) != 0)
- continue;
-
- res = parse_ofw_memory(phandle, "reg", &OFmem[msz]);
- msz += res/sizeof(struct mem_region);
- if (OF_getproplen(phandle, "available") >= 0)
- res = parse_ofw_memory(phandle, "available",
- &OFavail[asz]);
- else
- res = parse_ofw_memory(phandle, "reg", &OFavail[asz]);
- asz += res/sizeof(struct mem_region);
- }
-
- /* Check for memory in ibm,dynamic-reconfiguration-memory */
- parse_drconf_memory(&msz, &asz, OFmem, OFavail);
+ phandle = OF_finddevice("/memory");
+ if (phandle == -1)
+ phandle = OF_finddevice("/memory@0");
- qsort(OFmem, msz, sizeof(*OFmem), mr_cmp);
- qsort(OFavail, asz, sizeof(*OFavail), mr_cmp);
+ msz = parse_ofw_memory(phandle, "reg", OFmem);
+ nOFmem = msz / sizeof(struct mem_region);
+ asz = parse_ofw_memory(phandle, "available", OFavail);
*memp = OFmem;
- *memsz = msz;
-
- /*
- * On some firmwares (SLOF), some memory may be marked available that
- * doesn't actually exist. This manifests as an extension of the last
- * available segment past the end of physical memory, so truncate that
- * one.
- */
- maxphysaddr = 0;
- for (i = 0; i < msz; i++)
- if (OFmem[i].mr_start + OFmem[i].mr_size > maxphysaddr)
- maxphysaddr = OFmem[i].mr_start + OFmem[i].mr_size;
-
- if (OFavail[asz - 1].mr_start + OFavail[asz - 1].mr_size > maxphysaddr)
- OFavail[asz - 1].mr_size = maxphysaddr -
- OFavail[asz - 1].mr_start;
-
+ *memsz = nOFmem;
+
/*
* OFavail may have overlapping regions - collapse these
* and copy out remaining regions to OFfree
*/
+ asz /= sizeof(struct mem_region);
do {
still_merging = FALSE;
for (i = 0; i < asz; i++) {
@@ -593,7 +469,12 @@ openfirmware(void *args)
int result;
#ifdef SMP
struct ofw_rv_args rv_args;
+ #endif
+ if (pmap_bootstrapped && ofw_real_mode)
+ args = (void *)pmap_kextract((vm_offset_t)args);
+
+ #ifdef SMP
rv_args.args = args;
rv_args.in_progress = 1;
smp_rendezvous(smp_no_rendevous_barrier, ofw_rendezvous_dispatch,