X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fcpu%2Fintel%2Fcar%2Fcache_as_ram_ht.inc;h=18fb176f992fbdfacf4ae8d1b7878207ad09c15f;hb=0078ceb553a1d87ea0a948c3e7e2c59ab4d2e65e;hp=a6cbd6bac5bb0e33efe41d970f3f65d7a950745e;hpb=f9d1a42d98b121088b0c242b4d9f5d0eb78d38de;p=coreboot.git diff --git a/src/cpu/intel/car/cache_as_ram_ht.inc b/src/cpu/intel/car/cache_as_ram_ht.inc index a6cbd6bac..18fb176f9 100644 --- a/src/cpu/intel/car/cache_as_ram_ht.inc +++ b/src/cpu/intel/car/cache_as_ram_ht.inc @@ -2,7 +2,9 @@ * This file is part of the coreboot project. * * Copyright (C) 2000,2007 Ronald G. Minnich + * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan) * Copyright (C) 2007-2008 coresystems GmbH + * Copyright (C) 2012 Kyösti Mälkki * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +27,7 @@ /* Macro to access Local APIC registers at default base. */ #define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x) +#define START_IPI_VECTOR ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff) #define CPU_MAXPHYADDR 36 #define CPU_PHYSMASK_HI (1 << (CPU_MAXPHYADDR - 32) - 1) @@ -41,12 +44,9 @@ cache_as_ram: post_code(0x20) - /* Send INIT IPI to all excluding ourself. */ - movl LAPIC(ICR), %edi - movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax - movl %eax, (%edi) - - /* Zero out all fixed range and variable range MTRRs. */ + /* Zero out all fixed range and variable range MTRRs. + * For hyper-threaded CPU MTRRs are shared so we actually + * clear them more than once, but we don't care. */ movl $mtrr_table, %esi movl $((mtrr_table_end - mtrr_table) / 2), %edi xorl %eax, %eax @@ -59,12 +59,127 @@ clear_mtrrs: dec %edi jnz clear_mtrrs + post_code(0x21) + /* Configure the default memory type to uncacheable. */ movl $MTRRdefType_MSR, %ecx rdmsr andl $(~0x00000cff), %eax wrmsr + post_code(0x22) + + /* Enable local apic. */ + movl $LAPIC_BASE_MSR, %ecx + rdmsr + andl $(~CPU_PHYSMASK_HI), %edx + andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax + orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax + wrmsr + andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax + jz ap_init + +bsp_init: + + post_code(0x23) + + /* Send INIT IPI to all excluding ourself. */ + movl LAPIC(ICR), %edi + movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax +1: movl %eax, (%edi) + movl $0x30, %ecx +2: pause + dec %ecx + jnz 2b + movl (%edi), %ecx + andl $LAPIC_ICR_BUSY, %ecx + jnz 1b + + post_code(0x24) + + /* For a hyper-threading processor, cache must not be disabled + * on an AP on the same physical package with the BSP. + */ + movl $01, %eax + cpuid + btl $28, %edx + jnc sipi_complete + bswapl %ebx + cmpb $01, %bh + jbe sipi_complete + +hyper_threading_cpu: + + /* delay 10 ms */ + movl $10000, %ecx +1: inb $0x80, %al + dec %ecx + jnz 1b + + post_code(0x25) + + /* Send Start IPI to all excluding ourself. */ + movl LAPIC(ICR), %edi + movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax +1: movl %eax, (%edi) + movl $0x30, %ecx +2: pause + dec %ecx + jnz 2b + movl (%edi), %ecx + andl $LAPIC_ICR_BUSY, %ecx + jnz 1b + + /* delay 250 us */ + movl $250, %ecx +1: inb $0x80, %al + dec %ecx + jnz 1b + + post_code(0x26) + + /* Wait for sibling CPU to start. */ +1: movl $(MTRRphysBase_MSR(0)), %ecx + rdmsr + andl %eax, %eax + jnz sipi_complete + + movl $0x30, %ecx +2: pause + dec %ecx + jnz 2b + jmp 1b + + +ap_init: + post_code(0x27) + + /* Do not disable cache (so BSP can enable it). */ + movl %cr0, %eax + andl $(~((1 << 30) | (1 << 29))), %eax + movl %eax, %cr0 + + post_code(0x28) + + /* MTRR registers are shared between HT siblings. */ + movl $(MTRRphysBase_MSR(0)), %ecx + movl $(1<<12), %eax + xorl %edx, %edx + wrmsr + + post_code(0x29) + +ap_halt: + cli +1: hlt + jnz 1b + + + +sipi_complete: + + post_code(0x2a) + /* Set Cache-as-RAM base address. */ movl $(MTRRphysBase_MSR(0)), %ecx movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax @@ -83,11 +198,44 @@ clear_mtrrs: orl $MTRRdefTypeEn, %eax wrmsr - /* Enable L2 cache. */ + post_code(0x2b) + + /* Enable L2 cache Write-Back (WBINVD and FLUSH#). + * + * MSR is set when DisplayFamily_DisplayModel is one of: + * 06_0x, 06_17, 06_1C + * + * Description says this bit enables use of WBINVD and FLUSH#. + * Should this be set only after the system bus and/or memory + * controller can successfully handle write cycles? + */ + +#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */ +#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4)) + + movl $1, %eax + cpuid + movl %eax, %ebx + andl $EAX_FAMILY(0x0f), %eax + cmpl $EAX_FAMILY(0x06), %eax + jne no_msr_11e + movl %ebx, %eax + andl $EAX_MODEL(0xff), %eax + cmpl $EAX_MODEL(0x17), %eax + je has_msr_11e + cmpl $EAX_MODEL(0x1c), %eax + je has_msr_11e + andl $EAX_MODEL(0xf0), %eax + cmpl $EAX_MODEL(0x00), %eax + jne no_msr_11e +has_msr_11e: movl $0x11e, %ecx rdmsr orl $(1 << 8), %eax wrmsr +no_msr_11e: + + post_code(0x2c) /* Enable cache (CR0.CD = 0, CR0.NW = 0). */ movl %cr0, %eax @@ -107,6 +255,8 @@ clear_mtrrs: orl $(1 << 30), %eax movl %eax, %cr0 + post_code(0x2d) + #if CONFIG_XIP_ROM_SIZE /* Enable cache for our code in Flash because we do XIP here */ movl $MTRRphysBase_MSR(1), %ecx @@ -131,6 +281,8 @@ clear_mtrrs: andl $(~((1 << 30) | (1 << 29))), %eax movl %eax, %cr0 + post_code(0x2e) + /* Set up the stack pointer. */ #if CONFIG_USBDEBUG /* Leave some space for the struct ehci_debug_info. */ @@ -144,14 +296,12 @@ clear_mtrrs: movl %esp, %ebp pushl %eax - post_code(0x23) + post_code(0x2f) /* Call romstage.c main function. */ call main addl $4, %esp - post_code(0x2f) - post_code(0x30) /* Disable cache. */ @@ -159,7 +309,7 @@ clear_mtrrs: orl $(1 << 30), %eax movl %eax, %cr0 - post_code(0x31) + post_code(0x34) /* Disable MTRR. */ movl $MTRRdefType_MSR, %ecx @@ -167,18 +317,18 @@ clear_mtrrs: andl $(~MTRRdefTypeEn), %eax wrmsr - post_code(0x31) + post_code(0x35) invd - post_code(0x33) + post_code(0x36) /* Enable cache. */ movl %cr0, %eax andl $~((1 << 30) | (1 << 29)), %eax movl %eax, %cr0 - post_code(0x36) + post_code(0x37) /* Disable cache. */ movl %cr0, %eax