LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* inverse mapping from a struct console to device
@ 2015-01-26 19:40 Jon Masters
  2015-01-26 20:20 ` Greg KH
  2015-01-26 20:50 ` Mark Rutland
  0 siblings, 2 replies; 10+ messages in thread
From: Jon Masters @ 2015-01-26 19:40 UTC (permalink / raw)
  To: linux-kernel

Hi Folks,

TLDR: I need a back reference from a console struct to its device. I
can't see an easy way to do this right now without adding one?

I've a quick question. I have prototype code that parses an ACPI table
known as the SPCR (Serial Port Console Redirection - exists on both x86
and ARM systems). It finds the correct serial device (but it's not a
Linux specific DT-style solution so there's no "console=" parameter
embedded in it or something) to use for the preferred console (I have
effectively the device object connected with the acpi_handle of the
underlying serial device, which I map on by walking the ACPI namespace
down from the root until I find the _ADR of the specified SPCR address).

One of the problems that I have is that I want to make the decision
about whether a console should be automatically configured once we get
to register_console, because that's where the existing logic is, and
it's one path I can be sure everyone is going to call (serial drivers
have a number of different APIs that they use during registration).

Once I'm in register_console, I have only the console struct to play
with. I can get from that to the tty_driver (by walking the tty driver
list and finding the back reference), but that still doesn't give me
what I want. I can add a reference to the underlying device in one of
these structs, but I would like to have additional opinions before I go
and make something hackish folks will balk at later. So, am I missing
something obvious? I hope I am because this seems slightly weird.

Jon.

P.S. I would love it if I could (for debug purposes only) just walk down
from the root of the kernel device hierarchy until I found a device that
had a resource matching the one I am looking for (you can do exactly
this in the ACPI namespace using exported methods), but the only code
that can do that today is unexported core core used during shutdown to
shutdown all devices recursively. Just a sidenote.

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

* Re: inverse mapping from a struct console to device
  2015-01-26 19:40 inverse mapping from a struct console to device Jon Masters
@ 2015-01-26 20:20 ` Greg KH
  2015-01-27  3:16   ` Jon Masters
  2015-01-26 20:50 ` Mark Rutland
  1 sibling, 1 reply; 10+ messages in thread
From: Greg KH @ 2015-01-26 20:20 UTC (permalink / raw)
  To: Jon Masters; +Cc: linux-kernel

On Mon, Jan 26, 2015 at 02:40:58PM -0500, Jon Masters wrote:
> Hi Folks,
> 
> TLDR: I need a back reference from a console struct to its device.

I know I'm going to regret answering this vague question, but, what
_exactly_ do you mean by "its device"?

> I can't see an easy way to do this right now without adding one?

>From within the kernel or from userspace?

If in the kernel, what part of the kernel are you doing this from?

If in userspace, what is wrong with /sys/class/tty/console?

> I've a quick question. I have prototype code that parses an ACPI table
> known as the SPCR (Serial Port Console Redirection - exists on both x86
> and ARM systems). It finds the correct serial device (but it's not a
> Linux specific DT-style solution so there's no "console=" parameter
> embedded in it or something) to use for the preferred console (I have
> effectively the device object connected with the acpi_handle of the
> underlying serial device, which I map on by walking the ACPI namespace
> down from the root until I find the _ADR of the specified SPCR address).
> 
> One of the problems that I have is that I want to make the decision
> about whether a console should be automatically configured once we get
> to register_console, because that's where the existing logic is, and
> it's one path I can be sure everyone is going to call (serial drivers
> have a number of different APIs that they use during registration).
> 
> Once I'm in register_console, I have only the console struct to play
> with. I can get from that to the tty_driver (by walking the tty driver
> list and finding the back reference), but that still doesn't give me
> what I want. I can add a reference to the underlying device in one of
> these structs, but I would like to have additional opinions before I go
> and make something hackish folks will balk at later. So, am I missing
> something obvious? I hope I am because this seems slightly weird.

I really don't understand what you are wanting to do here.  Who wants to
"automatically configure" a console?

> P.S. I would love it if I could (for debug purposes only) just walk down
> from the root of the kernel device hierarchy until I found a device that
> had a resource matching the one I am looking for (you can do exactly
> this in the ACPI namespace using exported methods), but the only code
> that can do that today is unexported core core used during shutdown to
> shutdown all devices recursively. Just a sidenote.

Sorry, you don't know what "type" of devices you are walking through, so
bad things can happen if you guess wrong.

greg k-h

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

* Re: inverse mapping from a struct console to device
  2015-01-26 19:40 inverse mapping from a struct console to device Jon Masters
  2015-01-26 20:20 ` Greg KH
