[LinuxBIOS] 64bit issues was: [PATCH] LBv3: fix printk format warnings

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Mon Aug 20 22:50:16 CEST 2007


On 15.08.2007 18:15, Stefan Reinauer wrote:
> Carl-Daniel Hailfinger wrote:
>> I have another patch pending which changes %Lx (L is unspecified for
>> integers, happens to work) to %llx ("official" long long for integers).
>>
>>   
> It doesn't "happen to work", it is implemented so that it works. %llx
> will not work if you don't change printk.

Quoting from v3/lib/vtxprintf.c:
                if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
                        qualifier = *fmt;
                        ++fmt;
                        if (*fmt == 'l') {
                                qualifier = 'L';
                                ++fmt;
                        }

%llx already works.

> I agree we should make it compatible to printf.

OK, I'll send followup patches.

>> Conclusions:
>> * "L" is for floats only.
>> * "t" or "z" might be handy for resource sizes.
>> * "h" and "hh" for u16 and u8 seem to be unknown to most coders (except
>> in util/dtc) and gcc doesn't warn about them. Should investigate
>> usefulness for us.
> 
> Then L really makes no sense. Then we want to drop it from the code
> completely to prevent people from using it with the wrong expectations
> (like I did, because I figured its meaning out from the code, not the
> man page of printf)

Will send patches.

>>> printk(BIOS_DEBUG, "ROM address for %s = %p\n", dev_path(dev), (void *) rom_address);
>>>
>>>     
>> Do I understand this correctly? (void *) conversion and usage of %p for
>> things that are essentially pointers.
> 
> What's unclear?

Nothing. I was just trying to make sure I had understood Ron correctly.

>>> Why do this? It's actually more portable, even across plan 9 and
>>> linux. It will probably work correctly in 64 bit mode. And, that
>>> rom_address really *is* an address.
>>>     
>> I like it, but... in the first example it seems this was an error, the
>> base is not an address, but some u16 value.
>> Stefan? Can you tell us what the reason is?
>>   
> rom_address a 16bit value? Which part of the  code? Sorry I lost you.
> 
> Are you talking about IO accesses which have a 16bit address space?

I was talking about ./superio/winbond/w83627hf/superio.c:init_hwm()
where Ron assumed that base was a pointer, however init_hwm defines it
as u16. Which is somewhat interesting because w83627hf_init() calls
init_hwm(res0->base + HWM_INDEX_PORT) where res0->base is resource_t aka
u64. That means we have an implicit truncation from u64 to u16. Is that
intentional?

>> The second example is more correct, but we still face a problem:
>> resource_t is u64 and as long as we don't use long mode, %p will expect
>> 32bit values. However, almost everything being a resource_t (base, size,
>> limit) is essentially a pointer of a pointerdiff. Now how do we handle that?
> 
> Which second example?

Reading that text again, it seems I was totally unclear.

./device/pci_rom.c:pci_rom_probe():
printk(BIOS_DEBUG, "ROM address for %s = %lx\n", dev_path(dev),
rom_address);

I was wondering whether rom_address (which is essentially a pointer)
should be resource_t.
Also, how should we printk anything that's resource_t? Everything with
type resource_t is essentially a pointer. %p won't work unless we
compile for 64bit. Maybe introduce %P or some other ugly hack.

>> And while we're at correct typing, shouldn't arch/x86/linuxbios_table.c
>> use resource_t in most places where it uses u64?
>>
>>   
> Interesting idea. You might be correct. resource_t should be a u64 in
> fact. It might be something different due to alignment requirements of
> the pci structures

It is typedef'ed to u64, so there aren't any differences. But when we
use resource_t instead of u64, we still have the freedom to define it to
u32 for some architectures.

>> I have a lot of open questions:
>> * How do we handle accesses to resources above 4 GB when we confine
>> ourselves to 32bit code?
>>   
> We don't confine ourselfes. There's PAE

Which we don't want to handle in LB.

>> * How do 32bit operating systems handle resources above 4 GB? Should we
>> just avoid locating resources up there? Only do it if unavoidable?
>> Consider a machine with 4 GB of RAM and a graphics card with 512 MB.
>> That combination can be bought today. Now what will happen if video RAM
>> grows to 4 GB? Can we boot such a machine in 32bit mode at all? Should
>> we show a warning? Refuse to boot any non-64bit OS?
> 
> 32bit OSes can not handle system resources above 4GB except with tricks
> (PAE). That is why 32bit OSes are dying out and are not being used
> anymore in environments where resources above 4GB happen.

The interesting question is whether we can set up resources in a way
that allows 32bit OSes to boot, e.g. by "moving" RAM to above 4G and
making it inaccessible that way.

> If you run a 32bit OS on a machine with 4G of RAM you simply can not be
> helped. Linux starts having severe performance problems in 32bit mode
> when you cross the 1G border. Which basically every machine does today,
> except lowend hobbyist stuff and embedded systems.

Yes, but we should allow it to boot if this is technically possible.

>> * Should we have some preference setting which controls 64bit resource
>> allocation?
> 
> We do have a CONFIG variable for that, and it packs resources into 32bit
> per default. This default will change at some point because a 3G PCI
> hole in 4G space makes only little sense. This is done on some machines
> so that _in theory_ you  _could_ run a 32bit OS.

There is not such CONFIG variable in v3.

>> * Is there any point trying to handle 64bit resources on 32bit machines?
>>   
> Not that I would know of. PCI resources can prefer to go to 64bit space,
> but on a 32bit machine that means you poke them out of  visibility.

OK.

>> * Do we have to compile 64bit code for 64bit machines?
>>
>>   
> No. Thanks to PAE we can access address space above 4G too. But in fact

Ugly.

> we want to go 64bit mode.
> The really broken thing with x86_64's long mode is that it does not work
> without paging enabled. That makes the effort to use it in the bios
> harder than the gain.

Seems we are caught between a rock and a hard place. PAE is ugly, long
mode is difficult.

> For an OS and other high level applications like that things are
> different though.

Yes.

Regards,
Carl-Daniel




More information about the coreboot mailing list