mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2025-04-21 12:27:27 +03:00
change the way ./files* and the generic kernel files are applied. ./files now applies to *ALL* kernel versions, and is copied along with ./files-* - this gets rid of quite a bit of redundancy in the extra kernel drivers.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13010 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
#
|
||||
# Makefile for the BCM47xx specific kernel interface routines
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y := irq.o prom.o setup.o time.o
|
||||
obj-y += nvram.o cfe_env.o
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* CFE environment variable access
|
||||
*
|
||||
* Copyright 2001-2003, Broadcom Corporation
|
||||
* Copyright 2006, Felix Fietkau <nbd@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define NVRAM_SIZE (0x1ff0)
|
||||
static char _nvdata[NVRAM_SIZE];
|
||||
static char _valuestr[256];
|
||||
|
||||
/*
|
||||
* TLV types. These codes are used in the "type-length-value"
|
||||
* encoding of the items stored in the NVRAM device (flash or EEPROM)
|
||||
*
|
||||
* The layout of the flash/nvram is as follows:
|
||||
*
|
||||
* <type> <length> <data ...> <type> <length> <data ...> <type_end>
|
||||
*
|
||||
* The type code of "ENV_TLV_TYPE_END" marks the end of the list.
|
||||
* The "length" field marks the length of the data section, not
|
||||
* including the type and length fields.
|
||||
*
|
||||
* Environment variables are stored as follows:
|
||||
*
|
||||
* <type_env> <length> <flags> <name> = <value>
|
||||
*
|
||||
* If bit 0 (low bit) is set, the length is an 8-bit value.
|
||||
* If bit 0 (low bit) is clear, the length is a 16-bit value
|
||||
*
|
||||
* Bit 7 set indicates "user" TLVs. In this case, bit 0 still
|
||||
* indicates the size of the length field.
|
||||
*
|
||||
* Flags are from the constants below:
|
||||
*
|
||||
*/
|
||||
#define ENV_LENGTH_16BITS 0x00 /* for low bit */
|
||||
#define ENV_LENGTH_8BITS 0x01
|
||||
|
||||
#define ENV_TYPE_USER 0x80
|
||||
|
||||
#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
|
||||
#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
|
||||
|
||||
/*
|
||||
* The actual TLV types we support
|
||||
*/
|
||||
|
||||
#define ENV_TLV_TYPE_END 0x00
|
||||
#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
|
||||
|
||||
/*
|
||||
* Environment variable flags
|
||||
*/
|
||||
|
||||
#define ENV_FLG_NORMAL 0x00 /* normal read/write */
|
||||
#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
|
||||
#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
|
||||
|
||||
#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
|
||||
#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
|
||||
|
||||
|
||||
/* *********************************************************************
|
||||
* _nvram_read(buffer,offset,length)
|
||||
*
|
||||
* Read data from the NVRAM device
|
||||
*
|
||||
* Input parameters:
|
||||
* buffer - destination buffer
|
||||
* offset - offset of data to read
|
||||
* length - number of bytes to read
|
||||
*
|
||||
* Return value:
|
||||
* number of bytes read, or <0 if error occured
|
||||
********************************************************************* */
|
||||
static int
|
||||
_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
|
||||
{
|
||||
int i;
|
||||
if (offset > NVRAM_SIZE)
|
||||
return -1;
|
||||
|
||||
for ( i = 0; i < length; i++) {
|
||||
buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
_strnchr(const char *dest,int c,size_t cnt)
|
||||
{
|
||||
while (*dest && (cnt > 0)) {
|
||||
if (*dest == c) return (char *) dest;
|
||||
dest++;
|
||||
cnt--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Core support API: Externally visible.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the value of an NVRAM variable
|
||||
* @param name name of variable to get
|
||||
* @return value of variable or NULL if undefined
|
||||
*/
|
||||
|
||||
char*
|
||||
cfe_env_get(unsigned char *nv_buf, char* name)
|
||||
{
|
||||
int size;
|
||||
unsigned char *buffer;
|
||||
unsigned char *ptr;
|
||||
unsigned char *envval;
|
||||
unsigned int reclen;
|
||||
unsigned int rectype;
|
||||
int offset;
|
||||
int flg;
|
||||
|
||||
if (!strcmp(name, "nvram_type"))
|
||||
return "cfe";
|
||||
|
||||
size = NVRAM_SIZE;
|
||||
buffer = &_nvdata[0];
|
||||
|
||||
ptr = buffer;
|
||||
offset = 0;
|
||||
|
||||
/* Read the record type and length */
|
||||
if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
|
||||
|
||||
/* Adjust pointer for TLV type */
|
||||
rectype = *(ptr);
|
||||
offset++;
|
||||
size--;
|
||||
|
||||
/*
|
||||
* Read the length. It can be either 1 or 2 bytes
|
||||
* depending on the code
|
||||
*/
|
||||
if (rectype & ENV_LENGTH_8BITS) {
|
||||
/* Read the record type and length - 8 bits */
|
||||
if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
|
||||
goto error;
|
||||
}
|
||||
reclen = *(ptr);
|
||||
size--;
|
||||
offset++;
|
||||
}
|
||||
else {
|
||||
/* Read the record type and length - 16 bits, MSB first */
|
||||
if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
|
||||
goto error;
|
||||
}
|
||||
reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
|
||||
size -= 2;
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
if (reclen > size)
|
||||
break; /* should not happen, bad NVRAM */
|
||||
|
||||
switch (rectype) {
|
||||
case ENV_TLV_TYPE_ENV:
|
||||
/* Read the TLV data */
|
||||
if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
|
||||
goto error;
|
||||
flg = *ptr++;
|
||||
envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
|
||||
if (envval) {
|
||||
*envval++ = '\0';
|
||||
memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
|
||||
_valuestr[(reclen-1)-(envval-ptr)] = '\0';
|
||||
#if 0
|
||||
printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
|
||||
#endif
|
||||
if(!strcmp(ptr, name)){
|
||||
return _valuestr;
|
||||
}
|
||||
if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
|
||||
return _valuestr;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown TLV type, skip it. */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advance to next TLV
|
||||
*/
|
||||
|
||||
size -= (int)reclen;
|
||||
offset += reclen;
|
||||
|
||||
/* Read the next record type */
|
||||
ptr = buffer;
|
||||
if (_nvram_read(nv_buf, ptr,offset,1) != 1)
|
||||
goto error;
|
||||
}
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __NVRAM_H
|
||||
#define __NVRAM_H
|
||||
|
||||
struct nvram_header {
|
||||
u32 magic;
|
||||
u32 len;
|
||||
u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
|
||||
u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
|
||||
u32 config_ncdl; /* ncdl values for memc */
|
||||
};
|
||||
|
||||
struct nvram_tuple {
|
||||
char *name;
|
||||
char *value;
|
||||
struct nvram_tuple *next;
|
||||
};
|
||||
|
||||
#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
|
||||
#define NVRAM_VERSION 1
|
||||
#define NVRAM_HEADER_SIZE 20
|
||||
#define NVRAM_SPACE 0x8000
|
||||
|
||||
#define NVRAM_MAX_VALUE_LEN 255
|
||||
#define NVRAM_MAX_PARAM_LEN 64
|
||||
|
||||
char *nvram_get(const char *name);
|
||||
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
|
||||
* Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
|
||||
|
||||
extern struct ssb_bus ssb;
|
||||
|
||||
|
||||
void plat_irq_dispatch(void)
|
||||
{
|
||||
u32 cause;
|
||||
|
||||
cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
|
||||
|
||||
clear_c0_status(cause);
|
||||
|
||||
if (cause & CAUSEF_IP7)
|
||||
do_IRQ(7);
|
||||
if (cause & CAUSEF_IP2)
|
||||
do_IRQ(2);
|
||||
if (cause & CAUSEF_IP3)
|
||||
do_IRQ(3);
|
||||
if (cause & CAUSEF_IP4)
|
||||
do_IRQ(4);
|
||||
if (cause & CAUSEF_IP5)
|
||||
do_IRQ(5);
|
||||
if (cause & CAUSEF_IP6)
|
||||
do_IRQ(6);
|
||||
}
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
mips_cpu_irq_init();
|
||||
}
|
||||
|
||||
int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = ssb_pcibios_map_irq(dev, slot, pin);
|
||||
if (res < 0) {
|
||||
printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
|
||||
dev->dev.bus_id);
|
||||
return 0;
|
||||
}
|
||||
/* IRQ-0 and IRQ-1 are software interrupts. */
|
||||
WARN_ON((res == 0) || (res == 1));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* BCM947xx nvram variable access
|
||||
*
|
||||
* Copyright 2005, Broadcom Corporation
|
||||
* Copyright 2006, Felix Fietkau <nbd@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <nvram.h>
|
||||
|
||||
#define MB * 1048576
|
||||
extern struct ssb_bus ssb;
|
||||
|
||||
static char nvram_buf[NVRAM_SPACE];
|
||||
static int cfe_env;
|
||||
extern char *cfe_env_get(char *nv_buf, const char *name);
|
||||
|
||||
/* Probe for NVRAM header */
|
||||
static void __init early_nvram_init(void)
|
||||
{
|
||||
struct ssb_mipscore *mcore = &ssb.mipscore;
|
||||
struct nvram_header *header;
|
||||
int i;
|
||||
u32 base, lim, off;
|
||||
u32 *src, *dst;
|
||||
|
||||
base = mcore->flash_window;
|
||||
lim = mcore->flash_window_size;
|
||||
cfe_env = 0;
|
||||
|
||||
|
||||
/* XXX: hack for supporting the CFE environment stuff on WGT634U */
|
||||
if (lim >= 8 MB) {
|
||||
src = (u32 *) KSEG1ADDR(base + 8 MB - 0x2000);
|
||||
dst = (u32 *) nvram_buf;
|
||||
|
||||
if ((*src & 0xff00ff) == 0x000001) {
|
||||
printk("early_nvram_init: WGT634U NVRAM found.\n");
|
||||
|
||||
for (i = 0; i < 0x1ff0; i++) {
|
||||
if (*src == 0xFFFFFFFF)
|
||||
break;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
cfe_env = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
off = 0x20000;
|
||||
while (off <= lim) {
|
||||
/* Windowed flash access */
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
goto found;
|
||||
off <<= 1;
|
||||
}
|
||||
|
||||
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 4096);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
goto found;
|
||||
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 1024);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
goto found;
|
||||
|
||||
return;
|
||||
|
||||
found:
|
||||
src = (u32 *) header;
|
||||
dst = (u32 *) nvram_buf;
|
||||
for (i = 0; i < sizeof(struct nvram_header); i += 4)
|
||||
*dst++ = *src++;
|
||||
for (; i < header->len && i < NVRAM_SPACE; i += 4)
|
||||
*dst++ = le32_to_cpu(*src++);
|
||||
}
|
||||
|
||||
char *nvram_get(const char *name)
|
||||
{
|
||||
char *var, *value, *end, *eq;
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
if (!nvram_buf[0])
|
||||
early_nvram_init();
|
||||
|
||||
if (cfe_env)
|
||||
return cfe_env_get(nvram_buf, name);
|
||||
|
||||
/* Look for name=value and return value */
|
||||
var = &nvram_buf[sizeof(struct nvram_header)];
|
||||
end = nvram_buf + sizeof(nvram_buf) - 2;
|
||||
end[0] = end[1] = '\0';
|
||||
for (; *var; var = value + strlen(value) + 1) {
|
||||
if (!(eq = strchr(var, '=')))
|
||||
break;
|
||||
value = eq + 1;
|
||||
if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
|
||||
return value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(nvram_get);
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/bootmem.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/pmon.h>
|
||||
#include "../cfe/cfe_private.h"
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return "Broadcom BCM47xx";
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
unsigned long mem;
|
||||
|
||||
mips_machgroup = MACH_GROUP_BRCM;
|
||||
mips_machtype = MACH_BCM47XX;
|
||||
|
||||
cfe_setup(fw_arg0, fw_arg1, fw_arg2, fw_arg3);
|
||||
|
||||
/* Figure out memory size by finding aliases */
|
||||
for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
|
||||
if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
|
||||
*(unsigned long *)(prom_init))
|
||||
break;
|
||||
}
|
||||
|
||||
add_memory_region(0, mem, BOOT_MEM_RAM);
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
|
||||
* Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2006-2008 Michael Buesch <mb@bu3sch.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/cfe.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/ssb/ssb_embedded.h>
|
||||
|
||||
#include <nvram.h>
|
||||
|
||||
extern void bcm47xx_pci_init(void);
|
||||
extern void bcm47xx_time_init(void);
|
||||
|
||||
struct ssb_bus ssb;
|
||||
|
||||
|
||||
int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ssb_pcibios_plat_dev_init(dev);
|
||||
if (err) {
|
||||
printk(KERN_ALERT "PCI: Failed to init device %s\n",
|
||||
pci_name(dev));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void bcm47xx_machine_restart(char *command)
|
||||
{
|
||||
printk(KERN_ALERT "Please stand by while rebooting the system...\n");
|
||||
local_irq_disable();
|
||||
/* CFE has a reboot callback, but that does not work.
|
||||
* Oopses with: Reserved instruction in kernel code.
|
||||
*/
|
||||
|
||||
/* Set the watchdog timer to reset immediately */
|
||||
if (ssb_watchdog_timer_set(&ssb, 1))
|
||||
printk(KERN_EMERG "SSB watchdog-triggered reboot failed!\n");
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void bcm47xx_machine_halt(void)
|
||||
{
|
||||
/* Disable interrupts and watchdog and spin forever */
|
||||
local_irq_disable();
|
||||
if (ssb_watchdog_timer_set(&ssb, 0))
|
||||
printk(KERN_EMERG "Failed to disable SSB watchdog!\n");
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void e_aton(char *str, char *dest)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (str == NULL) {
|
||||
memset(dest, 0, 6);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
dest[i++] = (char) simple_strtoul(str, NULL, 16);
|
||||
str += 2;
|
||||
if (!*str++ || i == 6)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
|
||||
{
|
||||
char *s;
|
||||
|
||||
memset(sprom, 0xFF, sizeof(struct ssb_sprom));
|
||||
|
||||
sprom->revision = 1;
|
||||
if ((s = nvram_get("il0macaddr")))
|
||||
e_aton(s, sprom->il0mac);
|
||||
if ((s = nvram_get("et0macaddr")))
|
||||
e_aton(s, sprom->et0mac);
|
||||
if ((s = nvram_get("et1macaddr")))
|
||||
e_aton(s, sprom->et1mac);
|
||||
if ((s = nvram_get("et0phyaddr")))
|
||||
sprom->et0phyaddr = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("et1phyaddr")))
|
||||
sprom->et1phyaddr = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("et0mdcport")))
|
||||
sprom->et0mdcport = !!simple_strtoul(s, NULL, 10);
|
||||
if ((s = nvram_get("et1mdcport")))
|
||||
sprom->et1mdcport = !!simple_strtoul(s, NULL, 10);
|
||||
if ((s = nvram_get("pa0b0")))
|
||||
sprom->pa0b0 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa0b1")))
|
||||
sprom->pa0b1 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa0b2")))
|
||||
sprom->pa0b2 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa1b0")))
|
||||
sprom->pa1b0 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa1b1")))
|
||||
sprom->pa1b1 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa1b2")))
|
||||
sprom->pa1b2 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("wl0gpio0")))
|
||||
sprom->gpio0 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("wl0gpio1")))
|
||||
sprom->gpio1 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("wl0gpio2")))
|
||||
sprom->gpio2 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("wl0gpio3")))
|
||||
sprom->gpio3 = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa0maxpwr")))
|
||||
sprom->maxpwr_bg = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa1maxpwr")))
|
||||
sprom->maxpwr_a = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa0itssit")))
|
||||
sprom->itssi_bg = simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("pa1itssit")))
|
||||
sprom->itssi_a = simple_strtoul(s, NULL, 0);
|
||||
sprom->boardflags_lo = 0;
|
||||
if ((s = nvram_get("boardflags")))
|
||||
sprom->boardflags_lo = simple_strtoul(s, NULL, 0);
|
||||
sprom->boardflags_hi = 0;
|
||||
if ((s = nvram_get("boardflags2")))
|
||||
sprom->boardflags_hi = simple_strtoul(s, NULL, 0);
|
||||
}
|
||||
|
||||
static int bcm47xx_get_invariants(struct ssb_bus *bus, struct ssb_init_invariants *iv)
|
||||
{
|
||||
char *s;
|
||||
|
||||
iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
|
||||
if ((s = nvram_get("boardtype")))
|
||||
iv->boardinfo.type = (u16)simple_strtoul(s, NULL, 0);
|
||||
if ((s = nvram_get("boardrev")))
|
||||
iv->boardinfo.rev = (u16)simple_strtoul(s, NULL, 0);
|
||||
|
||||
bcm47xx_fill_sprom(&iv->sprom);
|
||||
|
||||
if ((s = nvram_get("cardbus")))
|
||||
iv->has_cardbus_slot = !!simple_strtoul(s, NULL, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
int i, err;
|
||||
char *s;
|
||||
struct ssb_mipscore *mcore;
|
||||
|
||||
err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_get_invariants);
|
||||
if (err) {
|
||||
const char *msg = "Failed to initialize SSB bus (err %d)\n";
|
||||
cfe_printk(msg, err); /* Make sure the message gets out of the box. */
|
||||
panic(msg, err);
|
||||
}
|
||||
mcore = &ssb.mipscore;
|
||||
|
||||
s = nvram_get("kernel_args");
|
||||
if (s && !strncmp(s, "console=ttyS1", 13)) {
|
||||
struct ssb_serial_port port;
|
||||
|
||||
cfe_printk("Swapping serial ports!\n");
|
||||
/* swap serial ports */
|
||||
memcpy(&port, &mcore->serial_ports[0], sizeof(port));
|
||||
memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port));
|
||||
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
|
||||
}
|
||||
|
||||
for (i = 0; i < mcore->nr_serial_ports; i++) {
|
||||
struct ssb_serial_port *port = &(mcore->serial_ports[i]);
|
||||
struct uart_port s;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.line = i;
|
||||
s.membase = port->regs;
|
||||
s.irq = port->irq + 2;
|
||||
s.uartclk = port->baud_base;
|
||||
s.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
|
||||
s.iotype = SERIAL_IO_MEM;
|
||||
s.regshift = port->reg_shift;
|
||||
|
||||
early_serial_setup(&s);
|
||||
}
|
||||
cfe_printk("Serial init done.\n");
|
||||
|
||||
_machine_restart = bcm47xx_machine_restart;
|
||||
_machine_halt = bcm47xx_machine_halt;
|
||||
pm_power_off = bcm47xx_machine_halt;
|
||||
board_time_init = bcm47xx_time_init;
|
||||
}
|
||||
|
||||
static int __init bcm47xx_register_gpiodev(void)
|
||||
{
|
||||
static struct resource res = {
|
||||
.start = 0xFFFFFFFF,
|
||||
};
|
||||
struct platform_device *pdev;
|
||||
|
||||
pdev = platform_device_register_simple("GPIODEV", 0, &res, 1);
|
||||
if (!pdev) {
|
||||
printk(KERN_ERR "bcm47xx: GPIODEV init failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(bcm47xx_register_gpiodev);
|
||||
|
||||
EXPORT_SYMBOL(ssb);
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
extern struct ssb_bus ssb;
|
||||
|
||||
void __init
|
||||
bcm47xx_time_init(void)
|
||||
{
|
||||
unsigned long hz;
|
||||
|
||||
/*
|
||||
* Use deterministic values for initial counter interrupt
|
||||
* so that calibrate delay avoids encountering a counter wrap.
|
||||
*/
|
||||
write_c0_count(0);
|
||||
write_c0_compare(0xffff);
|
||||
|
||||
hz = ssb_cpu_clock(&ssb.mipscore) / 2;
|
||||
if (!hz)
|
||||
hz = 100000000;
|
||||
|
||||
/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
|
||||
mips_hpt_frequency = hz;
|
||||
}
|
||||
|
||||
void __init
|
||||
plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
/* Enable the timer interrupt */
|
||||
setup_irq(7, irq);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#
|
||||
# Makefile for the Broadcom Common Firmware Environment support
|
||||
#
|
||||
|
||||
obj-y += cfe.o
|
||||
@@ -1,533 +0,0 @@
|
||||
/*
|
||||
* Broadcom Common Firmware Environment (CFE) support
|
||||
*
|
||||
* Copyright 2000, 2001, 2002
|
||||
* Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2006 Michael Buesch
|
||||
*
|
||||
* Original Authors: Mitch Lichtenberg, Chris Demetriou
|
||||
*
|
||||
* This software is furnished under license and may be used and copied only
|
||||
* in accordance with the following terms and conditions. Subject to these
|
||||
* conditions, you may download, copy, install, use, modify and distribute
|
||||
* modified or unmodified copies of this software in source and/or binary
|
||||
* form. No title or ownership is transferred hereby.
|
||||
*
|
||||
* 1) Any source code used, modified or distributed must reproduce and
|
||||
* retain this copyright notice and list of conditions as they appear in
|
||||
* the source file.
|
||||
*
|
||||
* 2) No right is granted to use any trade name, trademark, or logo of
|
||||
* Broadcom Corporation. The "Broadcom Corporation" name may not be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without the prior written permission of Broadcom Corporation.
|
||||
*
|
||||
* 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
|
||||
* FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
|
||||
* LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/cfe.h>
|
||||
|
||||
#include "cfe_private.h"
|
||||
|
||||
|
||||
static cfe_uint_t cfe_handle;
|
||||
static int (*cfe_trampoline)(long handle, long iocb);
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
|
||||
unsigned long fwarg2, unsigned long fwarg3)
|
||||
{
|
||||
if (fwarg3 == 0x80300000) {
|
||||
/* WRT54G workaround */
|
||||
fwarg3 = CFE_EPTSEAL;
|
||||
fwarg2 = 0xBFC00500;
|
||||
}
|
||||
if (fwarg3 != CFE_EPTSEAL) {
|
||||
/* We are not booted from CFE */
|
||||
return;
|
||||
}
|
||||
if (fwarg1 == 0) {
|
||||
/* We are on the boot CPU */
|
||||
cfe_handle = (cfe_uint_t)fwarg0;
|
||||
cfe_trampoline = CFE_TO_PTR(fwarg2);
|
||||
}
|
||||
}
|
||||
|
||||
int cfe_vprintk(const char *fmt, va_list args)
|
||||
{
|
||||
static char buffer[1024];
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
static const char pfx[] = "CFE-console: ";
|
||||
static const size_t pfx_len = sizeof(pfx) - 1;
|
||||
unsigned long flags;
|
||||
int len, cnt, pos;
|
||||
int handle;
|
||||
int res;
|
||||
|
||||
if (!cfe_present())
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_irqsave(&lock, flags);
|
||||
handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
|
||||
if (CFE_ISERR(handle)) {
|
||||
len = -EIO;
|
||||
goto out;
|
||||
}
|
||||
strcpy(buffer, pfx);
|
||||
len = vscnprintf(buffer + pfx_len,
|
||||
sizeof(buffer) - pfx_len - 2,
|
||||
fmt, args);
|
||||
len += pfx_len;
|
||||
/* The CFE console requires CR-LF line-ends.
|
||||
* Add a CR, if we only terminate lines with a LF.
|
||||
* This does only fix CR-LF at the end of the string.
|
||||
* So for multiple lines, use multiple cfe_vprintk calls.
|
||||
*/
|
||||
if (len > 1 &&
|
||||
buffer[len - 1] == '\n' && buffer[len - 2] != '\r') {
|
||||
buffer[len - 1] = '\r';
|
||||
buffer[len] = '\n';
|
||||
len += 1;
|
||||
}
|
||||
cnt = len;
|
||||
pos = 0;
|
||||
while (cnt > 0) {
|
||||
res = cfe_write(handle, buffer + pos, len - pos);
|
||||
if (CFE_ISERR(res)) {
|
||||
len = -EIO;
|
||||
goto out;
|
||||
}
|
||||
cnt -= res;
|
||||
pos += res;
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&lock, flags);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int cfe_printk(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int res;
|
||||
|
||||
va_start(args, fmt);
|
||||
res = cfe_vprintk(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cfe_iocb_dispatch(struct cfe_iocb *iocb)
|
||||
{
|
||||
if (!cfe_present())
|
||||
return CFE_ERR_UNSUPPORTED;
|
||||
return cfe_trampoline((long)cfe_handle, (long)iocb);
|
||||
}
|
||||
|
||||
int cfe_present(void)
|
||||
{
|
||||
return (cfe_trampoline != NULL);
|
||||
}
|
||||
|
||||
int cfe_close(int handle)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_CLOSE;
|
||||
iocb.handle = handle;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_CPUCTL;
|
||||
iocb.psize = sizeof(struct cfe_iocb_cpuctl);
|
||||
iocb.cpuctl.number = cpu;
|
||||
iocb.cpuctl.command = CFE_CPU_CMD_START;
|
||||
iocb.cpuctl.gp = gp;
|
||||
iocb.cpuctl.sp = sp;
|
||||
iocb.cpuctl.a1 = a1;
|
||||
iocb.cpuctl.start_addr = (long)fn;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_cpu_stop(int cpu)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_CPUCTL;
|
||||
iocb.psize = sizeof(struct cfe_iocb_cpuctl);
|
||||
iocb.cpuctl.number = cpu;
|
||||
iocb.cpuctl.command = CFE_CPU_CMD_STOP;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_ENV_ENUM;
|
||||
iocb.psize = sizeof(struct cfe_iocb_envbuf);
|
||||
iocb.envbuf.index = idx;
|
||||
iocb.envbuf.name = PTR_TO_CFE(name);
|
||||
iocb.envbuf.name_len = namelen;
|
||||
iocb.envbuf.val = PTR_TO_CFE(val);
|
||||
iocb.envbuf.val_len = vallen;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_enumdev(int idx, char *name, int namelen)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
|
||||
iocb.fcode = CFE_CMD_DEV_ENUM;
|
||||
iocb.psize = sizeof(struct cfe_iocb_envbuf);
|
||||
iocb.envbuf.index = idx;
|
||||
iocb.envbuf.name = PTR_TO_CFE(name);
|
||||
iocb.envbuf.name_len = namelen;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
|
||||
u64 *type)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
|
||||
iocb.fcode = CFE_CMD_FW_MEMENUM;
|
||||
iocb.flags = flags;
|
||||
iocb.psize = sizeof(struct cfe_iocb_meminfo);
|
||||
iocb.meminfo.index = idx;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (!CFE_ISERR(iocb.status)) {
|
||||
*start = iocb.meminfo.addr;
|
||||
*length = iocb.meminfo.size;
|
||||
*type = iocb.meminfo.type;
|
||||
}
|
||||
|
||||
return iocb.status;
|
||||
}
|
||||
|
||||
int cfe_exit(int warm, int status)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
printk("CFE REBOOT\n");
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_RESTART;
|
||||
if (warm)
|
||||
iocb.flags = CFE_FLG_WARMSTART;
|
||||
iocb.psize = sizeof(struct cfe_iocb_exitstat);
|
||||
iocb.exitstat.status = status;
|
||||
|
||||
printk("CALL\n");
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
printk("DONE\n");
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_flushcache(int flags)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_FLUSHCACHE;
|
||||
iocb.flags = flags;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_getdevinfo(char *name)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_GETINFO;
|
||||
iocb.psize = sizeof(struct cfe_iocb_buf);
|
||||
iocb.buffer.ptr = PTR_TO_CFE(name);
|
||||
iocb.buffer.length = strlen(name);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.buffer.devflags;
|
||||
}
|
||||
|
||||
int cfe_getenv(char *name, char *dest, int destlen)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
dest[0] = '\0';
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_ENV_GET;
|
||||
iocb.psize = sizeof(struct cfe_iocb_envbuf);
|
||||
iocb.envbuf.name = PTR_TO_CFE(name);
|
||||
iocb.envbuf.name_len = strlen(name);
|
||||
iocb.envbuf.val = PTR_TO_CFE(dest);
|
||||
iocb.envbuf.val_len = destlen;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_getfwinfo(struct cfe_fwinfo *info)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_GETINFO;
|
||||
iocb.psize = sizeof(struct cfe_iocb_fwinfo);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return err;
|
||||
|
||||
info->version = iocb.fwinfo.version;
|
||||
info->totalmem = iocb.fwinfo.totalmem;
|
||||
info->flags = iocb.fwinfo.flags;
|
||||
info->boardid = iocb.fwinfo.boardid;
|
||||
info->bootarea_va = iocb.fwinfo.bootarea_va;
|
||||
info->bootarea_pa = iocb.fwinfo.bootarea_pa;
|
||||
info->bootarea_size = iocb.fwinfo.bootarea_size;
|
||||
|
||||
return iocb.status;
|
||||
}
|
||||
|
||||
int cfe_getstdhandle(int handletype)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_GETHANDLE;
|
||||
iocb.flags = handletype;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.handle;
|
||||
}
|
||||
|
||||
int cfe_getticks(s64 *ticks)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_FW_GETTIME;
|
||||
iocb.psize = sizeof(struct cfe_iocb_time);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (!CFE_ISERR(iocb.status))
|
||||
*ticks = iocb.time.ticks;
|
||||
|
||||
return iocb.status;
|
||||
}
|
||||
|
||||
int cfe_inpstat(int handle)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_INPSTAT;
|
||||
iocb.handle = handle;
|
||||
iocb.psize = sizeof(struct cfe_iocb_inpstat);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.inpstat.status;
|
||||
}
|
||||
|
||||
int cfe_ioctl(int handle, unsigned int ioctlnum,
|
||||
unsigned char *buffer, int length,
|
||||
int *retlen, u64 offset)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_IOCTL;
|
||||
iocb.handle = handle;
|
||||
iocb.psize = sizeof(struct cfe_iocb_buf);
|
||||
iocb.buffer.offset = offset;
|
||||
iocb.buffer.ioctlcmd = ioctlnum;
|
||||
iocb.buffer.ptr = PTR_TO_CFE(buffer);
|
||||
iocb.buffer.length = length;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
if (retlen)
|
||||
*retlen = iocb.buffer.retlen;
|
||||
|
||||
return iocb.status;
|
||||
}
|
||||
|
||||
int cfe_open(char *name)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_OPEN;
|
||||
iocb.psize = sizeof(struct cfe_iocb_buf);
|
||||
iocb.buffer.ptr = PTR_TO_CFE(name);
|
||||
iocb.buffer.length = strlen(name);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.handle;
|
||||
}
|
||||
|
||||
int cfe_read(int handle, unsigned char *buffer, int length)
|
||||
{
|
||||
return cfe_readblk(handle, 0, buffer, length);
|
||||
}
|
||||
|
||||
int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_READ;
|
||||
iocb.handle = handle;
|
||||
iocb.psize = sizeof(struct cfe_iocb_buf);
|
||||
iocb.buffer.offset = offset;
|
||||
iocb.buffer.ptr = PTR_TO_CFE(buffer);
|
||||
iocb.buffer.length = length;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.buffer.retlen;
|
||||
}
|
||||
|
||||
int cfe_setenv(char *name, char *val)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_ENV_SET;
|
||||
iocb.psize = sizeof(struct cfe_iocb_envbuf);
|
||||
iocb.envbuf.name = PTR_TO_CFE(name);
|
||||
iocb.envbuf.name_len = strlen(name);
|
||||
iocb.envbuf.val = PTR_TO_CFE(val);
|
||||
iocb.envbuf.val_len = strlen(val);
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
|
||||
return (CFE_ISERR(err)) ? err : iocb.status;
|
||||
}
|
||||
|
||||
int cfe_write(int handle, unsigned char *buffer, int length)
|
||||
{
|
||||
return cfe_writeblk(handle, 0, buffer, length);
|
||||
}
|
||||
|
||||
int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
|
||||
{
|
||||
struct cfe_iocb iocb;
|
||||
int err;
|
||||
|
||||
memset(&iocb, 0, sizeof(iocb));
|
||||
iocb.fcode = CFE_CMD_DEV_WRITE;
|
||||
iocb.handle = handle;
|
||||
iocb.psize = sizeof(struct cfe_iocb_buf);
|
||||
iocb.buffer.offset = offset;
|
||||
iocb.buffer.ptr = PTR_TO_CFE(buffer);
|
||||
iocb.buffer.length = length;
|
||||
|
||||
err = cfe_iocb_dispatch(&iocb);
|
||||
if (CFE_ISERR(err))
|
||||
return err;
|
||||
if (CFE_ISERR(iocb.status))
|
||||
return iocb.status;
|
||||
|
||||
return iocb.buffer.retlen;
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Broadcom Common Firmware Environment (CFE) support
|
||||
*
|
||||
* Copyright 2000, 2001, 2002
|
||||
* Broadcom Corporation. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2006 Michael Buesch
|
||||
*
|
||||
* Original Authors: Mitch Lichtenberg, Chris Demetriou
|
||||
*
|
||||
* This software is furnished under license and may be used and copied only
|
||||
* in accordance with the following terms and conditions. Subject to these
|
||||
* conditions, you may download, copy, install, use, modify and distribute
|
||||
* modified or unmodified copies of this software in source and/or binary
|
||||
* form. No title or ownership is transferred hereby.
|
||||
*
|
||||
* 1) Any source code used, modified or distributed must reproduce and
|
||||
* retain this copyright notice and list of conditions as they appear in
|
||||
* the source file.
|
||||
*
|
||||
* 2) No right is granted to use any trade name, trademark, or logo of
|
||||
* Broadcom Corporation. The "Broadcom Corporation" name may not be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without the prior written permission of Broadcom Corporation.
|
||||
*
|
||||
* 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
|
||||
* FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
|
||||
* LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_CFE_PRIVATE_H_
|
||||
#define LINUX_CFE_PRIVATE_H_
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* Seal indicating CFE's presence, passed to the kernel. */
|
||||
#define CFE_EPTSEAL 0x43464531
|
||||
|
||||
#define CFE_CMD_FW_GETINFO 0
|
||||
#define CFE_CMD_FW_RESTART 1
|
||||
#define CFE_CMD_FW_BOOT 2
|
||||
#define CFE_CMD_FW_CPUCTL 3
|
||||
#define CFE_CMD_FW_GETTIME 4
|
||||
#define CFE_CMD_FW_MEMENUM 5
|
||||
#define CFE_CMD_FW_FLUSHCACHE 6
|
||||
|
||||
#define CFE_CMD_DEV_GETHANDLE 9
|
||||
#define CFE_CMD_DEV_ENUM 10
|
||||
#define CFE_CMD_DEV_OPEN 11
|
||||
#define CFE_CMD_DEV_INPSTAT 12
|
||||
#define CFE_CMD_DEV_READ 13
|
||||
#define CFE_CMD_DEV_WRITE 14
|
||||
#define CFE_CMD_DEV_IOCTL 15
|
||||
#define CFE_CMD_DEV_CLOSE 16
|
||||
#define CFE_CMD_DEV_GETINFO 17
|
||||
|
||||
#define CFE_CMD_ENV_ENUM 20
|
||||
#define CFE_CMD_ENV_GET 22
|
||||
#define CFE_CMD_ENV_SET 23
|
||||
#define CFE_CMD_ENV_DEL 24
|
||||
|
||||
#define CFE_CMD_MAX 32
|
||||
|
||||
#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
|
||||
|
||||
typedef u64 cfe_uint_t;
|
||||
typedef s64 cfe_int_t;
|
||||
typedef s64 cfe_ptr_t;
|
||||
|
||||
/* Cast a pointer from native to CFE-API pointer and back */
|
||||
#define CFE_TO_PTR(p) ((void *)(unsigned long)(p))
|
||||
#define PTR_TO_CFE(p) ((cfe_ptr_t)(unsigned long)(p))
|
||||
|
||||
struct cfe_iocb_buf {
|
||||
cfe_uint_t offset; /* offset on device (bytes) */
|
||||
cfe_ptr_t ptr; /* pointer to a buffer */
|
||||
cfe_uint_t length; /* length of this buffer */
|
||||
cfe_uint_t retlen; /* returned length (for read ops) */
|
||||
union {
|
||||
cfe_uint_t ioctlcmd; /* IOCTL command (used only for IOCTLs) */
|
||||
cfe_uint_t devflags; /* Returned device info flags */
|
||||
};
|
||||
};
|
||||
|
||||
struct cfe_iocb_inpstat {
|
||||
cfe_uint_t status; /* 1 means input available */
|
||||
};
|
||||
|
||||
struct cfe_iocb_envbuf {
|
||||
cfe_int_t index; /* 0-based enumeration index */
|
||||
cfe_ptr_t name; /* name string buffer */
|
||||
cfe_int_t name_len; /* size of name buffer */
|
||||
cfe_ptr_t val; /* value string buffer */
|
||||
cfe_int_t val_len; /* size of value string buffer */
|
||||
};
|
||||
|
||||
struct cfe_iocb_cpuctl {
|
||||
cfe_uint_t number; /* cpu number to control */
|
||||
cfe_uint_t command; /* command to issue to CPU */
|
||||
cfe_uint_t start_addr; /* CPU start address */
|
||||
cfe_uint_t gp; /* starting GP value */
|
||||
cfe_uint_t sp; /* starting SP value */
|
||||
cfe_uint_t a1; /* starting A1 value */
|
||||
};
|
||||
|
||||
struct cfe_iocb_time {
|
||||
cfe_int_t ticks; /* current time in ticks */
|
||||
};
|
||||
|
||||
struct cfe_iocb_exitstat {
|
||||
cfe_int_t status;
|
||||
};
|
||||
|
||||
struct cfe_iocb_meminfo {
|
||||
cfe_int_t index; /* 0-based enumeration index */
|
||||
cfe_int_t type; /* type of memory block */
|
||||
cfe_uint_t addr; /* physical start address */
|
||||
cfe_uint_t size; /* block size */
|
||||
};
|
||||
|
||||
struct cfe_iocb_fwinfo {
|
||||
cfe_int_t version; /* major, minor, eco version */
|
||||
cfe_int_t totalmem; /* total installed mem */
|
||||
cfe_int_t flags; /* various flags */
|
||||
cfe_int_t boardid; /* board ID */
|
||||
cfe_int_t bootarea_va; /* VA of boot area */
|
||||
cfe_int_t bootarea_pa; /* PA of boot area */
|
||||
cfe_int_t bootarea_size; /* size of boot area */
|
||||
cfe_int_t reserved1;
|
||||
cfe_int_t reserved2;
|
||||
cfe_int_t reserved3;
|
||||
};
|
||||
|
||||
/* CFE I/O Control Block */
|
||||
struct cfe_iocb {
|
||||
cfe_uint_t fcode; /* IOCB function code */
|
||||
cfe_int_t status; /* return status */
|
||||
cfe_int_t handle; /* file/device handle */
|
||||
cfe_uint_t flags; /* flags for this IOCB */
|
||||
cfe_uint_t psize; /* size of parameter list */
|
||||
union {
|
||||
struct cfe_iocb_buf buffer; /* buffer parameters */
|
||||
struct cfe_iocb_inpstat inpstat; /* input status parameters */
|
||||
struct cfe_iocb_envbuf envbuf; /* environment function parameters */
|
||||
struct cfe_iocb_cpuctl cpuctl; /* CPU control parameters */
|
||||
struct cfe_iocb_time time; /* timer parameters */
|
||||
struct cfe_iocb_meminfo meminfo; /* memory arena info parameters */
|
||||
struct cfe_iocb_fwinfo fwinfo; /* firmware information */
|
||||
struct cfe_iocb_exitstat exitstat; /* Exit Status */
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
|
||||
unsigned long fwarg2, unsigned long fwarg3);
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
.macro cfe_early_init
|
||||
#ifdef CONFIG_CFE
|
||||
jal cfe_setup
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* LINUX_CFE_PRIVATE_H_ */
|
||||
Reference in New Issue
Block a user