[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