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