Mercurial > illumos > illumos-gate
changeset 892:3d350db28f2a
6315921 lgrp node memory computation needs to pay attention to enabled bits
author | jjc |
---|---|
date | Fri, 11 Nov 2005 16:30:15 -0800 |
parents | 2bdd1c2cd902 |
children | 76977629f0d7 |
files | usr/src/uts/i86pc/os/lgrpplat.c |
diffstat | 1 files changed, 52 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/i86pc/os/lgrpplat.c Fri Nov 11 16:13:54 2005 -0800 +++ b/usr/src/uts/i86pc/os/lgrpplat.c Fri Nov 11 16:30:15 2005 -0800 @@ -96,9 +96,9 @@ /* * Bit masks defining what's in Opteron DRAM Address Map base register */ -#define OPT_DRAMBASE_MASK_RE 0x1 /* read enable */ -#define OPT_DRAMBASE_MASK_WE 0x2 /* write enable */ -#define OPT_DRAMBASE_MASK_INTRLVEN 0x700 /* interleave */ +#define OPT_DRAMBASE_MASK_RE 0x1 /* read enable */ +#define OPT_DRAMBASE_MASK_WE 0x2 /* write enable */ +#define OPT_DRAMBASE_MASK_INTRLVEN 0x700 /* interleave */ #define OPT_DRAMBASE_MASK_ADDR 0xFFFF0000 /* address bits 39-24 */ @@ -215,6 +215,7 @@ typedef struct phys_addr_map { pfn_t start; pfn_t end; + int exists; } phys_addr_map_t; @@ -377,6 +378,12 @@ return (0); for (node = 0; node < lgrp_plat_node_cnt; node++) { + /* + * Skip nodes with no memory + */ + if (!lgrp_plat_node_memory[node].exists) + continue; + if (pfn >= lgrp_plat_node_memory[node].start && pfn <= lgrp_plat_node_memory[node].end) return (node); @@ -392,8 +399,10 @@ void plat_build_mem_nodes(struct memlist *list) { - pfn_t cur_start, cur_end; /* start & end addr of subrange */ - pfn_t start, end; /* start & end addr of whole range */ + pfn_t cur_start; /* start addr of subrange */ + pfn_t cur_end; /* end addr of subrange */ + pfn_t start; /* start addr of whole range */ + pfn_t end; /* end addr of whole range */ /* * Boot install lists are arranged <addr, len>, ... @@ -430,16 +439,29 @@ cur_start = start; do { node = plat_pfn_to_mem_node(cur_start); - ASSERT(cur_start >= - lgrp_plat_node_memory[node].start && - cur_start <= lgrp_plat_node_memory[node].end); - cur_end = end; + /* + * Panic if DRAM address map registers or SRAT say + * memory in node doesn't exist or address from + * boot installed memory list entry isn't in this node. + * This shouldn't happen and rest of code can't deal + * with this if it does. + */ + if (node < 0 || node >= lgrp_plat_node_cnt || + !lgrp_plat_node_memory[node].exists || + cur_start < lgrp_plat_node_memory[node].start || + cur_start > lgrp_plat_node_memory[node].end) { + cmn_err(CE_PANIC, "Don't know which memnode " + "to add installed memory address 0x%lx\n", + cur_start); + } /* * End of current subrange should not span memnodes */ - if (cur_end > lgrp_plat_node_memory[node].end) + cur_end = end; + if (lgrp_plat_node_memory[node].exists && + cur_end > lgrp_plat_node_memory[node].end) cur_end = lgrp_plat_node_memory[node].end; mem_node_add_slice(cur_start, cur_end); @@ -532,6 +554,23 @@ dev++; /* + * Both read and write enable bits must be enabled in DRAM + * address map base register for physical memory to exist in + * node + */ + if ((opt_dram_map[node].base & OPT_DRAMBASE_MASK_RE) == 0 || + (opt_dram_map[node].base & OPT_DRAMBASE_MASK_WE) == 0) { + /* + * Mark node memory as non-existent and set start and + * end addresses to be same in lgrp_plat_node_memory[] + */ + lgrp_plat_node_memory[node].exists = 0; + lgrp_plat_node_memory[node].start = + lgrp_plat_node_memory[node].end = (pfn_t)-1; + continue; + } + + /* * Get PFN for first page in each node, * so we can probe memory to determine latency topology */ @@ -539,8 +578,10 @@ btop(OPT_DRAMBASE(opt_dram_map[node].base)); /* - * Remember physical address range of each node for use later + * Mark node memory as existing and remember physical address + * range of each node for use later */ + lgrp_plat_node_memory[node].exists = 1; lgrp_plat_node_memory[node].start = btop(OPT_DRAMBASE(opt_dram_map[node].base)); lgrp_plat_node_memory[node].end =