1210284Sjmallett/***********************license start*************** 2232812Sjmallett * Copyright (c) 2003-2010 Cavium Inc. (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 18232812Sjmallett * * Neither the name of Cavium Inc. 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" 29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. 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/** 47210284Sjmallett * @file 48210284Sjmallett * 49210284Sjmallett * This module provides system/board/application information obtained by the bootloader. 50210284Sjmallett * 51232812Sjmallett * <hr>$Revision: 70030 $<hr> 52210284Sjmallett * 53210284Sjmallett */ 54210284Sjmallett 55215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 56215990Sjmallett#include <linux/module.h> 57215990Sjmallett 58215990Sjmallett#include <asm/octeon/cvmx.h> 59215990Sjmallett#include <asm/octeon/cvmx-spinlock.h> 60215990Sjmallett#include <asm/octeon/cvmx-sysinfo.h> 61215990Sjmallett#else 62210284Sjmallett#include "cvmx.h" 63210284Sjmallett#include "cvmx-spinlock.h" 64210284Sjmallett#include "cvmx-sysinfo.h" 65215990Sjmallett#endif 66210284Sjmallett 67210284Sjmallett 68210284Sjmallett/** 69210284Sjmallett * This structure defines the private state maintained by sysinfo module. 70210284Sjmallett * 71210284Sjmallett */ 72210284Sjmallett#if defined(CVMX_BUILD_FOR_UBOOT) && CONFIG_OCTEON_NAND_STAGE2 73210284Sjmallett/* For u-boot, put this in the text section so that we can use this in early 74210284Sjmallett** boot when running from ram(or L2 cache). This is primarily used for NAND 75210284Sjmallett** access during NAND boot. The 'data_in_text' section is merged with the 76210284Sjmallett** text section by the linker script to avoid an assembler warning. */ 77210284Sjmallettstatic struct { 78210284Sjmallett 79210284Sjmallett cvmx_sysinfo_t sysinfo; /**< system information */ 80210284Sjmallett cvmx_spinlock_t lock; /**< mutex spinlock */ 81210284Sjmallett 82210284Sjmallett} state __attribute__ ((section (".data_in_text"))) = { 83210284Sjmallett .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER 84210284Sjmallett}; 85210284Sjmallett#else 86210284SjmallettCVMX_SHARED static struct { 87210284Sjmallett 88215990Sjmallett struct cvmx_sysinfo sysinfo; /**< system information */ 89210284Sjmallett cvmx_spinlock_t lock; /**< mutex spinlock */ 90210284Sjmallett 91210284Sjmallett} state = { 92210284Sjmallett .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER 93210284Sjmallett}; 94210284Sjmallett#endif 95210284Sjmallett 96210284Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_USER 97210284Sjmallett/* Global variable with the processor ID since we can't read it directly */ 98210284SjmallettCVMX_SHARED uint32_t cvmx_app_init_processor_id; 99210284Sjmallett#endif 100210284Sjmallett 101210284Sjmallett/* Global variables that define the min/max of the memory region set up for 32 bit userspace access */ 102210284Sjmallettuint64_t linux_mem32_min = 0; 103210284Sjmallettuint64_t linux_mem32_max = 0; 104210284Sjmallettuint64_t linux_mem32_wired = 0; 105210284Sjmallettuint64_t linux_mem32_offset = 0; 106210284Sjmallett 107210284Sjmallett/** 108210284Sjmallett * This function returns the application information as obtained 109210284Sjmallett * by the bootloader. This provides the core mask of the cores 110210284Sjmallett * running the same application image, as well as the physical 111210284Sjmallett * memory regions available to the core. 112210284Sjmallett * 113210284Sjmallett * @return Pointer to the boot information structure 114210284Sjmallett * 115210284Sjmallett */ 116215990Sjmallettstruct cvmx_sysinfo *cvmx_sysinfo_get(void) 117210284Sjmallett{ 118210284Sjmallett return &(state.sysinfo); 119210284Sjmallett} 120232812Sjmallett 121232812Sjmallettvoid cvmx_sysinfo_add_self_to_core_mask(void) 122232812Sjmallett{ 123232812Sjmallett int core = cvmx_get_core_num(); 124232812Sjmallett uint32_t core_mask = 1 << core; 125232812Sjmallett 126232812Sjmallett cvmx_spinlock_lock(&state.lock); 127232812Sjmallett state.sysinfo.core_mask = state.sysinfo.core_mask | core_mask; 128232812Sjmallett cvmx_spinlock_unlock(&state.lock); 129232812Sjmallett} 130232812Sjmallett 131232812Sjmallettvoid cvmx_sysinfo_remove_self_from_core_mask(void) 132232812Sjmallett{ 133232812Sjmallett int core = cvmx_get_core_num(); 134232812Sjmallett uint32_t core_mask = 1 << core; 135232812Sjmallett 136232812Sjmallett cvmx_spinlock_lock(&state.lock); 137232812Sjmallett state.sysinfo.core_mask = state.sysinfo.core_mask & ~core_mask; 138232812Sjmallett cvmx_spinlock_unlock(&state.lock); 139232812Sjmallett} 140232812Sjmallett 141215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 142215990SjmallettEXPORT_SYMBOL(cvmx_sysinfo_get); 143215990Sjmallett#endif 144210284Sjmallett 145210284Sjmallett 146210284Sjmallett/** 147210284Sjmallett * This function is used in non-simple executive environments (such as Linux kernel, u-boot, etc.) 148210284Sjmallett * to configure the minimal fields that are required to use 149210284Sjmallett * simple executive files directly. 150210284Sjmallett * 151210284Sjmallett * Locking (if required) must be handled outside of this 152210284Sjmallett * function 153210284Sjmallett * 154215990Sjmallett * @param phy_mem_desc_addr 155215990Sjmallett * Address of the global physical memory descriptor (bootmem 156215990Sjmallett * descriptor) 157210284Sjmallett * @param board_type Octeon board type enumeration 158210284Sjmallett * 159210284Sjmallett * @param board_rev_major 160210284Sjmallett * Board major revision 161210284Sjmallett * @param board_rev_minor 162210284Sjmallett * Board minor revision 163210284Sjmallett * @param cpu_clock_hz 164210284Sjmallett * CPU clock freqency in hertz 165210284Sjmallett * 166210284Sjmallett * @return 0: Failure 167210284Sjmallett * 1: success 168210284Sjmallett */ 169215990Sjmallettint cvmx_sysinfo_minimal_initialize(uint64_t phy_mem_desc_addr, uint16_t board_type, uint8_t board_rev_major, 170210284Sjmallett uint8_t board_rev_minor, uint32_t cpu_clock_hz) 171210284Sjmallett{ 172210284Sjmallett 173210284Sjmallett 174210284Sjmallett memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo)); 175215990Sjmallett state.sysinfo.phy_mem_desc_addr = phy_mem_desc_addr; 176210284Sjmallett state.sysinfo.board_type = board_type; 177210284Sjmallett state.sysinfo.board_rev_major = board_rev_major; 178210284Sjmallett state.sysinfo.board_rev_minor = board_rev_minor; 179210284Sjmallett state.sysinfo.cpu_clock_hz = cpu_clock_hz; 180210284Sjmallett 181210284Sjmallett return(1); 182210284Sjmallett} 183210284Sjmallett 184210284Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_USER 185210284Sjmallett/** 186210284Sjmallett * Initialize the sysinfo structure when running on 187210284Sjmallett * Octeon under Linux userspace 188210284Sjmallett */ 189210284Sjmallettvoid cvmx_sysinfo_linux_userspace_initialize(void) 190210284Sjmallett{ 191210284Sjmallett cvmx_sysinfo_t *system_info = cvmx_sysinfo_get(); 192210284Sjmallett memset(system_info, 0, sizeof(cvmx_sysinfo_t)); 193210284Sjmallett 194210284Sjmallett system_info->core_mask = 0; 195210284Sjmallett system_info->init_core = -1; 196210284Sjmallett 197210284Sjmallett FILE *infile = fopen("/proc/octeon_info", "r"); 198210284Sjmallett if (infile == NULL) 199210284Sjmallett { 200210284Sjmallett perror("Error opening /proc/octeon_info"); 201210284Sjmallett exit(-1); 202210284Sjmallett } 203210284Sjmallett 204210284Sjmallett while (!feof(infile)) 205210284Sjmallett { 206210284Sjmallett char buffer[80]; 207210284Sjmallett if (fgets(buffer, sizeof(buffer), infile)) 208210284Sjmallett { 209210284Sjmallett const char *field = strtok(buffer, " "); 210210284Sjmallett const char *valueS = strtok(NULL, " "); 211210284Sjmallett if (field == NULL) 212210284Sjmallett continue; 213210284Sjmallett if (valueS == NULL) 214210284Sjmallett continue; 215210284Sjmallett unsigned long long value; 216210284Sjmallett sscanf(valueS, "%lli", &value); 217210284Sjmallett 218210284Sjmallett if (strcmp(field, "dram_size:") == 0) 219232812Sjmallett system_info->system_dram_size = value << 20; 220210284Sjmallett else if (strcmp(field, "phy_mem_desc_addr:") == 0) 221215990Sjmallett system_info->phy_mem_desc_addr = value; 222210284Sjmallett else if (strcmp(field, "eclock_hz:") == 0) 223210284Sjmallett system_info->cpu_clock_hz = value; 224210284Sjmallett else if (strcmp(field, "dclock_hz:") == 0) 225210284Sjmallett system_info->dram_data_rate_hz = value * 2; 226210284Sjmallett else if (strcmp(field, "board_type:") == 0) 227210284Sjmallett system_info->board_type = value; 228210284Sjmallett else if (strcmp(field, "board_rev_major:") == 0) 229210284Sjmallett system_info->board_rev_major = value; 230210284Sjmallett else if (strcmp(field, "board_rev_minor:") == 0) 231210284Sjmallett system_info->board_rev_minor = value; 232210284Sjmallett else if (strcmp(field, "board_serial_number:") == 0) 233210284Sjmallett strncpy(system_info->board_serial_number, valueS, sizeof(system_info->board_serial_number)); 234210284Sjmallett else if (strcmp(field, "mac_addr_base:") == 0) 235210284Sjmallett { 236210284Sjmallett int i; 237210284Sjmallett int m[6]; 238210284Sjmallett sscanf(valueS, "%02x:%02x:%02x:%02x:%02x:%02x", m+0, m+1, m+2, m+3, m+4, m+5); 239210284Sjmallett for (i=0; i<6; i++) 240210284Sjmallett system_info->mac_addr_base[i] = m[i]; 241210284Sjmallett } 242210284Sjmallett else if (strcmp(field, "mac_addr_count:") == 0) 243210284Sjmallett system_info->mac_addr_count = value; 244232812Sjmallett else if (strcmp(field, "fdt_addr:") == 0) 245232812Sjmallett system_info->fdt_addr = UNMAPPED_PTR(value); 246210284Sjmallett else if (strcmp(field, "32bit_shared_mem_base:") == 0) 247210284Sjmallett linux_mem32_min = value; 248210284Sjmallett else if (strcmp(field, "32bit_shared_mem_size:") == 0) 249210284Sjmallett linux_mem32_max = linux_mem32_min + value - 1; 250210284Sjmallett else if (strcmp(field, "processor_id:") == 0) 251210284Sjmallett cvmx_app_init_processor_id = value; 252210284Sjmallett else if (strcmp(field, "32bit_shared_mem_wired:") == 0) 253210284Sjmallett linux_mem32_wired = value; 254210284Sjmallett } 255210284Sjmallett } 256215990Sjmallett 257232812Sjmallett /* 258232812Sjmallett * set up the feature map. 259232812Sjmallett */ 260232812Sjmallett octeon_feature_init(); 261232812Sjmallett 262215990Sjmallett system_info->cpu_clock_hz = cvmx_clock_get_rate(CVMX_CLOCK_CORE); 263210284Sjmallett} 264210284Sjmallett#endif 265