devicetree-spec.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* How to describe internal flash (ROM) in the microcontroller
@ 2017-04-22 18:47 Freddie Chopin
       [not found] ` <1492886823.1240.5.camel-FWhLrETftxM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Freddie Chopin @ 2017-04-22 18:47 UTC (permalink / raw)
  To: devicetree-spec-u79uwXL29TY76Z2rM5mHXA

Hello!

For my project - http://distortos.org/ - which is a C++ RTOS for
microcontrollers, I decided to use devicetree to configure hardware.
Currently the project uses kconfig, but for configuring hardware this
gets unmanageable and just too big and too restrictive. My plan is to
gradually convert to *.dts and the first step I wanted to make is to
convert addresses and sizes of memory (which I'll later read from *.dts
file to generate linker script).

To cut a long story short - there's no issue in adding RAM (internal
chip's SRAM) - just add that as one or more /memory node. However I
also need to do something for which I found absolutely no info, no
example and no binding - I also need to describe **internal** ROM
(internal on-chip flash memory). Please note that this is _not_
something which can be described as "nand-flash", "nor-flash", "emmc",
"qspi" or things like that - this memory is not externally connected
via some interface - it is "built-in" into the chip.

I have thought about two options to do that, but can't decide which one
fits better, so I decided to ask here, as you've been working with
devicetrees for quite a long time.

Option 1

Generally this is similar to what Zephyr RTOS has done, which is to
just introduce a new /flash node. This has a disadvantage of being non-
standard.

https://github.com/zephyrproject-rtos/zephyr/blob/master/dts/arm/st/stm32l476.dtsi#L11

Option 2

Describe flash as a separate /memory node and add "read-only;" property
there to designate it as "not-RAM". In my personal opinion this fits
nicely with other parts of spec (and fits with /reserved-memory nodes
concept from Linux). However I'm not sure whether the idea of "read-
only" memory region makes any sense according to your concepts. BTW
some other property would also work fine here, generally anything that
would allow me to know which is flash and which is RAM, so I could use
them for different parts of linker script.

Or maybe instead of adding "read-only;" I should use sth like this in
my flash /memory node:

compatible="internal-flash";

For "option 2" there's also another question - I may need to add some
more non-standard properties for such nodes, for example with
configuration of latency or for configuration of LMA address which will
be used by linker (for example in STM32F7 microcontrollers flash can be
accessed via two different buses, but written only via one - as the one
which can be used for writes is slower, it is preferable to use
different VMA/LMA addresses). This can actually be done with virtual-
reg property (where reg would have LMA and virtual-reg - VMA), but I'm
sure the need for something non-standard would arrive some day or
another. Would that still fit?

Thanks in advance for all ideas!

Regards,
FCh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found] ` <1492886823.1240.5.camel-FWhLrETftxM@public.gmane.org>
@ 2017-04-24  1:27   ` David Gibson
       [not found]     ` <20170424012734.GB16882-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: David Gibson @ 2017-04-24  1:27 UTC (permalink / raw)
  To: Freddie Chopin; +Cc: devicetree-spec-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 5172 bytes --]

On Sat, Apr 22, 2017 at 08:47:03PM +0200, Freddie Chopin wrote:
> Hello!
> 
> For my project - http://distortos.org/ - which is a C++ RTOS for
> microcontrollers, I decided to use devicetree to configure hardware.
> Currently the project uses kconfig, but for configuring hardware this
> gets unmanageable and just too big and too restrictive. My plan is to
> gradually convert to *.dts and the first step I wanted to make is to
> convert addresses and sizes of memory (which I'll later read from *.dts
> file to generate linker script).
> 
> To cut a long story short - there's no issue in adding RAM (internal
> chip's SRAM) - just add that as one or more /memory node. However I
> also need to do something for which I found absolutely no info, no
> example and no binding - I also need to describe **internal** ROM
> (internal on-chip flash memory). Please note that this is _not_
> something which can be described as "nand-flash", "nor-flash", "emmc",
> "qspi" or things like that - this memory is not externally connected
> via some interface - it is "built-in" into the chip.
> 
> I have thought about two options to do that, but can't decide which one
> fits better, so I decided to ask here, as you've been working with
> devicetrees for quite a long time.
> 
> Option 1
> 
> Generally this is similar to what Zephyr RTOS has done, which is to
> just introduce a new /flash node. This has a disadvantage of being non-
> standard.
> 
> https://github.com/zephyrproject-rtos/zephyr/blob/master/dts/arm/st/stm32l476.dtsi#L11
> 
> Option 2
> 
> Describe flash as a separate /memory node and add "read-only;" property
> there to designate it as "not-RAM". In my personal opinion this fits
> nicely with other parts of spec (and fits with /reserved-memory nodes
> concept from Linux). However I'm not sure whether the idea of "read-
> only" memory region makes any sense according to your concepts. BTW
> some other property would also work fine here, generally anything that
> would allow me to know which is flash and which is RAM, so I could use
> them for different parts of linker script.
> 
> Or maybe instead of adding "read-only;" I should use sth like this in
> my flash /memory node:
> 
> compatible="internal-flash";
> 
> For "option 2" there's also another question - I may need to add some
> more non-standard properties for such nodes, for example with
> configuration of latency or for configuration of LMA address which will
> be used by linker (for example in STM32F7 microcontrollers flash can be
> accessed via two different buses, but written only via one - as the one
> which can be used for writes is slower, it is preferable to use
> different VMA/LMA addresses). This can actually be done with virtual-
> reg property (where reg would have LMA and virtual-reg - VMA), but I'm
> sure the need for something non-standard would arrive some day or
> another. Would that still fit?
> 
> Thanks in advance for all ideas!

