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

Idwer Vollering vidwer at gmail.com
Wed Mar 28 15:00:19 CEST 2012


Op 28 maart 2012 14:52 heeft ali hagigat <hagigatali at gmail.com> het
volgende geschreven:
> --------- 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")!

Please show your code in diff-formatting, because what you have shown
isn't reallye readable: it does not show your additions in a clear
way.

Also I want to emphasize Stefan's answer (
http://www.coreboot.org/pipermail/coreboot/2012-February/068335.html
): "But generally, I suggest you rewrite this in C, so it's a lot more
readable..."


> 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
>>
>
> --
> coreboot mailing list: coreboot at coreboot.org
> http://www.coreboot.org/mailman/listinfo/coreboot




More information about the coreboot mailing list