@ 2015-01-26 20:50 ` Mark Rutland
  2015-01-27  3:06   ` Jon Masters
  1 sibling, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2015-01-26 20:50 UTC (permalink / raw)
  To: Jon Masters; +Cc: linux-kernel, leif.lindholm, grant.likely

On Mon, Jan 26, 2015 at 07:40:58PM +0000, Jon Masters wrote:
> Hi Folks,
> 
> TLDR: I need a back reference from a console struct to its device. I
> can't see an easy way to do this right now without adding one?

I don't think that's quite what you need. All you need is to be able to
refer to the SPCR at serial probe time (more on that below), when you
should have the data you want.

> I've a quick question. I have prototype code that parses an ACPI table
> known as the SPCR (Serial Port Console Redirection - exists on both x86
> and ARM systems). It finds the correct serial device (but it's not a
> Linux specific DT-style solution so there's no "console=" parameter
> embedded in it or something)

In DT we have /chosen/stdout-path which offers analagous functionality.
It is independent of the command line, and has a standard set of
parameters (<baud>{<parity>{<bits>{<flow>}}}).

To make this work we check against the stdout-path when we register the
UART. Take a look at of_console check (called from uart_add_one_port).

Assuming your UART probing looks similar for ACPI, you can have an
analagous function that goes and checks uport->dev.acpi_dev_node against
entires in the SPCR, configuring the UART as required at this point at
registration time.

This requires that you parse the SPCR earlier, but presumably the SPCR
is simple enough that this is possible (no AML, for instance).

Is there some reason that approach is unworkable?

Mark.

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

* Re: inverse mapping from a struct console to device
  2015-01-26 20:50 ` Mark Rutland
@ 2015-01-27  3:06   ` Jon Masters
  2015-01-27 10:14     ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Jon Masters @ 2015-01-27  3:06 UTC (permalink / raw)
  To: Mark Rutland; +Cc: linux-kernel, leif.lindholm, grant.likely

On 01/26/2015 03:50 PM, Mark Rutland wrote:
> On Mon, Jan 26, 2015 at 07:40:58PM +0000, Jon Masters wrote:
>> Hi Folks,
>>
>> TLDR: I need a back reference from a console struct to its device. I
>> can't see an easy way to do this right now without adding one?
> 
> I don't think that's quite what you need. All you need is to be able to
> refer to the SPCR at serial probe time (more on that below), when you
> should have the data you want.

Hmm. I wanted to do it in console_register due to the existing logic for
adding a preferred console there. But that's a silly reason.

>> I've a quick question. I have prototype code that parses an ACPI table
>> known as the SPCR (Serial Port Console Redirection - exists on both x86
>> and ARM systems). It finds the correct serial device (but it's not a
>> Linux specific DT-style solution so there's no "console=" parameter
>> embedded in it or something)
> 
> In DT we have /chosen/stdout-path which offers analagous functionality.
> It is independent of the command line, and has a standard set of
> parameters (<baud>{<parity>{<bits>{<flow>}}}).

Hmm. I thought it was embedding a Linux specific console parameter, but
I see when I actually check the code and the Documentation (sorry) that
it is indeed similar in capability. Which is awesome. I'll do similar.

> To make this work we check against the stdout-path when we register the
> UART. Take a look at of_console check (called from uart_add_one_port).

Great. Thanks. I looked at modifying uart_add_one_port, but I wasn't
convinced it was called by every serial driver (for example, the
sbsauart driver). I don't know the tty/serial code as well as I'd like.
But I'll implement it the same way as in the OF case for the moment, and
if we need to fix up a driver or two we can always do that.

> Assuming your UART probing looks similar for ACPI, you can have an
> analagous function that goes and checks uport->dev.acpi_dev_node against
> entires in the SPCR, configuring the UART as required at this point at
> registration time.

> This requires that you parse the SPCR earlier, but presumably the SPCR
> is simple enough that this is possible (no AML, for instance).

I already parse it as an initcall early in boot and indeed have it prior
to the port being registered.

> Is there some reason that approach is unworkable?

Apparently not, just need to check a couple of drivers.

Thanks Mark. I'll post a patch later for SPCR setup.

Jon.


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

* Re: inverse mapping from a struct console to device
  2015-01-26 20:20 ` Greg KH
@ 2015-01-27  3:16   ` Jon Masters
  0 siblings, 0 replies; 10+ messages in thread
From: Jon Masters @ 2015-01-27  3:16 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

On 01/26/2015 03:20 PM, Greg KH wrote:
> On Mon, Jan 26, 2015 at 02:40:58PM -0500, Jon Masters wrote:

