cvmx-app-init.c revision 215990
1210284Sjmallett/***********************license start*************** 2215990Sjmallett * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 3215990Sjmallett * reserved. 4210284Sjmallett * 5210284Sjmallett * 6215990Sjmallett * Redistribution and use in source and binary forms, with or without 7215990Sjmallett * modification, are permitted provided that the following conditions are 8215990Sjmallett * met: 9210284Sjmallett * 10215990Sjmallett * * Redistributions of source code must retain the above copyright 11215990Sjmallett * notice, this list of conditions and the following disclaimer. 12210284Sjmallett * 13215990Sjmallett * * Redistributions in binary form must reproduce the above 14215990Sjmallett * copyright notice, this list of conditions and the following 15215990Sjmallett * disclaimer in the documentation and/or other materials provided 16215990Sjmallett * with the distribution. 17215990Sjmallett 18215990Sjmallett * * Neither the name of Cavium Networks nor the names of 19215990Sjmallett * its contributors may be used to endorse or promote products 20215990Sjmallett * derived from this software without specific prior written 21215990Sjmallett * permission. 22215990Sjmallett 23215990Sjmallett * This Software, including technical data, may be subject to U.S. export control 24215990Sjmallett * laws, including the U.S. Export Administration Act and its associated 25215990Sjmallett * regulations, and may be subject to export or import regulations in other 26215990Sjmallett * countries. 27215990Sjmallett 28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29215990Sjmallett * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38210284Sjmallett ***********************license end**************************************/ 39210284Sjmallett 40210284Sjmallett 41210284Sjmallett 42210284Sjmallett 43210284Sjmallett 44210284Sjmallett 45215990Sjmallett 46210284Sjmallett#include <stdio.h> 47210284Sjmallett#include <stdint.h> 48210284Sjmallett#include <stdlib.h> 49210284Sjmallett#include <string.h> 50210284Sjmallett#include "cvmx-config.h" 51210284Sjmallett#include "cvmx.h" 52210284Sjmallett#include "cvmx-spinlock.h" 53210284Sjmallett#include <octeon-app-init.h> 54210284Sjmallett#include "cvmx-sysinfo.h" 55210284Sjmallett#include "cvmx-bootmem.h" 56210284Sjmallett#include "cvmx-uart.h" 57210284Sjmallett#include "cvmx-coremask.h" 58210284Sjmallett#include "cvmx-core.h" 59210284Sjmallett#include "cvmx-interrupt.h" 60210284Sjmallett#include "cvmx-ebt3000.h" 61215990Sjmallett#include "cvmx-sim-magic.h" 62215990Sjmallett#include "cvmx-debug.h" 63210284Sjmallett#include "../../bootloader/u-boot/include/octeon_mem_map.h" 64210284Sjmallett 65215990Sjmallettint cvmx_debug_uart = -1; 66210284Sjmallett 67210284Sjmallett/** 68210284Sjmallett * @file 69210284Sjmallett * 70210284Sjmallett * Main entry point for all simple executive based programs. 71210284Sjmallett */ 72210284Sjmallett 73210284Sjmallett 74210284Sjmallettextern void cvmx_interrupt_initialize(void); 75210284Sjmallett 76210284Sjmallett 77210284Sjmallett 78210284Sjmallett/** 79210284Sjmallett * Main entry point for all simple executive based programs. 80210284Sjmallett * This is the first C function called. It completes 81210284Sjmallett * initialization, calls main, and performs C level cleanup. 82210284Sjmallett * 83210284Sjmallett * @param app_desc_addr 84210284Sjmallett * Address of the application description structure passed 85210284Sjmallett * brom the boot loader. 86210284Sjmallett */ 87210284SjmallettEXTERN_ASM void __cvmx_app_init(uint64_t app_desc_addr); 88210284Sjmallett 89210284Sjmallett 90210284Sjmallett/** 91210284Sjmallett * Set up sysinfo structure from boot descriptor versions 6 and higher. 92210284Sjmallett * In these versions, the interesting data in not in the boot info structure 93210284Sjmallett * defined by the toolchain, but is in the cvmx_bootinfo structure defined in 94210284Sjmallett * the simple exec. 95210284Sjmallett * 96210284Sjmallett * @param app_desc_ptr 97210284Sjmallett * pointer to boot descriptor block 98210284Sjmallett * 99210284Sjmallett * @param sys_info_ptr 100210284Sjmallett * pointer to sysinfo structure to fill in 101210284Sjmallett */ 102210284Sjmallettstatic void process_boot_desc_ver_6(octeon_boot_descriptor_t *app_desc_ptr, cvmx_sysinfo_t *sys_info_ptr) 103210284Sjmallett{ 104210284Sjmallett cvmx_bootinfo_t *cvmx_bootinfo_ptr = CASTPTR(cvmx_bootinfo_t, app_desc_ptr->cvmx_desc_vaddr); 105210284Sjmallett 106210284Sjmallett /* copy application information for simple exec use */ 107210284Sjmallett /* Populate the sys_info structure from the boot descriptor block created by the bootloader. 108210284Sjmallett ** The boot descriptor block is put in the top of the heap, so it will be overwritten when the 109210284Sjmallett ** heap is fully used. Information that is to be used must be copied before that. 110210284Sjmallett ** Applications should only use the sys_info structure, not the boot descriptor 111210284Sjmallett */ 112210284Sjmallett if (cvmx_bootinfo_ptr->major_version == 1) 113210284Sjmallett { 114210284Sjmallett sys_info_ptr->core_mask = cvmx_bootinfo_ptr->core_mask; 115210284Sjmallett sys_info_ptr->heap_base = cvmx_bootinfo_ptr->heap_base; 116210284Sjmallett sys_info_ptr->heap_size = cvmx_bootinfo_ptr->heap_end - cvmx_bootinfo_ptr->heap_base; 117210284Sjmallett sys_info_ptr->stack_top = cvmx_bootinfo_ptr->stack_top; 118210284Sjmallett sys_info_ptr->stack_size = cvmx_bootinfo_ptr->stack_size; 119210284Sjmallett sys_info_ptr->init_core = cvmx_get_core_num(); 120215990Sjmallett sys_info_ptr->phy_mem_desc_addr = cvmx_bootinfo_ptr->phy_mem_desc_addr; 121210284Sjmallett sys_info_ptr->exception_base_addr = cvmx_bootinfo_ptr->exception_base_addr; 122210284Sjmallett sys_info_ptr->cpu_clock_hz = cvmx_bootinfo_ptr->eclock_hz; 123210284Sjmallett sys_info_ptr->dram_data_rate_hz = cvmx_bootinfo_ptr->dclock_hz * 2; 124210284Sjmallett 125210284Sjmallett sys_info_ptr->board_type = cvmx_bootinfo_ptr->board_type; 126210284Sjmallett sys_info_ptr->board_rev_major = cvmx_bootinfo_ptr->board_rev_major; 127210284Sjmallett sys_info_ptr->board_rev_minor = cvmx_bootinfo_ptr->board_rev_minor; 128210284Sjmallett memcpy(sys_info_ptr->mac_addr_base, cvmx_bootinfo_ptr->mac_addr_base, 6); 129210284Sjmallett sys_info_ptr->mac_addr_count = cvmx_bootinfo_ptr->mac_addr_count; 130210284Sjmallett memcpy(sys_info_ptr->board_serial_number, cvmx_bootinfo_ptr->board_serial_number, CVMX_BOOTINFO_OCTEON_SERIAL_LEN); 131210284Sjmallett sys_info_ptr->console_uart_num = 0; 132210284Sjmallett if (cvmx_bootinfo_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) 133210284Sjmallett sys_info_ptr->console_uart_num = 1; 134210284Sjmallett 135215990Sjmallett if (cvmx_bootinfo_ptr->dram_size > 32*1024*1024) 136210284Sjmallett sys_info_ptr->system_dram_size = (uint64_t)cvmx_bootinfo_ptr->dram_size; /* older bootloaders incorrectly gave this in bytes, so don't convert */ 137210284Sjmallett else 138210284Sjmallett sys_info_ptr->system_dram_size = (uint64_t)cvmx_bootinfo_ptr->dram_size * 1024 * 1024; /* convert from Megabytes to bytes */ 139210284Sjmallett if (cvmx_bootinfo_ptr->minor_version >= 1) 140210284Sjmallett { 141210284Sjmallett sys_info_ptr->compact_flash_common_base_addr = cvmx_bootinfo_ptr->compact_flash_common_base_addr; 142210284Sjmallett sys_info_ptr->compact_flash_attribute_base_addr = cvmx_bootinfo_ptr->compact_flash_attribute_base_addr; 143210284Sjmallett sys_info_ptr->led_display_base_addr = cvmx_bootinfo_ptr->led_display_base_addr; 144210284Sjmallett } 145210284Sjmallett else if (sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT3000 || 146215990Sjmallett sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT5800 || 147215990Sjmallett sys_info_ptr->board_type == CVMX_BOARD_TYPE_EBT5810) 148210284Sjmallett { 149210284Sjmallett /* Default these variables so that users of structure can be the same no 150210284Sjmallett ** matter what version fo boot info block the bootloader passes */ 151210284Sjmallett sys_info_ptr->compact_flash_common_base_addr = 0x1d000000 + 0x800; 152210284Sjmallett sys_info_ptr->compact_flash_attribute_base_addr = 0x1d010000; 153210284Sjmallett if (sys_info_ptr->board_rev_major == 1) 154210284Sjmallett sys_info_ptr->led_display_base_addr = 0x1d020000; 155210284Sjmallett else 156210284Sjmallett sys_info_ptr->led_display_base_addr = 0x1d020000 + 0xf8; 157210284Sjmallett } 158210284Sjmallett else 159210284Sjmallett { 160210284Sjmallett sys_info_ptr->compact_flash_common_base_addr = 0; 161210284Sjmallett sys_info_ptr->compact_flash_attribute_base_addr = 0; 162210284Sjmallett sys_info_ptr->led_display_base_addr = 0; 163210284Sjmallett } 164210284Sjmallett 165210284Sjmallett if (cvmx_bootinfo_ptr->minor_version >= 2) 166210284Sjmallett { 167210284Sjmallett sys_info_ptr->dfa_ref_clock_hz = cvmx_bootinfo_ptr->dfa_ref_clock_hz; 168210284Sjmallett sys_info_ptr->bootloader_config_flags = cvmx_bootinfo_ptr->config_flags; 169210284Sjmallett } 170210284Sjmallett else 171210284Sjmallett { 172210284Sjmallett sys_info_ptr->dfa_ref_clock_hz = 0; 173210284Sjmallett sys_info_ptr->bootloader_config_flags = 0; 174210284Sjmallett if (app_desc_ptr->flags & OCTEON_BL_FLAG_DEBUG) 175210284Sjmallett sys_info_ptr->bootloader_config_flags |= CVMX_BOOTINFO_CFG_FLAG_DEBUG; 176210284Sjmallett if (app_desc_ptr->flags & OCTEON_BL_FLAG_NO_MAGIC) 177210284Sjmallett sys_info_ptr->bootloader_config_flags |= CVMX_BOOTINFO_CFG_FLAG_NO_MAGIC; 178210284Sjmallett } 179210284Sjmallett 180210284Sjmallett } 181210284Sjmallett else 182210284Sjmallett { 183210284Sjmallett printf("ERROR: Incompatible CVMX descriptor passed by bootloader: %d.%d\n", 184210284Sjmallett (int)cvmx_bootinfo_ptr->major_version, (int)cvmx_bootinfo_ptr->minor_version); 185215990Sjmallett exit(-1); 186210284Sjmallett } 187210284Sjmallett} 188210284Sjmallett 189210284Sjmallett 190210284Sjmallett/** 191210284Sjmallett * Interrupt handler for calling exit on Control-C interrupts. 192210284Sjmallett * 193210284Sjmallett * @param irq_number IRQ interrupt number 194210284Sjmallett * @param registers CPU registers at the time of the interrupt 195210284Sjmallett * @param user_arg Unused user argument 196210284Sjmallett */ 197210284Sjmallettstatic void process_break_interrupt(int irq_number, uint64_t registers[32], void *user_arg) 198210284Sjmallett{ 199210284Sjmallett /* Exclude new functionality when building with older toolchains */ 200210284Sjmallett#if OCTEON_APP_INIT_H_VERSION >= 3 201210284Sjmallett int uart = irq_number - CVMX_IRQ_UART0; 202210284Sjmallett cvmx_uart_lsr_t lsrval; 203210284Sjmallett 204210284Sjmallett /* Check for a Control-C interrupt from the console. This loop will eat 205210284Sjmallett all input received on the uart */ 206210284Sjmallett lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart)); 207210284Sjmallett while (lsrval.s.dr) 208210284Sjmallett { 209210284Sjmallett int c = cvmx_read_csr(CVMX_MIO_UARTX_RBR(uart)); 210210284Sjmallett if (c == '\003') 211210284Sjmallett { 212210284Sjmallett register uint64_t tmp; 213210284Sjmallett 214210284Sjmallett /* Wait for an another Control-C if right now we have no 215210284Sjmallett access to the console. After this point we hold the 216210284Sjmallett lock and use a different lock to synchronize between 217210284Sjmallett the memfile dumps from different cores. As a 218210284Sjmallett consequence regular printfs *don't* work after this 219210284Sjmallett point! */ 220210284Sjmallett if (__octeon_uart_trylock () == 1) 221210284Sjmallett return; 222210284Sjmallett 223210284Sjmallett /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also 224210284Sjmallett set the MCD0 to be not masked by this core so we know 225210284Sjmallett the signal is received by someone */ 226210284Sjmallett asm volatile ( 227210284Sjmallett "dmfc0 %0, $22\n" 228210284Sjmallett "ori %0, %0, 0x1110\n" 229210284Sjmallett "dmtc0 %0, $22\n" 230210284Sjmallett : "=r" (tmp)); 231210284Sjmallett } 232210284Sjmallett lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(uart)); 233210284Sjmallett } 234210284Sjmallett#endif 235210284Sjmallett} 236210284Sjmallett 237210284Sjmallett/** 238210284Sjmallett * This is the debug exception handler with "break". Before calling exit to 239210284Sjmallett * dump the profile-feedback output it releases the lock on the console. 240210284Sjmallett * This way if there is buffered data in stdout it can still be flushed. 241210284Sjmallett * stdio is required to flush all output during an fread. 242210284Sjmallett */ 243210284Sjmallett 244210284Sjmallettstatic void exit_on_break(void) 245210284Sjmallett{ 246210284Sjmallett#if OCTEON_APP_INIT_H_VERSION >= 4 247210284Sjmallett unsigned int coremask = cvmx_sysinfo_get()->core_mask; 248210284Sjmallett 249210284Sjmallett cvmx_coremask_barrier_sync(coremask); 250210284Sjmallett if (cvmx_coremask_first_core(coremask)) 251210284Sjmallett __octeon_uart_unlock(); 252210284Sjmallett#endif 253210284Sjmallett 254210284Sjmallett exit(0); 255210284Sjmallett} 256210284Sjmallett 257210284Sjmallett/* Add string signature to applications so that we can easily tell what 258210284Sjmallett** Octeon revision they were compiled for. Don't make static to avoid unused 259210284Sjmallett** variable warning. */ 260210284Sjmallett#define xstr(s) str(s) 261210284Sjmallett#define str(s) #s 262210284Sjmallett 263210284Sjmallettint octeon_model_version_check(uint32_t chip_id); 264210284Sjmallett 265210284Sjmallett#define OMS xstr(OCTEON_MODEL) 266210284Sjmallettchar octeon_rev_signature[] = 267210284Sjmallett#ifdef USE_RUNTIME_MODEL_CHECKS 268210284Sjmallett "Compiled for runtime Octeon model checking"; 269210284Sjmallett#else 270210284Sjmallett "Compiled for Octeon processor id: "OMS; 271210284Sjmallett#endif 272210284Sjmallett 273210284Sjmallettvoid __cvmx_app_init(uint64_t app_desc_addr) 274210284Sjmallett{ 275210284Sjmallett /* App descriptor used by bootloader */ 276210284Sjmallett octeon_boot_descriptor_t *app_desc_ptr = CASTPTR(octeon_boot_descriptor_t, app_desc_addr); 277210284Sjmallett 278210284Sjmallett /* app info structure used by the simple exec */ 279210284Sjmallett cvmx_sysinfo_t *sys_info_ptr = cvmx_sysinfo_get(); 280215990Sjmallett int breakflag = 0; 281210284Sjmallett 282210284Sjmallett if (cvmx_coremask_first_core(app_desc_ptr->core_mask)) 283210284Sjmallett { 284210284Sjmallett /* do once per application setup */ 285210284Sjmallett if (app_desc_ptr->desc_version < 6) 286210284Sjmallett { 287210284Sjmallett printf("Obsolete bootloader, can't run application\n"); 288215990Sjmallett exit(-1); 289210284Sjmallett } 290210284Sjmallett else 291210284Sjmallett { 292210284Sjmallett /* Handle all newer versions here.... */ 293210284Sjmallett if (app_desc_ptr->desc_version > 7) 294210284Sjmallett { 295210284Sjmallett printf("Warning: newer boot descripter version than expected\n"); 296210284Sjmallett } 297210284Sjmallett process_boot_desc_ver_6(app_desc_ptr,sys_info_ptr); 298210284Sjmallett 299210284Sjmallett } 300210284Sjmallett } 301210284Sjmallett cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 302210284Sjmallett 303215990Sjmallett breakflag = sys_info_ptr->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_BREAK; 304215990Sjmallett 305215990Sjmallett /* No need to initialize bootmem, interrupts, interrupt handler and error handler 306215990Sjmallett if version does not match. */ 307215990Sjmallett if (cvmx_coremask_first_core(sys_info_ptr->core_mask)) 308210284Sjmallett { 309215990Sjmallett /* Check to make sure the Chip version matches the configured version */ 310215990Sjmallett uint32_t chip_id = cvmx_get_proc_id(); 311215990Sjmallett /* Make sure we can properly run on this chip */ 312215990Sjmallett octeon_model_version_check(chip_id); 313210284Sjmallett } 314210284Sjmallett 315210284Sjmallett cvmx_interrupt_initialize(); 316210284Sjmallett 317210284Sjmallett if (cvmx_coremask_first_core(sys_info_ptr->core_mask)) 318210284Sjmallett { 319215990Sjmallett int break_uart = 0; 320215990Sjmallett unsigned int i; 321210284Sjmallett 322210284Sjmallett /* Intialize the bootmem allocator with the descriptor that was provided by 323215990Sjmallett * the bootloader 324215990Sjmallett * IMPORTANT: All printfs must happen after this since PCI console uses named 325215990Sjmallett * blocks. 326215990Sjmallett */ 327215990Sjmallett cvmx_bootmem_init(sys_info_ptr->phy_mem_desc_addr); 328215990Sjmallett if (breakflag && cvmx_debug_booted()) 329215990Sjmallett { 330215990Sjmallett printf("ERROR: Using debug and break together in not supported.\n"); 331215990Sjmallett while (1) 332215990Sjmallett ; 333215990Sjmallett } 334210284Sjmallett 335215990Sjmallett /* Search through the arguments for a break=X or a debug=X. */ 336215990Sjmallett for (i = 0; i < app_desc_ptr->argc; i++) 337215990Sjmallett { 338215990Sjmallett const char *argv = CASTPTR(const char, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, app_desc_ptr->argv[i])); 339215990Sjmallett if (strncmp(argv, "break=", 6) == 0) 340215990Sjmallett break_uart = atoi(argv + 6); 341215990Sjmallett else if (strncmp(argv, "debug=", 6) == 0) 342215990Sjmallett cvmx_debug_uart = atoi(argv + 6); 343215990Sjmallett } 344210284Sjmallett 345215990Sjmallett if (breakflag) 346210284Sjmallett { 347215990Sjmallett int32_t *trampoline = CASTPTR(int32_t, CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0, BOOTLOADER_DEBUG_TRAMPOLINE)); 348215990Sjmallett /* On debug exception, call exit_on_break from all cores. */ 349215990Sjmallett *trampoline = (int32_t)(long)&exit_on_break; 350215990Sjmallett cvmx_uart_enable_intr(break_uart, process_break_interrupt); 351210284Sjmallett } 352210284Sjmallett } 353210284Sjmallett 354215990Sjmallett cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 355215990Sjmallett 356210284Sjmallett /* Clear BEV now that we have installed exception handlers. */ 357210284Sjmallett uint64_t tmp; 358210284Sjmallett asm volatile ( 359210284Sjmallett " .set push \n" 360210284Sjmallett " .set mips64 \n" 361210284Sjmallett " .set noreorder \n" 362210284Sjmallett " .set noat \n" 363210284Sjmallett " mfc0 %[tmp], $12, 0 \n" 364210284Sjmallett " li $at, 1 << 22 \n" 365210284Sjmallett " not $at, $at \n" 366210284Sjmallett " and %[tmp], $at \n" 367210284Sjmallett " mtc0 %[tmp], $12, 0 \n" 368210284Sjmallett " .set pop \n" 369210284Sjmallett : [tmp] "=&r" (tmp) : ); 370210284Sjmallett 371210284Sjmallett /* Set all cores to stop on MCD0 signals */ 372210284Sjmallett asm volatile( 373210284Sjmallett "dmfc0 %0, $22, 0\n" 374210284Sjmallett "or %0, %0, 0x1100\n" 375210284Sjmallett "dmtc0 %0, $22, 0\n" : "=r" (tmp)); 376210284Sjmallett 377210284Sjmallett CVMX_SYNC; 378215990Sjmallett 379215990Sjmallett /* Now intialize the debug exception handler as BEV is cleared. */ 380215990Sjmallett if (!breakflag) 381215990Sjmallett cvmx_debug_init(); 382215990Sjmallett 383210284Sjmallett /* Synchronise all cores at this point */ 384210284Sjmallett cvmx_coremask_barrier_sync(app_desc_ptr->core_mask); 385210284Sjmallett 386210284Sjmallett} 387210284Sjmallett 388210284Sjmallettint cvmx_user_app_init(void) 389210284Sjmallett{ 390210284Sjmallett uint64_t bist_val; 391210284Sjmallett uint64_t mask; 392210284Sjmallett int bist_errors = 0; 393210284Sjmallett uint64_t tmp; 394210284Sjmallett uint64_t base_addr; 395210284Sjmallett 396210284Sjmallett 397210284Sjmallett /* Put message on LED display */ 398210284Sjmallett if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) 399210284Sjmallett ebt3000_str_write("CVMX "); 400210284Sjmallett 401210284Sjmallett /* Check BIST results for COP0 registers, some values only meaningful in pass 2 */ 402210284Sjmallett CVMX_MF_CACHE_ERR(bist_val); 403210284Sjmallett mask = (1ULL<<32) | (1ULL<<33) | (1ULL<<34) | (1ULL<<35) | (1ULL<<36); 404210284Sjmallett bist_val &= mask; 405210284Sjmallett if (bist_val) 406210284Sjmallett { 407210284Sjmallett printf("BIST FAILURE: COP0_CACHE_ERR: 0x%llx\n", (unsigned long long)bist_val); 408210284Sjmallett bist_errors++; 409210284Sjmallett } 410210284Sjmallett 411210284Sjmallett mask = 0xfc00000000000000ull; 412210284Sjmallett CVMX_MF_CVM_MEM_CTL(bist_val); 413210284Sjmallett bist_val &= mask; 414210284Sjmallett if (bist_val) 415210284Sjmallett { 416210284Sjmallett printf("BIST FAILURE: COP0_CVM_MEM_CTL: 0x%llx\n", (unsigned long long)bist_val); 417210284Sjmallett bist_errors++; 418210284Sjmallett } 419210284Sjmallett 420210284Sjmallett /* Set up 4 cache lines of local memory, make available from Kernel space */ 421210284Sjmallett CVMX_MF_CVM_MEM_CTL(tmp); 422210284Sjmallett tmp &= ~0x1ffull; 423210284Sjmallett tmp |= 0x104ull; 424215990Sjmallett /* Set WBTHRESH=4 as per Core-14752 errata in cn63xxp1.X. */ 425215990Sjmallett if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 426215990Sjmallett { 427215990Sjmallett tmp &= ~(0xfull << 11); 428215990Sjmallett tmp |= 4 << 11; 429215990Sjmallett } 430210284Sjmallett CVMX_MT_CVM_MEM_CTL(tmp); 431210284Sjmallett 432210284Sjmallett 433210284Sjmallett#if CVMX_USE_1_TO_1_TLB_MAPPINGS 434210284Sjmallett 435210284Sjmallett /* Check to see if the bootloader is indicating that the application is outside 436210284Sjmallett ** of the 0x10000000 0x20000000 range, in which case we can't use 1-1 mappings */ 437210284Sjmallett if (cvmx_sysinfo_get()->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_OVERSIZE_TLB_MAPPING) 438210284Sjmallett { 439210284Sjmallett printf("ERROR: 1-1 TLB mappings configured and oversize application loaded.\n"); 440210284Sjmallett printf("ERROR: Either 1-1 TLB mappings must be disabled or application size reduced.\n"); 441215990Sjmallett exit(-1); 442210284Sjmallett } 443210284Sjmallett 444210284Sjmallett /* Create 1-1 Mappings for all DRAM up to 8 gigs, excluding the low 1 Megabyte. This area 445210284Sjmallett ** is reserved for the bootloader and exception vectors. By not mapping this area, NULL pointer 446210284Sjmallett ** dereferences will be caught with TLB exceptions. Exception handlers should be written 447210284Sjmallett ** using XKPHYS or KSEG0 addresses. */ 448210284Sjmallett#if CVMX_NULL_POINTER_PROTECT 449210284Sjmallett /* Exclude low 1 MByte from mapping to detect NULL pointer accesses. 450210284Sjmallett ** The only down side of this is it uses more TLB mappings */ 451210284Sjmallett cvmx_core_add_fixed_tlb_mapping_bits(0x0, 0x0, 0x100000 | TLB_DIRTY | TLB_VALID | TLB_GLOBAL, CVMX_TLB_PAGEMASK_1M); 452210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x200000, 0x200000, 0x300000, CVMX_TLB_PAGEMASK_1M); 453210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x400000, 0x400000, 0x500000, CVMX_TLB_PAGEMASK_1M); 454210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x600000, 0x600000, 0x700000, CVMX_TLB_PAGEMASK_1M); 455210284Sjmallett 456210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x800000, 0x800000, 0xC00000, CVMX_TLB_PAGEMASK_4M); 457210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x1000000, 0x1000000, 0x1400000, CVMX_TLB_PAGEMASK_4M); 458210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x1800000, 0x1800000, 0x1c00000, CVMX_TLB_PAGEMASK_4M); 459210284Sjmallett 460210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x2000000, 0x2000000, 0x3000000, CVMX_TLB_PAGEMASK_16M); 461210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x4000000, 0x4000000, 0x5000000, CVMX_TLB_PAGEMASK_16M); 462210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x6000000, 0x6000000, 0x7000000, CVMX_TLB_PAGEMASK_16M); 463210284Sjmallett#else 464210284Sjmallett /* Map entire low 128 Megs, including 0x0 */ 465210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x0, 0x0, 0x4000000ULL, CVMX_TLB_PAGEMASK_64M); 466210284Sjmallett#endif 467210284Sjmallett cvmx_core_add_fixed_tlb_mapping(0x8000000ULL, 0x8000000ULL, 0xc000000ULL, CVMX_TLB_PAGEMASK_64M); 468210284Sjmallett 469215990Sjmallett if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) 470210284Sjmallett { 471215990Sjmallett for (base_addr = 0x20000000ULL; base_addr < (cvmx_sysinfo_get()->system_dram_size + 0x10000000ULL); base_addr += 0x20000000ULL) 472210284Sjmallett { 473210284Sjmallett if (0 > cvmx_core_add_fixed_tlb_mapping(base_addr, base_addr, base_addr + 0x10000000ULL, CVMX_TLB_PAGEMASK_256M)) 474210284Sjmallett { 475210284Sjmallett printf("ERROR adding 1-1 TLB mapping for address 0x%llx\n", (unsigned long long)base_addr); 476215990Sjmallett /* Exit from here, as expected memory mappings aren't set 477215990Sjmallett up if this fails */ 478215990Sjmallett exit(-1); 479210284Sjmallett } 480210284Sjmallett } 481210284Sjmallett } 482215990Sjmallett else 483215990Sjmallett { 484215990Sjmallett /* Create 1-1 mapping for next 256 megs 485215990Sjmallett ** bottom page is not valid */ 486215990Sjmallett cvmx_core_add_fixed_tlb_mapping_bits(0x400000000ULL, 0, 0x410000000ULL | TLB_DIRTY | TLB_VALID | TLB_GLOBAL, CVMX_TLB_PAGEMASK_256M); 487210284Sjmallett 488215990Sjmallett /* Map from 0.5 up to the installed memory size in 512 MByte chunks. If this loop runs out of memory, 489215990Sjmallett ** the NULL pointer detection can be disabled to free up more TLB entries. */ 490215990Sjmallett if (cvmx_sysinfo_get()->system_dram_size > 0x20000000ULL) 491215990Sjmallett { 492215990Sjmallett for (base_addr = 0x20000000ULL; base_addr <= (cvmx_sysinfo_get()->system_dram_size - 0x20000000ULL); base_addr += 0x20000000ULL) 493215990Sjmallett { 494215990Sjmallett if (0 > cvmx_core_add_fixed_tlb_mapping(base_addr, base_addr, base_addr + 0x10000000ULL, CVMX_TLB_PAGEMASK_256M)) 495215990Sjmallett { 496215990Sjmallett printf("ERROR adding 1-1 TLB mapping for address 0x%llx\n", (unsigned long long)base_addr); 497215990Sjmallett /* Exit from here, as expected memory mappings 498215990Sjmallett aren't set up if this fails */ 499215990Sjmallett exit(-1); 500215990Sjmallett } 501215990Sjmallett } 502215990Sjmallett } 503215990Sjmallett } 504210284Sjmallett#endif 505210284Sjmallett 506210284Sjmallett 507210284Sjmallett cvmx_sysinfo_t *sys_info_ptr = cvmx_sysinfo_get(); 508215990Sjmallett cvmx_bootmem_init(sys_info_ptr->phy_mem_desc_addr); 509210284Sjmallett 510210284Sjmallett return(0); 511210284Sjmallett} 512210284Sjmallett 513210284Sjmallettvoid __cvmx_app_exit(void) 514210284Sjmallett{ 515215990Sjmallett cvmx_debug_finish(); 516215990Sjmallett 517215990Sjmallett if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 518210284Sjmallett { 519215990Sjmallett CVMX_BREAK; 520215990Sjmallett } 521215990Sjmallett /* Hang forever, until more appropriate stand alone simple executive 522215990Sjmallett exit() is implemented */ 523210284Sjmallett 524215990Sjmallett while (1); 525210284Sjmallett} 526210284Sjmallett 527210284Sjmallett 528210284Sjmallett 529