diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/amd/model_fxx/Config.lb | 2 | ||||
-rw-r--r-- | src/cpu/amd/mtrr/amd_mtrr.c | 85 | ||||
-rw-r--r-- | src/cpu/amd/socket_940/Config.lb | 4 | ||||
-rw-r--r-- | src/cpu/amd/socket_940/socket_940.c | 1 | ||||
-rw-r--r-- | src/cpu/intel/model_f0x/Config.lb | 2 | ||||
-rw-r--r-- | src/cpu/intel/model_f1x/Config.lb | 2 | ||||
-rw-r--r-- | src/cpu/intel/model_f2x/Config.lb | 2 | ||||
-rw-r--r-- | src/cpu/intel/model_f3x/Config.lb | 2 | ||||
-rw-r--r-- | src/cpu/x86/16bit/reset16.inc | 5 | ||||
-rw-r--r-- | src/cpu/x86/16bit/reset16.lds | 4 | ||||
-rw-r--r-- | src/cpu/x86/lapic/secondary.S | 3 | ||||
-rw-r--r-- | src/cpu/x86/mtrr/earlymtrr.c | 22 | ||||
-rw-r--r-- | src/cpu/x86/mtrr/mtrr.c | 126 |
13 files changed, 139 insertions, 121 deletions
diff --git a/src/cpu/amd/model_fxx/Config.lb b/src/cpu/amd/model_fxx/Config.lb index 044fe8670f..bf7b9987cc 100644 --- a/src/cpu/amd/model_fxx/Config.lb +++ b/src/cpu/amd/model_fxx/Config.lb @@ -1,5 +1,7 @@ uses HAVE_INIT_TIMER +uses HAVE_MOVNTI default HAVE_INIT_TIMER=1 +default HAVE_MOVNTI=1 dir /cpu/x86/tsc dir /cpu/x86/fpu dir /cpu/x86/mmx diff --git a/src/cpu/amd/mtrr/amd_mtrr.c b/src/cpu/amd/mtrr/amd_mtrr.c index 0247fd00d3..506e017457 100644 --- a/src/cpu/amd/mtrr/amd_mtrr.c +++ b/src/cpu/amd/mtrr/amd_mtrr.c @@ -75,13 +75,41 @@ static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char } } +struct mem_state { + unsigned long mmio_basek, tomk; +}; +static void set_fixed_mtrr_resource(void *gp, struct device *dev, struct resource *res) +{ + struct mem_state *state = gp; + unsigned long topk; + unsigned int start_mtrr; + unsigned int last_mtrr; + + topk = resk(res->base + res->size); + if (state->tomk < topk) { + state->tomk = topk; + } + if ((topk < 4*1024*1024) && (state->mmio_basek < topk)) { + state->mmio_basek = topk; + } + start_mtrr = fixed_mtrr_index(resk(res->base)); + last_mtrr = fixed_mtrr_index(resk((res->base + res->size))); + if (start_mtrr >= NUM_FIXED_RANGES) { + return; + } + printk_debug("Setting fixed MTRRs(%d-%d) Type: WB\n", + start_mtrr, last_mtrr); + set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM); + +} + + #endif void amd_setup_mtrrs(void) { - unsigned long mmio_basek, tomk; + struct mem_state state; unsigned long i; - device_t dev; msr_t msr; /* Enable the access to AMD RdDram and WrDram extension bits */ @@ -99,54 +127,29 @@ void amd_setup_mtrrs(void) * significant holes in the address space, so just account * for those two and move on. */ - mmio_basek = tomk = 0; - for(dev = all_devices; dev; dev = dev->next) { - struct resource *res, *last; - last = &dev->resource[dev->resources]; - for(res = &dev->resource[0]; res < last; res++) { - unsigned long topk; - unsigned long start_mtrr, last_mtrr; - if (!(res->flags & IORESOURCE_MEM) || - (!(res->flags & IORESOURCE_CACHEABLE))) { - continue; - } - topk = resk(res->base + res->size); - if (tomk < topk) { - tomk = topk; - } - if ((topk < 4*1024*1024) && (mmio_basek < topk)) { - mmio_basek = topk; - } - - start_mtrr = fixed_mtrr_index(resk(res->base)); - last_mtrr = fixed_mtrr_index(resk(res->base + res->size)); - if (start_mtrr >= NUM_FIXED_RANGES) { - continue; - } - printk_debug("Setting fixed MTRRs(%d-%d) Type: WB\n", - start_mtrr, last_mtrr); - set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM); - } - } + state.mmio_basek = state.tomk = 0; + search_global_resources( + IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, + set_fixed_mtrr_resource, &state); printk_debug("DONE fixed MTRRs\n"); - if (mmio_basek > tomk) { - mmio_basek = tomk; + if (state.mmio_basek > state.tomk) { + state.mmio_basek = state.tomk; } - /* Round mmio_basek down to the nearst size that will fit in TOP_MEM */ - mmio_basek = mmio_basek & ~TOP_MEM_MASK_KB; - /* Round tomk up to the next greater size that will fit in TOP_MEM */ - tomk = (tomk + TOP_MEM_MASK_KB) & ~TOP_MEM_MASK_KB; + /* Round state.mmio_basek down to the nearst size that will fit in TOP_MEM */ + state.mmio_basek = state.mmio_basek & ~TOP_MEM_MASK_KB; + /* Round state.tomk up to the next greater size that will fit in TOP_MEM */ + state.tomk = (state.tomk + TOP_MEM_MASK_KB) & ~TOP_MEM_MASK_KB; disable_cache(); /* Setup TOP_MEM */ - msr.hi = mmio_basek >> 22; - msr.lo = mmio_basek << 10; + msr.hi = state.mmio_basek >> 22; + msr.lo = state.mmio_basek << 10; wrmsr(TOP_MEM, msr); /* Setup TOP_MEM2 */ - msr.hi = tomk >> 22; - msr.lo = tomk << 10; + msr.hi = state.tomk >> 22; + msr.lo = state.tomk << 10; wrmsr(TOP_MEM2, msr); /* zero the IORR's before we enable to prevent diff --git a/src/cpu/amd/socket_940/Config.lb b/src/cpu/amd/socket_940/Config.lb index 9f0e6c689a..4b23f0b46a 100644 --- a/src/cpu/amd/socket_940/Config.lb +++ b/src/cpu/amd/socket_940/Config.lb @@ -1,3 +1,3 @@ -config chip.h -object socket_940.o +#config chip.h +#object socket_940.o dir /cpu/amd/model_fxx diff --git a/src/cpu/amd/socket_940/socket_940.c b/src/cpu/amd/socket_940/socket_940.c index d62834f4e7..46d0cbd449 100644 --- a/src/cpu/amd/socket_940/socket_940.c +++ b/src/cpu/amd/socket_940/socket_940.c @@ -3,5 +3,4 @@ struct chip_operations cpu_amd_socket_940_ops = { - .name = "socket 940", }; diff --git a/src/cpu/intel/model_f0x/Config.lb b/src/cpu/intel/model_f0x/Config.lb index 1e6126c3cc..2458c81c14 100644 --- a/src/cpu/intel/model_f0x/Config.lb +++ b/src/cpu/intel/model_f0x/Config.lb @@ -1,3 +1,5 @@ +uses HAVE_MOVNTI +default HAVE_MOVNTI=1 dir /cpu/x86/tsc dir /cpu/x86/mtrr dir /cpu/x86/fpu diff --git a/src/cpu/intel/model_f1x/Config.lb b/src/cpu/intel/model_f1x/Config.lb index d318ee538d..5387d455f1 100644 --- a/src/cpu/intel/model_f1x/Config.lb +++ b/src/cpu/intel/model_f1x/Config.lb @@ -1,3 +1,5 @@ +uses HAVE_MOVNTI +default HAVE_MOVNTI=1 dir /cpu/x86/tsc dir /cpu/x86/mtrr dir /cpu/x86/fpu diff --git a/src/cpu/intel/model_f2x/Config.lb b/src/cpu/intel/model_f2x/Config.lb index 10fe8b767b..ef9d095ac5 100644 --- a/src/cpu/intel/model_f2x/Config.lb +++ b/src/cpu/intel/model_f2x/Config.lb @@ -1,3 +1,5 @@ +uses HAVE_MOVNTI +default HAVE_MOVNTI=1 dir /cpu/x86/tsc dir /cpu/x86/mtrr dir /cpu/x86/fpu diff --git a/src/cpu/intel/model_f3x/Config.lb b/src/cpu/intel/model_f3x/Config.lb index dc58d7df50..175ff58919 100644 --- a/src/cpu/intel/model_f3x/Config.lb +++ b/src/cpu/intel/model_f3x/Config.lb @@ -1,3 +1,5 @@ +uses HAVE_MOVNTI +default HAVE_MOVNTI=1 dir /cpu/x86/tsc dir /cpu/x86/mtrr dir /cpu/x86/fpu diff --git a/src/cpu/x86/16bit/reset16.inc b/src/cpu/x86/16bit/reset16.inc index d36c94085e..1be0e3a94c 100644 --- a/src/cpu/x86/16bit/reset16.inc +++ b/src/cpu/x86/16bit/reset16.inc @@ -2,8 +2,6 @@ .code16 .globl reset_vector reset_vector: -#if _ROMBASE >= 0xffff0000 - /* jmp _start */ .byte 0xe9 .int _start - ( . + 2 ) /* Note: The above jump is hand coded to work around bugs in binutils. @@ -12,9 +10,6 @@ reset_vector: * instead of the weird 16 bit relocations that binutils does not * handle consistenly between versions because they are used so rarely. */ -#else -# error _ROMBASE is an unsupported value -#endif . = 0x8; .code32 jmp protected_start diff --git a/src/cpu/x86/16bit/reset16.lds b/src/cpu/x86/16bit/reset16.lds index 80f2fc0c6f..d01f094b3c 100644 --- a/src/cpu/x86/16bit/reset16.lds +++ b/src/cpu/x86/16bit/reset16.lds @@ -4,7 +4,8 @@ */ SECTIONS { - _ROMTOP = (_ROMBASE >= 0xffff0000)? 0xfffffff0 : 0xffff0; + /* Trigger an error if I have an unuseable start address */ + _ROMTOP = (_start >= 0xffff0000) ? 0xfffffff0 : 0xffffffff8; . = _ROMTOP; .reset . : { *(.reset) @@ -12,3 +13,4 @@ SECTIONS { BYTE(0x00); } } + diff --git a/src/cpu/x86/lapic/secondary.S b/src/cpu/x86/lapic/secondary.S index 786c31e532..5185021c3c 100644 --- a/src/cpu/x86/lapic/secondary.S +++ b/src/cpu/x86/lapic/secondary.S @@ -36,6 +36,9 @@ _secondary_start: movw %ax, %fs movw %ax, %gs + /* Load the Interrupt descriptor table */ + lidt idtarg + /* Set the stack pointer, and flag that we are done */ xorl %eax, %eax movl secondary_stack, %esp diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c index e8fda994af..74e0a64dce 100644 --- a/src/cpu/x86/mtrr/earlymtrr.c +++ b/src/cpu/x86/mtrr/earlymtrr.c @@ -6,20 +6,26 @@ /* Validate XIP_ROM_SIZE and XIP_ROM_BASE */ #if defined(XIP_ROM_SIZE) && !defined(XIP_ROM_BASE) -#error "XIP_ROM_SIZE without XIP_ROM_BASE" +# error "XIP_ROM_SIZE without XIP_ROM_BASE" #endif #if defined(XIP_ROM_BASE) && !defined(XIP_ROM_SIZE) -#error "XIP_ROM_BASE without XIP_ROM_SIZE" +# error "XIP_ROM_BASE without XIP_ROM_SIZE" #endif #if !defined(CONFIG_LB_MEM_TOPK) -#error "CONFIG_LB_MEM_TOPK not defined" +# error "CONFIG_LB_MEM_TOPK not defined" #endif -#if defined(XIP_ROM_SIZE) && ((XIP_ROM_SIZE & (XIP_ROM_SIZE -1)) != 0) -#error "XIP_ROM_SIZE is not a power of 2" -#endif -#if defined(XIP_ROM_SIZE) && ((XIP_ROM_BASE % XIP_ROM_SIZE) != 0) -#error "XIP_ROM_BASE is not a multiple of XIP_ROM_SIZE" +#if __ROMCC__ == 0 && __ROMCC_MINOR__ <= 64 + +#warning "Not checking if XIP_ROM_SIZE is valid to avoid romcc preprocessor deficiency" + +#else +# if defined(XIP_ROM_SIZE) && ((XIP_ROM_SIZE & (XIP_ROM_SIZE -1)) != 0) +# error "XIP_ROM_SIZE is not a power of 2" +# endif +# if defined(XIP_ROM_SIZE) && ((XIP_ROM_BASE % XIP_ROM_SIZE) != 0) +# error "XIP_ROM_BASE is not a multiple of XIP_ROM_SIZE" +# endif #endif #if (CONFIG_LB_MEM_TOPK & (CONFIG_LB_MEM_TOPK -1)) != 0 diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 5ffaaf053f..dcf9f008e2 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -23,6 +23,7 @@ * Reference: Intel Architecture Software Developer's Manual, Volume 3: System Programming */ +#include <stddef.h> #include <console/console.h> #include <device/device.h> #include <cpu/x86/msr.h> @@ -250,15 +251,61 @@ static unsigned long resk(uint64_t value) return resultk; } +static void set_fixed_mtrr_resource(void *gp, struct device *dev, struct resource *res) +{ + unsigned int start_mtrr; + unsigned int last_mtrr; + start_mtrr = fixed_mtrr_index(resk(res->base)); + last_mtrr = fixed_mtrr_index(resk((res->base + res->size))); + if (start_mtrr >= NUM_FIXED_RANGES) { + return; + } + printk_debug("Setting fixed MTRRs(%d-%d) Type: WB\n", + start_mtrr, last_mtrr); + set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK); + +} + +struct var_mtrr_state { + unsigned long range_startk, range_sizek; + unsigned int reg; +}; + +void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res) +{ + struct var_mtrr_state *state = gp; + unsigned long basek, sizek; + if (state->reg >= BIOS_MTRRS) + return; + basek = resk(res->base); + sizek = resk(res->size); + /* See if I can merge with the last range + * Either I am below 1M and the fixed mtrrs handle it, or + * the ranges touch. + */ + if ((basek <= 1024) || (state->range_startk + state->range_sizek == basek)) { + unsigned long endk = basek + sizek; + state->range_sizek = endk - state->range_startk; + return; + } + /* Write the range mtrrs */ + if (state->range_sizek != 0) { + state->reg = range_to_mtrr(state->reg, state->range_startk, state->range_sizek, basek); + state->range_startk = 0; + state->range_sizek = 0; + } + /* Allocate an msr */ + state->range_startk = basek; + state->range_sizek = sizek; +} + void x86_setup_mtrrs(void) { /* Try this the simple way of incrementally adding together * mtrrs. If this doesn't work out we can get smart again * and clear out the mtrrs. */ - struct device *dev; - unsigned long range_startk, range_sizek; - unsigned int reg; + struct var_mtrr_state var_state; printk_debug("\n"); /* Initialized the fixed_mtrrs to uncached */ @@ -268,76 +315,29 @@ void x86_setup_mtrrs(void) /* Now see which of the fixed mtrrs cover ram. */ - for(dev = all_devices; dev; dev = dev->next) { - struct resource *res, *last; - last = &dev->resource[dev->resources]; - for(res = &dev->resource[0]; res < last; res++) { - unsigned int start_mtrr; - unsigned int last_mtrr; - if (!(res->flags & IORESOURCE_MEM) || - !(res->flags & IORESOURCE_CACHEABLE)) - { - continue; - } - start_mtrr = fixed_mtrr_index(resk(res->base)); - last_mtrr = fixed_mtrr_index(resk((res->base + res->size))); - if (start_mtrr >= NUM_FIXED_RANGES) { - continue; - } - printk_debug("Setting fixed MTRRs(%d-%d) Type: WB\n", - start_mtrr, last_mtrr); - set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK); - } - } + search_global_resources( + IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, + set_fixed_mtrr_resource, NULL); printk_debug("DONE fixed MTRRs\n"); + /* Cache as many memory areas as possible */ /* FIXME is there an algorithm for computing the optimal set of mtrrs? * In some cases it is definitely possible to do better. */ - range_startk = 0; - range_sizek = 0; - reg = 0; - for(dev = all_devices; dev; dev = dev->next) { - struct resource *res, *last; - last = &dev->resource[dev->resources]; - for(res = &dev->resource[0]; res < last; res++) { - unsigned long basek, sizek; - if (!(res->flags & IORESOURCE_MEM) || - !(res->flags & IORESOURCE_CACHEABLE)) { - continue; - } - basek = resk(res->base); - sizek = resk(res->size); - /* See if I can merge with the last range - * Either I am below 1M and the fixed mtrrs handle it, or - * the ranges touch. - */ - if ((basek <= 1024) || (range_startk + range_sizek == basek)) { - unsigned long endk = basek + sizek; - range_sizek = endk - range_startk; - continue; - } - /* Write the range mtrrs */ - if (range_sizek != 0) { - reg = range_to_mtrr(reg, range_startk, range_sizek, basek); - range_startk = 0; - range_sizek = 0; - if (reg >= BIOS_MTRRS) - goto last_msr; - } - /* Allocate an msr */ - range_startk = basek; - range_sizek = sizek; - } - } + var_state.range_startk = 0; + var_state.range_sizek = 0; + var_state.reg = 0; + search_global_resources( + IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, + set_var_mtrr_resource, &var_state); last_msr: /* Write the last range */ - reg = range_to_mtrr(reg, range_startk, range_sizek, 0); + var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, var_state.range_sizek, 0); printk_debug("DONE variable MTRRs\n"); printk_debug("Clear out the extra MTRR's\n"); /* Clear out the extra MTRR's */ - while(reg < MTRRS) { - set_var_mtrr(reg++, 0, 0, 0); + while(var_state.reg < MTRRS) { + set_var_mtrr(var_state.reg++, 0, 0, 0); } /* enable fixed MTRR */ printk_spew("call enable_fixed_mtrr()\n"); |