Device tree with early buffer allocations and aliased memory
Grant Likely
grant.likely at secretlab.ca
Sun Oct 31 14:57:34 EST 2010
On Wed, Oct 27, 2010 at 2:49 PM, David VomLehn <dvomlehn at cisco.com> wrote:
> This is a very long question and appreciate your forebearance--I'm using
> Linux and I have a pretty complicated memory structure for which I'm
> trying to define a device tree and I need some help making sense out
> it all. The basic scenario:
> 1 I'm using a MIPS processor, which has low memory from 0x0 to
> 0x1fffffff.
> 2. I have two banks of memory with the following DMA addresses:
> Bank 0 0x20000000-0x3fffffff
> Bank 1 0x60000000-0x7fffffff
> With a page map, the processor can also get to these so they
> are also physical addresses.
> 3. All device registers are at physical addresses < 0x10000000.
Inside of the low memory region?
> 4. Since the processor needs memory to run, the first 0x0fc00000
> bytes also appear at 0x10000000. Our hardware guys call this
> a memory "alias". These addresses are physical, but not DMA
> addresses. (The hole is so we can alias the reset vector)
Not sure I'm clear. How does the hole work? It might be useful to
draw a map of the various ranges rather than trying to describe it in
prose. So is phys address range 0x00000000-0x0fc00000 aliased to
0x10000000-0x1fc00000?
> 5. We need huge buffers (up to 80 MiB) that are way too large to
> allocate with the usual functions, so we allocate them very
> early through the bootmem allocator. Some of these must be
> at a fixed address and some may be allocated in one or the
> other bank of memory. Dynamic address assignment is generally
> preferred to avoid overlapping static assignments.
>
> Memory seems straight-forward-just use the process physical addresses
> wherever possible:
>
> memories {
> memory at 10000000 {
> device_type = "memory";
> reg = <10000000 0x0fc00000>;
> };
> memory at 20000000 {
> device_type = "memory";
> reg = <2fc00000 10400000>;
> };
> memory at 60000000 {
> default_type = "memory";
> reg = <60000000 20000000>;
> };
> };
You don't need three separate nodes here. Just do it thusly:
memory at 10000000 {
device_type = "memory";
reg = <0x10000000 0x0fc00000
0x2fc00000 0x10400000
0x60000000 0x20000000>;
}
Since (I assume) both #address-cells and #size-cells are 1, the OS can
interpret three memory ranges from a single node.
> For a device with buffers allocated at a static address in memory
> without an alias I use a new property, cisco,memory-buffers, which
> specifies triples for buffers where:
> item 1 Lowest allowable address of the first byte of the buffer
> item 2 Highest allowable address of the last byte of the buffer
> item 3 Number of bytes in the buffer.
This is a little odd. Is the dma-ranges property not suitable to
describe which address ranges are actually available for DMA'ing into
for each bus?
> If item 1 = item 2 - item 3 this buffer must be allocated at the address
> given in item 1, i.e. it has a static address. Otherwise it may be
> dynamically allocated within the given range:
>
> static-dev-noalias at 08000000 {
> compatible = "cisco,static-dev-noalias";
> reg = <0x08000000>;
Unless the paren't #size-cells = 0, this reg property is broken
because it doesn't have the size field.
> cisco,memory-buffers=<0x60000000 0x60200000 0x00200000>;
> };
>
> I think this is reasonable, though I'd prefer a standard way to specify
> memory buffers allocation parameters. Things get complicated for a device
> with buffers dynamically allocated in the part of memory with an alias.
> The device registers are still in non-aliased memory, so this isn't a
> completely independent bus:
>
> dyn-dev-alias at 08001000 {
> compatible = "cisco,dyn-dev-alias";
> reg = <0x08001000>;
> cisco,memory-buffers = <0x10000000 0x1fb00000 0x00100000>;
> };
>
> The problem is that I haven't supplied enough information to turn the
> memory buffer physical addresses into DMA addresses, but if I wrap this
> in something like a simple-bus, the address for the reg property will
> be wrong.
How so? Address translation should work if the properties are set up correctly.
> I could simply adjust it, but then it gets a lot harder to
> read and maintain.
>
> So, questions:
> 1. Is there a better way to specify parameters for very early
> buffer allocations?
Well, dma-ranges (see ePAPR) can set up the DMA constraints, and then
you can have a simple property just for specifying the required DMA
region size.
> 2. Is there a better way to handle devices whose device registers
> live nicely in physical address space but whose buffers live
> in different physical and DMA address spaces?
dma-ranges is probably what you want.
g.
More information about the devicetree-discuss
mailing list