Right, so basically you need a binding for your flash device - a
binding is the formal description of how a particular sort of device
should be represented in the device tree.  It's not uncommon for new
ports to require a few new bindings for "system" devices.

First off, I think you want option 1, more or less.  Although I think
it originally had a wider meaning, for a long time memory@ nodes have
been used pretty much exclusively for general purpose RAM.  I wouldn't
suggest overloading that binding for something quite different.


I guess in theory I should tell you that all bindings shoul be made
clearly, standardized, published and so forth.  In practice, well,
it's a tradeoff.  Getting a binding reviewed, published and so forth
will generally improve its quality, mean less work for others who use
the device in the future and other good things.  On the other hand it
it can be a lot of work.  It's definitely worth it for common devices;
maybe not so much for board-specific one-offs.

Obviously, the first step is to look for an existing binding for the
device.  How to establish and maintain a canonical repository of
bindings is a subject of continuing debate.  In the meantime the
places to look are Documentation/devicetree/bindings in the Linux
kernel source, and devicetree.org.  There may be other places, but I
don't know them off hand.

From the description of your device, I kind of doubt there's an
existing binding, though.  So you'll need to write one.  Good news is
your device is pretty simple - you can probably copy a binding for a
similar device, and just change the 'compatible' value and make any
few tweaks you need.

I do recommend posting your draft binding here and getting at least
cursory new.  If you're new to writing bindings, there are a fair few
gotchas - things that might not make the binding unusable, but will
differ from existing conventions enough to make life harder for
people.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]     ` <20170424012734.GB16882-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
@ 2017-04-28  7:21       ` Freddie Chopin
       [not found]         ` <1493364100.1425.6.camel-FWhLrETftxM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Freddie Chopin @ 2017-04-28  7:21 UTC (permalink / raw)
  To: devicetree-spec

Hello again!

On Mon, 2017-04-24 at 11:27 +1000, David Gibson wrote:
> Right, so basically you need a binding for your flash device - a
> binding is the formal description of how a particular sort of device
> should be represented in the device tree.  It's not uncommon for new
> ports to require a few new bindings for "system" devices.
> 
> First off, I think you want option 1, more or less.  Although I think
> it originally had a wider meaning, for a long time memory@ nodes have
> been used pretty much exclusively for general purpose RAM.  I
> wouldn't
> suggest overloading that binding for something quite different.
> 
> I guess in theory I should tell you that all bindings shoul be made
> clearly, standardized, published and so forth.  In practice, well,
> it's a tradeoff.  Getting a binding reviewed, published and so forth
> will generally improve its quality, mean less work for others who use
> the device in the future and other good things.  On the other hand it
> it can be a lot of work.  It's definitely worth it for common
> devices;
> maybe not so much for board-specific one-offs.
> 
> Obviously, the first step is to look for an existing binding for the
> device.  How to establish and maintain a canonical repository of
> bindings is a subject of continuing debate.  In the meantime the
> places to look are Documentation/devicetree/bindings in the Linux
> kernel source, and devicetree.org.  There may be other places, but I
> don't know them off hand.
> 
> From the description of your device, I kind of doubt there's an
> existing binding, though.  So you'll need to write one.  Good news is
> your device is pretty simple - you can probably copy a binding for a
> similar device, and just change the 'compatible' value and make any
> few tweaks you need.
> 
> I do recommend posting your draft binding here and getting at least
> cursory new.  If you're new to writing bindings, there are a fair few
> gotchas - things that might not make the binding unusable, but will
> differ from existing conventions enough to make life harder for
> people.

Thank you David for your reply! When I have something ready, I'll post
it here in the hope of some review. As you noticed - this "device" is
indeed extremely simple, so I hope it won't be that hard (;

I'm not so sure about the "standardization" and "publication" part. I
do realize that primary usage of devicetrees will be on "desktop PC"
and the use in microcontrollers is just an interesting curiosity for
now. Apart from the Zephyr project which I mentioned, I only found one
more project for microcontrollers which was using *.dts files - the
F4OS, which unfortunately seems dead. And if Zephyr didn't bother to
standarize and publish anything... (; We'll see how things will evolve.

Anyway - a few more days with devicetree and I have another question. I
don't want to start a new thread for that, as it is related to the
first one anyway. This one is harder, as I found no examples at all, so
I have absolutely nothing to start with. There are microcontroller
cores which may or may not contain a floating-point unit (FPU) - for
example ARM Cortex-M4 may have one or none. There are also
microcontroller cores which may contain either a single-precision or
double-precision FPU - for example ARM Cortex-M7, which may have either
fpv5-sp-d16 or fpv5-d16 FPU. Currently I include that info in the
kconfig system, where appropriate hidden options are set when selecting
a particular chip model/family. As you may imagine I would also like to
have that info in the devicetree. I see several options to express that
information, but I'm not sure which one fits best.

1. In some places the cores which have FPU are suffixed with "F" ("ARM
Cortex-M4" becomes "ARM Cortex-M4F"), so I'm considering embedding that
info inside "compatible" string of the cpu nodes (for example
"arm,cortex-m4" or "arm,cortex-m4f"). The problem here is that this
naming is not official and this wouldn't allow to differentiate between
different types of FPU (for example - does "arm,cortex-m7f" have
single-precision or double-precision FPU).

2. I could just add a non-standard property to cpu nodes (or maybe to
cpus node?), something like:

distortos,fpu = "fpv5-d16";

3. I could add FPU as a new node, where I could describe it with the
standard "compatible" property. I think this is actually the best
approach, but I'm having hard time thinking about location of such node
- should it be placed in the root of the devicetree, or maybe as a
child of the cpu node? The second variant seems to be the best one, as
it fits the scenario of Asymmetric Multiprocessing, where the FPU may
be present only on selected cores.

Could anyone share any pointers on that matter? Again - thanks in
advance!

Regards,
FCh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]         ` <1493364100.1425.6.camel-FWhLrETftxM@public.gmane.org>
@ 2017-04-28 12:59           ` Rob Herring
       [not found]             ` <CAL_Jsq+Gbu35bps2VcQ=pO3WyQE9VZhsuvpKtZ3TJ++B10jPWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Rob Herring @ 2017-04-28 12:59 UTC (permalink / raw)
  To: Freddie Chopin; +Cc: devicetree-spec

