diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2012-02-09 16:07:41 +0200 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2012-02-13 21:56:38 +0100 |
commit | 7916f4cef62bf032af86368a9df45db833d09b79 (patch) | |
tree | ab2a85208db187624f8615c135acf605777fc7d8 /src/cpu/amd/geode_gx2 | |
parent | 50759ed4ff438db6f3b093984fbb79d6445ebcb3 (diff) | |
download | coreboot-7916f4cef62bf032af86368a9df45db833d09b79.tar.xz |
AMD Geode cpus: apply un-written naming rules
Kconfig directives to select chip drivers for compile literally
match the chip directory names capitalized and underscored.
Rename directories and Kconfig as follows:
model_lx -> geode_lx
model_gx1 -> geode_gx1
model_gx2 -> geode_gx2
Change-Id: Ib8bf1e758b88f9efed1cf8b11c76b796388e7147
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/613
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/cpu/amd/geode_gx2')
-rw-r--r-- | src/cpu/amd/geode_gx2/Kconfig | 58 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/Makefile.inc | 9 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/cache_as_ram.inc | 208 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/cpubug.c | 349 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/cpureginit.c | 129 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/geode_gx2_init.c | 46 | ||||
-rw-r--r-- | src/cpu/amd/geode_gx2/syspreinit.c | 20 |
7 files changed, 819 insertions, 0 deletions
diff --git a/src/cpu/amd/geode_gx2/Kconfig b/src/cpu/amd/geode_gx2/Kconfig new file mode 100644 index 0000000000..0e25542582 --- /dev/null +++ b/src/cpu/amd/geode_gx2/Kconfig @@ -0,0 +1,58 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2010 coresystems GmbH +## +## 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 +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config CPU_AMD_GEODE_GX2 + bool + +if CPU_AMD_GEODE_GX2 + +config CPU_SPECIFIC_OPTIONS + def_bool y + select CACHE_AS_RAM + +config DCACHE_RAM_BASE + hex + default 0xc8000 + +config DCACHE_RAM_SIZE + hex + default 0x04000 + +config GEODE_VSA + bool + default y + select PCI_OPTION_ROM_RUN_REALMODE + +config GEODE_VSA_FILE + bool "Add a VSA image" + help + Select this option if you have an AMD Geode GX2 vsa that you would + like to add to your ROM. + + You will be able to specify the location and file name of the + image later. + +config VSA_FILENAME + string "AMD Geode GX2 VSA path and filename" + depends on GEODE_VSA_FILE + default "gpl_vsa_gx_102.bin" + help + The path and filename of the file to use as VSA. + +endif # CPU_AMD_GEODE_GX2 diff --git a/src/cpu/amd/geode_gx2/Makefile.inc b/src/cpu/amd/geode_gx2/Makefile.inc new file mode 100644 index 0000000000..b70537accf --- /dev/null +++ b/src/cpu/amd/geode_gx2/Makefile.inc @@ -0,0 +1,9 @@ +subdirs-y += ../../x86/tsc +subdirs-y += ../../x86/lapic +subdirs-y += ../../x86/cache +subdirs-y += ../../x86/smm + +driver-y += geode_gx2_init.c +ramstage-y += cpubug.c + +cpu_incs += $(src)/cpu/amd/geode_gx2/cache_as_ram.inc diff --git a/src/cpu/amd/geode_gx2/cache_as_ram.inc b/src/cpu/amd/geode_gx2/cache_as_ram.inc new file mode 100644 index 0000000000..0af2fdf488 --- /dev/null +++ b/src/cpu/amd/geode_gx2/cache_as_ram.inc @@ -0,0 +1,208 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Advanced Micro Devices, Inc. + * Copyright (C) 2010 Nils Jacobs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define GX2_STACK_BASE CONFIG_DCACHE_RAM_BASE /* this is where the DCache will be mapped and be used as stack, It would be cool if it was the same base as coreboot normal stack */ +#define GX2_STACK_END GX2_STACK_BASE+(CONFIG_DCACHE_RAM_SIZE-1) + +#define GX2_NUM_CACHELINES 0x080 /* there are 128lines per way */ +#define GX2_CACHELINE_SIZE 0x020 /* there are 32bytes per line */ +#define GX2_CACHEWAY_SIZE (GX2_NUM_CACHELINES * GX2_CACHELINE_SIZE) +#define CR0_CD 0x40000000 /* bit 30 = Cache Disable */ +#define CR0_NW 0x20000000 /* bit 29 = Not Write Through */ +#include <cpu/amd/gx2def.h> +#include <cpu/x86/post_code.h> +/*************************************************************************** +/** +/** DCacheSetup +/** +/** Setup data cache for use as RAM for a stack. +/** +/** Max. size data cache =0x4000 (16KB) +/** +/***************************************************************************/ +DCacheSetup: + /* Save the BIST result */ + movl %eax, %ebx + + invd + /* set cache properties */ + movl $CPU_RCONF_DEFAULT, %ecx + rdmsr + movl $0x010010000, %eax /*1MB system memory in write back 1|00100|00 */ + wrmsr + + /* in GX2 DCDIS is set after POR which disables the cache..., clear this bit */ + movl $CPU_DM_CONFIG0, %ecx + rdmsr + andl $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax /* TODO: make consistent with i$ init, either whole reg = 0, or just this bit... */ + wrmsr + + /* Get cleaned up. */ + xorl %edi, %edi + xorl %esi, %esi + xorl %ebp, %ebp + + /* DCache Ways0 through Ways3 will be tagged for GX2_STACK_BASE + CONFIG_DCACHE_RAM_SIZE for holding stack */ + /* remember, there is NO stack yet... */ + + /* Tell cache we want to fill WAY 0 starting at the top */ + xorl %edx, %edx + xorl %eax, %eax + movl $CPU_DC_INDEX, %ecx + wrmsr + + /* startaddress for tag of Way0: ebp will hold the incrementing address. dont destroy! */ + movl $GX2_STACK_BASE, %ebp /* init to start address */ + orl $1, %ebp /* set valid bit and tag for this Way (B[31:12] : Cache tag value for line/way curr. selected by CPU_DC_INDEX */ + + /* start tag Ways 0 with 128 lines with 32bytes each: edi will hold the line counter. dont destroy! */ + movl $GX2_NUM_CACHELINES, %edi +DCacheSetupFillWay: + + /* fill with dummy data: zero it so we can tell it from PCI memory space (returns FFs). */ + /* We will now store a line (32 bytes = 4 x 8bytes = 4 quadWords) */ + movw $0x04, %si + xorl %edx, %edx + xorl %eax, %eax + movl $CPU_DC_DATA, %ecx +DCacheSetup_quadWordLoop: + wrmsr + decw %si + jnz DCacheSetup_quadWordLoop + + /* Set the tag for this line,need to do this for every new cache line to validate it! */ + /* accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX increment and thus cont. in the next cache line... */ + xorl %edx, %edx + movl %ebp, %eax + movl $CPU_DC_TAG, %ecx + wrmsr + + /* switch to next line */ + /* lines are in Bits8:2 */ + /* when index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is not a valid CL anymore! */ + movl $CPU_DC_INDEX, %ecx + rdmsr + addl $0x04, %eax /* inc DC_LINE. TODO: prob. would be more elegant to calc. this from counter var edi... */ + wrmsr + + decl %edi + jnz DCacheSetupFillWay + + /* 1 Way has been filled, forward start address for next Way, terminate if we have reached end of desired address range */ + addl $GX2_CACHEWAY_SIZE, %ebp + cmpl $GX2_STACK_END, %ebp + jge leave_DCacheSetup + movl $GX2_NUM_CACHELINES, %edi + + /* switch to next way */ + movl $CPU_DC_INDEX, %ecx + rdmsr + addl $0x01, %eax + andl $0xFFFFFE03, %eax /* lets be sure: reset line index Bits8:2 */ + wrmsr + + jmp DCacheSetupFillWay + +leave_DCacheSetup: + xorl %edi, %edi + xorl %esi, %esi + xorl %ebp, %ebp + + /* Disable the cache, but ... DO NOT INVALIDATE the tags. */ + /* Memory reads and writes will all hit in the cache. */ + /* Cache updates and memory write-backs will not occur ! */ + movl %cr0, %eax + orl $(CR0_CD + CR0_NW), %eax /* set the CD and NW bits */ + movl %eax, %cr0 + + /* Now point sp to the cached stack. */ + /* The stack will be fully functional at this location. No system memory is required at all ! */ + /* set up the stack pointer */ + movl $GX2_STACK_END, %eax + movl %eax, %esp + + /* test the stack*/ + movl $0x0F0F05A5A, %edx + pushl %edx + popl %ecx + cmpl %ecx, %edx + je DCacheSetupGood + + post_code(0xc5) +DCacheSetupBad: + hlt /* issues */ + jmp DCacheSetupBad +DCacheSetupGood: + /* Go do early init and memory setup */ + + /* Restore the BIST result */ + movl %ebx, %eax + movl %esp, %ebp + pushl %eax + + post_code(0x23) + + /* Call romstage.c main function */ + call main +done_cache_as_ram_main: + + /* We now run over the stack-in-cache, copying it back to itself to invalidate the cache */ + + push %edi + mov $(CONFIG_DCACHE_RAM_SIZE/4),%ecx + push %esi + mov $(CONFIG_DCACHE_RAM_BASE),%edi + mov %edi,%esi + cld + rep movsl %ds:(%esi),%es:(%edi) + pop %esi + pop %edi + + /* Clear the cache out to ram */ + wbinvd + /* re-enable the cache */ + movl %cr0, %eax + xorl $(CR0_CD + CR0_NW), %eax /* clear the CD and NW bits */ + movl %eax, %cr0 + + /* clear boot_complete flag */ + xorl %ebp, %ebp +__main: + post_code(POST_PREPARE_RAMSTAGE) + + /* TODO For suspend/resume the cache will have to live between + * CONFIG_RAMBASE and CONFIG_RAMTOP + */ + + cld /* clear direction flag */ + + /* copy coreboot from it's initial load location to + * the location it is compiled to run at. + * Normally this is copying from FLASH ROM to RAM. + */ + movl %ebp, %esi + pushl %esi + call copy_and_run + +.Lhlt: + post_code(POST_DEAD_CODE) + hlt + jmp .Lhlt + diff --git a/src/cpu/amd/geode_gx2/cpubug.c b/src/cpu/amd/geode_gx2/cpubug.c new file mode 100644 index 0000000000..473766c8a4 --- /dev/null +++ b/src/cpu/amd/geode_gx2/cpubug.c @@ -0,0 +1,349 @@ +#include <console/console.h> +#include <arch/io.h> +#include <stdint.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <stdlib.h> +#include <string.h> +#include <bitops.h> +#include <cpu/amd/gx2def.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/cache.h> + +#if 0 +void bug645(void) +{ + msr_t msr; + rdmsr(CPU_ID_CONFIG); + msr.whatever |= ID_CONFIG_SERIAL_SET; + wrmsr(msr); +} + +void bug573(void) +{ + msr_t msr; + msr = rdmsr(MC_GLD_MSR_PM); + msr.eax &= 0xfff3; + wrmsr(MC_GLD_MSR_PM); +} +#endif + +/* pcideadlock + * + * Bugtool #465 and #609 + * PCI cache deadlock + * There is also fix code in cache and PCI functions. This bug is very is pervasive. + */ +static void pcideadlock(void) +{ + msr_t msr; + + /* forces serialization of all load misses. Setting this bit prevents the + * DM pipe from backing up if a read request has to be held up waiting + * for PCI writes to complete. + */ + msr = rdmsr(CPU_DM_CONFIG0); + msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT); + msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT); + msr.lo |= DM_CONFIG0_LOWER_MISSER_SET; + wrmsr(CPU_DM_CONFIG0, msr); + + /* interlock instruction fetches to WS regions with data accesses. + * This prevents an instruction fetch from going out to PCI if the + * data side is about to make a request. + */ + msr = rdmsr(CPU_IM_CONFIG); + msr.lo |= IM_CONFIG_LOWER_QWT_SET; + wrmsr(CPU_IM_CONFIG, msr); + + /* write serialize memory hole to PCI. Need to unWS when something is + * shadowed regardless of cachablility. + */ + msr.lo = 0x021212121; + msr.hi = 0x021212121; + wrmsr( CPU_RCONF_A0_BF, msr); + wrmsr( CPU_RCONF_C0_DF, msr); + wrmsr( CPU_RCONF_E0_FF, msr); +} + +/* CPUbug784 + * + * Bugtool #784 + #792 + * + * Fix CPUID instructions for < 3.0 CPUs + */ +static void bug784(void) +{ + msr_t msr; + //static char *name = "Geode by NSC"; + + /* we'll do this the stupid way, for now, but that's the string they want. NO ONE KNOWS why you + * would do this -- the OS can figure this type of stuff out! + */ + msr = rdmsr(0x3006); + msr.hi = 0x646f6547; + wrmsr(0x3006, msr); + + msr = rdmsr(0x3007); + msr.hi = 0x79622065; + msr.lo = 0x43534e20; + wrmsr(0x3007, msr); + + msr = rdmsr(0x3002); + wrmsr(0x3008, msr); + + /* More CPUID to match AMD better. #792*/ + msr = rdmsr(0x3009); + msr.hi = 0x0C0C0A13D; + msr.lo = 0x00000000; + wrmsr(0x3009, msr); +} + +/* cpubug 1398: enable MC if we KNOW we have DDR*/ + +/* CPUbugIAENG1398 + * + * ClearQuest #IAENG1398 + * The MC can not be enabled with SDR memory but can for DDR. Enable for + * DDR here if the setup token is "Default" + * Add this back to core by default once 2.0 CPUs are not supported. + */ +static void eng1398(void) +{ + msr_t msr; + + msr = rdmsr(MSR_GLCP+0x17); + if ((msr.lo & 0xff) <= CPU_REV_2_0) { + msr = rdmsr(GLCP_SYS_RSTPLL); + if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT)) + return; + } + + /* no CMOS/NVRAM to check, so enable MC Clock Gating */ + msr = rdmsr(MC_GLD_MSR_PM); + msr.lo |= 3; /* enable MC clock gating.*/ + wrmsr(MC_GLD_MSR_PM, msr); +} + +/* CPUbugIAENG2900 + * + * Clear Quest IAENG00002900, VSS 118.150 + * + * BTB issue causes blue screen in windows, but the fix is required + * for all operating systems. + */ +static void eng2900(void) +{ + msr_t msr; + + printk(BIOS_DEBUG, "CPU_BUG:%s\n", __func__); + /* Clear bit 43, disables the sysenter/sysexit in CPUID3 */ + msr = rdmsr(0x3003); + msr.hi &= 0xFFFFF7FF; + wrmsr(0x3003, msr); + + /* change this value to zero if you need to disable this BTB SWAPSiF. */ + if (1) { + + /* Disable enable_actions in DIAGCTL while setting up GLCP */ + msr.hi = 0; + msr.lo = 0; + wrmsr(MSR_GLCP + 0x005f, msr); + + /* Changing DBGCLKCTL register to GeodeLink */ + msr.hi = 0; + msr.lo = 0; + wrmsr(MSR_GLCP + 0x0016, msr); + + msr.hi = 0; + msr.lo = 2; + wrmsr(MSR_GLCP + 0x0016, msr); + + /* The code below sets up the CPU to stall for 4 GeodeLink + * clocks when CPU is snooped. Because setting XSTATE to 0 + * overrides any other XSTATE action, the code will always + * stall for 4 GeodeLink clocks after a snoop request goes + * away even if it occured a clock or two later than a + * different snoop; the stall signal will never 'glitch high' + * for only one or two CPU clocks with this code. + */ + + /* Send mb0 port 3 requests to upper GeodeLink diag bits + [63:32] */ + msr.hi = 0; + msr.lo = 0x80338041; + wrmsr(MSR_GLIU0 + 0x2005, msr); + + /* set5m watches request ready from mb0 to CPU (snoop) */ + msr.hi = 0x5ad68000; + msr.lo = 0; + wrmsr(MSR_GLCP + 0x0045, msr); + + /* SET4M will be high when state is idle (XSTATE=11) */ + msr.hi = 0; + msr.lo = 0x0140; + wrmsr(MSR_GLCP + 0x0044, msr); + + /* SET5n to watch for processor stalled state */ + msr.hi = 0x2000; + msr.lo = 0; + wrmsr(MSR_GLCP + 0x004D, msr); + + /* Writing action number 13: XSTATE=0 to occur when CPU is + snooped unless we're stalled */ + msr.hi = 0; + msr.lo = 0x00400000; + wrmsr(MSR_GLCP + 0x0075, msr); + + /* Writing action number 11: inc XSTATE every GeodeLink clock + unless we're idle */ + msr.hi = 0; + msr.lo = 0x30000; + wrmsr(MSR_GLCP + 0x0073, msr); + + /* Writing action number 5: STALL_CPU_PIPE when exitting idle + state or not in idle state */ + msr.hi = 0; + msr.lo = 0x00430000; + wrmsr(MSR_GLCP + 0x006D, msr); + + /* Writing DIAGCTL Register to enable the stall action and to + let set5m watch the upper GeodeLink diag bits. */ + msr.hi = 0; + msr.lo = 0x80004000; + wrmsr(MSR_GLCP + 0x005f, msr); + } +} + +static void bug118253(void) +{ + /* GLPCI PIO Post Control shouldn't be enabled */ + msr_t msr; + + msr = rdmsr(GLPCI_SPARE); + msr.lo &= ~GLPCI_SPARE_LOWER_PPC_SET; + wrmsr(GLPCI_SPARE, msr); +} + +static void bug118339(void) +{ + /* per AMD, do this always */ + msr_t msr = {0,0}; + int msrnum; + + /* Disable enable_actions in DIAGCTL while setting up GLCP */ + wrmsr(MSR_GLCP + 0x005f, msr); + + /* SET2M fires if VG pri is odd (3, not 2) and Ystate=0 */ + msrnum = MSR_GLCP + 0x042; + /* msr.hi = 2d6b8000h */; + msr.hi = 0x596b8000; + msr.lo = 0x00000a00; + wrmsr(msrnum, msr); + + /* SET3M fires if MBUS changed and VG pri is odd */ + msrnum = MSR_GLCP + 0x043; + msr.hi = 0x596b8040; + msr.lo = 0; + wrmsr(msrnum, msr); + + /* Put VG request data on lower diag bus */ + msrnum = MSR_GLIU0 + 0x2005; + msr.hi = 0; + msr.lo = 0x80338041; + wrmsr(msrnum, msr); + + /* Increment Y state if SET3M if true */ + msrnum = MSR_GLCP + 0x074; + msr.hi = 0; + msr.lo = 0x0000c000; + wrmsr(msrnum, msr); + + /* Set up MBUS action to PRI=3 read of MBIU */ + msrnum = MSR_GLCP + 0x020; + msr.hi = 0x0000d863; + msr.lo = 0x20002000; + wrmsr(msrnum, msr); + + /* Trigger MBUS action if VG=pri3 and Y=0, this blocks most PCI */ + msrnum = MSR_GLCP + 0x071; + msr.hi = 0; + msr.lo = 0x00000c00; + wrmsr(msrnum, msr); + + /* Writing DIAGCTL */ + msrnum = MSR_GLCP + 0x005f; + msr.hi = 0; + msr.lo = 0x80004000; + wrmsr(msrnum, msr); + + /* Code to enable FS2 even when BTB and VGTEAR SWAPSiFs are enabled + * As per Todd Roberts in PBz1094 and PBz1095 + * Moved from CPUREG to CPUBUG per Tom Sylla + */ + msrnum = 0x04C000042; /* GLCP SETMCTL Register */ + msr = rdmsr(msrnum); + msr.hi |= 8; /* Bit 35 = MCP_IN */ + wrmsr(msrnum, msr); +} + + + +/* DisableMemoryReorder + * + * PBZ 3659: + * The MC reordered transactions incorrectly and breaks coherency. + * Disable reording and take a potential performance hit. + * This is safe to do here and not in MC init since there is nothing + * to maintain coherency with and the cache is not enabled yet. + */ +static void disablememoryreadorder(void) +{ + msr_t msr; + + msr = rdmsr(MC_CF8F_DATA); + msr.hi |= CF8F_UPPER_REORDER_DIS_SET; + wrmsr(MC_CF8F_DATA, msr); +} + +void cpubug(void) +{ + msr_t msr; + int rev; + + msr = rdmsr(GLCP_CHIP_REVID); + + rev = msr.lo & 0xff; + if (rev < 0x20) { + printk(BIOS_ERR, "%s: rev < 0x20! bailing!\n", __func__); + return; + } + printk(BIOS_DEBUG, "Doing cpubug fixes for rev 0x%x\n", rev); + switch(rev) + { + case 0x20: + pcideadlock(); + eng1398(); + /* cs 5530 bug; ignore + bug752(); + */ + break; + case 0x21: + pcideadlock(); + eng1398(); + eng2900(); + bug118339(); + break; + case 0x22: + case 0x30: + break; + default: + printk(BIOS_ERR, "unknown rev %x, bailing\n", rev); + return; + } + bug784(); + bug118253(); + disablememoryreadorder(); + printk(BIOS_DEBUG, "Done cpubug fixes \n"); +} diff --git a/src/cpu/amd/geode_gx2/cpureginit.c b/src/cpu/amd/geode_gx2/cpureginit.c new file mode 100644 index 0000000000..0fc852d531 --- /dev/null +++ b/src/cpu/amd/geode_gx2/cpureginit.c @@ -0,0 +1,129 @@ + +/* cpuRegInit */ +void cpuRegInit (void) +{ + int msrnum; + msr_t msr; + /* The following is only for diagnostics mode; do not use for OLPC */ + if (0) { + /* Set Diagnostic Mode */ + msrnum = CPU_GLD_MSR_DIAG; + msr.hi = 0; + msr.lo = DIAG_SEL1_SET | DIAG_SET0_SET; + wrmsr(msrnum, msr); + + /* Set up GLCP to grab BTM data. */ + msrnum = GLCP_DBGOUT; /* GLCP_DBGOUT MSR */ + msr.hi = 0x0; + msr.lo = 0x08; /* reset value (SCOPE_SEL = 0) causes FIFO toshift out, */ + wrmsr(msrnum, msr); /* exchange it to anything else to prevent this */ + + /* Turn off debug clock */ + msrnum = GLCP_DBGCLKCTL; /* DBG_CLK_CTL */ + msr.lo = 0x00; /* No clock */ + msr.hi = 0x00; + wrmsr(msrnum, msr); + + /* Set debug clock to CPU */ + msrnum = GLCP_DBGCLKCTL; /* DBG_CLK_CTL */ + msr.lo = 0x01; /* CPU CLOCK */ + msr.hi = 0x00; + wrmsr(msrnum, msr); + + /* Set fifo ctl to BTM bits wide */ + msrnum = GLCP_FIFOCTL; /* FIFO_CTL */ + msr.lo = 0x003880000; /* Bit [25:24] are size (11=BTM, 10 = 64 bit, 01= 32 bit, 00 = 16bit) */ + wrmsr(msrnum, msr); /* Bit [23:21] are position (100 = CPU downto0) */ + /* Bit [19] sets it up in slow data mode. */ + + /* enable fifo loading - BTM sizing will constrain */ + /* only valid BTM packets to load - this action should always be on */ + msrnum = 0x04C00006F; /* GLCP ACTION7 - load fifo */ + msr.lo = 0x00000F000; /* Any nibble all 1's will always trigger */ + msr.hi = 0x000000000; + wrmsr(msrnum, msr); + + /* start storing diag data in the fifo */ + msrnum = 0x04C00005F; /* DIAG CTL */ + msr.lo = 0x080000000; /* enable actions */ + msr.hi = 0x000000000; + wrmsr(msrnum, msr); + + /* Set up delay on data lines, so that the hold time */ + /* is 1 ns. */ + msrnum = GLCP_PROCSTAT; /* GLCP IO DELAY CONTROLS */ + msr.lo = 0x082b5ad68; + msr.hi = 0x080ad6b57; /* RGB delay = 0x07 */ + wrmsr(msrnum, msr); + + /* Set up DF to output diag information on DF pins. */ + msrnum = DF_GLD_MSR_MASTER_CONF; + msr.lo = 0x0220; + msr.hi = 0; + wrmsr(msrnum, msr); + + msrnum = GLCP_DBGOUT; /* GLCP_DBGOUT MSR */ + msr.hi = 0x0; + msr.lo = 0x0; /* reset value (SCOPE_SEL = 0) causes FIFO to shift out, */ + wrmsr(msrnum, msr); + /* end of code for BTM */ + } + + /* Enable Suspend on Halt */ + msrnum = CPU_XC_CONFIG; + msr = rdmsr(msrnum); + msr.lo |= XC_CONFIG_SUSP_ON_HLT; + wrmsr(msrnum, msr); + + /* ENable SUSP and allow TSC to run in Suspend */ + /* to keep speed detection happy */ + msrnum = CPU_BC_CONF_0; + msr = rdmsr(msrnum); + msr.lo |= TSC_SUSP_SET | SUSP_EN_SET; + wrmsr(msrnum, msr); + + /* Setup throttling to proper mode if it is ever enabled. */ + msrnum = GLCP_TH_OD; + msr.hi = 0x000000000; + msr.lo = 0x00000603C; + wrmsr(msrnum, msr); + +/* FooGlue Setup */ + /* Set CS5535/CS5536 mode in FooGlue */ + msrnum = FG_GIO_MSR_SEL; + msr = rdmsr(msrnum); + msr.lo &= ~3; + msr.lo |= 2; /* IIOC mode CS5535/CS5536 enable. (according to Jordan Crouse the databook is wrong bits 1:0 have to be 2 instead of 1) */ + wrmsr(msrnum, msr); + +/* Disable DOT PLL. Graphics init will enable it if needed. */ + msrnum = GLCP_DOTPLL; + msr = rdmsr(msrnum); + msr.lo |= DOTPPL_LOWER_PD_SET; + wrmsr(msrnum, msr); + +/* Enable RSDC */ + msrnum = CPU_AC_SMM_CTL; + msr = rdmsr(msrnum); + msr.lo |= 0x08; + wrmsr(msrnum, msr); + +/* Enable BTB */ + /* I hate to put this check here but it doesn't really work in cpubug.asm */ + msrnum = GLCP_CHIP_REVID; + msr = rdmsr(msrnum); + if (msr.lo >= CPU_REV_2_1){ + msrnum = CPU_PF_BTB_CONF; + msr = rdmsr(msrnum); + msr.lo |= BTB_ENABLE_SET | RETURN_STACK_ENABLE_SET; + wrmsr(msrnum, msr); + } + +/* FPU impercise exceptions bit */ + { + msrnum = CPU_FPU_MSR_MODE; + msr = rdmsr(msrnum); + msr.lo |= FPU_IE_SET; + wrmsr(msrnum, msr); + } +} diff --git a/src/cpu/amd/geode_gx2/geode_gx2_init.c b/src/cpu/amd/geode_gx2/geode_gx2_init.c new file mode 100644 index 0000000000..7e481b5390 --- /dev/null +++ b/src/cpu/amd/geode_gx2/geode_gx2_init.c @@ -0,0 +1,46 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <string.h> +#include <cpu/cpu.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/cache.h> + +static void vsm_end_post_smi(void) +{ + __asm__ volatile ( + "push %ax\n" + "mov $0x5000, %ax\n" + ".byte 0x0f, 0x38\n" + "pop %ax\n" + ); +} + +static void geode_gx2_init(device_t dev) +{ + printk(BIOS_DEBUG, "geode_gx2_init\n"); + + /* Turn on caching if we haven't already */ + x86_enable_cache(); + + /* Enable the local cpu apics */ + //setup_lapic(); + + vsm_end_post_smi(); + + printk(BIOS_DEBUG, "geode_gx2_init DONE\n"); +}; + +static struct device_operations cpu_dev_ops = { + .init = geode_gx2_init, +}; + +static struct cpu_device_id cpu_table[] = { + { X86_VENDOR_NSC, 0x0552 }, + { 0, 0 }, +}; + +static const struct cpu_driver driver __cpu_driver = { + .ops = &cpu_dev_ops, + .id_table = cpu_table, +}; diff --git a/src/cpu/amd/geode_gx2/syspreinit.c b/src/cpu/amd/geode_gx2/syspreinit.c new file mode 100644 index 0000000000..814034823c --- /dev/null +++ b/src/cpu/amd/geode_gx2/syspreinit.c @@ -0,0 +1,20 @@ +/* StartTimer1 + * + * Entry: none + * Exit: Starts Timer 1 for port 61 use + * Destroys: Al, + */ +static void StartTimer1(void) +{ + outb(0x56, 0x43); + outb(0x12, 0x41); +} + +void SystemPreInit(void) +{ + /* they want a jump ... */ +#if !CONFIG_CACHE_AS_RAM + __asm__ __volatile__("jmp .+2\ninvd\njmp .+2\n"); +#endif + StartTimer1(); +} |