This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips memory sizing in libgloss


libgloss/mips/cma101.c has a function called __sizemem() that cleverly
switches to non-cached kseg1 to size memory.  However, our vr9721
boards seem to have some cache still enabled even in kseg1, so we end
up with the wrong $sp at startup.

I wrote a new function __destructive_mem_top() that tests for the top
of memory in a way that flushes the cache anyway.  It returns the
correct value, but can't replace __sizemem() for other purposes
(sbrk() calls it) because it's destructive, although it does set
__sizemem_default to avoid duplicate work.

Comments?  Problems?  Approval? ;-)

DJ

	* mips/cma101.c (__destructive_mem_top): New.
	* mips/crt0.S: Use it.

Index: cma101.c
===================================================================
RCS file: /cvs/src/src/libgloss/mips/cma101.c,v
retrieving revision 1.5
diff -p -U3 -r1.5 cma101.c
--- cma101.c	2 May 2003 20:06:52 -0000	1.5
+++ cma101.c	1 Jun 2007 21:05:12 -0000
@@ -258,6 +258,68 @@ __sizemem ()
   return((probe - base) * sizeof(unsigned int));
 }
 
+/* Similar to the above, but destructively tests in case the cache is
+   partially enabled (vr9721).  Used only by crt0.  */
+void *
+__destructive_mem_top ()
+{
+  volatile unsigned int *base;
+  volatile unsigned int *probe, *maxtop;
+  unsigned int baseorig;
+  unsigned int sr;
+  extern char end[];
+  char *endptr = (char *)&end;
+  int extra, offset;
+
+  /* Max of 2Gb RAM.  */
+  maxtop = 0x80000000;
+  offset = 0;
+
+  /* If we are running in kernel segment 0 (possibly cached), try sizing memory
+     in kernel segment 1 (uncached) to avoid some problems with monitors.  */
+  if (endptr >= K0BASE_ADDR && endptr < K1BASE_ADDR)
+    {
+      endptr = (endptr - K0BASE_ADDR) + K1BASE_ADDR;
+      /* Should be 0xB0000000 - 512M RAM.  */
+      maxtop = K1BASE_ADDR + (K1BASE_ADDR - K0BASE_ADDR);
+      offset = K1BASE_ADDR - K0BASE_ADDR;
+    }
+
+  INTDISABLE(sr,baseorig); /* disable all interrupt masks */
+
+  __default_buserr_handler();
+  __cpu_flush();
+
+  DOSYNC();
+
+  /* Align to our step, so that the first failing step is just after
+     the last byte of memory.  */
+  extra = ((int) endptr & (SM_INCR - 1));
+  base = ((void *) endptr + SM_INCR - extra);
+  baseorig = *base;
+
+  for (probe = base; probe < maxtop; probe += SM_INCR)
+    *probe = (unsigned int)probe;
+  DOSYNC();
+  for (probe = base; probe < maxtop; probe += SM_INCR)
+    if (*probe != (unsigned int)probe)
+      break;
+
+  probe -= (SM_INCR / sizeof(*probe));
+
+  *base = baseorig;
+  __restore_buserr_handler();
+  __cpu_flush();
+
+  DOSYNC();
+
+  INTRESTORE(sr); /* restore interrupt mask to entry state */
+
+  __sizemem_default = ((probe - base) * sizeof(unsigned int));
+
+  return (char *)probe - offset;
+}
+
 /* Provided as a function, so as to avoid reading the I/O location
    multiple times: */
 static int
Index: crt0.S
===================================================================
RCS file: /cvs/src/src/libgloss/mips/crt0.S,v
retrieving revision 1.11
diff -p -U3 -r1.11 crt0.S
--- crt0.S	27 Nov 2006 16:12:51 -0000	1.11
+++ crt0.S	1 Jun 2007 21:05:12 -0000
@@ -161,12 +161,11 @@ zerobss:
 	bne	t0,zero,4f
 	nop
 
-	/* NOTE: a0[0] contains the amount of memory available, and
-	         not the last memory address. */
-	la	a0, __memsize
-	lw	t0,0(a0)			# last address of memory available
-	la	t1,K0BASE			# cached kernel memory
-	addu	t0,t0,t1			# get the end of memory address
+	jal	__destructive_mem_top
+	nop
+	/* NOTE: v0 now contains a pointer to the first invalid memory location. */
+
+	move	t0,v0
 	/* Allocate 32 bytes for the register parameters.  Allocate 16
 	   bytes for a null argv and envp.  Round the result up to 64
 	   bytes to preserve alignment.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]