aboutsummaryrefslogtreecommitdiff
path: root/arch/blackfin/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r--arch/blackfin/kernel/setup.c131
1 files changed, 107 insertions, 24 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 2255c289a71..8efea004aec 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -35,6 +35,7 @@ u16 _bfin_swrst;
EXPORT_SYMBOL(_bfin_swrst);
unsigned long memory_start, memory_end, physical_mem_end;
+unsigned long _rambase, _ramstart, _ramend;
unsigned long reserved_mem_dcache_on;
unsigned long reserved_mem_icache_on;
EXPORT_SYMBOL(memory_start);
@@ -106,7 +107,7 @@ void __init bf53x_relocate_l1_mem(void)
l1_code_length = _etext_l1 - _stext_l1;
if (l1_code_length > L1_CODE_LENGTH)
- l1_code_length = L1_CODE_LENGTH;
+ panic("L1 Instruction SRAM Overflow\n");
/* cannot complain as printk is not available as yet.
* But we can continue booting and complain later!
*/
@@ -116,19 +117,18 @@ void __init bf53x_relocate_l1_mem(void)
l1_data_a_length = _ebss_l1 - _sdata_l1;
if (l1_data_a_length > L1_DATA_A_LENGTH)
- l1_data_a_length = L1_DATA_A_LENGTH;
+ panic("L1 Data SRAM Bank A Overflow\n");
/* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */
dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
l1_data_b_length = _ebss_b_l1 - _sdata_b_l1;
if (l1_data_b_length > L1_DATA_B_LENGTH)
- l1_data_b_length = L1_DATA_B_LENGTH;
+ panic("L1 Data SRAM Bank B Overflow\n");
/* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */
dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
l1_data_a_length, l1_data_b_length);
-
}
/* add_memory_region to memmap */
@@ -547,11 +547,38 @@ static __init void memory_setup(void)
);
}
+/*
+ * Find the lowest, highest page frame number we have available
+ */
+void __init find_min_max_pfn(void)
+{
+ int i;
+
+ max_pfn = 0;
+ min_low_pfn = memory_end;
+
+ for (i = 0; i < bfin_memmap.nr_map; i++) {
+ unsigned long start, end;
+ /* RAM? */
+ if (bfin_memmap.map[i].type != BFIN_MEMMAP_RAM)
+ continue;
+ start = PFN_UP(bfin_memmap.map[i].addr);
+ end = PFN_DOWN(bfin_memmap.map[i].addr +
+ bfin_memmap.map[i].size);
+ if (start >= end)
+ continue;
+ if (end > max_pfn)
+ max_pfn = end;
+ if (start < min_low_pfn)
+ min_low_pfn = start;
+ }
+}
+
static __init void setup_bootmem_allocator(void)
{
int bootmap_size;
int i;
- unsigned long min_pfn, max_pfn;
+ unsigned long start_pfn, end_pfn;
unsigned long curr_pfn, last_pfn, size;
/* mark memory between memory_start and memory_end usable */
@@ -561,8 +588,19 @@ static __init void setup_bootmem_allocator(void)
sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map);
print_memory_map("boot memmap");
- min_pfn = PAGE_OFFSET >> PAGE_SHIFT;
- max_pfn = memory_end >> PAGE_SHIFT;
+ /* intialize globals in linux/bootmem.h */
+ find_min_max_pfn();
+ /* pfn of the last usable page frame */
+ if (max_pfn > memory_end >> PAGE_SHIFT)
+ max_pfn = memory_end >> PAGE_SHIFT;
+ /* pfn of last page frame directly mapped by kernel */
+ max_low_pfn = max_pfn;
+ /* pfn of the first usable page frame after kernel image*/
+ if (min_low_pfn < memory_start >> PAGE_SHIFT)
+ min_low_pfn = memory_start >> PAGE_SHIFT;
+
+ start_pfn = PAGE_OFFSET >> PAGE_SHIFT;
+ end_pfn = memory_end >> PAGE_SHIFT;
/*
* give all the memory to the bootmap allocator, tell it to put the
@@ -570,7 +608,7 @@ static __init void setup_bootmem_allocator(void)
*/
bootmap_size = init_bootmem_node(NODE_DATA(0),
memory_start >> PAGE_SHIFT, /* map goes here */
- min_pfn, max_pfn);
+ start_pfn, end_pfn);
/* register the memmap regions with the bootmem allocator */
for (i = 0; i < bfin_memmap.nr_map; i++) {
@@ -583,7 +621,7 @@ static __init void setup_bootmem_allocator(void)
* We are rounding up the start address of usable memory:
*/
curr_pfn = PFN_UP(bfin_memmap.map[i].addr);
- if (curr_pfn >= max_pfn)
+ if (curr_pfn >= end_pfn)
continue;
/*
* ... and at the end of the usable range downwards:
@@ -591,8 +629,8 @@ static __init void setup_bootmem_allocator(void)
last_pfn = PFN_DOWN(bfin_memmap.map[i].addr +
bfin_memmap.map[i].size);
- if (last_pfn > max_pfn)
- last_pfn = max_pfn;
+ if (last_pfn > end_pfn)
+ last_pfn = end_pfn;
/*
* .. finally, did all the rounding and playing
@@ -611,9 +649,59 @@ static __init void setup_bootmem_allocator(void)
BOOTMEM_DEFAULT);
}
+#define EBSZ_TO_MEG(ebsz) \
+({ \
+ int meg = 0; \
+ switch (ebsz & 0xf) { \
+ case 0x1: meg = 16; break; \
+ case 0x3: meg = 32; break; \
+ case 0x5: meg = 64; break; \
+ case 0x7: meg = 128; break; \
+ case 0x9: meg = 256; break; \
+ case 0xb: meg = 512; break; \
+ } \
+ meg; \
+})
+static inline int __init get_mem_size(void)
+{
+#ifdef CONFIG_MEM_SIZE
+ return CONFIG_MEM_SIZE;
+#else
+# if defined(EBIU_SDBCTL)
+# if defined(BF561_FAMILY)
+ int ret = 0;
+ u32 sdbctl = bfin_read_EBIU_SDBCTL();
+ ret += EBSZ_TO_MEG(sdbctl >> 0);
+ ret += EBSZ_TO_MEG(sdbctl >> 8);
+ ret += EBSZ_TO_MEG(sdbctl >> 16);
+ ret += EBSZ_TO_MEG(sdbctl >> 24);
+ return ret;
+# else
+ return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL());
+# endif
+# elif defined(EBIU_DDRCTL1)
+ u32 ddrctl = bfin_read_EBIU_DDRCTL1();
+ int ret = 0;
+ switch (ddrctl & 0xc0000) {
+ case DEVSZ_64: ret = 64 / 8;
+ case DEVSZ_128: ret = 128 / 8;
+ case DEVSZ_256: ret = 256 / 8;
+ case DEVSZ_512: ret = 512 / 8;
+ }
+ switch (ddrctl & 0x30000) {
+ case DEVWD_4: ret *= 2;
+ case DEVWD_8: ret *= 2;
+ case DEVWD_16: break;
+ }
+ return ret;
+# endif
+#endif
+ BUG();
+}
+
void __init setup_arch(char **cmdline_p)
{
- unsigned long l1_length, sclk, cclk;
+ unsigned long sclk, cclk;
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -631,7 +719,7 @@ void __init setup_arch(char **cmdline_p)
/* setup memory defaults from the user config */
physical_mem_end = 0;
- _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
+ _ramend = get_mem_size() * 1024 * 1024;
memset(&bfin_memmap, 0, sizeof(bfin_memmap));
@@ -712,15 +800,6 @@ void __init setup_arch(char **cmdline_p)
paging_init();
- /* check the size of the l1 area */
- l1_length = _etext_l1 - _stext_l1;
- if (l1_length > L1_CODE_LENGTH)
- panic("L1 code memory overflow\n");
-
- l1_length = _ebss_l1 - _sdata_l1;
- if (l1_length > L1_DATA_A_LENGTH)
- panic("L1 data memory overflow\n");
-
/* Copy atomic sequences to their fixed location, and sanity check that
these locations are the ones that we advertise to userspace. */
memcpy((void *)FIXED_CODE_START, &fixed_code_start,
@@ -859,12 +938,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %d\n"
"vendor_id\t: %s\n"
"cpu family\t: 0x%x\n"
- "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK)\n"
+ "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n"
"stepping\t: %d\n",
0,
vendor,
(bfin_read_CHIPID() & CHIPID_FAMILY),
cpu, cclk/1000000, sclk/1000000,
+#ifdef CONFIG_MPU
+ "mpu on",
+#else
+ "mpu off",
+#endif
revid);
seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
@@ -973,7 +1057,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "No Ways are locked\n");
}
#endif
-
seq_printf(m, "board name\t: %s\n", bfin_board_name);
seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);