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