Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 348814
b: refs/heads/master
c: a9acc53
h: refs/heads/master
v: v3
  • Loading branch information
Jesse Barnes authored and H. Peter Anvin committed Jan 11, 2013
1 parent a18575a commit e9168b0
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 886d751a2ea99a160f2d0a472231566d9cb0cf58
refs/heads/master: a9acc5365dbda29f7be2884efb63771dc24bd815
78 changes: 78 additions & 0 deletions trunk/arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,81 @@ static __init void reserve_ibft_region(void)

static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;

static bool __init snb_gfx_workaround_needed(void)
{
int i;
u16 vendor, devid;
static const u16 snb_ids[] = {
0x0102,
0x0112,
0x0122,
0x0106,
0x0116,
0x0126,
0x010a,
};

/* Assume no if something weird is going on with PCI */
if (!early_pci_allowed())
return false;

vendor = read_pci_config_16(0, 2, 0, PCI_VENDOR_ID);
if (vendor != 0x8086)
return false;

devid = read_pci_config_16(0, 2, 0, PCI_DEVICE_ID);
for (i = 0; i < ARRAY_SIZE(snb_ids); i++)
if (devid == snb_ids[i])
return true;

return false;
}

/*
* Sandy Bridge graphics has trouble with certain ranges, exclude
* them from allocation.
*/
static void __init trim_snb_memory(void)
{
static const unsigned long bad_pages[] = {
0x20050000,
0x20110000,
0x20130000,
0x20138000,
0x40004000,
};
int i;

if (!snb_gfx_workaround_needed())
return;

printk(KERN_DEBUG "reserving inaccessible SNB gfx pages\n");

/*
* Reserve all memory below the 1 MB mark that has not
* already been reserved.
*/
memblock_reserve(0, 1<<20);

for (i = 0; i < ARRAY_SIZE(bad_pages); i++) {
if (memblock_reserve(bad_pages[i], PAGE_SIZE))
printk(KERN_WARNING "failed to reserve 0x%08lx\n",
bad_pages[i]);
}
}

/*
* Here we put platform-specific memory range workarounds, i.e.
* memory known to be corrupt or otherwise in need to be reserved on
* specific platforms.
*
* If this gets used more widely it could use a real dispatch mechanism.
*/
static void __init trim_platform_memory_ranges(void)
{
trim_snb_memory();
}

static void __init trim_bios_range(void)
{
/*
Expand All @@ -630,6 +705,7 @@ static void __init trim_bios_range(void)
* take them out.
*/
e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);

sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
}

Expand Down Expand Up @@ -908,6 +984,8 @@ void __init setup_arch(char **cmdline_p)

setup_real_mode();

trim_platform_memory_ranges();

init_gbpages();

/* max_pfn_mapped is updated here */
Expand Down

0 comments on commit e9168b0

Please sign in to comment.