setup.c revision 0c0497c257c12c9ecb8825490a339bfce8a0532f
1/* 2 * arch/blackfin/kernel/setup.c 3 * 4 * Copyright 2004-2006 Analog Devices Inc. 5 * 6 * Enter bugs at http://blackfin.uclinux.org/ 7 * 8 * Licensed under the GPL-2 or later. 9 */ 10 11#include <linux/delay.h> 12#include <linux/console.h> 13#include <linux/bootmem.h> 14#include <linux/seq_file.h> 15#include <linux/cpu.h> 16#include <linux/module.h> 17#include <linux/tty.h> 18#include <linux/pfn.h> 19 20#include <linux/ext2_fs.h> 21#include <linux/cramfs_fs.h> 22#include <linux/romfs_fs.h> 23 24#include <asm/cplb.h> 25#include <asm/cacheflush.h> 26#include <asm/blackfin.h> 27#include <asm/cplbinit.h> 28#include <asm/div64.h> 29#include <asm/fixed_code.h> 30#include <asm/early_printk.h> 31 32static DEFINE_PER_CPU(struct cpu, cpu_devices); 33 34u16 _bfin_swrst; 35EXPORT_SYMBOL(_bfin_swrst); 36 37unsigned long memory_start, memory_end, physical_mem_end; 38unsigned long _rambase, _ramstart, _ramend; 39unsigned long reserved_mem_dcache_on; 40unsigned long reserved_mem_icache_on; 41EXPORT_SYMBOL(memory_start); 42EXPORT_SYMBOL(memory_end); 43EXPORT_SYMBOL(physical_mem_end); 44EXPORT_SYMBOL(_ramend); 45 46#ifdef CONFIG_MTD_UCLINUX 47unsigned long memory_mtd_end, memory_mtd_start, mtd_size; 48unsigned long _ebss; 49EXPORT_SYMBOL(memory_mtd_end); 50EXPORT_SYMBOL(memory_mtd_start); 51EXPORT_SYMBOL(mtd_size); 52#endif 53 54char __initdata command_line[COMMAND_LINE_SIZE]; 55void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, 56 *init_saved_icplb_fault_addr, *init_saved_dcplb_fault_addr; 57 58/* boot memmap, for parsing "memmap=" */ 59#define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ 60#define BFIN_MEMMAP_RAM 1 61#define BFIN_MEMMAP_RESERVED 2 62struct bfin_memmap { 63 int nr_map; 64 struct bfin_memmap_entry { 65 unsigned long long addr; /* start of memory segment */ 66 unsigned long long size; 67 unsigned long type; 68 } map[BFIN_MEMMAP_MAX]; 69} bfin_memmap __initdata; 70 71/* for memmap sanitization */ 72struct change_member { 73 struct bfin_memmap_entry *pentry; /* pointer to original entry */ 74 unsigned long long addr; /* address for this change point */ 75}; 76static struct change_member change_point_list[2*BFIN_MEMMAP_MAX] __initdata; 77static struct change_member *change_point[2*BFIN_MEMMAP_MAX] __initdata; 78static struct bfin_memmap_entry *overlap_list[BFIN_MEMMAP_MAX] __initdata; 79static struct bfin_memmap_entry new_map[BFIN_MEMMAP_MAX] __initdata; 80 81void __init bfin_cache_init(void) 82{ 83#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE) 84 generate_cplb_tables(); 85#endif 86 87#ifdef CONFIG_BFIN_ICACHE 88 bfin_icache_init(); 89 printk(KERN_INFO "Instruction Cache Enabled\n"); 90#endif 91 92#ifdef CONFIG_BFIN_DCACHE 93 bfin_dcache_init(); 94 printk(KERN_INFO "Data Cache Enabled" 95# if defined CONFIG_BFIN_WB 96 " (write-back)" 97# elif defined CONFIG_BFIN_WT 98 " (write-through)" 99# endif 100 "\n"); 101#endif 102} 103 104void __init bfin_relocate_l1_mem(void) 105{ 106 unsigned long l1_code_length; 107 unsigned long l1_data_a_length; 108 unsigned long l1_data_b_length; 109 unsigned long l2_length; 110 111 l1_code_length = _etext_l1 - _stext_l1; 112 if (l1_code_length > L1_CODE_LENGTH) 113 panic("L1 Instruction SRAM Overflow\n"); 114 /* cannot complain as printk is not available as yet. 115 * But we can continue booting and complain later! 116 */ 117 118 /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ 119 dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); 120 121 l1_data_a_length = _ebss_l1 - _sdata_l1; 122 if (l1_data_a_length > L1_DATA_A_LENGTH) 123 panic("L1 Data SRAM Bank A Overflow\n"); 124 125 /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ 126 dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); 127 128 l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; 129 if (l1_data_b_length > L1_DATA_B_LENGTH) 130 panic("L1 Data SRAM Bank B Overflow\n"); 131 132 /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ 133 dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + 134 l1_data_a_length, l1_data_b_length); 135 136 if (L2_LENGTH != 0) { 137 l2_length = _ebss_l2 - _stext_l2; 138 if (l2_length > L2_LENGTH) 139 panic("L2 SRAM Overflow\n"); 140 141 /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ 142 dma_memcpy(_stext_l2, _l2_lma_start, l2_length); 143 } 144} 145 146/* add_memory_region to memmap */ 147static void __init add_memory_region(unsigned long long start, 148 unsigned long long size, int type) 149{ 150 int i; 151 152 i = bfin_memmap.nr_map; 153 154 if (i == BFIN_MEMMAP_MAX) { 155 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); 156 return; 157 } 158 159 bfin_memmap.map[i].addr = start; 160 bfin_memmap.map[i].size = size; 161 bfin_memmap.map[i].type = type; 162 bfin_memmap.nr_map++; 163} 164 165/* 166 * Sanitize the boot memmap, removing overlaps. 167 */ 168static int __init sanitize_memmap(struct bfin_memmap_entry *map, int *pnr_map) 169{ 170 struct change_member *change_tmp; 171 unsigned long current_type, last_type; 172 unsigned long long last_addr; 173 int chgidx, still_changing; 174 int overlap_entries; 175 int new_entry; 176 int old_nr, new_nr, chg_nr; 177 int i; 178 179 /* 180 Visually we're performing the following (1,2,3,4 = memory types) 181 182 Sample memory map (w/overlaps): 183 ____22__________________ 184 ______________________4_ 185 ____1111________________ 186 _44_____________________ 187 11111111________________ 188 ____________________33__ 189 ___________44___________ 190 __________33333_________ 191 ______________22________ 192 ___________________2222_ 193 _________111111111______ 194 _____________________11_ 195 _________________4______ 196 197 Sanitized equivalent (no overlap): 198 1_______________________ 199 _44_____________________ 200 ___1____________________ 201 ____22__________________ 202 ______11________________ 203 _________1______________ 204 __________3_____________ 205 ___________44___________ 206 _____________33_________ 207 _______________2________ 208 ________________1_______ 209 _________________4______ 210 ___________________2____ 211 ____________________33__ 212 ______________________4_ 213 */ 214 /* if there's only one memory region, don't bother */ 215 if (*pnr_map < 2) 216 return -1; 217 218 old_nr = *pnr_map; 219 220 /* bail out if we find any unreasonable addresses in memmap */ 221 for (i = 0; i < old_nr; i++) 222 if (map[i].addr + map[i].size < map[i].addr) 223 return -1; 224 225 /* create pointers for initial change-point information (for sorting) */ 226 for (i = 0; i < 2*old_nr; i++) 227 change_point[i] = &change_point_list[i]; 228 229 /* record all known change-points (starting and ending addresses), 230 omitting those that are for empty memory regions */ 231 chgidx = 0; 232 for (i = 0; i < old_nr; i++) { 233 if (map[i].size != 0) { 234 change_point[chgidx]->addr = map[i].addr; 235 change_point[chgidx++]->pentry = &map[i]; 236 change_point[chgidx]->addr = map[i].addr + map[i].size; 237 change_point[chgidx++]->pentry = &map[i]; 238 } 239 } 240 chg_nr = chgidx; /* true number of change-points */ 241 242 /* sort change-point list by memory addresses (low -> high) */ 243 still_changing = 1; 244 while (still_changing) { 245 still_changing = 0; 246 for (i = 1; i < chg_nr; i++) { 247 /* if <current_addr> > <last_addr>, swap */ 248 /* or, if current=<start_addr> & last=<end_addr>, swap */ 249 if ((change_point[i]->addr < change_point[i-1]->addr) || 250 ((change_point[i]->addr == change_point[i-1]->addr) && 251 (change_point[i]->addr == change_point[i]->pentry->addr) && 252 (change_point[i-1]->addr != change_point[i-1]->pentry->addr)) 253 ) { 254 change_tmp = change_point[i]; 255 change_point[i] = change_point[i-1]; 256 change_point[i-1] = change_tmp; 257 still_changing = 1; 258 } 259 } 260 } 261 262 /* create a new memmap, removing overlaps */ 263 overlap_entries = 0; /* number of entries in the overlap table */ 264 new_entry = 0; /* index for creating new memmap entries */ 265 last_type = 0; /* start with undefined memory type */ 266 last_addr = 0; /* start with 0 as last starting address */ 267 /* loop through change-points, determining affect on the new memmap */ 268 for (chgidx = 0; chgidx < chg_nr; chgidx++) { 269 /* keep track of all overlapping memmap entries */ 270 if (change_point[chgidx]->addr == change_point[chgidx]->pentry->addr) { 271 /* add map entry to overlap list (> 1 entry implies an overlap) */ 272 overlap_list[overlap_entries++] = change_point[chgidx]->pentry; 273 } else { 274 /* remove entry from list (order independent, so swap with last) */ 275 for (i = 0; i < overlap_entries; i++) { 276 if (overlap_list[i] == change_point[chgidx]->pentry) 277 overlap_list[i] = overlap_list[overlap_entries-1]; 278 } 279 overlap_entries--; 280 } 281 /* if there are overlapping entries, decide which "type" to use */ 282 /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ 283 current_type = 0; 284 for (i = 0; i < overlap_entries; i++) 285 if (overlap_list[i]->type > current_type) 286 current_type = overlap_list[i]->type; 287 /* continue building up new memmap based on this information */ 288 if (current_type != last_type) { 289 if (last_type != 0) { 290 new_map[new_entry].size = 291 change_point[chgidx]->addr - last_addr; 292 /* move forward only if the new size was non-zero */ 293 if (new_map[new_entry].size != 0) 294 if (++new_entry >= BFIN_MEMMAP_MAX) 295 break; /* no more space left for new entries */ 296 } 297 if (current_type != 0) { 298 new_map[new_entry].addr = change_point[chgidx]->addr; 299 new_map[new_entry].type = current_type; 300 last_addr = change_point[chgidx]->addr; 301 } 302 last_type = current_type; 303 } 304 } 305 new_nr = new_entry; /* retain count for new entries */ 306 307 /* copy new mapping into original location */ 308 memcpy(map, new_map, new_nr*sizeof(struct bfin_memmap_entry)); 309 *pnr_map = new_nr; 310 311 return 0; 312} 313 314static void __init print_memory_map(char *who) 315{ 316 int i; 317 318 for (i = 0; i < bfin_memmap.nr_map; i++) { 319 printk(KERN_DEBUG " %s: %016Lx - %016Lx ", who, 320 bfin_memmap.map[i].addr, 321 bfin_memmap.map[i].addr + bfin_memmap.map[i].size); 322 switch (bfin_memmap.map[i].type) { 323 case BFIN_MEMMAP_RAM: 324 printk("(usable)\n"); 325 break; 326 case BFIN_MEMMAP_RESERVED: 327 printk("(reserved)\n"); 328 break; 329 default: printk("type %lu\n", bfin_memmap.map[i].type); 330 break; 331 } 332 } 333} 334 335static __init int parse_memmap(char *arg) 336{ 337 unsigned long long start_at, mem_size; 338 339 if (!arg) 340 return -EINVAL; 341 342 mem_size = memparse(arg, &arg); 343 if (*arg == '@') { 344 start_at = memparse(arg+1, &arg); 345 add_memory_region(start_at, mem_size, BFIN_MEMMAP_RAM); 346 } else if (*arg == '$') { 347 start_at = memparse(arg+1, &arg); 348 add_memory_region(start_at, mem_size, BFIN_MEMMAP_RESERVED); 349 } 350 351 return 0; 352} 353 354/* 355 * Initial parsing of the command line. Currently, we support: 356 * - Controlling the linux memory size: mem=xxx[KMG] 357 * - Controlling the physical memory size: max_mem=xxx[KMG][$][#] 358 * $ -> reserved memory is dcacheable 359 * # -> reserved memory is icacheable 360 * - "memmap=XXX[KkmM][@][$]XXX[KkmM]" defines a memory region 361 * @ from <start> to <start>+<mem>, type RAM 362 * $ from <start> to <start>+<mem>, type RESERVED 363 * 364 */ 365static __init void parse_cmdline_early(char *cmdline_p) 366{ 367 char c = ' ', *to = cmdline_p; 368 unsigned int memsize; 369 for (;;) { 370 if (c == ' ') { 371 if (!memcmp(to, "mem=", 4)) { 372 to += 4; 373 memsize = memparse(to, &to); 374 if (memsize) 375 _ramend = memsize; 376 377 } else if (!memcmp(to, "max_mem=", 8)) { 378 to += 8; 379 memsize = memparse(to, &to); 380 if (memsize) { 381 physical_mem_end = memsize; 382 if (*to != ' ') { 383 if (*to == '$' 384 || *(to + 1) == '$') 385 reserved_mem_dcache_on = 386 1; 387 if (*to == '#' 388 || *(to + 1) == '#') 389 reserved_mem_icache_on = 390 1; 391 } 392 } 393 } else if (!memcmp(to, "earlyprintk=", 12)) { 394 to += 12; 395 setup_early_printk(to); 396 } else if (!memcmp(to, "memmap=", 7)) { 397 to += 7; 398 parse_memmap(to); 399 } 400 } 401 c = *(to++); 402 if (!c) 403 break; 404 } 405} 406 407/* 408 * Setup memory defaults from user config. 409 * The physical memory layout looks like: 410 * 411 * [_rambase, _ramstart]: kernel image 412 * [memory_start, memory_end]: dynamic memory managed by kernel 413 * [memory_end, _ramend]: reserved memory 414 * [meory_mtd_start(memory_end), 415 * memory_mtd_start + mtd_size]: rootfs (if any) 416 * [_ramend - DMA_UNCACHED_REGION, 417 * _ramend]: uncached DMA region 418 * [_ramend, physical_mem_end]: memory not managed by kernel 419 * 420 */ 421static __init void memory_setup(void) 422{ 423#ifdef CONFIG_MTD_UCLINUX 424 unsigned long mtd_phys = 0; 425#endif 426 427 _rambase = (unsigned long)_stext; 428 _ramstart = (unsigned long)_end; 429 430 if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) { 431 console_init(); 432 panic("DMA region exceeds memory limit: %lu.\n", 433 _ramend - _ramstart); 434 } 435 memory_end = _ramend - DMA_UNCACHED_REGION; 436 437#ifdef CONFIG_MPU 438 /* Round up to multiple of 4MB. */ 439 memory_start = (_ramstart + 0x3fffff) & ~0x3fffff; 440#else 441 memory_start = PAGE_ALIGN(_ramstart); 442#endif 443 444#if defined(CONFIG_MTD_UCLINUX) 445 /* generic memory mapped MTD driver */ 446 memory_mtd_end = memory_end; 447 448 mtd_phys = _ramstart; 449 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); 450 451# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) 452 if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) 453 mtd_size = 454 PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); 455# endif 456 457# if defined(CONFIG_CRAMFS) 458 if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) 459 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); 460# endif 461 462# if defined(CONFIG_ROMFS_FS) 463 if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 464 && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) 465 mtd_size = 466 PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); 467# if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263) 468 /* Due to a Hardware Anomaly we need to limit the size of usable 469 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 470 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 471 */ 472# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) 473 if (memory_end >= 56 * 1024 * 1024) 474 memory_end = 56 * 1024 * 1024; 475# else 476 if (memory_end >= 60 * 1024 * 1024) 477 memory_end = 60 * 1024 * 1024; 478# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ 479# endif /* ANOMALY_05000263 */ 480# endif /* CONFIG_ROMFS_FS */ 481 482 memory_end -= mtd_size; 483 484 if (mtd_size == 0) { 485 console_init(); 486 panic("Don't boot kernel without rootfs attached.\n"); 487 } 488 489 /* Relocate MTD image to the top of memory after the uncached memory area */ 490 dma_memcpy((char *)memory_end, _end, mtd_size); 491 492 memory_mtd_start = memory_end; 493 _ebss = memory_mtd_start; /* define _ebss for compatible */ 494#endif /* CONFIG_MTD_UCLINUX */ 495 496#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263) 497 /* Due to a Hardware Anomaly we need to limit the size of usable 498 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 499 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 500 */ 501#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) 502 if (memory_end >= 56 * 1024 * 1024) 503 memory_end = 56 * 1024 * 1024; 504#else 505 if (memory_end >= 60 * 1024 * 1024) 506 memory_end = 60 * 1024 * 1024; 507#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ 508 printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); 509#endif /* ANOMALY_05000263 */ 510 511#ifdef CONFIG_MPU 512 page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; 513 page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); 514#endif 515 516#if !defined(CONFIG_MTD_UCLINUX) 517 /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ 518 memory_end -= SIZE_4K; 519#endif 520 521 init_mm.start_code = (unsigned long)_stext; 522 init_mm.end_code = (unsigned long)_etext; 523 init_mm.end_data = (unsigned long)_edata; 524 init_mm.brk = (unsigned long)0; 525 526 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); 527 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); 528 529 printk(KERN_INFO "Memory map:\n" 530 KERN_INFO " fixedcode = 0x%p-0x%p\n" 531 KERN_INFO " text = 0x%p-0x%p\n" 532 KERN_INFO " rodata = 0x%p-0x%p\n" 533 KERN_INFO " bss = 0x%p-0x%p\n" 534 KERN_INFO " data = 0x%p-0x%p\n" 535 KERN_INFO " stack = 0x%p-0x%p\n" 536 KERN_INFO " init = 0x%p-0x%p\n" 537 KERN_INFO " available = 0x%p-0x%p\n" 538#ifdef CONFIG_MTD_UCLINUX 539 KERN_INFO " rootfs = 0x%p-0x%p\n" 540#endif 541#if DMA_UNCACHED_REGION > 0 542 KERN_INFO " DMA Zone = 0x%p-0x%p\n" 543#endif 544 , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END, 545 _stext, _etext, 546 __start_rodata, __end_rodata, 547 __bss_start, __bss_stop, 548 _sdata, _edata, 549 (void *)&init_thread_union, 550 (void *)((int)(&init_thread_union) + 0x2000), 551 __init_begin, __init_end, 552 (void *)_ramstart, (void *)memory_end 553#ifdef CONFIG_MTD_UCLINUX 554 , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size) 555#endif 556#if DMA_UNCACHED_REGION > 0 557 , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend) 558#endif 559 ); 560} 561 562/* 563 * Find the lowest, highest page frame number we have available 564 */ 565void __init find_min_max_pfn(void) 566{ 567 int i; 568 569 max_pfn = 0; 570 min_low_pfn = memory_end; 571 572 for (i = 0; i < bfin_memmap.nr_map; i++) { 573 unsigned long start, end; 574 /* RAM? */ 575 if (bfin_memmap.map[i].type != BFIN_MEMMAP_RAM) 576 continue; 577 start = PFN_UP(bfin_memmap.map[i].addr); 578 end = PFN_DOWN(bfin_memmap.map[i].addr + 579 bfin_memmap.map[i].size); 580 if (start >= end) 581 continue; 582 if (end > max_pfn) 583 max_pfn = end; 584 if (start < min_low_pfn) 585 min_low_pfn = start; 586 } 587} 588 589static __init void setup_bootmem_allocator(void) 590{ 591 int bootmap_size; 592 int i; 593 unsigned long start_pfn, end_pfn; 594 unsigned long curr_pfn, last_pfn, size; 595 596 /* mark memory between memory_start and memory_end usable */ 597 add_memory_region(memory_start, 598 memory_end - memory_start, BFIN_MEMMAP_RAM); 599 /* sanity check for overlap */ 600 sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map); 601 print_memory_map("boot memmap"); 602 603 /* intialize globals in linux/bootmem.h */ 604 find_min_max_pfn(); 605 /* pfn of the last usable page frame */ 606 if (max_pfn > memory_end >> PAGE_SHIFT) 607 max_pfn = memory_end >> PAGE_SHIFT; 608 /* pfn of last page frame directly mapped by kernel */ 609 max_low_pfn = max_pfn; 610 /* pfn of the first usable page frame after kernel image*/ 611 if (min_low_pfn < memory_start >> PAGE_SHIFT) 612 min_low_pfn = memory_start >> PAGE_SHIFT; 613 614 start_pfn = PAGE_OFFSET >> PAGE_SHIFT; 615 end_pfn = memory_end >> PAGE_SHIFT; 616 617 /* 618 * give all the memory to the bootmap allocator, tell it to put the 619 * boot mem_map at the start of memory. 620 */ 621 bootmap_size = init_bootmem_node(NODE_DATA(0), 622 memory_start >> PAGE_SHIFT, /* map goes here */ 623 start_pfn, end_pfn); 624 625 /* register the memmap regions with the bootmem allocator */ 626 for (i = 0; i < bfin_memmap.nr_map; i++) { 627 /* 628 * Reserve usable memory 629 */ 630 if (bfin_memmap.map[i].type != BFIN_MEMMAP_RAM) 631 continue; 632 /* 633 * We are rounding up the start address of usable memory: 634 */ 635 curr_pfn = PFN_UP(bfin_memmap.map[i].addr); 636 if (curr_pfn >= end_pfn) 637 continue; 638 /* 639 * ... and at the end of the usable range downwards: 640 */ 641 last_pfn = PFN_DOWN(bfin_memmap.map[i].addr + 642 bfin_memmap.map[i].size); 643 644 if (last_pfn > end_pfn) 645 last_pfn = end_pfn; 646 647 /* 648 * .. finally, did all the rounding and playing 649 * around just make the area go away? 650 */ 651 if (last_pfn <= curr_pfn) 652 continue; 653 654 size = last_pfn - curr_pfn; 655 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); 656 } 657 658 /* reserve memory before memory_start, including bootmap */ 659 reserve_bootmem(PAGE_OFFSET, 660 memory_start + bootmap_size + PAGE_SIZE - 1 - PAGE_OFFSET, 661 BOOTMEM_DEFAULT); 662} 663 664#define EBSZ_TO_MEG(ebsz) \ 665({ \ 666 int meg = 0; \ 667 switch (ebsz & 0xf) { \ 668 case 0x1: meg = 16; break; \ 669 case 0x3: meg = 32; break; \ 670 case 0x5: meg = 64; break; \ 671 case 0x7: meg = 128; break; \ 672 case 0x9: meg = 256; break; \ 673 case 0xb: meg = 512; break; \ 674 } \ 675 meg; \ 676}) 677static inline int __init get_mem_size(void) 678{ 679#if defined(EBIU_SDBCTL) 680# if defined(BF561_FAMILY) 681 int ret = 0; 682 u32 sdbctl = bfin_read_EBIU_SDBCTL(); 683 ret += EBSZ_TO_MEG(sdbctl >> 0); 684 ret += EBSZ_TO_MEG(sdbctl >> 8); 685 ret += EBSZ_TO_MEG(sdbctl >> 16); 686 ret += EBSZ_TO_MEG(sdbctl >> 24); 687 return ret; 688# else 689 return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); 690# endif 691#elif defined(EBIU_DDRCTL1) 692 u32 ddrctl = bfin_read_EBIU_DDRCTL1(); 693 int ret = 0; 694 switch (ddrctl & 0xc0000) { 695 case DEVSZ_64: ret = 64 / 8; 696 case DEVSZ_128: ret = 128 / 8; 697 case DEVSZ_256: ret = 256 / 8; 698 case DEVSZ_512: ret = 512 / 8; 699 } 700 switch (ddrctl & 0x30000) { 701 case DEVWD_4: ret *= 2; 702 case DEVWD_8: ret *= 2; 703 case DEVWD_16: break; 704 } 705 if ((ddrctl & 0xc000) == 0x4000) 706 ret *= 2; 707 return ret; 708#endif 709 BUG(); 710} 711 712void __init setup_arch(char **cmdline_p) 713{ 714 unsigned long sclk, cclk; 715 716#ifdef CONFIG_DUMMY_CONSOLE 717 conswitchp = &dummy_con; 718#endif 719 720#if defined(CONFIG_CMDLINE_BOOL) 721 strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); 722 command_line[sizeof(command_line) - 1] = 0; 723#endif 724 725 /* Keep a copy of command line */ 726 *cmdline_p = &command_line[0]; 727 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 728 boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; 729 730 /* setup memory defaults from the user config */ 731 physical_mem_end = 0; 732 _ramend = get_mem_size() * 1024 * 1024; 733 734 memset(&bfin_memmap, 0, sizeof(bfin_memmap)); 735 736 parse_cmdline_early(&command_line[0]); 737 738 if (physical_mem_end == 0) 739 physical_mem_end = _ramend; 740 741 memory_setup(); 742 743 /* Initialize Async memory banks */ 744 bfin_write_EBIU_AMBCTL0(AMBCTL0VAL); 745 bfin_write_EBIU_AMBCTL1(AMBCTL1VAL); 746 bfin_write_EBIU_AMGCTL(AMGCTLVAL); 747#ifdef CONFIG_EBIU_MBSCTLVAL 748 bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTLVAL); 749 bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL); 750 bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL); 751#endif 752 753 cclk = get_cclk(); 754 sclk = get_sclk(); 755 756#if !defined(CONFIG_BFIN_KERNEL_CLOCK) 757 if (ANOMALY_05000273 && cclk == sclk) 758 panic("ANOMALY 05000273, SCLK can not be same as CCLK"); 759#endif 760 761#ifdef BF561_FAMILY 762 if (ANOMALY_05000266) { 763 bfin_read_IMDMA_D0_IRQ_STATUS(); 764 bfin_read_IMDMA_D1_IRQ_STATUS(); 765 } 766#endif 767 printk(KERN_INFO "Hardware Trace "); 768 if (bfin_read_TBUFCTL() & 0x1) 769 printk("Active "); 770 else 771 printk("Off "); 772 if (bfin_read_TBUFCTL() & 0x2) 773 printk("and Enabled\n"); 774 else 775 printk("and Disabled\n"); 776 777#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 778 /* we need to initialize the Flashrom device here since we might 779 * do things with flash early on in the boot 780 */ 781 flash_probe(); 782#endif 783 784 _bfin_swrst = bfin_read_SWRST(); 785 786#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT 787 bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); 788#endif 789#ifdef CONFIG_DEBUG_DOUBLEFAULT_RESET 790 bfin_write_SWRST(_bfin_swrst | DOUBLE_FAULT); 791#endif 792 793 if (_bfin_swrst & RESET_DOUBLE) { 794 printk(KERN_EMERG "Recovering from DOUBLE FAULT event\n"); 795#ifdef CONFIG_DEBUG_DOUBLEFAULT 796 /* We assume the crashing kernel, and the current symbol table match */ 797 printk(KERN_EMERG " While handling exception (EXCAUSE = 0x%x) at %pF\n", 798 (int)init_saved_seqstat & SEQSTAT_EXCAUSE, init_saved_retx); 799 printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %pF\n", init_saved_dcplb_fault_addr); 800 printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %pF\n", init_saved_icplb_fault_addr); 801#endif 802 printk(KERN_NOTICE " The instruction at %pF caused a double exception\n", 803 init_retx); 804 } else if (_bfin_swrst & RESET_WDOG) 805 printk(KERN_INFO "Recovering from Watchdog event\n"); 806 else if (_bfin_swrst & RESET_SOFTWARE) 807 printk(KERN_NOTICE "Reset caused by Software reset\n"); 808 809 printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n"); 810 if (bfin_compiled_revid() == 0xffff) 811 printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); 812 else if (bfin_compiled_revid() == -1) 813 printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU); 814 else 815 printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); 816 if (bfin_revid() != bfin_compiled_revid()) { 817 if (bfin_compiled_revid() == -1) 818 printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n", 819 bfin_revid()); 820 else if (bfin_compiled_revid() != 0xffff) 821 printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", 822 bfin_compiled_revid(), bfin_revid()); 823 } 824 if (bfin_revid() <= CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) 825 printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", 826 CPU, bfin_revid()); 827 828 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); 829 830 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", 831 cclk / 1000000, sclk / 1000000); 832 833 if (ANOMALY_05000273 && (cclk >> 1) <= sclk) 834 printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); 835 836 setup_bootmem_allocator(); 837 838 paging_init(); 839 840 /* Copy atomic sequences to their fixed location, and sanity check that 841 these locations are the ones that we advertise to userspace. */ 842 memcpy((void *)FIXED_CODE_START, &fixed_code_start, 843 FIXED_CODE_END - FIXED_CODE_START); 844 BUG_ON((char *)&sigreturn_stub - (char *)&fixed_code_start 845 != SIGRETURN_STUB - FIXED_CODE_START); 846 BUG_ON((char *)&atomic_xchg32 - (char *)&fixed_code_start 847 != ATOMIC_XCHG32 - FIXED_CODE_START); 848 BUG_ON((char *)&atomic_cas32 - (char *)&fixed_code_start 849 != ATOMIC_CAS32 - FIXED_CODE_START); 850 BUG_ON((char *)&atomic_add32 - (char *)&fixed_code_start 851 != ATOMIC_ADD32 - FIXED_CODE_START); 852 BUG_ON((char *)&atomic_sub32 - (char *)&fixed_code_start 853 != ATOMIC_SUB32 - FIXED_CODE_START); 854 BUG_ON((char *)&atomic_ior32 - (char *)&fixed_code_start 855 != ATOMIC_IOR32 - FIXED_CODE_START); 856 BUG_ON((char *)&atomic_and32 - (char *)&fixed_code_start 857 != ATOMIC_AND32 - FIXED_CODE_START); 858 BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start 859 != ATOMIC_XOR32 - FIXED_CODE_START); 860 BUG_ON((char *)&safe_user_instruction - (char *)&fixed_code_start 861 != SAFE_USER_INSTRUCTION - FIXED_CODE_START); 862 863 init_exception_vectors(); 864 bfin_cache_init(); 865} 866 867static int __init topology_init(void) 868{ 869 int cpu; 870 871 for_each_possible_cpu(cpu) { 872 struct cpu *c = &per_cpu(cpu_devices, cpu); 873 874 register_cpu(c, cpu); 875 } 876 877 return 0; 878} 879 880subsys_initcall(topology_init); 881 882/* Get the voltage input multiplier */ 883static u_long cached_vco_pll_ctl, cached_vco; 884static u_long get_vco(void) 885{ 886 u_long msel; 887 888 u_long pll_ctl = bfin_read_PLL_CTL(); 889 if (pll_ctl == cached_vco_pll_ctl) 890 return cached_vco; 891 else 892 cached_vco_pll_ctl = pll_ctl; 893 894 msel = (pll_ctl >> 9) & 0x3F; 895 if (0 == msel) 896 msel = 64; 897 898 cached_vco = CONFIG_CLKIN_HZ; 899 cached_vco >>= (1 & pll_ctl); /* DF bit */ 900 cached_vco *= msel; 901 return cached_vco; 902} 903 904/* Get the Core clock */ 905static u_long cached_cclk_pll_div, cached_cclk; 906u_long get_cclk(void) 907{ 908 u_long csel, ssel; 909 910 if (bfin_read_PLL_STAT() & 0x1) 911 return CONFIG_CLKIN_HZ; 912 913 ssel = bfin_read_PLL_DIV(); 914 if (ssel == cached_cclk_pll_div) 915 return cached_cclk; 916 else 917 cached_cclk_pll_div = ssel; 918 919 csel = ((ssel >> 4) & 0x03); 920 ssel &= 0xf; 921 if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ 922 cached_cclk = get_vco() / ssel; 923 else 924 cached_cclk = get_vco() >> csel; 925 return cached_cclk; 926} 927EXPORT_SYMBOL(get_cclk); 928 929/* Get the System clock */ 930static u_long cached_sclk_pll_div, cached_sclk; 931u_long get_sclk(void) 932{ 933 u_long ssel; 934 935 if (bfin_read_PLL_STAT() & 0x1) 936 return CONFIG_CLKIN_HZ; 937 938 ssel = bfin_read_PLL_DIV(); 939 if (ssel == cached_sclk_pll_div) 940 return cached_sclk; 941 else 942 cached_sclk_pll_div = ssel; 943 944 ssel &= 0xf; 945 if (0 == ssel) { 946 printk(KERN_WARNING "Invalid System Clock\n"); 947 ssel = 1; 948 } 949 950 cached_sclk = get_vco() / ssel; 951 return cached_sclk; 952} 953EXPORT_SYMBOL(get_sclk); 954 955unsigned long sclk_to_usecs(unsigned long sclk) 956{ 957 u64 tmp = USEC_PER_SEC * (u64)sclk; 958 do_div(tmp, get_sclk()); 959 return tmp; 960} 961EXPORT_SYMBOL(sclk_to_usecs); 962 963unsigned long usecs_to_sclk(unsigned long usecs) 964{ 965 u64 tmp = get_sclk() * (u64)usecs; 966 do_div(tmp, USEC_PER_SEC); 967 return tmp; 968} 969EXPORT_SYMBOL(usecs_to_sclk); 970 971/* 972 * Get CPU information for use by the procfs. 973 */ 974static int show_cpuinfo(struct seq_file *m, void *v) 975{ 976 char *cpu, *mmu, *fpu, *vendor, *cache; 977 uint32_t revid; 978 979 u_long cclk = 0, sclk = 0; 980 u_int icache_size = BFIN_ICACHESIZE / 1024, dcache_size = 0, dsup_banks = 0; 981 982 cpu = CPU; 983 mmu = "none"; 984 fpu = "none"; 985 revid = bfin_revid(); 986 987 cclk = get_cclk(); 988 sclk = get_sclk(); 989 990 switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) { 991 case 0xca: 992 vendor = "Analog Devices"; 993 break; 994 default: 995 vendor = "unknown"; 996 break; 997 } 998 999 seq_printf(m, "processor\t: %d\n" 1000 "vendor_id\t: %s\n" 1001 "cpu family\t: 0x%x\n" 1002 "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n" 1003 "stepping\t: %d\n", 1004 *(unsigned int *)v, 1005 vendor, 1006 (bfin_read_CHIPID() & CHIPID_FAMILY), 1007 cpu, cclk/1000000, sclk/1000000, 1008#ifdef CONFIG_MPU 1009 "mpu on", 1010#else 1011 "mpu off", 1012#endif 1013 revid); 1014 1015 seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n", 1016 cclk/1000000, cclk%1000000, 1017 sclk/1000000, sclk%1000000); 1018 seq_printf(m, "bogomips\t: %lu.%02lu\n" 1019 "Calibration\t: %lu loops\n", 1020 (loops_per_jiffy * HZ) / 500000, 1021 ((loops_per_jiffy * HZ) / 5000) % 100, 1022 (loops_per_jiffy * HZ)); 1023 1024 /* Check Cache configutation */ 1025 switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { 1026 case ACACHE_BSRAM: 1027 cache = "dbank-A/B\t: cache/sram"; 1028 dcache_size = 16; 1029 dsup_banks = 1; 1030 break; 1031 case ACACHE_BCACHE: 1032 cache = "dbank-A/B\t: cache/cache"; 1033 dcache_size = 32; 1034 dsup_banks = 2; 1035 break; 1036 case ASRAM_BSRAM: 1037 cache = "dbank-A/B\t: sram/sram"; 1038 dcache_size = 0; 1039 dsup_banks = 0; 1040 break; 1041 default: 1042 cache = "unknown"; 1043 dcache_size = 0; 1044 dsup_banks = 0; 1045 break; 1046 } 1047 1048 /* Is it turned on? */ 1049 if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) 1050 dcache_size = 0; 1051 1052 if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) != (IMC | ENICPLB)) 1053 icache_size = 0; 1054 1055 seq_printf(m, "cache size\t: %d KB(L1 icache) " 1056 "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", 1057 icache_size, dcache_size, 1058#if defined CONFIG_BFIN_WB 1059 "wb" 1060#elif defined CONFIG_BFIN_WT 1061 "wt" 1062#endif 1063 "", 0); 1064 1065 seq_printf(m, "%s\n", cache); 1066 1067 if (icache_size) 1068 seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", 1069 BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); 1070 else 1071 seq_printf(m, "icache setup\t: off\n"); 1072 1073 seq_printf(m, 1074 "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", 1075 dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, 1076 BFIN_DLINES); 1077#ifdef CONFIG_BFIN_ICACHE_LOCK 1078 switch ((bfin_read_IMEM_CONTROL() >> 3) & WAYALL_L) { 1079 case WAY0_L: 1080 seq_printf(m, "Way0 Locked-Down\n"); 1081 break; 1082 case WAY1_L: 1083 seq_printf(m, "Way1 Locked-Down\n"); 1084 break; 1085 case WAY01_L: 1086 seq_printf(m, "Way0,Way1 Locked-Down\n"); 1087 break; 1088 case WAY2_L: 1089 seq_printf(m, "Way2 Locked-Down\n"); 1090 break; 1091 case WAY02_L: 1092 seq_printf(m, "Way0,Way2 Locked-Down\n"); 1093 break; 1094 case WAY12_L: 1095 seq_printf(m, "Way1,Way2 Locked-Down\n"); 1096 break; 1097 case WAY012_L: 1098 seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n"); 1099 break; 1100 case WAY3_L: 1101 seq_printf(m, "Way3 Locked-Down\n"); 1102 break; 1103 case WAY03_L: 1104 seq_printf(m, "Way0,Way3 Locked-Down\n"); 1105 break; 1106 case WAY13_L: 1107 seq_printf(m, "Way1,Way3 Locked-Down\n"); 1108 break; 1109 case WAY013_L: 1110 seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n"); 1111 break; 1112 case WAY32_L: 1113 seq_printf(m, "Way3,Way2 Locked-Down\n"); 1114 break; 1115 case WAY320_L: 1116 seq_printf(m, "Way3,Way2,Way0 Locked-Down\n"); 1117 break; 1118 case WAY321_L: 1119 seq_printf(m, "Way3,Way2,Way1 Locked-Down\n"); 1120 break; 1121 case WAYALL_L: 1122 seq_printf(m, "All Ways are locked\n"); 1123 break; 1124 default: 1125 seq_printf(m, "No Ways are locked\n"); 1126 } 1127#endif 1128 seq_printf(m, "board name\t: %s\n", bfin_board_name); 1129 seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n", 1130 physical_mem_end >> 10, (void *)0, (void *)physical_mem_end); 1131 seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n", 1132 ((int)memory_end - (int)_stext) >> 10, 1133 _stext, 1134 (void *)memory_end); 1135 1136 return 0; 1137} 1138 1139static void *c_start(struct seq_file *m, loff_t *pos) 1140{ 1141 if (*pos == 0) 1142 *pos = first_cpu(cpu_online_map); 1143 if (*pos >= num_online_cpus()) 1144 return NULL; 1145 1146 return pos; 1147} 1148 1149static void *c_next(struct seq_file *m, void *v, loff_t *pos) 1150{ 1151 *pos = next_cpu(*pos, cpu_online_map); 1152 1153 return c_start(m, pos); 1154} 1155 1156static void c_stop(struct seq_file *m, void *v) 1157{ 1158} 1159 1160const struct seq_operations cpuinfo_op = { 1161 .start = c_start, 1162 .next = c_next, 1163 .stop = c_stop, 1164 .show = show_cpuinfo, 1165}; 1166 1167void __init cmdline_init(const char *r0) 1168{ 1169 if (r0) 1170 strncpy(command_line, r0, COMMAND_LINE_SIZE); 1171} 1172