diff mbox

[U-Boot,13/69] x86: Allow use of serial soon after relocation

Message ID 1457317732-18406-14-git-send-email-sjg@chromium.org
State Superseded
Delegated to: Bin Meng
Headers show

Commit Message

Simon Glass March 7, 2016, 2:27 a.m. UTC
At present on x86 machines with use cache-as-RAM, the memory goes away just
before board_init_r() is called. This means that serial drivers are
no-longer unavailable, until initr_dm() it called, etc.

Any attempt to use printf() within this period will cause a hang.

To fix this, mark the serial devices as 'unavailable' when it is no-longer
available. Bring it back when serial_initialize() is called. This means that
the debug UART will be used instead for this period.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/board_f.c               | 7 +++++++
 drivers/serial/serial-uclass.c | 1 +
 2 files changed, 8 insertions(+)

Comments

Bin Meng March 11, 2016, 4:31 a.m. UTC | #1
Hi Simon,

On Mon, Mar 7, 2016 at 10:27 AM, Simon Glass <sjg@chromium.org> wrote:
> At present on x86 machines with use cache-as-RAM, the memory goes away just
> before board_init_r() is called. This means that serial drivers are
> no-longer unavailable, until initr_dm() it called, etc.
>
> Any attempt to use printf() within this period will cause a hang.
>
> To fix this, mark the serial devices as 'unavailable' when it is no-longer
> available. Bring it back when serial_initialize() is called. This means that
> the debug UART will be used instead for this period.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  common/board_f.c               | 7 +++++++
>  drivers/serial/serial-uclass.c | 1 +
>  2 files changed, 8 insertions(+)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index 622093a..109025a 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -1096,6 +1096,13 @@ void board_init_f_r(void)
>                 hang();
>
>         /*
> +        * The pre-relocation drivers may be using memory that has now gone
> +        * away. Mark serial as unavailable - this will fall back to the debug
> +        * UART if available.
> +        */
> +       gd->flags &= ~GD_FLG_SERIAL_READY;
> +

What about other architectures (non-X86 and non-ARC)?

> +       /*
>          * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
>          * Transfer execution from Flash to RAM by calculating the address
>          * of the in-RAM copy of board_init_r() and calling it
> diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
> index 1c447ff..6562be0 100644
> --- a/drivers/serial/serial-uclass.c
> +++ b/drivers/serial/serial-uclass.c
> @@ -116,6 +116,7 @@ int serial_init(void)
>  void serial_initialize(void)
>  {
>         serial_find_console_or_panic();
> +       gd->flags |= GD_FLG_SERIAL_READY;

I think we can simply replace this to:

void serial_initialize(void)
{
    serial_init();
}

Regards,
Bin
Simon Glass March 12, 2016, 5:04 a.m. UTC | #2
Hi Bin,

On 10 March 2016 at 21:31, Bin Meng <bmeng.cn@gmail.com> wrote:
> Hi Simon,
>
> On Mon, Mar 7, 2016 at 10:27 AM, Simon Glass <sjg@chromium.org> wrote:
>> At present on x86 machines with use cache-as-RAM, the memory goes away just
>> before board_init_r() is called. This means that serial drivers are
>> no-longer unavailable, until initr_dm() it called, etc.
>>
>> Any attempt to use printf() within this period will cause a hang.
>>
>> To fix this, mark the serial devices as 'unavailable' when it is no-longer
>> available. Bring it back when serial_initialize() is called. This means that
>> the debug UART will be used instead for this period.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>>  common/board_f.c               | 7 +++++++
>>  drivers/serial/serial-uclass.c | 1 +
>>  2 files changed, 8 insertions(+)
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index 622093a..109025a 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -1096,6 +1096,13 @@ void board_init_f_r(void)
>>                 hang();
>>
>>         /*
>> +        * The pre-relocation drivers may be using memory that has now gone
>> +        * away. Mark serial as unavailable - this will fall back to the debug
>> +        * UART if available.
>> +        */
>> +       gd->flags &= ~GD_FLG_SERIAL_READY;
>> +
>
> What about other architectures (non-X86 and non-ARC)?

This problem hasn't happened on any ARM chip I am aware of. I am
pretty sure it is x86-specific.

>
>> +       /*
>>          * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
>>          * Transfer execution from Flash to RAM by calculating the address
>>          * of the in-RAM copy of board_init_r() and calling it
>> diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
>> index 1c447ff..6562be0 100644
>> --- a/drivers/serial/serial-uclass.c
>> +++ b/drivers/serial/serial-uclass.c
>> @@ -116,6 +116,7 @@ int serial_init(void)
>>  void serial_initialize(void)
>>  {
>>         serial_find_console_or_panic();
>> +       gd->flags |= GD_FLG_SERIAL_READY;
>
> I think we can simply replace this to:
>
> void serial_initialize(void)
> {
>     serial_init();
> }

OK.

Regards,
Simon
diff mbox

Patch

diff --git a/common/board_f.c b/common/board_f.c
index 622093a..109025a 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -1096,6 +1096,13 @@  void board_init_f_r(void)
 		hang();
 
 	/*
+	 * The pre-relocation drivers may be using memory that has now gone
+	 * away. Mark serial as unavailable - this will fall back to the debug
+	 * UART if available.
+	 */
+	gd->flags &= ~GD_FLG_SERIAL_READY;
+
+	/*
 	 * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
 	 * Transfer execution from Flash to RAM by calculating the address
 	 * of the in-RAM copy of board_init_r() and calling it
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 1c447ff..6562be0 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -116,6 +116,7 @@  int serial_init(void)
 void serial_initialize(void)
 {
 	serial_find_console_or_panic();
+	gd->flags |= GD_FLG_SERIAL_READY;
 }
 
 static void _serial_putc(struct udevice *dev, char ch)