linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: Question: Multiple board support is broken
Date: Fri, 7 Dec 2012 16:17:54 +0000	[thread overview]
Message-ID: <20121207161754.GV14363@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20121207193143.2d2029daf2041683bc7b2474@mail.ru>

On Fri, Dec 07, 2012 at 07:31:43PM +0400, Alexander Shiyan wrote:
> Hello.
> 
> Today I was tested multiple boards (not multiplatform) in the kernel
> and found problems with booting.

Err, I test this almost constantly and it works, and it's been working
100% correctly for about the last 12 years.  There is no problem here.

> Exacly, if multiple boards defined
> in. config, we can proceed to boot only the last (determined by mach number).

The mach-types file doesn't have anything to do with which board gets chosen.
That file just provides the IDs, and a bunch of _optimized_ macros to
allow the compiler to perform optimizations.

Let's look at how this works today - let me pull out two entries:

#ifdef CONFIG_ARCH_EBSA285
# ifdef machine_arch_type
#  undef machine_arch_type
#  define machine_arch_type     __machine_arch_type
# else
#  define machine_arch_type     MACH_TYPE_EBSA285
# endif
# define machine_is_ebsa285()   (machine_arch_type == MACH_TYPE_EBSA285)
#else
# define machine_is_ebsa285()   (0)
#endif

#ifdef CONFIG_ARCH_NETWINDER
# ifdef machine_arch_type
#  undef machine_arch_type
#  define machine_arch_type     __machine_arch_type
# else
#  define machine_arch_type     MACH_TYPE_NETWINDER
# endif
# define machine_is_netwinder() (machine_arch_type == MACH_TYPE_NETWINDER)
#else
# define machine_is_netwinder() (0)
#endif

#ifndef machine_arch_type
#define machine_arch_type       __machine_arch_type
#endif

Now, if CONFIG_ARCH_EBSA285=y and CONFIG_ARCH_NETWINDER=n, then follow
through what the preprocessor does.  In the first case, machine_arch_type
is _not_ defined as a pre-processor symbol, so the "ifdef" is false.
That means machine_arch_type gets defined as MACH_TYPE_EBSA285.

machine_is_ebsa285() gets defined as (machine_arch_type == MACH_TYPE_EBSA285)
and when all the macro subsitutions occur (which happens where it's used)
this ends up becoming (MACH_TYPE_EBSA285 == MACH_TYPE_EBSA285).  This is
always true, so any code inside an if (machine_is_ebsa285()) {} block will
be compiled into the kernel and will be executed unconditionally - which
is exactly what we want.

Now, machine_is_netwinder() gets defined as constant (0).  This is always
false, so any code inside an if (machine_is_netwinder()) {} block will
be optimized away - exactly what we want.  This isn't affected by the
machine_arch_type definition.

Next, you can do the same thing for the CONFIG_ARCH_EBSA285=n and
CONFIG_ARCH_NETWINDER=y case, and you'll end up with similar results.

Finally for the case where CONFIG_ARCH_EBSA285=y and CONFIG_ARCH_NETWINDER=y.
In this case, it starts off just like the CONFIG_ARCH_EBSA285=y case above.
When we hit the CONFIG_ARCH_NETWINDER block a very important change happens.
This time machine_arch_type is already defined.

So, what happens is machine_arch_type first gets undefined to avoid any
compiler warnings about multiple definitions.  We then define
machine_arch_type to be the C variable __machine_arch_type.

This makes any references to (machine_arch_type == MACH_TYPE_WHATEVER)
become a runtime interpreted condition, which occurs for any machine type
that has its config symbol enabled.  So, machine_is_ebsa285() becomes
(__machine_arch_type == MACH_TYPE_EBSA285) and machine_is_netwinder()
becomes (__machine_arch_type == MACH_TYPE_NETWINDER), while other
platforms machine_is_xxx() macros remain defined to constant 0.

So, this all works exactly as we want.  There is no bug here.

  reply	other threads:[~2012-12-07 16:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-07 15:31 Question: Multiple board support is broken Alexander Shiyan
2012-12-07 16:17 ` Russell King - ARM Linux [this message]
2012-12-08  8:28   ` Alexander Shiyan
2012-12-08  9:26     ` Russell King - ARM Linux
2012-12-08  9:58       ` Alexander Shiyan
2012-12-08 10:38         ` Russell King - ARM Linux
2012-12-08 11:18           ` Alexander Shiyan
2012-12-08 11:23             ` Russell King - ARM Linux
2012-12-08 11:59               ` Alexander Shiyan
2012-12-08 12:02               ` [PATCH] ARM: Do not use definition "machine_arch_type" outside mach-types.h Alexander Shiyan
2012-12-08 12:14                 ` Russell King - ARM Linux
2012-12-09  5:21                   ` [PATCH] ARM: Pass real "__machine_arch_type" variable to setup_machine_tags() procedure Alexander Shiyan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121207161754.GV14363@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).