- To reduce confuse rename the parts of linuxbios bios that run from
ram linuxbios_ram instead of linuxbios_c and linuxbios_payload... - Reordered the linker sections so the LinuxBIOS fallback image can take more the 64KiB on x86 - ROM_IMAGE_SIZE now will work when it is specified as larger than 64KiB. - Tweaked the reset16.inc and reset16.lds to move the sanity check to see if everything will work. - Start using romcc's built in preprocessor (This will simplify header compiler checks) - Add helper functions for examining all of the resources - Remove debug strings from chip.h - Add llshell to src/arch/i386/llshell (Sometime later I can try it...) - Add the ability to catch exceptions on x86 - Add gdb_stub support to x86 - Removed old cpu options - Added an option so we can detect movnti support - Remove some duplicate definitions from pci_ids.h - Remove the 64bit resource code in amdk8/northbridge.c in preparation for making it generic - Minor romcc bug fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1727 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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");
|
||||
|
Reference in New Issue
Block a user