On Tue, Nov 23, 2010 at 11:32:13AM +0100, Gerd Hoffmann wrote:
On 11/23/10 02:13, Kevin O'Connor wrote:
On Mon, Nov 22, 2010 at 07:40:36PM -0500, Kevin O'Connor wrote:
It should be possible to extend call32() to do what you need -
FYI - here's what call32 extended to pass a parameter looks like:
--- a/src/stacks.c +++ b/src/stacks.c @@ -37,14 +37,14 @@ static inline void lgdt(struct descloc_s *desc) { }
// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function. -static inline int -call32(void *func) +static inline u32 +call32(void *func, u32 eax, u32 errret)
Tried to use that (see patch). Failed. When calling pci_readl from real mode I see the pci_readl debug printf but not the one from pci_readl_32 ...
You need to make sure the 32bit function is only available in 32bit mode. See below.
I briefly tested this and the call completes, but it caused issues with bootup - I'm not sure if this is due to a bug somewhere or due to 32bit mode switching being inherently unsafe.
-Kevin
--- a/src/stacks.c +++ b/src/stacks.c @@ -395,3 +395,28 @@ check_preempt(void)
call32(yield_preempt, 0, 0); } + +extern u32 pci_readl_32(u32 addr); +#if MODESEGMENT == 0 +u32 VISIBLE32FLAT +pci_readl_32(u32 addr) +{ + dprintf(1, "pci rd32: %x\n", addr); + return readl((void*)addr); +} +#endif + +u32 pci_readl(u32 addr) +{ + dprintf(1, "pci read: %x\n", addr); + if (MODESEGMENT) + return call32(pci_readl_32, addr, -1); + return pci_readl_32(addr); +} + +void pci_writel(u32 addr, u32 val) +{ + dprintf(1, "pci write: %x, %x\n", addr, val); + if (!MODESEGMENT) + writel((void*)addr, val); +}