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.
I agree we should make it compatible to printf.
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)
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?
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?
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?
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
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
- 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.
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.
- 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.
- 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.
- 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 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.
For an OS and other high level applications like that things are different though.