>> I've a quick question. I have prototype code that parses an ACPI table
>> known as the SPCR (Serial Port Console Redirection - exists on both x86
>> and ARM systems). It finds the correct serial device (but it's not a
>> Linux specific DT-style solution so there's no "console=" parameter
>> embedded in it or something) to use for the preferred console (I have
>> effectively the device object connected with the acpi_handle of the
>> underlying serial device, which I map on by walking the ACPI namespace
>> down from the root until I find the _ADR of the specified SPCR address).
>>
>> One of the problems that I have is that I want to make the decision
>> about whether a console should be automatically configured once we get
>> to register_console, because that's where the existing logic is, and
>> it's one path I can be sure everyone is going to call (serial drivers
>> have a number of different APIs that they use during registration).
>>
>> Once I'm in register_console, I have only the console struct to play
>> with. I can get from that to the tty_driver (by walking the tty driver
>> list and finding the back reference), but that still doesn't give me
>> what I want. I can add a reference to the underlying device in one of
>> these structs, but I would like to have additional opinions before I go
>> and make something hackish folks will balk at later. So, am I missing
>> something obvious? I hope I am because this seems slightly weird.
> 
> I really don't understand what you are wanting to do here.  Who wants to
> "automatically configure" a console?

On ARM systems, we've several possible serial devices that could be in
use. We don't want to have to specify the console on the kernel command
line at install/boot time. Additionally, we want to (later)
automatically configure earlycon parameters. Fortunately there's an ACPI
table known as the SPCR which provides information about the preferred
serial uart, including type/address/interrupt/etc. SPCR exists on x86
systems too, and in fact has been used by Windows for over a decade to
handle the setup of its SAC (Special Administration Console). The
license on the underlying SPCR spec has been opened in the past couple
of years to cover other OS implementations using it.

Currently, we internally have a hack that sets up the console as a
preferred console, but it's not a long term solution. For that, I had
the SPCR made a requirement in the ARM SBBR specification. Windows on
x86 doesn't use the GSIV (ACPI interrupt) from my understanding so I
preemptively asked that it be made a requirement that this be populated,
along with requiring revision 2+ of the table. That way, we can propose
patches to use the SPCR for setup that might be useful on x86 (and if
limiting to revision 2+ it won't break existing systems as essentially
no PC class system reports that revision of the table yet).

For the rest - Mark Rutland's followup and my reply covers it I think.

Thanks,

Jon.


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

* Re: inverse mapping from a struct console to device
  2015-01-27  3:06   ` Jon Masters
@ 2015-01-27 10:14     ` Mark Rutland
  2015-01-27 11:54       ` Jon Masters
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2015-01-27 10:14 UTC (permalink / raw)
  To: Jon Masters; +Cc: linux-kernel, leif.lindholm, grant.likely, andre.przywara

On Tue, Jan 27, 2015 at 03:06:35AM +0000, Jon Masters wrote:
> On 01/26/2015 03:50 PM, Mark Rutland wrote:
> > On Mon, Jan 26, 2015 at 07:40:58PM +0000, Jon Masters wrote:
> >> Hi Folks,
> >>
> >> TLDR: I need a back reference from a console struct to its device. I
> >> can't see an easy way to do this right now without adding one?
> > 
> > I don't think that's quite what you need. All you need is to be able to
> > refer to the SPCR at serial probe time (more on that below), when you
> > should have the data you want.
> 
> Hmm. I wanted to do it in console_register due to the existing logic for
> adding a preferred console there. But that's a silly reason.
> 
> >> I've a quick question. I have prototype code that parses an ACPI table
> >> known as the SPCR (Serial Port Console Redirection - exists on both x86
> >> and ARM systems). It finds the correct serial device (but it's not a
> >> Linux specific DT-style solution so there's no "console=" parameter
> >> embedded in it or something)
> > 
> > In DT we have /chosen/stdout-path which offers analagous functionality.
> > It is independent of the command line, and has a standard set of
> > parameters (<baud>{<parity>{<bits>{<flow>}}}).
> 
> Hmm. I thought it was embedding a Linux specific console parameter, but
> I see when I actually check the code and the Documentation (sorry) that
> it is indeed similar in capability. Which is awesome. I'll do similar.
> 
> > To make this work we check against the stdout-path when we register the
> > UART. Take a look at of_console check (called from uart_add_one_port).
> 
> Great. Thanks. I looked at modifying uart_add_one_port, but I wasn't
> convinced it was called by every serial driver (for example, the
> sbsauart driver). I don't know the tty/serial code as well as I'd like.
> But I'll implement it the same way as in the OF case for the moment, and
> if we need to fix up a driver or two we can always do that.

The SBSA UART is a bit of a special case, given it cannot be
reconfigured. While Andre's SBSA UART driver [1] will call
uart_add_one_port (as the PL011 driver seems to currently), I believe
any configuration is ignored.

In the DT case, we'd expect the SBSA UART node to have a current-speed
property describing the fixed, preconfigured speed. This has no bearing
on the operation of the driver (because there's nothing to configure)
and is only used to report the speed to userspace.

I guess we don't have something on the ACPI node, and you want to use
the SPCR to determine the preconfigured rate in this case?

> > Assuming your UART probing looks similar for ACPI, you can have an
> > analagous function that goes and checks uport->dev.acpi_dev_node against
> > entires in the SPCR, configuring the UART as required at this point at
> > registration time.
> 
> > This requires that you parse the SPCR earlier, but presumably the SPCR
> > is simple enough that this is possible (no AML, for instance).
> 
> I already parse it as an initcall early in boot and indeed have it prior
> to the port being registered.
> 
> > Is there some reason that approach is unworkable?
> 
> Apparently not, just need to check a couple of drivers.
> 
> Thanks Mark. I'll post a patch later for SPCR setup.

Great!

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317146.html

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

* Re: inverse mapping from a struct console to device
  2015-01-27 10:14     ` Mark Rutland
