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