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/** 47210284Sjmallett * @file 48210284Sjmallett * 49210284Sjmallett * This module provides system/board/application information obtained by the bootloader. 50210284Sjmallett * 51215990Sjmallett * <hr>$Revision: 52004 $<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} 120215990Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 121215990SjmallettEXPORT_SYMBOL(cvmx_sysinfo_get); 122215990Sjmallett#endif 123210284Sjmallett 124210284Sjmallett 125210284Sjmallett/** 126210284Sjmallett * This function is used in non-simple executive environments (such as Linux kernel, u-boot, etc.) 127210284Sjmallett * to configure the minimal fields that are required to use 128210284Sjmallett * simple executive files directly. 129210284Sjmallett * 130210284Sjmallett * Locking (if required) must be handled outside of this 131210284Sjmallett * function 132210284Sjmallett * 133215990Sjmallett * @param phy_mem_desc_addr 134215990Sjmallett * Address of the global physical memory descriptor (bootmem 135215990Sjmallett * descriptor) 136210284Sjmallett * @param board_type Octeon board type enumeration 137210284Sjmallett * 138210284Sjmallett * @param board_rev_major 139210284Sjmallett * Board major revision 140210284Sjmallett * @param board_rev_minor 141210284Sjmallett * Board minor revision 142210284Sjmallett * @param cpu_clock_hz 143210284Sjmallett * CPU clock freqency in hertz 144210284Sjmallett * 145210284Sjmallett * @return 0: Failure 146210284Sjmallett * 1: success 147210284Sjmallett */ 148215990Sjmallettint cvmx_sysinfo_minimal_initialize(uint64_t phy_mem_desc_addr, uint16_t board_type, uint8_t board_rev_major, 149210284Sjmallett uint8_t board_rev_minor, uint32_t cpu_clock_hz) 150210284Sjmallett{ 151210284Sjmallett 152210284Sjmallett 153210284Sjmallett memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo)); 154215990Sjmallett state.sysinfo.phy_mem_desc_addr = phy_mem_desc_addr; 155210284Sjmallett state.sysinfo.board_type = board_type; 156210284Sjmallett state.sysinfo.board_rev_major = board_rev_major; 157210284Sjmallett state.sysinfo.board_rev_minor = board_rev_minor; 158210284Sjmallett state.sysinfo.cpu_clock_hz = cpu_clock_hz; 159210284Sjmallett 160210284Sjmallett return(1); 161210284Sjmallett} 162210284Sjmallett 163210284Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_USER 164210284Sjmallett/** 165210284Sjmallett * Initialize the sysinfo structure when running on 166210284Sjmallett * Octeon under Linux userspace 167210284Sjmallett */ 168210284Sjmallettvoid cvmx_sysinfo_linux_userspace_initialize(void) 169210284Sjmallett{ 170210284Sjmallett cvmx_sysinfo_t *system_info = cvmx_sysinfo_get(); 171210284Sjmallett memset(system_info, 0, sizeof(cvmx_sysinfo_t)); 172210284Sjmallett 173210284Sjmallett system_info->core_mask = 0; 174210284Sjmallett system_info->init_core = -1; 175210284Sjmallett 176210284Sjmallett FILE *infile = fopen("/proc/octeon_info", "r"); 177210284Sjmallett if (infile == NULL) 178210284Sjmallett { 179210284Sjmallett perror("Error opening /proc/octeon_info"); 180210284Sjmallett exit(-1); 181210284Sjmallett } 182210284Sjmallett 183210284Sjmallett while (!feof(infile)) 184210284Sjmallett { 185210284Sjmallett char buffer[80]; 186210284Sjmallett if (fgets(buffer, sizeof(buffer), infile)) 187210284Sjmallett { 188210284Sjmallett const char *field = strtok(buffer, " "); 189210284Sjmallett const char *valueS = strtok(NULL, " "); 190210284Sjmallett if (field == NULL) 191210284Sjmallett continue; 192210284Sjmallett if (valueS == NULL) 193210284Sjmallett continue; 194210284Sjmallett unsigned long long value; 195210284Sjmallett sscanf(valueS, "%lli", &value); 196210284Sjmallett 197210284Sjmallett if (strcmp(field, "dram_size:") == 0) 198210284Sjmallett system_info->system_dram_size = value; 199210284Sjmallett else if (strcmp(field, "phy_mem_desc_addr:") == 0) 200215990Sjmallett system_info->phy_mem_desc_addr = value; 201210284Sjmallett else if (strcmp(field, "eclock_hz:") == 0) 202210284Sjmallett system_info->cpu_clock_hz = value; 203210284Sjmallett else if (strcmp(field, "dclock_hz:") == 0) 204210284Sjmallett system_info->dram_data_rate_hz = value * 2; 205210284Sjmallett else if (strcmp(field, "board_type:") == 0) 206210284Sjmallett system_info->board_type = value; 207210284Sjmallett else if (strcmp(field, "board_rev_major:") == 0) 208210284Sjmallett system_info->board_rev_major = value; 209210284Sjmallett else if (strcmp(field, "board_rev_minor:") == 0) 210210284Sjmallett system_info->board_rev_minor = value; 211210284Sjmallett else if (strcmp(field, "board_serial_number:") == 0) 212210284Sjmallett strncpy(system_info->board_serial_number, valueS, sizeof(system_info->board_serial_number)); 213210284Sjmallett else if (strcmp(field, "mac_addr_base:") == 0) 214210284Sjmallett { 215210284Sjmallett int i; 216210284Sjmallett int m[6]; 217210284Sjmallett sscanf(valueS, "%02x:%02x:%02x:%02x:%02x:%02x", m+0, m+1, m+2, m+3, m+4, m+5); 218210284Sjmallett for (i=0; i<6; i++) 219210284Sjmallett system_info->mac_addr_base[i] = m[i]; 220210284Sjmallett } 221210284Sjmallett else if (strcmp(field, "mac_addr_count:") == 0) 222210284Sjmallett system_info->mac_addr_count = value; 223210284Sjmallett else if (strcmp(field, "32bit_shared_mem_base:") == 0) 224210284Sjmallett linux_mem32_min = value; 225210284Sjmallett else if (strcmp(field, "32bit_shared_mem_size:") == 0) 226210284Sjmallett linux_mem32_max = linux_mem32_min + value - 1; 227210284Sjmallett else if (strcmp(field, "processor_id:") == 0) 228210284Sjmallett cvmx_app_init_processor_id = value; 229210284Sjmallett else if (strcmp(field, "32bit_shared_mem_wired:") == 0) 230210284Sjmallett linux_mem32_wired = value; 231210284Sjmallett } 232210284Sjmallett } 233215990Sjmallett 234215990Sjmallett system_info->cpu_clock_hz = cvmx_clock_get_rate(CVMX_CLOCK_CORE); 235210284Sjmallett} 236210284Sjmallett#endif 237