@ 2015-01-27 11:54       ` Jon Masters
  2015-01-27 12:30         ` Mark Rutland
  0 siblings, 1 reply; 10+ messages in thread
From: Jon Masters @ 2015-01-27 11:54 UTC (permalink / raw)
  To: Mark Rutland; +Cc: linux-kernel, leif.lindholm, grant.likely, andre.przywara

On 01/27/2015 05:14 AM, Mark Rutland wrote:
> On Tue, Jan 27, 2015 at 03:06:35AM +0000, Jon Masters wrote:
>> On 01/26/2015 03:50 PM, Mark Rutland wrote:
>>> On Mon, Jan 26, 2015 at 07:40:58PM +0000, Jon Masters wrote:
>>>> Hi Folks,
>>>>
>>>> TLDR: I need a back reference from a console struct to its device. I
>>>> can't see an easy way to do this right now without adding one?
>>>
>>> I don't think that's quite what you need. All you need is to be able to
>>> refer to the SPCR at serial probe time (more on that below), when you
>>> should have the data you want.
>>
>> Hmm. I wanted to do it in console_register due to the existing logic for
>> adding a preferred console there. But that's a silly reason.
>>
>>>> I've a quick question. I have prototype code that parses an ACPI table
>>>> known as the SPCR (Serial Port Console Redirection - exists on both x86
>>>> and ARM systems). It finds the correct serial device (but it's not a
>>>> Linux specific DT-style solution so there's no "console=" parameter
>>>> embedded in it or something)
>>>
>>> In DT we have /chosen/stdout-path which offers analagous functionality.
>>> It is independent of the command line, and has a standard set of
>>> parameters (<baud>{<parity>{<bits>{<flow>}}}).
>>
>> Hmm. I thought it was embedding a Linux specific console parameter, but
>> I see when I actually check the code and the Documentation (sorry) that
>> it is indeed similar in capability. Which is awesome. I'll do similar.
>>
>>> To make this work we check against the stdout-path when we register the
>>> UART. Take a look at of_console check (called from uart_add_one_port).

I have working SPCR setup on a system using an 8250 interface (Mustang)
with ACPI. The preferred console comes up nicely. So, that's good.

>> Great. Thanks. I looked at modifying uart_add_one_port, but I wasn't
>> convinced it was called by every serial driver (for example, the
>> sbsauart driver). I don't know the tty/serial code as well as I'd like.
>> But I'll implement it the same way as in the OF case for the moment, and
>> if we need to fix up a driver or two we can always do that.

Confirmed that the existing sbsauart driver I have doesn't use
uart_add_one_port (it's an older driver based on Linaro's code). It
seems like we need to update, which I'll follow up on separately.

> The SBSA UART is a bit of a special case, given it cannot be
> reconfigured. While Andre's SBSA UART driver [1] will call
> uart_add_one_port (as the PL011 driver seems to currently), I believe
> any configuration is ignored.

Indeed. And we don't need to reconfigure it, but we still want to know
which console to use since it could be an SBSA or 8250. And in theory
someone could build something else (but not conforming to SBBR).

