summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/amd/model_fxx/Config.lb2
-rw-r--r--src/cpu/amd/mtrr/amd_mtrr.c85
-rw-r--r--src/cpu/amd/socket_940/Config.lb4
-rw-r--r--src/cpu/amd/socket_940/socket_940.c1
-rw-r--r--src/cpu/intel/model_f0x/Config.lb2
-rw-r--r--src/cpu/intel/model_f1x/Config.lb2
-rw-r--r--src/cpu/intel/model_f2x/Config.lb2
-rw-r--r--src/cpu/intel/model_f3x/Config.lb2
-rw-r--r--src/cpu/x86/16bit/reset16.inc5
-rw-r--r--src/cpu/x86/16bit/reset16.lds4
-rw-r--r--src/cpu/x86/lapic/secondary.S3
-rw-r--r--src/cpu/x86/mtrr/earlymtrr.c22
-rw-r--r--src/cpu/x86/mtrr/mtrr.c126
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");