On Fri, Apr 28, 2017 at 2:21 AM, Freddie Chopin <freddie_chopin-FWhLrETftxM@public.gmane.org> wrote:
> Hello again!
>
> On Mon, 2017-04-24 at 11:27 +1000, David Gibson wrote:
>> Right, so basically you need a binding for your flash device - a
>> binding is the formal description of how a particular sort of device
>> should be represented in the device tree.  It's not uncommon for new
>> ports to require a few new bindings for "system" devices.
>>
>> First off, I think you want option 1, more or less.  Although I think
>> it originally had a wider meaning, for a long time memory@ nodes have
>> been used pretty much exclusively for general purpose RAM.  I
>> wouldn't
>> suggest overloading that binding for something quite different.
>>
>> I guess in theory I should tell you that all bindings shoul be made
>> clearly, standardized, published and so forth.  In practice, well,
>> it's a tradeoff.  Getting a binding reviewed, published and so forth
>> will generally improve its quality, mean less work for others who use
>> the device in the future and other good things.  On the other hand it
>> it can be a lot of work.  It's definitely worth it for common
>> devices;
>> maybe not so much for board-specific one-offs.
>>
>> Obviously, the first step is to look for an existing binding for the
>> device.  How to establish and maintain a canonical repository of
>> bindings is a subject of continuing debate.  In the meantime the
>> places to look are Documentation/devicetree/bindings in the Linux
>> kernel source, and devicetree.org.  There may be other places, but I
>> don't know them off hand.
>>
>> From the description of your device, I kind of doubt there's an
>> existing binding, though.  So you'll need to write one.  Good news is
>> your device is pretty simple - you can probably copy a binding for a
>> similar device, and just change the 'compatible' value and make any
>> few tweaks you need.
>>
>> I do recommend posting your draft binding here and getting at least
>> cursory new.  If you're new to writing bindings, there are a fair few
>> gotchas - things that might not make the binding unusable, but will
>> differ from existing conventions enough to make life harder for
>> people.
>
> Thank you David for your reply! When I have something ready, I'll post
> it here in the hope of some review. As you noticed - this "device" is
> indeed extremely simple, so I hope it won't be that hard (;
>
> I'm not so sure about the "standardization" and "publication" part. I
> do realize that primary usage of devicetrees will be on "desktop PC"

PC's use ACPI.

