cvmx-sysinfo.c revision 210284
1/***********************license start*************** 2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 * 23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39 40 41 42 43 44/** 45 * @file 46 * 47 * This module provides system/board/application information obtained by the bootloader. 48 * 49 * <hr>$Revision: 41586 $<hr> 50 * 51 */ 52 53#include "cvmx.h" 54#include "cvmx-spinlock.h" 55#include "cvmx-sysinfo.h" 56 57 58/** 59 * This structure defines the private state maintained by sysinfo module. 60 * 61 */ 62#if defined(CVMX_BUILD_FOR_UBOOT) && CONFIG_OCTEON_NAND_STAGE2 63/* For u-boot, put this in the text section so that we can use this in early 64** boot when running from ram(or L2 cache). This is primarily used for NAND 65** access during NAND boot. The 'data_in_text' section is merged with the 66** text section by the linker script to avoid an assembler warning. */ 67static struct { 68 69 cvmx_sysinfo_t sysinfo; /**< system information */ 70 cvmx_spinlock_t lock; /**< mutex spinlock */ 71 72} state __attribute__ ((section (".data_in_text"))) = { 73 .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER 74}; 75#else 76CVMX_SHARED static struct { 77 78 cvmx_sysinfo_t sysinfo; /**< system information */ 79 cvmx_spinlock_t lock; /**< mutex spinlock */ 80 81} state = { 82 .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER 83}; 84#endif 85 86#ifdef CVMX_BUILD_FOR_LINUX_USER 87/* Global variable with the processor ID since we can't read it directly */ 88CVMX_SHARED uint32_t cvmx_app_init_processor_id; 89#endif 90 91/* Global variables that define the min/max of the memory region set up for 32 bit userspace access */ 92uint64_t linux_mem32_min = 0; 93uint64_t linux_mem32_max = 0; 94uint64_t linux_mem32_wired = 0; 95uint64_t linux_mem32_offset = 0; 96 97/** 98 * This function returns the application information as obtained 99 * by the bootloader. This provides the core mask of the cores 100 * running the same application image, as well as the physical 101 * memory regions available to the core. 102 * 103 * @return Pointer to the boot information structure 104 * 105 */ 106cvmx_sysinfo_t * cvmx_sysinfo_get(void) 107{ 108 return &(state.sysinfo); 109} 110 111 112/** 113 * This function is used in non-simple executive environments (such as Linux kernel, u-boot, etc.) 114 * to configure the minimal fields that are required to use 115 * simple executive files directly. 116 * 117 * Locking (if required) must be handled outside of this 118 * function 119 * 120 * @param phy_mem_desc_ptr 121 * Pointer to global physical memory descriptor (bootmem descriptor) 122 * @param board_type Octeon board type enumeration 123 * 124 * @param board_rev_major 125 * Board major revision 126 * @param board_rev_minor 127 * Board minor revision 128 * @param cpu_clock_hz 129 * CPU clock freqency in hertz 130 * 131 * @return 0: Failure 132 * 1: success 133 */ 134int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr, uint16_t board_type, uint8_t board_rev_major, 135 uint8_t board_rev_minor, uint32_t cpu_clock_hz) 136{ 137 138 139 memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo)); 140 state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr; 141 state.sysinfo.board_type = board_type; 142 state.sysinfo.board_rev_major = board_rev_major; 143 state.sysinfo.board_rev_minor = board_rev_minor; 144 state.sysinfo.cpu_clock_hz = cpu_clock_hz; 145 146 return(1); 147} 148 149#ifdef CVMX_BUILD_FOR_LINUX_USER 150/** 151 * Initialize the sysinfo structure when running on 152 * Octeon under Linux userspace 153 */ 154void cvmx_sysinfo_linux_userspace_initialize(void) 155{ 156 cvmx_sysinfo_t *system_info = cvmx_sysinfo_get(); 157 memset(system_info, 0, sizeof(cvmx_sysinfo_t)); 158 159 system_info->core_mask = 0; 160 system_info->init_core = -1; 161 162 FILE *infile = fopen("/proc/octeon_info", "r"); 163 if (infile == NULL) 164 { 165 perror("Error opening /proc/octeon_info"); 166 exit(-1); 167 } 168 169 while (!feof(infile)) 170 { 171 char buffer[80]; 172 if (fgets(buffer, sizeof(buffer), infile)) 173 { 174 const char *field = strtok(buffer, " "); 175 const char *valueS = strtok(NULL, " "); 176 if (field == NULL) 177 continue; 178 if (valueS == NULL) 179 continue; 180 unsigned long long value; 181 sscanf(valueS, "%lli", &value); 182 183 if (strcmp(field, "dram_size:") == 0) 184 system_info->system_dram_size = value; 185 else if (strcmp(field, "phy_mem_desc_addr:") == 0) 186 system_info->phy_mem_desc_ptr = cvmx_phys_to_ptr(value); 187 else if (strcmp(field, "eclock_hz:") == 0) 188 system_info->cpu_clock_hz = value; 189 else if (strcmp(field, "dclock_hz:") == 0) 190 system_info->dram_data_rate_hz = value * 2; 191 else if (strcmp(field, "board_type:") == 0) 192 system_info->board_type = value; 193 else if (strcmp(field, "board_rev_major:") == 0) 194 system_info->board_rev_major = value; 195 else if (strcmp(field, "board_rev_minor:") == 0) 196 system_info->board_rev_minor = value; 197 else if (strcmp(field, "board_serial_number:") == 0) 198 strncpy(system_info->board_serial_number, valueS, sizeof(system_info->board_serial_number)); 199 else if (strcmp(field, "mac_addr_base:") == 0) 200 { 201 int i; 202 int m[6]; 203 sscanf(valueS, "%02x:%02x:%02x:%02x:%02x:%02x", m+0, m+1, m+2, m+3, m+4, m+5); 204 for (i=0; i<6; i++) 205 system_info->mac_addr_base[i] = m[i]; 206 } 207 else if (strcmp(field, "mac_addr_count:") == 0) 208 system_info->mac_addr_count = value; 209 else if (strcmp(field, "32bit_shared_mem_base:") == 0) 210 linux_mem32_min = value; 211 else if (strcmp(field, "32bit_shared_mem_size:") == 0) 212 linux_mem32_max = linux_mem32_min + value - 1; 213 else if (strcmp(field, "processor_id:") == 0) 214 cvmx_app_init_processor_id = value; 215 else if (strcmp(field, "32bit_shared_mem_wired:") == 0) 216 linux_mem32_wired = value; 217 } 218 } 219} 220#endif 221