Re: [Etherboot-developers] Relocation problems
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: <ebi...@ln...> - 2003-05-23 07:12:33
|
Michael Brown <mb...@fe...> writes: > I'm having big problems getting the UNDI driver to work with relocation. > An UNDI API call that works fine when the Etherboot code is in base memory > fails when called with the *exact* same parameters (i.e. all the real-mode > segment:offset addresses are the same) if the Etherboot code has been > relocated out of base memory. This is the very first UNDI API call: the > one that installs the UNDI driver into base memory (the base memory having > been allocated using allot_base_memory()). > Within the "10: .code16" section of a real-mode call, are there any > registers (other than %ss and %sp) that need to be preserved in order for > the return from real mode to function correctly? There should not be but it is possible there is some architecture state we depend on. To a certain mild extent we can even tolerate changes in %sp so long as we return to that stack. > Any other ideas very welcome; I've run out. If I had the time I would look but baring that: I have seen alignment issues depending on the relocation address chosen. There is a potential for the status of the A20 line to be significant. I once saw an instruction that was invalid on a 486 but worked on later processors. It is possible the undi driver is allocating high memory with some BIOS call and stomping etherboot. But my gut reaction is that something somewhere is missing a virt_to_phys or a phys_to_virt.. But in general when I am faced with these things I take my serial debugging prints statements and instrument the code and find out exactly where it is failing so I can do something about the failure. My debug print statements are attached below. The expand inline and increase the code size but by doing so have a very minimal register impact and not stack impact so can be used in all kinds of situations. The code works find as either 16bit or 32bit code. Note: I have this bad habit of not believing I have registers when I am coding in assembly. It will be very interesting to find out if the undi initialization even attempts to return. Eric #if 1 /* Base Address */ #define TTYS0_BASE 0x3f8 /* Data */ #define TTYS0_RBR (TTYS0_BASE+0x00) #define TTYS0_TBR (TTYS0_BASE+0x00) /* Control */ #define TTYS0_IER (TTYS0_BASE+0x01) #define TTYS0_IIR (TTYS0_BASE+0x02) #define TTYS0_FCR (TTYS0_BASE+0x02) #define TTYS0_LCR (TTYS0_BASE+0x03) #define TTYS0_MCR (TTYS0_BASE+0x04) #define TTYS0_DLL (TTYS0_BASE+0x00) #define TTYS0_DLM (TTYS0_BASE+0x01) /* Status */ #define TTYS0_LSR (TTYS0_BASE+0x05) #define TTYS0_MSR (TTYS0_BASE+0x06) #define TTYS0_SCR (TTYS0_BASE+0x07) #define TTYS0_BAUD 9600 #define TTYS0_DIV (115200/TTYS0_BAUD) #define TTYS0_DIV_LO (TTYS0_DIV&0xFF) #define TTYS0_DIV_HI ((TTYS0_DIV >> 8)&0xFF) #if ((115200%TTYS0_BAUD) != 0) #error Bad ttyS0 baud rate #endif #define TTYS0_INIT \ /* disable interrupts */ \ movb $0x00, %al ; \ movw $TTYS0_IER, %dx ; \ outb %al, %dx ; \ ; \ /* enable fifos */ \ movb $0x01, %al ; \ movw $TTYS0_FCR, %dx ; \ outb %al, %dx ; \ ; \ /* Set Baud Rate Divisor to TTYS0_BAUD */ \ movw $TTYS0_LCR, %dx ; \ movb $0x83, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLL, %dx ; \ movb $TTYS0_DIV_LO, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLM, %dx ; \ movb $TTYS0_DIV_HI, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_LCR, %dx ; \ movb $0x03, %al ; \ outb %al, %dx /* uses: ax, dx */ #define TTYS0_TX_AL \ mov %al, %ah ; \ 9: mov $TTYS0_LSR, %dx ; \ inb %dx, %al ; \ test $0x20, %al ; \ je 9b ; \ mov $TTYS0_TBR, %dx ; \ mov %ah, %al ; \ outb %al, %dx /* uses: ax, dx */ #define TTYS0_TX_CHAR(byte) \ mov byte, %al ; \ TTYS0_TX_AL #define TTYS0_TX_HEX32(lword) \ mov lword, %eax ; \ shr $28, %eax ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $24, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $20, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $16, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $12, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $8, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $4, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL #define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #endif |