Skip to contentSkip to conversation

Preprocessor arithmetic in dtsi files (base + offset)

DISCUSSION Mason 5 participants 7 messages Nov 26, 2015 – Dec 2, 2015

lore
Share & tools
lore

Mason

author
#0 lore raw

Hello,

In the device tree for my ARM platform, I have several nodes with addresses within the SCU block:

	scu: scu at 20000000 {
		compatible = "arm,cortex-a9-scu";
		reg = <0x20000000 0x100>;

	gic: interrupt-controller at 20001000 {
		compatible = "arm,cortex-a9-gic";
		reg = <0x20001000 0x1000>, <0x20000100 0x0100>;

	twd-timer at 20000600 {
		compatible = "arm,cortex-a9-twd-timer";
		reg = <0x20000600 0x10>;

Can I use preprocessor arithmetic to abstract the base address, as would be done in C?

#define SCU_BASE 0x20000000

	scu: scu at XXX {
		compatible = "arm,cortex-a9-scu";
		reg = <SCU_BASE 0x100>;
	
	gic: interrupt-controller at XXX {
		compatible = "arm,cortex-a9-gic";
		reg = <SCU_BASE+0x1000 0x1000>, <SCU_BASE+0x100 0x0100>;

	twd-timer at XXX {
		compatible = "arm,cortex-a9-twd-timer";
		reg = <SCU_BASE+0x600 0x10>;

Are the @XXX important? Can they be removed altogether?

Regards.

#1 lore raw
Quoted 22 lines · Mason

Hello,

In the device tree for my ARM platform, I have several nodes with addresses within the SCU block:

	scu: scu at 20000000 {
		compatible = "arm,cortex-a9-scu";
		reg = <0x20000000 0x100>;

	gic: interrupt-controller at 20001000 {
		compatible = "arm,cortex-a9-gic";
		reg = <0x20001000 0x1000>, <0x20000100 0x0100>;

	twd-timer at 20000600 {
		compatible = "arm,cortex-a9-twd-timer";
		reg = <0x20000600 0x10>;

Can I use preprocessor arithmetic to abstract the base address, as would be done in C?

#define SCU_BASE 0x20000000

Quoted 7 lines
	scu: scu at XXX {
		compatible = "arm,cortex-a9-scu";
		reg = <SCU_BASE 0x100>;
	
	gic: interrupt-controller at XXX {
		compatible = "arm,cortex-a9-gic";
		reg = <SCU_BASE+0x1000 0x1000>, <SCU_BASE+0x100 0x0100>;

The pre-processor would only do substitution, not arithmetic. So the '+' would flow all the way to DTC.

DTC does have some basic integer expression support (see [1]), but it looks like it can only work at the cell level, so generally it needs to be avoided (in case #address-cells >1, for example).

So generally I think that such arithmetic should be avoided.

Quoted 5 lines
	twd-timer at XXX {
		compatible = "arm,cortex-a9-twd-timer";
		reg = <SCU_BASE+0x600 0x10>;

Are the @XXX important? Can they be removed altogether?

The bit after the @ is called the unit-address.

It's meant to be there (matching the base address of the first reg entry) to disambiguate nodes and make it simple to figure out where a node lives in the physical address space.

They should stay.

Thanks,
Mark.

[1] https://git.kernel.org/cgit/linux/kernel/git/jdl/dtc.git/commit/?id=5f0c3b2d6235dec65fff1628a97f45e21680b36d

#2 lore raw
In reply to Mason
Quoted 9 lines · Mason

#define SCU_BASE 0x20000000

	scu: scu at XXX {
		compatible = "arm,cortex-a9-scu";
		reg = <SCU_BASE 0x100>;
	
	gic: interrupt-controller at XXX {
		compatible = "arm,cortex-a9-gic";
		reg = <SCU_BASE+0x1000 0x1000>, <SCU_BASE+0x100 0x0100>;

You don't get preprocessor arithmetic here. What you get is this passed to DTC:

		reg = <0x20000000+0x1000 0x1000>...

The only time the preprocessor does arithmetic is when it needs to evaluate an expression, eg, in an #if statement.

The @XXX are part of the requirements from ePAPR, and are required to be conformant with the spec.

Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
author
#3 lore raw
Quoted 11 lines · Russell King - ARM Linux
Quoted 9 lines · Mason

#define SCU_BASE 0x20000000

	scu: scu at XXX {
		compatible = "arm,cortex-a9-scu";
		reg = <SCU_BASE 0x100>;
	
	gic: interrupt-controller at XXX {
		compatible = "arm,cortex-a9-gic";
		reg = <SCU_BASE+0x1000 0x1000>, <SCU_BASE+0x100 0x0100>;
Quoted 7 lines

You don't get preprocessor arithmetic here. What you get is this passed to DTC:

		reg = <0x20000000+0x1000 0x1000>...

The only time the preprocessor does arithmetic is when it needs to evaluate an expression, eg, in an #if statement.

Doh! Brain malfunction. No arithmetic indeed.
Working with the preprocessor would have to involve token-pasting.

#define SCU_BASE(OFFSET) 2000##OFFSET
#define SCU_BASEX(OFFSET) 0x2000##OFFSET

	gic: interrupt-controller at SCU_BASE(1000) {
		reg = <SCU_BASEX(1000) 0x1000>, <SCU_BASEX(0100) 0x0100>;
	};

My very own abomination!

Regards.

#4 lore raw
Quoted 23 lines · Mason
Quoted 11 lines · Russell King - ARM Linux
Quoted 9 lines · Mason

#define SCU_BASE 0x20000000

     scu: scu at XXX {
             compatible = "arm,cortex-a9-scu";
             reg = <SCU_BASE 0x100>;

     gic: interrupt-controller at XXX {
             compatible = "arm,cortex-a9-gic";
             reg = <SCU_BASE+0x1000 0x1000>, <SCU_BASE+0x100 0x0100>;
Quoted 7 lines

You don't get preprocessor arithmetic here. What you get is this passed to DTC:

              reg = <0x20000000+0x1000 0x1000>...

The only time the preprocessor does arithmetic is when it needs to evaluate an expression, eg, in an #if statement.

Doh! Brain malfunction. No arithmetic indeed.
Working with the preprocessor would have to involve token-pasting.

Quoted 8 lines

#define SCU_BASE(OFFSET) 2000##OFFSET
#define SCU_BASEX(OFFSET) 0x2000##OFFSET

        gic: interrupt-controller at SCU_BASE(1000) {
                reg = <SCU_BASEX(1000) 0x1000>, <SCU_BASEX(0100) 0x0100>;
        };

My very own abomination!

Yeah! ;-)

I guess this would work, too?

scu_container at 20000000 {
        compatible = "simple-bus";

        ranges = <0x0 0x20000000 0x10000>;
        #address-cells = <1>;
        #size-cells = <1>;

        scu: scu at 0 {
                compatible = "arm,cortex-a9-scu";
                reg = <0x0000 0x100>;

        gic: interrupt-controller at 1000 {
                compatible = "arm,cortex-a9-gic";
                reg = <0x1000 0x1000>, <0x0100 0x0100>;

        twd-timer at 0600 {
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x0600 0x10>;
};

No more explicit arithmetic needed, just substitue "20000000".

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#5 lore raw

On 26/11/15 16:23, Geert Uytterhoeven wrote:
[...]

Quoted 22 lines

I guess this would work, too?

scu_container at 20000000 {
         compatible = "simple-bus";

         ranges = <0x0 0x20000000 0x10000>;
         #address-cells = <1>;
         #size-cells = <1>;

         scu: scu at 0 {
                 compatible = "arm,cortex-a9-scu";
                 reg = <0x0000 0x100>;

         gic: interrupt-controller at 1000 {
                 compatible = "arm,cortex-a9-gic";
                 reg = <0x1000 0x1000>, <0x0100 0x0100>;

         twd-timer at 0600 {
                 compatible = "arm,cortex-a9-twd-timer";
                 reg = <0x0600 0x10>;
};
Quoted 1 line

No more explicit arithmetic needed, just substitue "20000000".

Which, funnily enough, ends up looking an awful lot like the definition in the hardware documentation[1] too ;)

Robin.

[1]:http://infocenter.arm.com/help/topic/com.arm.doc.ddi0407i/CACCJFCJ.html

Quoted 16 lines

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

author
#6 lore raw
In reply to Geert Uytterhoeven
Quoted 22 lines · Geert Uytterhoeven

I guess this would work, too?

scu_container at 20000000 {
        compatible = "simple-bus";

        ranges = <0x0 0x20000000 0x10000>;
        #address-cells = <1>;
        #size-cells = <1>;

        scu: scu at 0 {
                compatible = "arm,cortex-a9-scu";
                reg = <0x0000 0x100>;

        gic: interrupt-controller at 1000 {
                compatible = "arm,cortex-a9-gic";
                reg = <0x1000 0x1000>, <0x0100 0x0100>;

        twd-timer at 0600 {
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x0600 0x10>;
};
Quoted 1 line

No more explicit arithmetic needed, just substitute "20000000".

I like it! Only one address to change in the next chip. Minimizes the risk of missing something.

(I see that armada did something similar, but they also grouped unrelated stuff. And bcm5301x did exactly what you suggested.)

Wondering if there are macro definitions for the intra-SCU offsets? So I could have symbolic names, such as

  twd-timer at 0600 {
    reg = <TWD_OFFSET 0x10>

Didn't see anything appropriate in include and arch/arm. Should I include my own definitions at the top of the dtsi?

Regards.