[coreboot] Fwd: porting Coreboot to a new motherboard....

ali hagigat hagigatali at gmail.com
Wed Mar 28 14:52:31 CEST 2012


--------- Forwarded message ----------
From: ali hagigat <hagigatali at 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 at 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 at 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
>




More information about the coreboot mailing list