--------- Forwarded message ----------
From: ali hagigat <hagigatali(a)gmail.com>
Date: Wed, Mar 28, 2012 at 4:58 PM
Subject: Re: [coreboot] porting Coreboot to a new motherboard....
To: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Dear Kyösti
I just added 10 "nop" assembly command("no operation")!
10 because the number of the Pentium III pipeline stages is 10.
Very simple and strange. After adding that, each time hardwaremain()
got executed and the code continued loading FILO.
Now another strange thing (and a similar work i saw before when i was
working on hardwaremain()):
I add some "nop" like:
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
to the start_linux() function of FILO ( in linux_load.c) and switch.S
as follows:
static int start_linux(uint32_t kern_addr, struct linux_params *params)
{
struct segment_desc *linux_gdt;
struct context *ctx;
#ifdef VGA_CONSOLE
extern int cursor_x, cursor_y;
#endif
#ifdef PCMCIA_CF
uint32_t cf_bar;
int i;
#endif
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx = init_context(phys_to_virt(STACK_LOC), 4096, 0);
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
/* Linux expects GDT being in low memory */
linux_gdt = phys_to_virt(GDT_LOC);
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
memset(linux_gdt, 0, 13*sizeof(struct segment_desc));
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
/* Normal kernel code/data segments */
linux_gdt[2] = gdt[FLAT_CODE];
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
linux_gdt[3] = gdt[FLAT_DATA];
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
/* 2.6 kernel uses 12 and 13, but head.S uses backward-compatible
* segments (2 and 3), so it SHOULD not be a problem.
* However, some distro kernels (eg. RH9) with backported threading
* patch use 12 and 13 also when booting... */
linux_gdt[12] = gdt[FLAT_CODE];
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
linux_gdt[13] = gdt[FLAT_DATA];
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->gdt_base = GDT_LOC;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->gdt_limit = 14*8-1;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->cs = 0x10;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->ds = 0x18;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->es = 0x18;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->fs = 0x18;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->gs = 0x18;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx->ss = 0x18;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
/* Parameter location */
ctx->esi = virt_to_phys(params);
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
/* Entry point */
ctx->eip = kern_addr;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
debug("eip=%#x\n", kern_addr);
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
printf("Jumping to entry point...\n");
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
#ifdef VGA_CONSOLE
/* Update VGA cursor position.
* This must be here because the printf changes the value! */
params->orig_x = cursor_x;
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
params->orig_y = cursor_y;
#endif
#ifdef PCMCIA_CF
cf_bar = phys_to_virt(pci_read32(PCI_ADDR(0, 0xa, 1), 0x10));
for( i = 0x836 ; i < 0x840 ; i++){
*(unsigned char *)(cf_bar+i) = 0;
}
#endif
/* Go... */
asm("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
ctx = switch_to(ctx);
/* It's impossible but... */
printf("Returned with eax=%#x\n", ctx->eax);
return ctx->eax;
}
__switch_context:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Save everything in current stack */
pushfl /* 56 */
pushl %ds /* 52 */
pushl %es /* 48 */
pushl %fs /* 44 */
pushl %gs /* 40 */
pushal /* 8 */
subl $8, %esp
movw %ss, (%esp) /* 0 */
sgdt 2(%esp) /* 2 */
#if 0
/* Swap %cs and %eip on the stack, so lret will work */
movl 60(%esp), %eax
xchgl %eax, 64(%esp)
movl %eax, 60(%esp)
#endif
/* At this point we don't know if we are on flat segment
* or relocated. So compute the address offset from %eip.
* Assuming CS.base==DS.base==SS.base.
*/
call 1f
1: popl %ebx
subl $1b, %ebx
/* Interrupts are not allowed... */
cli
/* Current context pointer is our stack pointer */
movl %esp, %esi
/* Normalize the ctx pointer */
subl %ebx, %esi
/* Swap it with new value */
xchgl %esi, __context(%ebx)
/* Adjust new ctx pointer for current address offset */
addl %ebx, %esi
/* Load new %ss and %esp to temporary */
movzwl (%esi), %edx
movl 20(%esi), %eax
/* Load new GDT */
lgdt 2(%esi)
/* Load new stack segment with new GDT */
movl %edx, %ss
/* Set new stack pointer, but we have to adjust it because
* pushal saves %esp value before pushal, and we want the value
* after pushal.
*/
leal -32(%eax), %esp
/* Load the rest from new stack */
popal
popl %gs
popl %fs
popl %es
popl %ds
popfl
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
/* Finally, load new %cs and %eip */
lret
The rest of the code(COREBOOT+FILO) is exactly the same. What happens
is that CPU executes the code till boot() function!! and stops! I can
not even see printf() output of autoboot_delay() function!!
What is happening here? I changed two functions which are executed
after boot() , how "nop" commands are effecting boot() and
autoboot_delay()?
Can you explain it?
Regards
On Wed, Mar 28, 2012 at 4:14 PM, Kyösti Mälkki <kyosti.malkki(a)gmail.com> wrote:
> On Wed, 2012-03-28 at 13:51 +0430, ali hagigat wrote:
>> I remember when i ported my RAM initialization code, hardwaremain()
>> could not be run. The problem was not RAM, it was CPU! i chaned
>> c_start() a bit to solve the problem.
>> What do you mean by earlyprintk(), do you suggest to change linux
>> kernel to monitor it?
>>
>> Regards
>>
>
> A diff of that c_start() change, please.
>
> Thanks,
> KM
>