cvmx-app-init.c revision 232812
1289848Sjkim/***********************license start*************** 2289848Sjkim * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 3289848Sjkim * reserved. 4289848Sjkim * 5289848Sjkim * 6289848Sjkim * Redistribution and use in source and binary forms, with or without 7289848Sjkim * modification, are permitted provided that the following conditions are 8289848Sjkim * met: 9289848Sjkim * 10289848Sjkim * * Redistributions of source code must retain the above copyright 11289848Sjkim * notice, this list of conditions and the following disclaimer. 12289848Sjkim * 13289848Sjkim * * Redistributions in binary form must reproduce the above 14289848Sjkim * copyright notice, this list of conditions and the following 15289848Sjkim * disclaimer in the documentation and/or other materials provided 16289848Sjkim * with the distribution. 17289848Sjkim 18289848Sjkim * * Neither the name of Cavium Inc. nor the names of 19289848Sjkim * its contributors may be used to endorse or promote products 20289848Sjkim * derived from this software without specific prior written 21289848Sjkim * permission. 22289848Sjkim 23289848Sjkim * This Software, including technical data, may be subject to U.S. export control 24289848Sjkim * laws, including the U.S. Export Administration Act and its associated 25289848Sjkim * regulations, and may be subject to export or import regulations in other 26289848Sjkim * countries. 27289848Sjkim 28289848Sjkim * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29289848Sjkim * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 30289848Sjkim * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31289848Sjkim * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32289848Sjkim * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33289848Sjkim * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34289848Sjkim * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35289848Sjkim * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36289848Sjkim * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37289848Sjkim * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38289848Sjkim ***********************license end**************************************/ 39289848Sjkim 40289848Sjkim 41289848Sjkim 42289848Sjkim 43289848Sjkim 44289848Sjkim 45289848Sjkim 46289848Sjkim#include <stdio.h> 47289848Sjkim#include <stdint.h> 48289848Sjkim#include <stdlib.h> 49289848Sjkim#include <string.h> 50289848Sjkim#include "executive-config.h" 51289848Sjkim#include "cvmx-config.h" 52289848Sjkim#include "cvmx.h" 53289848Sjkim#include "cvmx-spinlock.h" 54289848Sjkim#include <octeon-app-init.h> 55289848Sjkim#include "cvmx-sysinfo.h" 56289848Sjkim#include "cvmx-bootmem.h" 57289848Sjkim#include "cvmx-uart.h" 58289848Sjkim#include "cvmx-coremask.h" 59289848Sjkim#include "cvmx-core.h" 60289848Sjkim#include "cvmx-interrupt.h" 61289848Sjkim#include "cvmx-ebt3000.h" 62289848Sjkim#include "cvmx-sim-magic.h" 63289848Sjkim#include "cvmx-debug.h" 64289848Sjkim#include "cvmx-qlm.h" 65289848Sjkim#include "cvmx-scratch.h" 66289848Sjkim#include "cvmx-helper-cfg.h" 67289848Sjkim#include "cvmx-helper-jtag.h" 68289848Sjkim#include <octeon_mem_map.h> 69#include "libfdt.h" 70int cvmx_debug_uart = -1; 71 72/** 73 * @file 74 * 75 * Main entry point for all simple executive based programs. 76 */ 77 78 79extern void cvmx_interrupt_initialize(void); 80 81 82 83/** 84 * Main entry point for all simple executive based programs. 85 * This is the first C function called. It completes 86 * initialization, calls main, and performs C level cleanup. 87 * 88 * @param app_desc_addr 89 * Address of the application description structure passed 90 * brom the boot loader. 91 */ 92EXTERN_ASM void __cvmx_app_init(uint64_t app_desc_addr); 93 94 95/** 96 * Set up sysinfo structure from boot descriptor versions 6 and higher. 97 * In these versions, the interesting data in not in the boot info structure 98 * defined by the toolchain, but is in the cvmx_bootinfo structure defined in 99 * the simple exec. 100 * 101 * @param app_desc_ptr 102 * pointer to boot descriptor block 103 * 104 * @param sys_info_ptr 105 * pointer to sysinfo structure to fill in 106 */ 107static void process_boot_desc_ver_6(octeon_boot_descriptor_t *app_desc_ptr, cvmx_sysinfo_t *sys_info_ptr) 108{ 109 cvmx_bootinfo_t *cvmx_bootinfo_ptr = CASTPTR(cvmx_bootinfo_t, app_desc_ptr->cvmx_desc_vaddr); 110 111 /* copy application information for simple exec use */ 112 /* Populate the sys_info structure from the boot descriptor block created by the bootloader. 113 ** The boot descriptor block is put in the top of the heap, so it will be overwritten when the 114 ** heap is fully used. Information that is to be used must be copied before that. 115 ** Applications should only use the sys_info structure, not the boot descriptor 116 */ 117 if (cvmx_bootinfo_ptr->major_version == 1) 118 { 119 sys_info_ptr->core_mask = cvmx_bootinfo_ptr->core_mask; 120 sys_info_ptr->heap_base = cvmx_bootinfo_ptr->heap_base; 121 sys_info_ptr->heap_size = cvmx_bootinfo_ptr->heap_end - cvmx_bootinfo_ptr->heap_base; 122 sys_info_ptr->stack_top = cvmx_bootinfo_ptr->stack_top; 123 sys_info_ptr->stack_size = cvmx_bootinfo_ptr->stack_size; 124 sys_info_ptr->init_core = cvmx_get_core_num(); 125 sys_info_ptr->phy_mem_desc_addr = cvmx_bootinfo_ptr->phy_mem_desc_addr; 126 sys_info_ptr->exception_base_addr = cvmx_bootinfo_ptr->exception_base_addr; 127 sys_info_ptr->cpu_clock_hz = cvmx_bootinfo_ptr->eclock_hz; 128 sys_info_ptr->dram_data_rate_hz = cvmx_bootinfo_ptr->dclock_hz * 2; 129 130 sys_info_ptr->board_type = cvmx_bootinfo_ptr->board_type; 131 sys_info_ptr->board_rev_major = cvmx_bootinfo_ptr->board_rev_major; 132 sys_info_ptr->board_rev_minor = cvmx_bootinfo_ptr->board_rev_minor; 133 memcpy(sys_info_ptr->mac_addr_base, cvmx_bootinfo_ptr->mac_addr_base, 6); 134 sys_info_ptr->mac_addr_count = cvmx_bootinfo_ptr->mac_addr_count; 135 memcpy(sys_info_ptr->board_serial_number, cvmx_bootinfo_ptr->board_serial_number, CVMX_BOOTINFO_OCTEON_SERIAL_LEN); 136 sys_info_ptr->console_uart_num = 0; 137 if (cvmx_bootinfo_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) 138 sys_info_ptr->console_uart_num = 1; 139 140 if (cvmx_bootinfo_ptr->dram_size > 32*1024*1024) 141 sys_info_ptr->system_dram_size = (uint64_t)cvmx_bootinfo_ptr->dram_size; /* older bootloaders incorrectly gave this in bytes, so don't convert */ 142 else 143 sys_info_ptr->system_dram_size = (uint64_t)cvmx_bootinfo_ptr->dram_size * 1024 * 1024; /* convert from Megabytes to bytes */ 144 if (cvmx_bootinfo_ptr->minor_version >= 1) 145 { 146 sys_info_ptr->compact_flash_common_base_addr = cvmx_bootinfo_ptr->compact_flash_common_base_addr; 147 sys_info_ptr->compact_flash_attribute_base_addr = cvmx_bootinfo_ptr->compact_flash_attribute_base_addr; 148 sys_info_ptr->led_display_base_addr = cvmx_bootinfo_ptr->led_display_base_addr; 149 } 150 else if (sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT3000 || 151 sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT5800 || 152 sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT5810) 153 { 154 /* Default these variables so that users of structure can be the same no 155 ** matter what version fo boot info block the bootloader passes */ 156 sys_info_ptr->compact_flash_common_base_addr = 0x1d000000 + 0x800; 157 sys_info_ptr->compact_flash_attribute_base_addr = 0x1d010000; 158 if (sys_info_ptr->board_rev_major == 1) 159 sys_info_ptr->led_display_base_addr = 0x1d020000; 160 else 161 sys_info_ptr->led_display_base_addr = 0x1d020000 + 0xf8; 162 } 163 else 164 { 165 sys_info_ptr->compact_flash_common_base_addr = 0; 166 sys_info_ptr->compact_flash_attribute_base_addr = 0; 167 sys_info_ptr->led_display_base_addr = 0; 168 } 169 170 if (cvmx_bootinfo_ptr->minor_version >= 2) 171 { 172 sys_info_ptr->dfa_ref_clock_hz = cvmx_bootinfo_ptr->dfa_ref_clock_hz; 173 sys_info_ptr->bootloader_config_flags = cvmx_bootinfo_ptr->config_flags; 174 } 175 else 176 { 177 sys_info_ptr->dfa_ref_clock_hz = 0; 178 sys_info_ptr->bootloader_config_flags = 0; 179 if (app_desc_ptr->flags & OCTEON_BL_FLAG_DEBUG) 180 sys_info_ptr->bootloader_config_flags |= CVMX_BOOTINFO_CFG_FLAG_DEBUG; 181 if (app_desc_ptr->flags & OCTEON_BL_FLAG_NO_MAGIC) 182 sys_info_ptr->bootloader_config_flags |= CVMX_BOOTINFO_CFG_FLAG_NO_MAGIC; 183 } 184 185 } 186 else 187 { 188 printf("ERROR: Incompatible CVMX descriptor passed by bootloader: %d.%d\n", 189 (int)cvmx_bootinfo_ptr->major_version, (int)cvmx_bootinfo_ptr->minor_version); 190 exit(-1); 191 } 192 if ((cvmx_bootinfo_ptr->minor_version >= 3) && (cvmx_bootinfo_ptr->fdt_addr != 0)) 193 { 194 sys_info_ptr->fdt_addr = UNMAPPED_PTR(cvmx_bootinfo_ptr->fdt_addr); 195 if (fdt_check_header((const void *)sys_info_ptr->fdt_addr)) 196 { 197 printf("ERROR : Corrupt Device Tree.\n"); 198 exit(-1); 199 } 200 printf("Using device tree\n"); 201 } 202 else 203 { 204 sys_info_ptr->fdt_addr = 0; 205 } 206} 207 208 209/** 210 * Interrupt handler for calling exit on Control-C interrupts. 211 * 212 * @param irq_number IRQ interrupt number 213 * @param registers CPU registers at the time of the interrupt 214 * @param user_arg Unused user argument 215 */ 216static void process_break_interrupt(int irq_number, uint64_t registers[32], void *user_arg) 217{ 218 /* Exclude new functionality when building with older toolchains */ 219#if OCTEON_APP_INIT_H_VERSION >= 3 220 int uart = irq_number - CVMX_IRQ_UART0; 221 cvmx_uart_lsr_t lsrval; 222 223 /* Check for a Control-C interrupt from the console. This loop will eat 224 all input received on the uart */ 225 lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart)); 226 while (lsrval.s.dr) 227 { 228 int c = cvmx_read_csr(CVMX_MIO_UARTX_RBR(uart)); 229 if (c == '\003') 230 { 231 register uint64_t tmp; 232 233 /* Wait for an another Control-C if right now we have no 234 access to the console. After this point we hold the 235 lock and use a different lock to synchronize between 236 the memfile dumps from different cores. As a 237 consequence regular printfs *don't* work after this 238 point! */ 239 if (__octeon_uart_trylock () == 1) 240 return; 241 242 /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also 243 set the MCD0 to be not masked by this core so we know 244 the signal is received by someone */ 245 asm volatile ( 246 "dmfc0 %0, $22\n" 247 "ori %0, %0, 0x1110\n" 248 "dmtc0 %0, $22\n" 249 : "=r" (tmp)); 250 } 251 lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart)); 252 } 253#endif 254} 255 256/** 257 * This is the debug exception handler with "break". Before calling exit to 258 * dump the profile-feedback output it releases the lock on the console. 259 * This way if there is buffered data in stdout it can still be flushed. 260 * stdio is required to flush all output during an fread. 261 */ 262 263static void exit_on_break(void) 264{ 265#if OCTEON_APP_INIT_H_VERSION >= 4 266 unsigned int coremask = cvmx_sysinfo_get()->core_mask; 267 268 cvmx_coremask_barrier_sync(coremask); 269 if (cvmx_coremask_first_core(coremask)) 270 __octeon_uart_unlock(); 271#endif 272 273 exit(0); 274} 275 276/* Add string signature to applications so that we can easily tell what 277** Octeon revision they were compiled for. Don't make static to avoid unused 278** variable warning. */ 279#define xstr(s) str(s) 280#define str(s) #s 281 282int octeon_model_version_check(uint32_t chip_id); 283 284#define OMS xstr(OCTEON_MODEL) 285char octeon_rev_signature[] = 286#ifdef USE_RUNTIME_MODEL_CHECKS 287 "Compiled for runtime Octeon model checking"; 288#else 289 "Compiled for Octeon processor id: "OMS; 290#endif 291 292#define OCTEON_BL_FLAG_HPLUG_CORES (1 << 6) 293void __cvmx_app_init(uint64_t app_desc_addr) 294{ 295 /* App descriptor used by bootloader */ 296 octeon_boot_descriptor_t *app_desc_ptr = CASTPTR(octeon_boot_descriptor_t, app_desc_addr); 297 298 /* app info structure used by the simple exec */ 299 cvmx_sysinfo_t *sys_info_ptr = cvmx_sysinfo_get(); 300 int breakflag = 0; 301 302 //printf("coremask=%08x flags=%08x \n", app_desc_ptr->core_mask, app_desc_ptr->flags); 303 if (cvmx_coremask_first_core(app_desc_ptr->core_mask)) 304 { 305 /* Intialize the bootmem allocator with the descriptor that was provided by 306 * the bootloader 307 * IMPORTANT: All printfs must happen after this since PCI console uses named 308 * blocks. 309 */ 310 cvmx_bootmem_init(CASTPTR(cvmx_bootinfo_t, app_desc_ptr->cvmx_desc_vaddr)->phy_mem_desc_addr); 311 312 /* do once per application setup */ 313 if (app_desc_ptr->desc_version < 6) 314 { 315 printf("Obsolete bootloader, can't run application\n"); 316 exit(-1); 317 } 318 else 319 { 320 /* Handle all newer versions here.... */ 321 if (app_desc_ptr->desc_version > 7) 322 { 323 printf("Warning: newer boot descripter version than expected\n"); 324 } 325 process_boot_desc_ver_6(app_desc_ptr,sys_info_ptr); 326 327 } 328 329 /* 330 * set up the feature map and config. 331 */ 332 octeon_feature_init(); 333 334 __cvmx_helper_cfg_init(); 335 } 336 /* The flags varibale get copied over at some places and tracing the origins 337 found that 338 ** In octeon_setup_boot_desc_block 339 . cvmx_bootinfo_array[core].flags is initialized and the various bits are set 340 . cvmx_bootinfo_array[core].flags gets copied to boot_desc[core].flags 341 . Then boot_desc then get copied over to the end of the application heap and 342 boot_info_block_array[core].boot_descr_addr is set to point to the boot_desc 343 in heap. 344 ** In start_app boot_vect->boot_info_addr->boot_desc_addr is referenced and passed on 345 to octeon_setup_crt0_tlb() and this puts it into r16 346 ** In ctr0.S of the toolchain r16 is picked up and passed on as a parameter to 347 __cvmx_app_init 348 349 Note : boot_vect->boot_info_addr points to boot_info_block_array[core] and this 350 pointer is setup in octeon_setup_boot_vector() 351 */ 352 353 if (!(app_desc_ptr->flags & OCTEON_BL_FLAG_HPLUG_CORES)) 354 cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 355 356 357 breakflag = sys_info_ptr->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_BREAK; 358 359 /* No need to initialize bootmem, interrupts, interrupt handler and error handler 360 if version does not match. */ 361 if (cvmx_coremask_first_core(sys_info_ptr->core_mask)) 362 { 363 /* Check to make sure the Chip version matches the configured version */ 364 uint32_t chip_id = cvmx_get_proc_id(); 365 /* Make sure we can properly run on this chip */ 366 octeon_model_version_check(chip_id); 367 } 368 cvmx_interrupt_initialize(); 369 if (cvmx_coremask_first_core(sys_info_ptr->core_mask)) 370 { 371 int break_uart = 0; 372 unsigned int i; 373 374 if (breakflag && cvmx_debug_booted()) 375 { 376 printf("ERROR: Using debug and break together in not supported.\n"); 377 while (1) 378 ; 379 } 380 381 /* Search through the arguments for a break=X or a debug=X. */ 382 for (i = 0; i < app_desc_ptr->argc; i++) 383 { 384 const char *argv = CASTPTR(const char, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, app_desc_ptr->argv[i])); 385 if (strncmp(argv, "break=", 6) == 0) 386 break_uart = atoi(argv + 6); 387 else if (strncmp(argv, "debug=", 6) == 0) 388 cvmx_debug_uart = atoi(argv + 6); 389 } 390 391 if (breakflag) 392 { 393 int32_t *trampoline = CASTPTR(int32_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, BOOTLOADER_DEBUG_TRAMPOLINE)); 394 /* On debug exception, call exit_on_break from all cores. */ 395 *trampoline = (int32_t)(long)&exit_on_break; 396 cvmx_uart_enable_intr(break_uart, process_break_interrupt); 397 } 398 } 399 if ( !(app_desc_ptr->flags & OCTEON_BL_FLAG_HPLUG_CORES)) 400 cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 401 402 /* Clear BEV now that we have installed exception handlers. */ 403 uint64_t tmp; 404 asm volatile ( 405 " .set push \n" 406 " .set mips64 \n" 407 " .set noreorder \n" 408 " .set noat \n" 409 " mfc0 %[tmp], $12, 0 \n" 410 " li $at, 1 << 22 \n" 411 " not $at, $at \n" 412 " and %[tmp], $at \n" 413 " mtc0 %[tmp], $12, 0 \n" 414 " .set pop \n" 415 : [tmp] "=&r" (tmp) : ); 416 417 /* Set all cores to stop on MCD0 signals */ 418 asm volatile( 419 "dmfc0 %0, $22, 0\n" 420 "or %0, %0, 0x1100\n" 421 "dmtc0 %0, $22, 0\n" : "=r" (tmp)); 422 423 CVMX_SYNC; 424 /* Now intialize the debug exception handler as BEV is cleared. */ 425 if ((!breakflag) && (!(app_desc_ptr->flags & OCTEON_BL_FLAG_HPLUG_CORES))) 426 cvmx_debug_init(); 427 428 /* Synchronise all cores at this point */ 429 if ( !(app_desc_ptr->flags & OCTEON_BL_FLAG_HPLUG_CORES)) 430 cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 431 432} 433 434int cvmx_user_app_init(void) 435{ 436 uint64_t bist_val; 437 uint64_t mask; 438 int bist_errors = 0; 439 uint64_t tmp; 440 uint64_t base_addr; 441 442 443 /* Put message on LED display */ 444 if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) 445 ebt3000_str_write("CVMX "); 446 447 /* Check BIST results for COP0 registers, some values only meaningful in pass 2 */ 448 CVMX_MF_CACHE_ERR(bist_val); 449 mask = (0x3fULL<<32); // Icache;BHT;AES;HSH/GFM;LRU;register file 450 bist_val &= mask; 451 if (bist_val) 452 { 453 printf("BIST FAILURE: COP0_CACHE_ERR: 0x%llx\n", (unsigned long long)bist_val); 454 bist_errors++; 455 } 456 457 mask = 0xfc00000000000000ull; 458 CVMX_MF_CVM_MEM_CTL(bist_val); 459 bist_val &= mask; 460 if (bist_val) 461 { 462 printf("BIST FAILURE: COP0_CVM_MEM_CTL: 0x%llx\n", (unsigned long long)bist_val); 463 bist_errors++; 464 } 465 466 /* Set up 4 cache lines of local memory, make available from Kernel space */ 467 CVMX_MF_CVM_MEM_CTL(tmp); 468 tmp &= ~0x1ffull; 469 tmp |= 0x104ull; 470 /* Set WBTHRESH=4 as per Core-14752 errata in cn63xxp1.X. */ 471 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 472 { 473 tmp &= ~(0xfull << 11); 474 tmp |= 4 << 11; 475 } 476 CVMX_MT_CVM_MEM_CTL(tmp); 477 478 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_X)) 479 { 480 /* Clear the lines of scratch memory configured, for 481 ** 63XX pass 2 errata Core-15169. */ 482 uint64_t addr; 483 unsigned num_lines; 484 CVMX_MF_CVM_MEM_CTL(tmp); 485 num_lines = tmp & 0x3f; 486 for (addr = 0; addr < CVMX_CACHE_LINE_SIZE * num_lines; addr += 8) 487 cvmx_scratch_write64(addr, 0); 488 } 489 490#if CVMX_USE_1_TO_1_TLB_MAPPINGS 491 492 /* Check to see if the bootloader is indicating that the application is outside 493 ** of the 0x10000000 0x20000000 range, in which case we can't use 1-1 mappings */ 494 if (cvmx_sysinfo_get()->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_OVERSIZE_TLB_MAPPING) 495 { 496 printf("ERROR: 1-1 TLB mappings configured and oversize application loaded.\n"); 497 printf("ERROR: Either 1-1 TLB mappings must be disabled or application size reduced.\n"); 498 exit(-1); 499 } 500 501 /* Create 1-1 Mappings for all DRAM up to 8 gigs, excluding the low 1 Megabyte. This area 502 ** is reserved for the bootloader and exception vectors. By not mapping this area, NULL pointer 503 ** dereferences will be caught with TLB exceptions. Exception handlers should be written 504 ** using XKPHYS or KSEG0 addresses. */ 505#if CVMX_NULL_POINTER_PROTECT 506 /* Exclude low 1 MByte from mapping to detect NULL pointer accesses. 507 ** The only down side of this is it uses more TLB mappings */ 508 cvmx_core_add_fixed_tlb_mapping_bits(0x0, 0x0, 0x100000 | TLB_DIRTY | TLB_VALID | TLB_GLOBAL, CVMX_TLB_PAGEMASK_1M); 509 cvmx_core_add_fixed_tlb_mapping(0x200000, 0x200000, 0x300000, CVMX_TLB_PAGEMASK_1M); 510 cvmx_core_add_fixed_tlb_mapping(0x400000, 0x400000, 0x500000, CVMX_TLB_PAGEMASK_1M); 511 cvmx_core_add_fixed_tlb_mapping(0x600000, 0x600000, 0x700000, CVMX_TLB_PAGEMASK_1M); 512 513 cvmx_core_add_fixed_tlb_mapping(0x800000, 0x800000, 0xC00000, CVMX_TLB_PAGEMASK_4M); 514 cvmx_core_add_fixed_tlb_mapping(0x1000000, 0x1000000, 0x1400000, CVMX_TLB_PAGEMASK_4M); 515 cvmx_core_add_fixed_tlb_mapping(0x1800000, 0x1800000, 0x1c00000, CVMX_TLB_PAGEMASK_4M); 516 517 cvmx_core_add_fixed_tlb_mapping(0x2000000, 0x2000000, 0x3000000, CVMX_TLB_PAGEMASK_16M); 518 cvmx_core_add_fixed_tlb_mapping(0x4000000, 0x4000000, 0x5000000, CVMX_TLB_PAGEMASK_16M); 519 cvmx_core_add_fixed_tlb_mapping(0x6000000, 0x6000000, 0x7000000, CVMX_TLB_PAGEMASK_16M); 520#else 521 /* Map entire low 128 Megs, including 0x0 */ 522 cvmx_core_add_fixed_tlb_mapping(0x0, 0x0, 0x4000000ULL, CVMX_TLB_PAGEMASK_64M); 523#endif 524 cvmx_core_add_fixed_tlb_mapping(0x8000000ULL, 0x8000000ULL, 0xc000000ULL, CVMX_TLB_PAGEMASK_64M); 525 526 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) 527 { 528 for (base_addr = 0x20000000ULL; base_addr < (cvmx_sysinfo_get()->system_dram_size + 0x10000000ULL); base_addr += 0x20000000ULL) 529 { 530 if (0 > cvmx_core_add_fixed_tlb_mapping(base_addr, base_addr, base_addr + 0x10000000ULL, CVMX_TLB_PAGEMASK_256M)) 531 { 532 printf("ERROR adding 1-1 TLB mapping for address 0x%llx\n", (unsigned long long)base_addr); 533 /* Exit from here, as expected memory mappings aren't set 534 up if this fails */ 535 exit(-1); 536 } 537 } 538 } 539 else 540 { 541 /* Create 1-1 mapping for next 256 megs 542 ** bottom page is not valid */ 543 cvmx_core_add_fixed_tlb_mapping_bits(0x400000000ULL, 0, 0x410000000ULL | TLB_DIRTY | TLB_VALID | TLB_GLOBAL, CVMX_TLB_PAGEMASK_256M); 544 545 /* Map from 0.5 up to the installed memory size in 512 MByte chunks. If this loop runs out of memory, 546 ** the NULL pointer detection can be disabled to free up more TLB entries. */ 547 if (cvmx_sysinfo_get()->system_dram_size > 0x20000000ULL) 548 { 549 for (base_addr = 0x20000000ULL; base_addr <= (cvmx_sysinfo_get()->system_dram_size - 0x20000000ULL); base_addr += 0x20000000ULL) 550 { 551 if (0 > cvmx_core_add_fixed_tlb_mapping(base_addr, base_addr, base_addr + 0x10000000ULL, CVMX_TLB_PAGEMASK_256M)) 552 { 553 printf("ERROR adding 1-1 TLB mapping for address 0x%llx\n", (unsigned long long)base_addr); 554 /* Exit from here, as expected memory mappings 555 aren't set up if this fails */ 556 exit(-1); 557 } 558 } 559 } 560 } 561#endif 562 563 564 cvmx_sysinfo_t *sys_info_ptr = cvmx_sysinfo_get(); 565 cvmx_bootmem_init(sys_info_ptr->phy_mem_desc_addr); 566 567 /* Initialize QLM and JTAG settings. Also apply any erratas. */ 568 if (cvmx_coremask_first_core(cvmx_sysinfo_get()->core_mask)) 569 cvmx_qlm_init(); 570 571 return(0); 572} 573 574void __cvmx_app_exit(void) 575{ 576 cvmx_debug_finish(); 577 578 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 579 { 580 CVMX_BREAK; 581 } 582 /* Hang forever, until more appropriate stand alone simple executive 583 exit() is implemented */ 584 585 while (1); 586} 587 588 589 590