On 27/08/11 23:48, Wolfgang Denk wrote:
> Dear Graeme Russ,
> 
> In message <1314449645-16900-1-git-send-email-graeme.r...@gmail.com> you 
> wrote:
>> This cropped up as an aside to another thread so I thought I would give
>> it a go. It's pretty rough-and-ready but it does the trick :)
> 
> Hm....the problem is that we need some buffer to store the data.  On
> some systems this may work, but on many (most?) it doesnt.

>From what I can tell, a lot of CPUs use on-die cache until SDRAM is
initialised. Now the AMD SC520 which I am using (which is a 12 year old
part) has 16kB which is way more than enough for initial Global Data, stack
and pre-console buffer

Now I'm not saying (like you so rightly point out) that every CPU will have
the required functionality. It would be interesting to know how much
'temporary memory' each of the various CPUs have.

> 
>> diff --git a/arch/x86/include/asm/global_data.h 
>> b/arch/x86/include/asm/global_data.h
>> index 2902e61..4ebc5bd 100644
>> --- a/arch/x86/include/asm/global_data.h
>> +++ b/arch/x86/include/asm/global_data.h
>> @@ -44,6 +44,7 @@ typedef    struct global_data {
>>      unsigned long   env_addr;       /* Address  of Environment struct */
>>      unsigned long   cpu_clk;        /* CPU clock in Hz!             */
>>      unsigned long   bus_clk;
>> +    unsigned long   con_buf_idx;    /* Console buffer index */
>>      unsigned long   relocaddr;      /* Start address of U-Boot in RAM */
>>      unsigned long   start_addr_sp;  /* start_addr_stackpointer */
>>      phys_size_t     ram_size;       /* RAM size */
>> @@ -65,13 +66,14 @@ extern gd_t *gd;
>>  #define GD_ENV_ADDR         5
>>  #define GD_CPU_CLK          6
>>  #define GD_BUS_CLK          7
>> -#define GD_RELOC_ADDR               8
>> -#define GD_START_ADDR_SP    9
>> -#define GD_RAM_SIZE         10
>> -#define GD_RESET_STATUS             11
>> -#define GD_JT                       12
>> +#define GD_CON_BUF_IDX              8
>> +#define GD_RELOC_ADDR               9
>> +#define GD_START_ADDR_SP    10
>> +#define GD_RAM_SIZE         11
>> +#define GD_RESET_STATUS             12
>> +#define GD_JT                       13
>>
>> -#define GD_SIZE                     13
>> +#define GD_SIZE                     14
> 
> Argh... your whole "Word Offsets into Global Data" needs to be
> removed.  This should be auto-generated as asm-offsets.

Agreed - I did some work on this but found the rabbit hole gets rather deep
as asm-offsets needs to be build in the 'depend' target to avoid file not
found errors while building the dependencies. Also, the temporary files
need to be cleaned up in the clean target. So I started digging and hit
rules.mk - I'm still working on it ;)

>> --- a/common/console.c
>> +++ b/common/console.c
>> @@ -323,6 +323,28 @@ int tstc(void)
>>      return serial_tstc();
>>  }
> 
> Hm... this adds a lot of code, unconditionally.  In thos form this is
> not acceptable, especially as many boards cannot make use of this, or
> eventually don't want to make use of it.

As I said, rough-and-ready. Yes, I would expect in the board config file:

#define CONFIG_PRE_CONSOLE_BUFFER

>> +    if (gd->flags & GD_FLG_HAVE_CONSOLE) {
>> +            if (gd->flags & GD_FLG_DEVINIT) {
>> +                    /* Send to the standard output */
>> +                    fputc(stdout, c);
>> +            } else {
>> +                    /* Send directly to the handler */
>> +                    serial_putc(c);
>> +            }
>>      } else {
>> -            /* Send directly to the handler */
>> -            serial_putc(c);
>> +            pre_console_putc(c);
>>      }
>>  }
> 
> And this is actually wrong.  If we can use the serial console for
> output, we definitely don;t want to use your buffer any more.

Look closer - It's a diff weirdness - The actual code is:

        if (gd->flags & GD_FLG_HAVE_CONSOLE) {
                if (gd->flags & GD_FLG_DEVINIT) {
                        /* Send to the standard output */
                        fputc(stdout, c);
                } else {
                        /* Send directly to the handler */
                        serial_putc(c);
                }
        } else {
                pre_console_putc(c);
        }

So if we have console, it goes there, otherwise it goes to the buffer

>> diff --git a/include/configs/eNET.h b/include/configs/eNET.h
>> index 548d52c..4fb971f 100644
>> --- a/include/configs/eNET.h
>> +++ b/include/configs/eNET.h
> 
> ...and compilation for all other boards breaks?

See above.

Also, I have noticed in drivers/i2c/ppc4xx_i2c.c:

                if (gd->flags & GD_FLG_HAVE_CONSOLE) {
                        printf("I2C %s: failed %d\n",
                               read ? "read" : "write", ret);
                }

and in drivers/i2c/soft_i2c.c:

#ifdef DEBUG_I2C
#define PRINTD(fmt,args...)     do {            \
        if (gd->flags & GD_FLG_HAVE_CONSOLE)    \
                printf (fmt ,##args);           \
        } while (0)
#else
#define PRINTD(fmt,args...)
#endif

So there are drivers that anticipate generating output before console is
initialised - I think we should not put the onus on the driver and move
these conditions to printf() in console.c - Unfortunately this could lead
to head-scratching when one _thinks_ a printf() should generate an output,
but it is squelched (which is what the pre-console buffer is for)

Regards,

Graeme





_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to