> In the DT case, we'd expect the SBSA UART node to have a current-speed
> property describing the fixed, preconfigured speed. This has no bearing
> on the operation of the driver (because there's nothing to configure)
> and is only used to report the speed to userspace.
> 
> I guess we don't have something on the ACPI node, and you want to use
> the SPCR to determine the preconfigured rate in this case?

Nope, I just want to know that I'm using the SBSA console and not
another. Hence the SPCR will tell me which to set as preferred.

Here's an example of the data we get in the SPCR for reference:

[0012]               Serial Port Register : [Generic Address Structure]
[0001]                           Space ID : 00 [SystemMemory]
[0001]                          Bit Width : 08
[0001]                         Bit Offset : 00
[0001]               Encoded Access Width : 01 [Byte Access:8]
[0008]                            Address : 000000001c020000

[0001]                     Interrupt Type : 08
[0001]                PCAT-compatible IRQ : 00
[0004]                          Interrupt : 0000006C
[0001]                          Baud Rate : 07
[0001]                             Parity : 00
[0001]                          Stop Bits : 01
[0001]                       Flow Control : 00
[0001]                      Terminal Type : 00
[0001]                           Reserved : 00

The actual structure is longer, but you get the idea. I first map this
to the correct Device in the DSDT with a device_initcall that will find
the table then walk the ACPI namespace to find the corresponding device.
This is stashed so that later we can perform the same kind of comparison
that you do with DT today. I also populate options, though so far have
only bothered to implement baud rate.

>> Thanks Mark. I'll post a patch later for SPCR setup.
> 
> Great!

Just need to switch out the SBSA UART driver and test that case on e.g.
Seattle with SBSA UART. It's working as described above on Mustang-like
platforms running with ACPI as of a few minutes ago.

Jon.


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

* Re: inverse mapping from a struct console to device
  2015-01-27 11:54       ` Jon Masters
@ 2015-01-27 12:30         ` Mark Rutland
  2015-01-27 20:42           ` Jon Masters
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Rutland @ 2015-01-27 12:30 UTC (permalink / raw)
  To: Jon Masters; +Cc: linux-kernel, leif.lindholm, grant.likely, Andre Przywara

On Tue, Jan 27, 2015 at 11:54:18AM +0000, Jon Masters wrote:
> On 01/27/2015 05:14 AM, Mark Rutland wrote:
> > On Tue, Jan 27, 2015 at 03:06:35AM +0000, Jon Masters wrote:
> >> On 01/26/2015 03:50 PM, Mark Rutland wrote:
> >>> On Mon, Jan 26, 2015 at 07:40:58PM +0000, Jon Masters wrote:
> >>>> Hi Folks,
> >>>>
> >>>> TLDR: I need a back reference from a console struct to its device. I
> >>>> can't see an easy way to do this right now without adding one?
> >>>
> >>> I don't think that's quite what you need. All you need is to be able to
> >>> refer to the SPCR at serial probe time (more on that below), when you
> >>> should have the data you want.
> >>
> >> Hmm. I wanted to do it in console_register due to the existing logic for
> >> adding a preferred console there. But that's a silly reason.
> >>
> >>>> I've a quick question. I have prototype code that parses an ACPI table
> >>>> known as the SPCR (Serial Port Console Redirection - exists on both x86
> >>>> and ARM systems). It finds the correct serial device (but it's not a
> >>>> Linux specific DT-style solution so there's no "console=" parameter
> >>>> embedded in it or something)
> >>>
> >>> In DT we have /chosen/stdout-path which offers analagous functionality.
> >>> It is independent of the command line, and has a standard set of
> >>> parameters (<baud>{<parity>{<bits>{<flow>}}}).
> >>
> >> Hmm. I thought it was embedding a Linux specific console parameter, but
> >> I see when I actually check the code and the Documentation (sorry) that
> >> it is indeed similar in capability. Which is awesome. I'll do similar.
> >>
> >>> To make this work we check against the stdout-path when we register the
> >>> UART. Take a look at of_console check (called from uart_add_one_port).
> 
> I have working SPCR setup on a system using an 8250 interface (Mustang)
> with ACPI. The preferred console comes up nicely. So, that's good.
> 
> >> Great. Thanks. I looked at modifying uart_add_one_port, but I wasn't
> >> convinced it was called by every serial driver (for example, the
> >> sbsauart driver). I don't know the tty/serial code as well as I'd like.
> >> But I'll implement it the same way as in the OF case for the moment, and
> >> if we need to fix up a driver or two we can always do that.
> 
> Confirmed that the existing sbsauart driver I have doesn't use
> uart_add_one_port (it's an older driver based on Linaro's code). It
> seems like we need to update, which I'll follow up on separately.
> 
> > The SBSA UART is a bit of a special case, given it cannot be
> > reconfigured. While Andre's SBSA UART driver [1] will call
> > uart_add_one_port (as the PL011 driver seems to currently), I believe
> > any configuration is ignored.
> 
> Indeed. And we don't need to reconfigure it, but we still want to know
> which console to use since it could be an SBSA or 8250. And in theory
> someone could build something else (but not conforming to SBBR).
> 
> > In the DT case, we'd expect the SBSA UART node to have a current-speed
> > property describing the fixed, preconfigured speed. This has no bearing
> > on the operation of the driver (because there's nothing to configure)
> > and is only used to report the speed to userspace.
> > 
> > I guess we don't have something on the ACPI node, and you want to use
> > the SPCR to determine the preconfigured rate in this case?
> 
> Nope, I just want to know that I'm using the SBSA console and not
> another. Hence the SPCR will tell me which to set as preferred.

Configuring the default UART should work, even with the SBSA UART.

The only issue that leaves is that the with the SBSA UART the baud rate
reported to userspace may be wrong (because the baud rate read from the
SPCR will be ignored by the driver as it thinks this is configuration).

If the ACPI node for the SBSA UART has the configured rate, we can
handle that as we do for DT. Otherwise we need to have the SBSA UART
driver see if there's a rate in the SPCR that it can report.

> Here's an example of the data we get in the SPCR for reference:
> 
> [0012]               Serial Port Register : [Generic Address Structure]
> [0001]                           Space ID : 00 [SystemMemory]
> [0001]                          Bit Width : 08
> [0001]                         Bit Offset : 00
> [0001]               Encoded Access Width : 01 [Byte Access:8]
> [0008]                            Address : 000000001c020000
> 
> [0001]                     Interrupt Type : 08
> [0001]                PCAT-compatible IRQ : 00
> [0004]                          Interrupt : 0000006C
> [0001]                          Baud Rate : 07
> [0001]                             Parity : 00
> [0001]                          Stop Bits : 01
> [0001]                       Flow Control : 00
> [0001]                      Terminal Type : 00
> [0001]                           Reserved : 00
> 
> The actual structure is longer, but you get the idea. I first map this
> to the correct Device in the DSDT with a device_initcall that will find
> the table then walk the ACPI namespace to find the corresponding device.
> This is stashed so that later we can perform the same kind of comparison
> that you do with DT today. I also populate options, though so far have
> only bothered to implement baud rate.

I would recommend that you set up as many of these ASAP. Otherwise
someone's certain to mess up a table and we can never add them later.

Otherwise, sounds good!

Mark.

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

* Re: inverse mapping from a struct console to device
  2015-01-27 12:30         ` Mark Rutland
@ 2015-01-27 20:42           ` Jon Masters
  2015-01-28 22:48             ` Peter Hurley
  0 siblings, 1 reply; 10+ messages in thread
From: Jon Masters @ 2015-01-27 20:42 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-kernel, leif.lindholm, grant.likely, Andre Przywara, Torez Smith

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

On 01/27/2015 07:30 AM, Mark Rutland wrote:
> On Tue, Jan 27, 2015 at 11:54:18AM +0000, Jon Masters wrote:

>> Here's an example of the data we get in the SPCR for reference:
>>
>> [0012]               Serial Port Register : [Generic Address Structure]
>> [0001]                           Space ID : 00 [SystemMemory]
>> [0001]                          Bit Width : 08
>> [0001]                         Bit Offset : 00
>> [0001]               Encoded Access Width : 01 [Byte Access:8]
>> [0008]                            Address : 000000001c020000
>>
>> [0001]                     Interrupt Type : 08
>> [0001]                PCAT-compatible IRQ : 00
>> [0004]                          Interrupt : 0000006C
>> [0001]                          Baud Rate : 07
>> [0001]                             Parity : 00
>> [0001]                          Stop Bits : 01
>> [0001]                       Flow Control : 00
>> [0001]                      Terminal Type : 00
>> [0001]                           Reserved : 00
>>
>> The actual structure is longer, but you get the idea. I first map this
>> to the correct Device in the DSDT with a device_initcall that will find
>> the table then walk the ACPI namespace to find the corresponding device.
>> This is stashed so that later we can perform the same kind of comparison
>> that you do with DT today. I also populate options, though so far have
>> only bothered to implement baud rate.
> 
> I would recommend that you set up as many of these ASAP. Otherwise
> someone's certain to mess up a table and we can never add them later.

So this is why I'm doing this (and other annoying things) right now - to
make sure that vendors shipping platforms have valid data we can also
use. If we wait until later, we'll have systems that potentially do the
wrong thing. The table above is an example of one for the Mustang. I had
the revision bumped to 2 and the IRQ information added to the reference
one, and I've also verified the tables for Seattle, as well as "other"
hardware that is in the pipeline from other vendors.

> Otherwise, sounds good!

So I'm handing this to Torez Smith to followup on (please keep her
copied on replies to this thread). I'm attaching a *hack* patch I put
together to proof of concept and then Torez will make this into
something actually useable/upstreamable (without hard coded static baud
strings and the like that I used to hack it up).

