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]

Re: mips memory sizing in libgloss


I haven't the mips expertise to review this. I might suggest you run it past one or more of the previous maintainers of cma101.c if you are looking for any potential oversights in your logic. Assuming you have tested the change and there are no other objections, consider this approval to apply.

-- Jeff J.

DJ Delorie wrote:
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]