> and the use in microcontrollers is just an interesting curiosity for
> now. Apart from the Zephyr project which I mentioned, I only found one
> more project for microcontrollers which was using *.dts files - the
> F4OS, which unfortunately seems dead. And if Zephyr didn't bother to
> standarize and publish anything... (; We'll see how things will evolve.

uC's capable of running Linux generally use DT, too.

> Anyway - a few more days with devicetree and I have another question. I
> don't want to start a new thread for that, as it is related to the
> first one anyway. This one is harder, as I found no examples at all, so
> I have absolutely nothing to start with. There are microcontroller
> cores which may or may not contain a floating-point unit (FPU) - for
> example ARM Cortex-M4 may have one or none. There are also
> microcontroller cores which may contain either a single-precision or
> double-precision FPU - for example ARM Cortex-M7, which may have either
> fpv5-sp-d16 or fpv5-d16 FPU. Currently I include that info in the
> kconfig system, where appropriate hidden options are set when selecting
> a particular chip model/family. As you may imagine I would also like to
> have that info in the devicetree. I see several options to express that
> information, but I'm not sure which one fits best.

Doesn't the M7 have ID registers registers with define the FP
capabilities? It should not be in DT if the feature is discoverable.

Or are you trying to use DT at build time like Zephyr?

> 1. In some places the cores which have FPU are suffixed with "F" ("ARM
> Cortex-M4" becomes "ARM Cortex-M4F"), so I'm considering embedding that
> info inside "compatible" string of the cpu nodes (for example
> "arm,cortex-m4" or "arm,cortex-m4f"). The problem here is that this
> naming is not official and this wouldn't allow to differentiate between
> different types of FPU (for example - does "arm,cortex-m7f" have
> single-precision or double-precision FPU).
>
> 2. I could just add a non-standard property to cpu nodes (or maybe to
> cpus node?), something like:
>
> distortos,fpu = "fpv5-d16";

Please don't. That would not scale if every OS out there did that.

I would probably append something to the cpu compatible if you must.
In any case, Zephyr folks are going to have the same problem, so we
should have a common solution.

> 3. I could add FPU as a new node, where I could describe it with the
> standard "compatible" property. I think this is actually the best
> approach, but I'm having hard time thinking about location of such node
> - should it be placed in the root of the devicetree, or maybe as a
> child of the cpu node? The second variant seems to be the best one, as
> it fits the scenario of Asymmetric Multiprocessing, where the FPU may
> be present only on selected cores.
>
> Could anyone share any pointers on that matter? Again - thanks in
> advance!
>
> Regards,
> FCh
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree-spec" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]             ` <CAL_Jsq+Gbu35bps2VcQ=pO3WyQE9VZhsuvpKtZ3TJ++B10jPWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2017-04-28 15:20               ` Freddie Chopin
       [not found]                 ` <1493392846.1425.12.camel-FWhLrETftxM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Freddie Chopin @ 2017-04-28 15:20 UTC (permalink / raw)
  To: devicetree-spec

Hello Rob!

On Fri, 2017-04-28 at 07:59 -0500, Rob Herring wrote:
> > I'm not so sure about the "standardization" and "publication" part.
> > I
> > do realize that primary usage of devicetrees will be on "desktop
> > PC"
> 
> PC's use ACPI.

Yes, what I wrote was wrong, because I was thinking about something
else (; I was thinking about devices capable of running a general
purpose operating system (like Linux), which are quite different from
microcontrollers. Sorry for the confusion, I have no idea why I wrote
about "PC" (;

> uC's capable of running Linux generally use DT, too.

You're right, and I'm targeting some of these microcontrollers too
(like STM32F4 or STM32F7). But my needs are a little bit different when
it comes to the "basics" (like on-chip flash memory, which is
completely ignored in Linux). I hope that's only an initial obstacle,
as I think using DT for typical peripherals like USART, SPI, DMA,
external hardware and so on will be very similar.

Generally my problems are not related to the hardware itself - it
doesn't really matter whether it's a small microcontroller of a
multicore applications processor. I think the root cause of the issues
I'm facing is that my "use case" (small embedded RTOS for
microcontrollers) is completely different from the use case of a huge
general purpose OS like Linux. I hope that this use case of mine is not
so different to be completely incompatible with devicetree (;

> > Anyway - a few more days with devicetree and I have another
> > question. I
> > don't want to start a new thread for that, as it is related to the
> > first one anyway. This one is harder, as I found no examples at
> > all, so
> > I have absolutely nothing to start with. There are microcontroller
> > cores which may or may not contain a floating-point unit (FPU) -
> > for
> > example ARM Cortex-M4 may have one or none. There are also
> > microcontroller cores which may contain either a single-precision
> > or
> > double-precision FPU - for example ARM Cortex-M7, which may have
> > either
> > fpv5-sp-d16 or fpv5-d16 FPU. Currently I include that info in the
> > kconfig system, where appropriate hidden options are set when
> > selecting
> > a particular chip model/family. As you may imagine I would also
> > like to
> > have that info in the devicetree. I see several options to express
> > that
> > information, but I'm not sure which one fits best.
> 
> Doesn't the M7 have ID registers registers with define the FP
> capabilities? It should not be in DT if the feature is discoverable.
> 
> Or are you trying to use DT at build time like Zephyr?

This is exactly my plan here. As I'm also targeting much smaller
devices, I'm planning to use DT only during compilation, with no
support for embedded binary devicetree blobs handled at run-time.
That's why I actually need some of the things which are discoverable to
be known during the build. For example if the device has no FPU, the
code to do context switching is much smaller (and faster) and uses less
stack space to save context. Other than that I will also need different
compiler flags to build the RTOS for targets with or without FPU. It
wouldn't be a good RTOS if the code size would be needlessly big... For
Linux is doesn't really matter whether the binary size is 10 or 11MB,
but here I'm dealing with targets which can have as little as a few
dozen kB of flash space for the whole executable, and typically
something around 128-256kB.

But you mentioned an important thing here - indeed DT contains (at
least it should) only the things which cannot be discovered during run-
time... So maybe my plan to add info about FPU to DT is not such a good
idea.

Generally for my project I need some way to easily describe "board"
(interfaces, external devices, GPIO pins, DMA channels, interrupts,
...), preferably in a single file, easily editable by hand. My current
plan is to use such "board description" to generate some real C++ code
with Python scripts - this code will define global objects (like serial
ports, GPIOs, EEPROM chips, ...), perform some low-level
initialization, configure interrupts and GPIOs, ... Some of that
functionality is already present and uses *.json file as input. But
after some reading I come to conclusion that there's no point in
inventing my own format to describe hardware, when there already is one
- devicetree. *.dts generally fits my needs pretty good, there are just
some small details which I need to handle somehow, and I'm still
thinking about the best way to integrate my concepts with kconfig and
build system.

> > 2. I could just add a non-standard property to cpu nodes (or maybe
> > to
> > cpus node?), something like:
> > 
> > distortos,fpu = "fpv5-d16";
> 
> Please don't. That would not scale if every OS out there did that.
> 
> I would probably append something to the cpu compatible if you must.
> In any case, Zephyr folks are going to have the same problem, so we
> should have a common solution.

Do you mean "append" as "add suffix" (compatible = "arm,cortex-m7f";)
or "append" as "add another value" (compatible = "arm,cortex-m7",
"arm,fpv5-d16";)?

In case of Zephyr - from what I understand - for now part of the
configuration is inside kconfig anyway, and this includes the FPU
information. Maybe I should do the same and just associate the
"compatible" property of the chip with some kconfig part? For example I
would require the board's compatible to have the chip model like that:

/ {
    compatible = "some-board", "st,stm32f407vg";
    ...

Which I would then map somehow to a kconfig fragment, which would be
just:

select HAS_FPU
select HAS_MPU
...

This way I wouldn't have to "pollute" the devicetree with that info. Do
you think this would be the preferable solution here?

I'm still trying to get a good grasp of devicetree, so some of my
questions and ideas are probably completely dumb (I hope they don't
make you mad (; ). As I wrote above - probably 90% of my needs are
already covered by DT, but some of the concepts important for small
platforms require me to improvise (; These would generally stem from
the fact that OS like Linux uses "compiled" *.dts file in run-time,
while I want to use *.dts file only as an input format for source code
generator and maybe during project configuration/compilation (for
example to select proper piece of code to be compiled - like context
switching routine  for appropriate core, with or without FPU).

Another idea - maybe I should just include every such "non-standard"
information in /chosen?

Thanks for the advices already offered and thanks in advance for any
further guidance you could share with me!

Regards,
FCh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]                 ` <1493392846.1425.12.camel-FWhLrETftxM@public.gmane.org>
@ 2017-05-01  4:38                   ` David Gibson
       [not found]                     ` <20170501043819.GE13773-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: David Gibson @ 2017-05-01  4:38 UTC (permalink / raw)
  To: Freddie Chopin; +Cc: devicetree-spec

[-- Attachment #1: Type: text/plain, Size: 11199 bytes --]

On Fri, Apr 28, 2017 at 05:20:46PM +0200, Freddie Chopin wrote:
> Hello Rob!
> 
> On Fri, 2017-04-28 at 07:59 -0500, Rob Herring wrote:
> > > I'm not so sure about the "standardization" and "publication" part.
> > > I
> > > do realize that primary usage of devicetrees will be on "desktop
> > > PC"
> > 
> > PC's use ACPI.
> 
> Yes, what I wrote was wrong, because I was thinking about something
> else (; I was thinking about devices capable of running a general
> purpose operating system (like Linux), which are quite different from
> microcontrollers. Sorry for the confusion, I have no idea why I wrote
> about "PC" (;
> 
> > uC's capable of running Linux generally use DT, too.
> 
> You're right, and I'm targeting some of these microcontrollers too
> (like STM32F4 or STM32F7). But my needs are a little bit different when
> it comes to the "basics" (like on-chip flash memory, which is
> completely ignored in Linux). I hope that's only an initial obstacle,
> as I think using DT for typical peripherals like USART, SPI, DMA,
> external hardware and so on will be very similar.
> 
> Generally my problems are not related to the hardware itself - it
> doesn't really matter whether it's a small microcontroller of a
> multicore applications processor. I think the root cause of the issues
> I'm facing is that my "use case" (small embedded RTOS for
> microcontrollers) is completely different from the use case of a huge
> general purpose OS like Linux. I hope that this use case of mine is not
> so different to be completely incompatible with devicetree (;

So far it doesn't sound like it.  It really just seems that you need
some details that have so far been left out because Linux doesn't
typically need them.

> > > Anyway - a few more days with devicetree and I have another
> > > question. I
> > > don't want to start a new thread for that, as it is related to the
> > > first one anyway. This one is harder, as I found no examples at
> > > all, so
> > > I have absolutely nothing to start with. There are microcontroller
> > > cores which may or may not contain a floating-point unit (FPU) -
> > > for
> > > example ARM Cortex-M4 may have one or none. There are also
> > > microcontroller cores which may contain either a single-precision
> > > or
> > > double-precision FPU - for example ARM Cortex-M7, which may have
> > > either
> > > fpv5-sp-d16 or fpv5-d16 FPU. Currently I include that info in the
> > > kconfig system, where appropriate hidden options are set when
> > > selecting
> > > a particular chip model/family. As you may imagine I would also
> > > like to
> > > have that info in the devicetree. I see several options to express
> > > that
> > > information, but I'm not sure which one fits best.
> > 
> > Doesn't the M7 have ID registers registers with define the FP
> > capabilities? It should not be in DT if the feature is discoverable.
> > 
> > Or are you trying to use DT at build time like Zephyr?
> 
> This is exactly my plan here. As I'm also targeting much smaller
> devices, I'm planning to use DT only during compilation, with no
> support for embedded binary devicetree blobs handled at run-time.
> That's why I actually need some of the things which are discoverable to
> be known during the build. For example if the device has no FPU, the
> code to do context switching is much smaller (and faster) and uses less
> stack space to save context. Other than that I will also need different
> compiler flags to build the RTOS for targets with or without FPU. It
> wouldn't be a good RTOS if the code size would be needlessly big... For
> Linux is doesn't really matter whether the binary size is 10 or 11MB,
> but here I'm dealing with targets which can have as little as a few
> dozen kB of flash space for the whole executable, and typically
> something around 128-256kB.

Ok.  Using the DT at build time does complicate things a bit, but
probably not fatally.

> But you mentioned an important thing here - indeed DT contains (at
> least it should) only the things which cannot be discovered during run-
> time... So maybe my plan to add info about FPU to DT is not such a good
> idea.

So, usually, yes, leaving out run-time discoverable information is a
good idea.  But again, there are definitely some grey areas and
trade-offs here.  In fact on POWER servers (where the device tree
content originates, though not the flattened encoding) it's quite
common to have run-time discoverable things duplicated in the device
tree.  Generally that's either because they wanted to encourage OSes
to generalize to allow them to support potential future devices
without code changes, or because they wanted to allow firmware to
filter the available features by changing what was advertised.

There can be some overlap there: virtualization can give you guest
cpus that are missing features that the model theoretically always
has, because the hypervisor won't let you have access to it.

So I don't think it's unreasonable for you to add some information
like this, even if it's theoretically runtime discoverable.  Some more
discussion of this below..

> Generally for my project I need some way to easily describe "board"
> (interfaces, external devices, GPIO pins, DMA channels, interrupts,
> ...), preferably in a single file, easily editable by hand. My current
> plan is to use such "board description" to generate some real C++ code
> with Python scripts - this code will define global objects (like serial
> ports, GPIOs, EEPROM chips, ...), perform some low-level
> initialization, configure interrupts and GPIOs, ... Some of that
> functionality is already present and uses *.json file as input. But
> after some reading I come to conclusion that there's no point in
> inventing my own format to describe hardware, when there already is one
> - devicetree. *.dts generally fits my needs pretty good, there are just
> some small details which I need to handle somehow, and I'm still
> thinking about the best way to integrate my concepts with kconfig and
> build system.

So.  The disctinction between runtime discoverable and not information
is actually not super important.  It's ok for the dt to have redundant
information, as long as it has enough; the OS will just ignore bits it
doesn't need, after all.

What is important is to distinguish between true hardware information
- what the hardware is capable of - and configuration information -
a suggested way to use it.  Restricting the DT to the former and the
latter is pretty important.  But even there, there's quite a lot of
grey areas.

For example, is the way firmware has set things up hardware
information or configuration.  In some cases the "firmware" might
include the hypervisor, so how you use things is enforced and might
not otherwise be discoverable.  In other cases it might be technically
not hardware information - the OS could use things a different way -
but doing so would badly violate platform conventions.  For example it
would mean the OS doing low-level reprogramming of board logic which
is usually set up by the firmware and left that way.  In that case
it can be best on balance to include the information in the device
tree, even though it's technically configuration and not hardware.

Then there's things that really are OS configuration, but it's just
awkward not to include.  Those can be ok if 1) kept to a minimum, 2)
clearly prefixed with vendor/OS tags, 3) are present *as well as* all
the necessary hardware information, not instead of.

> > > 2. I could just add a non-standard property to cpu nodes (or maybe
> > > to
> > > cpus node?), something like:
> > > 
> > > distortos,fpu = "fpv5-d16";
> > 
> > Please don't. That would not scale if every OS out there did that.
> > 
> > I would probably append something to the cpu compatible if you must.
> > In any case, Zephyr folks are going to have the same problem, so we
> > should have a common solution.

Hm.  So, I'm not terribly familiar with ARM, so that might mislead
me.  But this actually wouldn't be my first choice.

There are existing CPU bindings which include additional properties
giving lists or bitmasks of optional features.  For example the PAPR
standard requires this for guest device trees on POWER.  It also
requires that there be a 'cpu-version' property which gives the
"logical PVR" which the OS is supposed to look at in most cases
instead of the physically discoverable PVR register contents.  This
has applications for CPUs put into compatibility modes for
virtualization, so the use case isn't a perfect match, but the ideas
may be adaptable.

What *is* a really good rule of thumb is don't invent a new way of
encoding this information if you can possibly avoid it.  I don't know
if the few cases of DT being used on x86 have something similar, but
if they do I'd expect it to use the same bitmask as the cpuid
instruction returns.  In your case, if there are existing (read only)
registers that give the information you need, you could mirror their
value into the device tree


> Do you mean "append" as "add suffix" (compatible = "arm,cortex-m7f";)
> or "append" as "add another value" (compatible = "arm,cortex-m7",
> "arm,fpv5-d16";)?
> 
> In case of Zephyr - from what I understand - for now part of the
> configuration is inside kconfig anyway, and this includes the FPU
> information. Maybe I should do the same and just associate the
> "compatible" property of the chip with some kconfig part? For example I
> would require the board's compatible to have the chip model like that:
> 
> / {
>     compatible = "some-board", "st,stm32f407vg";
>     ...
> 
> Which I would then map somehow to a kconfig fragment, which would be
> just:
> 
> select HAS_FPU
> select HAS_MPU
> ...
> 
> This way I wouldn't have to "pollute" the devicetree with that info. Do
> you think this would be the preferable solution here?
> 
> I'm still trying to get a good grasp of devicetree, so some of my
> questions and ideas are probably completely dumb (I hope they don't
> make you mad (; ). As I wrote above - probably 90% of my needs are
> already covered by DT, but some of the concepts important for small
> platforms require me to improvise (; These would generally stem from
> the fact that OS like Linux uses "compiled" *.dts file in run-time,
> while I want to use *.dts file only as an input format for source code
> generator and maybe during project configuration/compilation (for
> example to select proper piece of code to be compiled - like context
> switching routine  for appropriate core, with or without FPU).
> 
> Another idea - maybe I should just include every such "non-standard"
> information in /chosen?
> 
> Thanks for the advices already offered and thanks in advance for any
> further guidance you could share with me!
> 
> Regards,
> FCh

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]                     ` <20170501043819.GE13773-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
@ 2017-05-03 10:17                       ` Freddie Chopin
       [not found]                         ` <1493806658.9572.2.camel-FWhLrETftxM@public.gmane.org>
  0 siblings, 1 reply; 8+ messages in thread
From: Freddie Chopin @ 2017-05-03 10:17 UTC (permalink / raw)
  To: devicetree-spec

Hi!

On Mon, 2017-05-01 at 14:38 +1000, David Gibson wrote:
> There are existing CPU bindings which include additional properties
> giving lists or bitmasks of optional features.  For example the PAPR
> standard requires this for guest device trees on POWER.  It also
> requires that there be a 'cpu-version' property which gives the
> "logical PVR" which the OS is supposed to look at in most cases
> instead of the physically discoverable PVR register contents.  This
> has applications for CPUs put into compatibility modes for
> virtualization, so the use case isn't a perfect match, but the ideas
> may be adaptable.
> 
> What *is* a really good rule of thumb is don't invent a new way of
> encoding this information if you can possibly avoid it.  I don't know
> if the few cases of DT being used on x86 have something similar, but
> if they do I'd expect it to use the same bitmask as the cpuid
> instruction returns.  In your case, if there are existing (read only)
> registers that give the information you need, you could mirror their
> value into the device tree

I've just browsed the manual for ARMv7-M architecture and there are 3
read-only registers which have that info, but with a small twist (;

If the core has single-precision FPU, MVFR0-MVFR2 register values are
0x10110021, 0x11000011 and 0x00000000. This would be ARM Cortex-M4 with
FPv4-SP-D16 or ARM Cortex-M7 with FPv5-SP-D16. If the core has double-
precision FPU, the values of these registers are 0x10110221, 0x12000011
and 0x00000040. This is a case for ARM Cortex-M7 with FPv5-D16. The
slight twist is when the core has no FPU at all, as in that case the
manual says these registers are not implemented at all, but I haven't
checked yet whether any attempt to read them causes a fault or just
returns zeroes.

Could you point me to the binding which describes the properties you
mentioned? I couldn't find 'cpu-version' in the device-tree-rebasing
repository...

Maybe - after all - it would be easier and more readable to have FPU as
a subnode of the CPU? Sth like:

cpus {
	cpu@0 {
		compatible = "arm,cortex-m4";

		fpu@0 {
			compatible = "arm,fpv4-sp-d16";
		};
	};
};

In this case it's pretty easy to extend that with an optional 'status =
"okay";' / 'status = "disabled";' for the cases where the user doesn't
want FPU to be "globally enabled" (useful when only one thread uses
FPU, so there's no point in saving its context).

Regards,
FCh

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to describe internal flash (ROM) in the microcontroller
       [not found]                         ` <1493806658.9572.2.camel-FWhLrETftxM@public.gmane.org>
@ 2017-05-08  5:38                           ` David Gibson
  0 siblings, 0 replies; 8+ messages in thread
From: David Gibson @ 2017-05-08  5:38 UTC (permalink / raw)
  To: Freddie Chopin; +Cc: devicetree-spec

[-- Attachment #1: Type: text/plain, Size: 3941 bytes --]

On Wed, May 03, 2017 at 12:17:38PM +0200, Freddie Chopin wrote:
> Hi!
> 
> On Mon, 2017-05-01 at 14:38 +1000, David Gibson wrote:
> > There are existing CPU bindings which include additional properties
> > giving lists or bitmasks of optional features.  For example the PAPR
> > standard requires this for guest device trees on POWER.  It also
> > requires that there be a 'cpu-version' property which gives the
> > "logical PVR" which the OS is supposed to look at in most cases
> > instead of the physically discoverable PVR register contents.  This
> > has applications for CPUs put into compatibility modes for
> > virtualization, so the use case isn't a perfect match, but the ideas
> > may be adaptable.
> > 
> > What *is* a really good rule of thumb is don't invent a new way of
> > encoding this information if you can possibly avoid it.  I don't know
> > if the few cases of DT being used on x86 have something similar, but
> > if they do I'd expect it to use the same bitmask as the cpuid
> > instruction returns.  In your case, if there are existing (read only)
> > registers that give the information you need, you could mirror their
> > value into the device tree
> 
> I've just browsed the manual for ARMv7-M architecture and there are 3
> read-only registers which have that info, but with a small twist (;
> 
> If the core has single-precision FPU, MVFR0-MVFR2 register values are
> 0x10110021, 0x11000011 and 0x00000000. This would be ARM Cortex-M4 with
> FPv4-SP-D16 or ARM Cortex-M7 with FPv5-SP-D16. If the core has double-
> precision FPU, the values of these registers are 0x10110221, 0x12000011
> and 0x00000040. This is a case for ARM Cortex-M7 with FPv5-D16. The
> slight twist is when the core has no FPU at all, as in that case the
> manual says these registers are not implemented at all, but I haven't
> checked yet whether any attempt to read them causes a fault or just
> returns zeroes.

That's ok - you can encode "register not present" by simply leaving
the property out, or leaving it empty (these are different and
distinguishable options).

> Could you point me to the binding which describes the properties you
> mentioned? I couldn't find 'cpu-version' in the device-tree-rebasing
> repository...

That should be in the LoPAPR spec, which you can get from

https://members.openpowerfoundation.org/document/dl/469

> Maybe - after all - it would be easier and more readable to have FPU as
> a subnode of the CPU? Sth like:
> 
> cpus {
> 	cpu@0 {
> 		compatible = "arm,cortex-m4";
> 
> 		fpu@0 {
> 			compatible = "arm,fpv4-sp-d16";
> 		};
> 	};
> };
> 
> In this case it's pretty easy to extend that with an optional 'status =
> "okay";' / 'status = "disabled";' for the cases where the user doesn't
> want FPU to be "globally enabled" (useful when only one thread uses
> FPU, so there's no point in saving its context).

Urgh..

So, if this was a completely new binding for a completely new CPU, I'd
say that sounds like an excellent way of doing it.  But it's not.

There are lots and lots of existing ARM bindings out there for lots of
ARM CPUs, mostly higher end ones, many of which I presume include an
FPU, but which won't have this new proposed node.  This is pretty much
what I mean when I say "don't invent new ways of encoding things".

I think this is an argument for using "empty property" rather than
"missing property" for encoding a missing FPU.  That way your DT
client code has these options:

    no property => unknown FPU state => this DT is not suitable
    empty property => no FPU
    properties present => FPU present, tells you which type

In the first case you can at least error out sensibly    

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-05-08  5:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-22 18:47 How to describe internal flash (ROM) in the microcontroller Freddie Chopin
     [not found] ` <1492886823.1240.5.camel-FWhLrETftxM@public.gmane.org>
2017-04-24  1:27   ` David Gibson
     [not found]     ` <20170424012734.GB16882-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
2017-04-28  7:21       ` Freddie Chopin
     [not found]         ` <1493364100.1425.6.camel-FWhLrETftxM@public.gmane.org>
2017-04-28 12:59           ` Rob Herring
     [not found]             ` <CAL_Jsq+Gbu35bps2VcQ=pO3WyQE9VZhsuvpKtZ3TJ++B10jPWA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-28 15:20               ` Freddie Chopin
     [not found]                 ` <1493392846.1425.12.camel-FWhLrETftxM@public.gmane.org>
2017-05-01  4:38                   ` David Gibson
     [not found]                     ` <20170501043819.GE13773-K0bRW+63XPQe6aEkudXLsA@public.gmane.org>
2017-05-03 10:17                       ` Freddie Chopin
     [not found]                         ` <1493806658.9572.2.camel-FWhLrETftxM@public.gmane.org>
2017-05-08  5:38                           ` David Gibson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).