Jon.


[-- Attachment #2: spcr_wip2.patch --]
[-- Type: text/x-patch, Size: 5761 bytes --]

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 6e692f4..13688c0 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -21,6 +21,13 @@ extern int acpi_disabled;
 extern int acpi_noirq;
 extern int acpi_pci_disabled;
 
+extern u64 spcr_serial_addr;
+extern int acpi_setup_spcr(void);
+extern struct acpi_device *acpi_spcr_serial_device;
+extern char *acpi_spcr_serial_options;
+extern bool acpi_spcr_console_check(struct acpi_device *adev,
+				    char *name, int index);
+
 /* 1 to indicate PSCI 0.2+ is implemented */
 static inline bool acpi_psci_present(void)
 {
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index d109b2f..90ae187 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -28,6 +28,9 @@
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 
+#include <linux/console.h>
+#include <linux/tty.h>
+
 int acpi_noirq;			/* skip ACPI IRQ initialization */
 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
@@ -40,6 +43,12 @@ static int enabled_cpus;	/* Processors (GICC) with enabled flag in MADT */
 static char *boot_method;
 static u64 parked_address[NR_CPUS];
 
+u64 spcr_serial_addr;
+struct acpi_device *acpi_spcr_serial_device;
+EXPORT_SYMBOL(acpi_spcr_serial_device);
+char *acpi_spcr_serial_options;
+EXPORT_SYMBOL(acpi_spcr_serial_options);
+
 /*
  * Since we're on ARM, the default interrupt routing model
  * clearly has to be GIC.
@@ -376,3 +385,106 @@ static int __init parse_acpi(char *arg)
 	return 0;
 }
 early_param("acpi", parse_acpi);
+
+bool acpi_spcr_console_check(struct acpi_device *adev, char *name, int index)
+{
+	printk("JCM: acpi_spcr_console_check: enter\n");
+	if (!adev || adev != acpi_spcr_serial_device || console_set_on_cmdline)
+	{
+		printk("JCM: conditional test failed\n");
+		return false;
+	}
+	printk("JCM: would set up preferred console\n");
+	printk("JCM: return !add_preferred_console(%s, %d, %s)\n",
+	       name, index, acpi_spcr_serial_options);
+
+	return !add_preferred_console(name, index,
+				      kstrdup(acpi_spcr_serial_options,
+					      GFP_KERNEL));
+}
+
+static int __init acpi_parse_spcr(struct acpi_table_header *table)
+{
+	struct acpi_table_spcr *spcr = (struct acpi_table_spcr *)table;
+
+	/* Handle possible alignment issues */
+	memcpy(&spcr_serial_addr,
+	       &spcr->serial_port.address, sizeof(spcr_serial_addr));
+
+	switch(spcr->baud_rate) {
+	case 3:
+		acpi_spcr_serial_options = "9600";
+		break;
+	case 4:
+		acpi_spcr_serial_options = "19200";
+		break;
+	case 6:
+		acpi_spcr_serial_options = "57600";
+		break;
+	case 7:
+		acpi_spcr_serial_options = "115200";
+		break;
+	default:
+		acpi_spcr_serial_options = "";
+		break;
+	}
+
+	printk("SPCR serial device: 0x%llx (options: %s)\n",
+	       spcr_serial_addr, acpi_spcr_serial_options);
+
+	return -EOPNOTSUPP; /* value not used yet */
+}	
+
+static acpi_status acpi_spcr_device_scan(acpi_handle handle,
+					 u32 level, void *context, void **retv)
+{
+	unsigned long long adr;
+	struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_status status = AE_OK;
+	struct acpi_device *adev;
+
+	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
+	if (ACPI_FAILURE(status)) {
+		return AE_OK; /* continue */
+	}
+
+	if (adr == spcr_serial_addr) {
+
+		adev = acpi_bus_get_acpi_device(handle);
+
+		if (!adev) {
+			printk("Error locating SPCR device from ACPI handle\n");
+			return AE_OK; /* skip this one */
+		}
+
+		acpi_spcr_serial_device = adev;
+
+		printk("SPCR serial console: %s (0x%llx)\n",
+		       (char *)(name_buffer.pointer), adr);
+
+		return AE_OK; /* harmless to continue */
+	}
+
+	/* continue */
+	return AE_OK; /* continue */
+}
+
+int __init acpi_setup_spcr()
+{
+	if (0 != acpi_table_parse(ACPI_SIG_SPCR, acpi_parse_spcr)) {
+		printk("SPCR table not found - automatic console disabled\n");
+		return -ENODEV;
+	}
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			    ACPI_UINT32_MAX, acpi_spcr_device_scan,
+			    NULL, NULL, NULL);
+
+	return 0;
+}
+
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 053a9b4..f66109e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -605,6 +605,7 @@ const struct seq_operations cpuinfo_op = {
  */
 static int __init arm64_console_setup(void)
 {
+
 	/* Allow cmdline to override our assumed preferences */
 	if (console_set_on_cmdline)
 		return 0;
@@ -621,3 +622,12 @@ static int __init arm64_console_setup(void)
 	return 0;
 }
 early_initcall(arm64_console_setup);
+
+static int __init arm64_spcr_setup(void)
+{
+	/* scan the ACPI tables for automatic console configuration */
+	acpi_setup_spcr();
+
+	return 0;
+}
+device_initcall(arm64_spcr_setup);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 57ca61b..143adad 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -34,6 +34,7 @@
 #include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/acpi.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -2664,8 +2665,12 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
 		spin_lock_init(&uport->lock);
 		lockdep_set_class(&uport->lock, &port_lock_key);
 	}
