Re: kmalloc

Gabriel Paubert (paubert@iram.es)
Thu, 28 Jan 1999 21:12:16 +0100 (MET)


On Thu, 28 Jan 1999, Linus Torvalds wrote:

> > And I'm not sure, whether
> > ioremap works correctly on PReP.
>
> Entirely possible. You might want to talk to the PPC people.

It does not work, and I'm trying to fix it among other problems...

>
> > (FYI, PowerStack I, 32MB RAM). I found only one working way:
> > `virt = vga_base + _ISA_MEM_BASE' - because of whole PCI MMIO space is
> > mapped at _ISA_MEM_BASE on PReP (sorry, do not ask me for patches for PPC,
> > I do not understand neither that architecture nor their assembly language).
>
> This is WRONG!
>
> If that is indeed the case, then what _should_ happen on PPC is:
>
> - ioremap() does nothing:
>
> #define ioremap(x,y) ((void *)(_ISA_MEM_BASE + (unsigned long)(x))
>
> - readX/writeX: probably just do something like
>
> #define readb(addr) (*(unsigned char *)(addr))
>
> but in NO case is your approach correct, and you should really complain to
> the PPC people if using ioremap/readb doesn't work.

Indeed, but not all MMIO space is permanently mapped on PPC (very hard to
fix with some devices and the way some FW spread addresses when
allocating PCI resources), so ioremap has to use the normal mapping
mechanism in some occasions.

> > At second, on some (all?) big endian archs, readl/writel stores data
> > in little-endian format. I do not know, whether this idea is correct
> > and I'm sure that it is not documented.
>
> Drivers that care about endianness should probably do the conversion
> themselves.

Yes, and read[bwl]/write[bwl] also add a barrier instruction after each
access. This may hurt badly, and it is perfectly possible to add barriers
explicitly in newly written drivers.

>
> > And at third, in structure pci_device, there is array with addresses
> > of PCI devices. It should contain CPU view of device address, i.e.
> > something suitable for ioremap(). It contains PCI bus view... So another
> > case.
>
> No, they should not. The driver should use ioremap().

Indeed, but I'm probably too stupid and I would like to understand what
the following code on the Alpha means (in arch/alpha/kernel/bios32.c,
but there is something similar in Sparc64):

pcibios_write_config_dword(bus->number, dev->devfn,
off, base);
new_io_reset(dev, off, orig_base);

handle = PCI_HANDLE(bus->number) | base;
dev->base_address[idx] = handle;

Obviously, unless the code is needlessly obfuscated, dev->base_address
will _not_ have the same value as the base register in the PCI
configuration space. Shouldn't it be the same on PreP, where to access the
MMIO at address 0x123456, the physical address is 0xC0123456 since the bridge
subtracts 0xc0000000 from the address appearing on the CPU pins ?

Then it's mapped at a different virtual address to avoid conflicts with
the kernel itself but it's another matter (handled by ioremap).

I've been trying to solve this problem but never got a clear answer. I had
come to the conclusion that it should be:

pci_read_config_dword(dev, PCI_BASE_ADDRESS_n, &base)

dev->base_address[n] = base+0xc0000000 (adjusted by pcibios_fixup())

address used in driver = ioremap(dev->base_address[n])

in this case, lspci -v and lspci -vb do not display the same addresses.
That's what I have right now and I had to make a minor fix to one driver
to get the system running.

What should it be before I send some patches to the PPC maintainers ?

Gabriel.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/