-	if (uport->cons && uport->dev)
+	if (uport->cons && uport->dev) {
+		printk("JCM: serial_core: checking for console\n");
 		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
+		acpi_spcr_console_check(ACPI_COMPANION(uport->dev),
+					uport->cons->name, uport->line);
+	}
 
 	uart_configure_port(drv, state, uport);
 

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

* Re: inverse mapping from a struct console to device
  2015-01-27 20:42           ` Jon Masters
@ 2015-01-28 22:48             ` Peter Hurley
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Hurley @ 2015-01-28 22:48 UTC (permalink / raw)
  To: Jon Masters, Mark Rutland
  Cc: linux-kernel, leif.lindholm, grant.likely, Andre Przywara, Torez Smith

Hi Jon,

On 01/27/2015 03:42 PM, Jon Masters wrote:
> On 01/27/2015 07:30 AM, Mark Rutland wrote:
>> On Tue, Jan 27, 2015 at 11:54:18AM +0000, Jon Masters wrote:
> 
>>> Here's an example of the data we get in the SPCR for reference:
>>>
>>> [0012]               Serial Port Register : [Generic Address Structure]
>>> [0001]                           Space ID : 00 [SystemMemory]
>>> [0001]                          Bit Width : 08
>>> [0001]                         Bit Offset : 00
>>> [0001]               Encoded Access Width : 01 [Byte Access:8]
>>> [0008]                            Address : 000000001c020000
>>>
>>> [0001]                     Interrupt Type : 08
>>> [0001]                PCAT-compatible IRQ : 00
>>> [0004]                          Interrupt : 0000006C
>>> [0001]                          Baud Rate : 07
>>> [0001]                             Parity : 00
>>> [0001]                          Stop Bits : 01
>>> [0001]                       Flow Control : 00
>>> [0001]                      Terminal Type : 00
>>> [0001]                           Reserved : 00
>>>
>>> The actual structure is longer, but you get the idea. I first map this
>>> to the correct Device in the DSDT with a device_initcall that will find
>>> the table then walk the ACPI namespace to find the corresponding device.
>>> This is stashed so that later we can perform the same kind of comparison
>>> that you do with DT today. I also populate options, though so far have
>>> only bothered to implement baud rate.
>>
>> I would recommend that you set up as many of these ASAP. Otherwise
>> someone's certain to mess up a table and we can never add them later.
> 
> So this is why I'm doing this (and other annoying things) right now - to
> make sure that vendors shipping platforms have valid data we can also
> use. If we wait until later, we'll have systems that potentially do the
> wrong thing. The table above is an example of one for the Mustang. I had
> the revision bumped to 2 and the IRQ information added to the reference
> one, and I've also verified the tables for Seattle, as well as "other"
> hardware that is in the pipeline from other vendors.
> 
>> Otherwise, sounds good!
> 
> So I'm handing this to Torez Smith to followup on (please keep her
> copied on replies to this thread). I'm attaching a *hack* patch I put
> together to proof of concept and then Torez will make this into
> something actually useable/upstreamable (without hard coded static baud
> strings and the like that I used to hack it up).

The Serial Port Console Redirection (SPCR) Table is patented by
Microsoft (spec and patent notice downloadable here
https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx )
and covered under the Microsoft Community Promise here
http://www.microsoft.com/openspecifications/en/us/programs/community-promise/default.aspx

The Micosoft Community Promise does not look compatible with GPL 2;
or more specifically, whomever eventually submitted the patch would likely not
be able to meet the criteria set forth by the Developer's Certificate of Origin 1.1
in Documentation/SubmittingPatches

Regards,
Peter Hurley

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

end of thread, other threads:[~2015-01-29  1:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-26 19:40 inverse mapping from a struct console to device Jon Masters
2015-01-26 20:20 ` Greg KH
2015-01-27  3:16   ` Jon Masters
2015-01-26 20:50 ` Mark Rutland
2015-01-27  3:06   ` Jon Masters
2015-01-27 10:14     ` Mark Rutland
2015-01-27 11:54       ` Jon Masters
2015-01-27 12:30         ` Mark Rutland
2015-01-27 20:42           ` Jon Masters
2015-01-28 22:48             ` Peter Hurley

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).