Major cleanup : - no more Broadcom kerSys* code - working runtime boot loader detection - updated flash map driver

SVN-Revision: 6896
lede-17.01
Florian Fainelli 2007-04-08 17:20:01 +00:00
parent 01e84cef1a
commit ebfd23d3b4
46 changed files with 2853 additions and 4978 deletions

View File

@ -1,41 +1,12 @@
CONFIG_32BIT=y CONFIG_32BIT=y
# CONFIG_64BIT is not set # CONFIG_64BIT is not set
# CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_64BIT_PHYS_ADDR is not set
# CONFIG_8139TOO is not set
CONFIG_AUDIT=y CONFIG_AUDIT=y
CONFIG_AUDIT_GENERIC=y CONFIG_AUDIT_GENERIC=y
# CONFIG_B44 is not set
CONFIG_BASE_SMALL=0 CONFIG_BASE_SMALL=0
# CONFIG_BCM96338 is not set
# CONFIG_BCM96345 is not set
CONFIG_BCM96348=y
CONFIG_BCM963XX=y CONFIG_BCM963XX=y
# CONFIG_BCM_ADSL is not set
CONFIG_BCM_ADSL_IMPL=1
# CONFIG_BCM_ATMAPI is not set
CONFIG_BCM_ATMAPI_IMPL=1
# CONFIG_BCM_ATMTEST is not set
CONFIG_BCM_ATMTEST_IMPL=1
CONFIG_BCM_BLAA_IMPL=1
# CONFIG_BCM_BOARD is not set
CONFIG_BCM_BOARD_IMPL=1
# CONFIG_BCM_ENDPOINT is not set
CONFIG_BCM_ENDPOINT_IMPL=1
# CONFIG_BCM_ENET is not set
CONFIG_BCM_ENET_IMPL=1
# CONFIG_BCM_HPNA is not set
CONFIG_BCM_HPNA_IMPL=0
CONFIG_BCM_PCI=y
CONFIG_BCM_PROCFS=y
CONFIG_BCM_PROCFS_IMPL=1
# CONFIG_BCM_SECURITY is not set
CONFIG_BCM_SECURITY_IMPL=1
CONFIG_BCM_SERIAL=y
CONFIG_BCM_SERIAL_IMPL=1
# CONFIG_BCM_USB is not set
CONFIG_BCM_USB_IMPL=1
# CONFIG_BCM_VDSL is not set
CONFIG_BCM_VDSL_IMPL=1
# CONFIG_BCM_WLAN is not set
CONFIG_BCM_WLAN_IMPL=1
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
# CONFIG_BLK_DEV_INITRD is not set # CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
@ -43,9 +14,7 @@ CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_NBD is not set
# CONFIG_BSD_DISKLABEL is not set # CONFIG_BSD_DISKLABEL is not set
CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_BT_HCIBCM203X is not set CONFIG_CFE=y
# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIBPA10X is not set
CONFIG_CICADA_PHY=m CONFIG_CICADA_PHY=m
# CONFIG_CIFS is not set # CONFIG_CIFS is not set
# CONFIG_CLS_U32_MARK is not set # CONFIG_CLS_U32_MARK is not set
@ -140,6 +109,7 @@ CONFIG_EQUALIZER=m
CONFIG_FIRMWARE_EDID=y CONFIG_FIRMWARE_EDID=y
# CONFIG_FIXED_PHY is not set # CONFIG_FIXED_PHY is not set
CONFIG_FORCED_INLINING=y CONFIG_FORCED_INLINING=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FW_LOADER=m CONFIG_FW_LOADER=m
CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_FIND_NEXT_BIT=y
# CONFIG_GEN_RTC is not set # CONFIG_GEN_RTC is not set
@ -181,8 +151,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_TUNNEL=m
CONFIG_IPW2100_DEBUG=y
CONFIG_IPW2200_DEBUG=y
# CONFIG_IP_DCCP_DEBUG is not set # CONFIG_IP_DCCP_DEBUG is not set
CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE=y
# CONFIG_IP_NF_ARPTABLES is not set # CONFIG_IP_NF_ARPTABLES is not set
@ -215,6 +183,7 @@ CONFIG_KEYBOARD_ATKBD=m
# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KGDB is not set # CONFIG_KGDB is not set
CONFIG_KMOD=y CONFIG_KMOD=y
# CONFIG_LAN_SAA9730 is not set
CONFIG_LBD=y CONFIG_LBD=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LLC2 is not set # CONFIG_LLC2 is not set
@ -273,20 +242,20 @@ CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set CONFIG_MTD_CFI_BE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not set # CONFIG_MTD_CFI_GEOMETRY is not set
CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set # CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_INTELEXT=y
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set # CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_NOSWAP=y # CONFIG_MTD_CFI_NOSWAP is not set
# CONFIG_MTD_CFI_STAA is not set CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_CONCAT=y CONFIG_MTD_CONCAT=y
# CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set
CONFIG_MTD_DEBUG=y CONFIG_MTD_DEBUG=y
@ -303,12 +272,10 @@ CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_NAND is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set
CONFIG_MTD_OBSOLETE_CHIPS=y
# CONFIG_MTD_ONENAND is not set # CONFIG_MTD_ONENAND is not set
# CONFIG_MTD_OTP is not set # CONFIG_MTD_OTP is not set
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_PCI is not set
# CONFIG_MTD_PHRAM is not set # CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_PLATRAM is not set # CONFIG_MTD_PLATRAM is not set
@ -319,8 +286,9 @@ CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
# CONFIG_MTD_ROM is not set # CONFIG_MTD_ROM is not set
# CONFIG_MTD_SHARP is not set
# CONFIG_MTD_SLRAM is not set # CONFIG_MTD_SLRAM is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_QUEUE=m
@ -330,7 +298,6 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
# CONFIG_NET_ACT_IPT is not set # CONFIG_NET_ACT_IPT is not set
CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SIMP=m
CONFIG_NET_KEY=y CONFIG_NET_KEY=y
# CONFIG_NET_PCI is not set
CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
# CONFIG_NET_SCH_CLK_JIFFIES is not set # CONFIG_NET_SCH_CLK_JIFFIES is not set
# CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_3COM is not set
@ -342,7 +309,7 @@ CONFIG_NLS_ASCII=m
CONFIG_PAGE_SIZE_4KB=y CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_64KB is not set # CONFIG_PAGE_SIZE_64KB is not set
# CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_8KB is not set
CONFIG_PCI_DEBUG=y # CONFIG_PCI_DEBUG is not set
CONFIG_PHYLIB=m CONFIG_PHYLIB=m
# CONFIG_PMC_YOSEMITE is not set # CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_JBS is not set
@ -415,68 +382,11 @@ CONFIG_TIPC=m
# CONFIG_TOSHIBA_RBTX4938 is not set # CONFIG_TOSHIBA_RBTX4938 is not set
CONFIG_TRAD_SIGNALS=y CONFIG_TRAD_SIGNALS=y
# CONFIG_UNUSED_SYMBOLS is not set # CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_USB_CATC is not set # CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_DEVICEFS is not set
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
CONFIG_USB_EHCI_SPLIT_ISO=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_KAWETH is not set
CONFIG_USB_MON=y
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_AIRPRIME is not set
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_CP2101 is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FUNSOFT is not set
# CONFIG_USB_SERIAL_GARMIN is not set
# CONFIG_USB_SERIAL_GENERIC is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IPW is not set
# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_KEYSPAN is not set
# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_KOBIL_SCT is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_MOS7720 is not set
# CONFIG_USB_SERIAL_MOS7840 is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_OMNINET is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_SAFE is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_USBNET is not set # CONFIG_VIA_RHINE is not set
# CONFIG_USB_USBNET_MII is not set
CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q=m
CONFIG_VM_EVENT_COUNTERS=y CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WAN_ROUTER=m CONFIG_WAN_ROUTER=m
# CONFIG_WATCHDOG is not set # CONFIG_WATCHDOG is not set
# CONFIG_XFS_FS is not set # CONFIG_XFS_FS is not set
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
CONFIG_YENTA_TI=y
CONFIG_YENTA_TOSHIBA=y

View File

@ -1,138 +0,0 @@
# Kernel and Driver configuration for Broadcom Commengine ADSL board
choice
prompt "Broadcom Commengine ADSL board"
depends on BCM963XX
default BCM96348
help
Select different Broadcom ADSL board
config BCM96338
bool "96338 ADSL board"
select DMA_NONCOHERENT
select HW_HAS_PCI
config BCM96345
bool "96345 ADSL board"
select DMA_NONCOHERENT
select HW_HAS_PCI
config BCM96348
bool "96348 ADSL board"
select DMA_NONCOHERENT
select HW_HAS_PCI
endchoice
config BCM_BOARD
bool "Support for Broadcom Board"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_SERIAL
bool "Support for Serial Port"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ENET
tristate "Support for Ethernet"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_USB
tristate "Support for USB"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_WLAN
tristate "Support for Wireless"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_PCI
bool "Support for PCI"
depends on BCM96338 || BCM96345 || BCM96348
select PCI
config BCM_ATMAPI
tristate "Support for ATM"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ATMTEST
tristate "Support for ATM Diagnostic"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ADSL
tristate "Support for ADSL"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ENDPOINT
tristate "Support for VOICE"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_PROCFS
tristate "Support for PROCFS"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_VDSL
tristate "Support for VDSL"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_SECURITY
tristate "Support for SECURITY"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_HPNA
tristate "Support for HPNA"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_BOARD_IMPL
int "Implementation index for ADSL Board"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_SERIAL_IMPL
int "Implementation index for Serial"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ENET_IMPL
int "Implementation index for Ethernet"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_USB_IMPL
int "Implementation index for USB"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_WLAN_IMPL
int "Implementation index for WIRELESS"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ATMAPI_IMPL
int "Implementation index for ATM"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ATMTEST_IMPL
int "Implementation index for ATM Diagnostic"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_BLAA_IMPL
int "Implementation index for BLAA"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ADSL_IMPL
int "Implementation index for ADSL"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_ENDPOINT_IMPL
int "Implementation index for VOICE"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_PROCFS_IMPL
int "Implementation index for PROCFS"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_VDSL_IMPL
int "Implementation index for VDSL"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_SECURITY_IMPL
int "Implementation index for SECURITY"
depends on BCM96338 || BCM96345 || BCM96348
config BCM_HPNA_IMPL
int "Implementation index for HPNA"
depends on BCM96338 || BCM96345 || BCM96348

View File

@ -1,23 +1,9 @@
# #
# Makefile for generic Broadcom MIPS boards # Makefile for the Broadcom BCM963xx SoC specific parts of the kernel
# #
# Copyright (C) 2004 Broadcom Corporation # Copyright (C) 2004 Broadcom Corporation
# #
obj-y := irq.o prom.o setup.o time.o ser_init.o bcm63xx_led.o board.o boardparms.o int-handler.o obj-y := irq.o prom.o setup.o time.o ser_init.o int-handler.o info.o
SRCBASE := $(TOPDIR) SRCBASE := $(TOPDIR)
EXTRA_CFLAGS += -I$(SRCBASE)/include EXTRA_CFLAGS += -I$(SRCBASE)/include
#EXTRA_CFLAGS += -I$(INC_ADSLDRV_PATH) -DDBG
EXTRA_CFLAGS += -I$(INC_ADSLDRV_PATH)
ifeq "$(ADSL)" "ANNEX_B"
EXTRA_CFLAGS += -DADSL_ANNEXB
endif
ifeq "$(ADSL)" "SADSL"
EXTRA_CFLAGS += -DADSL_SADSL
endif
ifeq "$(ADSL)" "ANNEX_C"
EXTRA_CFLAGS += -DADSL_ANNEXC
endif

View File

@ -1,582 +0,0 @@
/*
<:copyright-gpl
Copyright 2002 Broadcom Corp. All Rights Reserved.
This program is free software; you can distribute it and/or modify it
under the terms of the GNU General Public License (Version 2) as
published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
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.,
59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
:>
*/
/***************************************************************************
* File Name : bcm63xx_led.c
*
* Description:
*
* This file contains bcm963xx board led control API functions.
*
* To use it, do the following
*
* 1). define in the board.c the following led mappping (this is for 6345GW board):
* const LED_MAP_PAIR cLedMapping45GW[] =
* { // led name Initial state physical pin (ledMask)
* {kLedUsb, kLedStateOff, GPIO_LED_PIN_7},
* {kLedAdsl, kLedStateOff, GPIO_LED_PIN_8},
* {kLedPPP, kLedStateOff, GPIO_LED_PIN_9}, // PPP and WanData share PIN_9
* {kLedWanData, kLedStateOff, GPIO_LED_PIN_9},
* {kLedWireless, kLedStateOff, GPIO_LED_PIN_10},
* {kLedEnd, kLedStateOff, 0 } // NOTE: kLedEnd has to be at the end.
*
* 2). };To initialize led API and initial state of the leds, call the following function with the mapping
* pointer from the above struct
*
* boardLedInit((PLED_MAP_PAIR) &cLedMapping45R);
*
* 3). Sample call for kernel mode:
*
* kerSysLedCtrl(kLedAdsl, kLedStateBlinkOnce); // kLedxxx defines in board.h
*
* 4). Sample call for user mode
*
* sysLedCtrl(kLedAdsl, kLedStateBlinkOnce); // kLedxxx defines in board_api.h
*
*
* Created on : 10/28/2002 seanl
*
***************************************************************************/
/* Includes. */
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/capability.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <asm/uaccess.h>
#include <bcm_map_part.h>
#include <board.h>
#define k100ms (HZ / 10) // ~100 ms
#define kFastBlinkCount 0 // ~100ms
#define kSlowBlinkCount 5 // ~600ms
#define MAX_VIRT_LEDS 12
// uncomment // for debug led
//#define DEBUG_LED
// global variables:
struct timer_list gLedTimer;
int gTimerOn = FALSE;
int gLedCount = 0;
typedef struct ledinfo
{
unsigned short ledMask; // mask for led: ie. giop 10 = 0x0400
unsigned short ledActiveLow; // GPIO bit reset to turn on LED
unsigned short ledMaskFail; // mask for led: ie. giop 10 = 0x0400
unsigned short ledActiveLowFail;// GPIO bit reset to turn on LED
BOARD_LED_STATE ledState; // current led state
BOARD_LED_STATE savedLedState; // used in blink once for restore to the orignal ledState
int blinkCountDown; // if == 0, do blink (toggle). Is assgined value and dec by 1 at each timer.
} LED_INFO, *PLED_INFO;
static PLED_INFO gLed = NULL;
static PLED_INFO gpVirtLeds[MAX_VIRT_LEDS];
static HANDLE_LED_FUNC gLedHwFunc[MAX_VIRT_LEDS];
static HANDLE_LED_FUNC gLedHwFailFunc[MAX_VIRT_LEDS];
#if 0 /* BROKEN */
#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
static int gLedOffInBridgeMode = 1;
#elif defined(CONFIG_BCM96345)
static int gLedOffInBridgeMode = 0;
#endif
#endif
void ledTimerExpire(void);
int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed );
//**************************************************************************************
// LED operations
//**************************************************************************************
// turn led on and set the ledState
void ledOn(PLED_INFO pLed)
{
if( pLed->ledMask )
{
GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one
if( pLed->ledActiveLow )
GPIO->GPIOio &= ~pLed->ledMask; // turn on the led
else
GPIO->GPIOio |= pLed->ledMask; // turn on the led
pLed->ledState = pLed->savedLedState = kLedStateOn;
}
}
// turn led off and set the ledState
void ledOff(PLED_INFO pLed)
{
if( pLed->ledMask )
{
GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one
if( pLed->ledActiveLow )
GPIO->GPIOio |= pLed->ledMask; // turn off the led
else
GPIO->GPIOio &= ~pLed->ledMask; // turn off the led
pLed->ledState = pLed->savedLedState = kLedStateOff;
}
}
// turn led on and set the ledState
void ledOnFail(PLED_INFO pLed)
{
if( pLed->ledMaskFail )
{
GPIO->GPIODir |= pLed->ledMaskFail; // turn on the direction bit in case was turned off by some one
if( pLed->ledActiveLowFail )
GPIO->GPIOio &= ~pLed->ledMaskFail;// turn on the led
else
GPIO->GPIOio |= pLed->ledMaskFail; // turn on the led
pLed->ledState = pLed->savedLedState = kLedStateFail;
}
}
// turn led off and set the ledState
void ledOffFail(PLED_INFO pLed)
{
if( pLed->ledMaskFail )
{
GPIO->GPIODir |= pLed->ledMaskFail; // turn on the direction bit in case was turned off by some one
if( pLed->ledActiveLowFail )
GPIO->GPIOio |= pLed->ledMaskFail; // turn off the led
else
GPIO->GPIOio &= ~pLed->ledMaskFail;// turn off the led
pLed->ledState = pLed->savedLedState = kLedStateOff;
}
}
// toggle the led and return the current ledState
BOARD_LED_STATE ledToggle(PLED_INFO pLed)
{
GPIO->GPIODir |= pLed->ledMask; // turn on the direction bit in case was turned off by some one
if (GPIO->GPIOio & pLed->ledMask)
{
GPIO->GPIOio &= ~(pLed->ledMask);
return( (pLed->ledActiveLow) ? kLedStateOn : kLedStateOff );
}
else
{
GPIO->GPIOio |= pLed->ledMask;
return( (pLed->ledActiveLow) ? kLedStateOff : kLedStateOn );
}
}
// led timer. Will return if timer is already on
void ledTimerStart(void)
{
if (gTimerOn)
return;
#if defined(DEBUG_LED)
printk("led: add_timer\n");
#endif
init_timer(&gLedTimer);
gLedTimer.function = (void*)ledTimerExpire;
gLedTimer.expires = jiffies + k100ms; // timer expires in ~100ms
add_timer (&gLedTimer);
gTimerOn = TRUE;
}
// led timer expire kicks in about ~100ms and perform the led operation according to the ledState and
// restart the timer according to ledState
void ledTimerExpire(void)
{
int i;
PLED_INFO pCurLed;
gTimerOn = FALSE;
for (i = 0, pCurLed = gLed; i < gLedCount; i++, pCurLed++)
{
#if defined(DEBUG_LED)
printk("led[%d]: Mask=0x%04x, State = %d, blcd=%d\n", i, pCurLed->ledMask, pCurLed->ledState, pCurLed->blinkCountDown);
#endif
switch (pCurLed->ledState)
{
case kLedStateOn:
case kLedStateOff:
case kLedStateFail:
pCurLed->blinkCountDown = 0; // reset the blink count down
break;
case kLedStateBlinkOnce:
ledToggle(pCurLed);
pCurLed->blinkCountDown = 0; // reset to 0
pCurLed->ledState = pCurLed->savedLedState;
if (pCurLed->ledState == kLedStateSlowBlinkContinues ||
pCurLed->ledState == kLedStateFastBlinkContinues)
ledTimerStart(); // start timer if in blinkContinues stats
break;
case kLedStateSlowBlinkContinues:
if (pCurLed->blinkCountDown-- == 0)
{
pCurLed->blinkCountDown = kSlowBlinkCount;
ledToggle(pCurLed);
}
ledTimerStart();
break;
case kLedStateFastBlinkContinues:
if (pCurLed->blinkCountDown-- == 0)
{
pCurLed->blinkCountDown = kFastBlinkCount;
ledToggle(pCurLed);
}
ledTimerStart();
break;
default:
printk("Invalid state = %d\n", pCurLed->ledState);
}
}
}
// initialize the gLedCount and allocate and fill gLed struct
void __init boardLedInit(PLED_MAP_PAIR cLedMapping)
{
PLED_MAP_PAIR p1, p2;
PLED_INFO pCurLed;
int needTimer = FALSE;
int alreadyUsed = 0;
#if defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
/* Set blink rate for BCM6348/BCM6338 hardware LEDs. */
GPIO->LEDCtrl &= ~LED_INTERVAL_SET_MASK;
GPIO->LEDCtrl |= LED_INTERVAL_SET_80MS;
#endif
memset( gpVirtLeds, 0x00, sizeof(gpVirtLeds) );
memset( gLedHwFunc, 0x00, sizeof(gLedHwFunc) );
memset( gLedHwFailFunc, 0x00, sizeof(gLedHwFailFunc) );
gLedCount = 0;
// Check for multiple LED names and multiple LED GPIO pins that share the
// same physical board LED.
for( p1 = cLedMapping; p1->ledName != kLedEnd; p1++ )
{
alreadyUsed = 0;
for( p2 = cLedMapping; p2 != p1; p2++ )
{
if( (p1->ledMask && p1->ledMask == p2->ledMask) ||
(p1->ledMaskFail && p1->ledMaskFail == p2->ledMaskFail) )
{
alreadyUsed = 1;
break;
}
}
if( alreadyUsed == 0 )
gLedCount++;
}
gLed = (PLED_INFO) kmalloc((gLedCount * sizeof(LED_INFO)), GFP_KERNEL);
if( gLed == NULL )
{
printk( "LED memory allocation error.\n" );
return;
}
memset( gLed, 0x00, gLedCount * sizeof(LED_INFO) );
// initial the gLed with unique ledMask and initial state. If more than 1 ledNames share the physical led
// (ledMask) the first defined led's ledInitState will be used.
pCurLed = gLed;
for( p1 = cLedMapping; p1->ledName != kLedEnd; p1++ )
{
if( (int) p1->ledName > MAX_VIRT_LEDS )
continue;
alreadyUsed = 0;
for( p2 = cLedMapping; p2 != p1; p2++ )
{
if( (p1->ledMask && p1->ledMask == p2->ledMask) ||
(p1->ledMaskFail && p1->ledMaskFail == p2->ledMaskFail) )
{
alreadyUsed = 1;
break;
}
}
if( alreadyUsed == 0 )
{
// Initialize the board LED for the first time.
needTimer = initLedInfo( p1, pCurLed );
gpVirtLeds[(int) p1->ledName] = pCurLed;
pCurLed++;
}
else
{
PLED_INFO pLed;
for( pLed = gLed; pLed != pCurLed; pLed++ )
{
// Find the LED_INFO structure that has already been initialized.
if((pLed->ledMask && pLed->ledMask == p1->ledMask) ||
(pLed->ledMaskFail && pLed->ledMaskFail==p1->ledMaskFail))
{
// The board LED has already been initialized but possibly
// not completely initialized.
if( p1->ledMask )
{
pLed->ledMask = p1->ledMask;
pLed->ledActiveLow = p1->ledActiveLow;
}
if( p1->ledMaskFail )
{
pLed->ledMaskFail = p1->ledMaskFail;
pLed->ledActiveLowFail = p1->ledActiveLowFail;
}
gpVirtLeds[(int) p1->ledName] = pLed;
break;
}
}
}
}
if (needTimer)
ledTimerStart();
#if defined(DEBUG_LED)
int i;
for (i=0; i < gLedCount; i++)
printk("initLed: led[%d]: mask=0x%04x, state=%d\n", i,(gLed+i)->ledMask, (gLed+i)->ledState);
#endif
}
// Initialize a structure that contains information about a physical board LED
// control. The board LED may contain more than one GPIO pin to control a
// normal condition (green) or a failure condition (red).
int initLedInfo( PLED_MAP_PAIR pCurMap, PLED_INFO pCurLed )
{
int needTimer = FALSE;
pCurLed->ledState = pCurLed->savedLedState = pCurMap->ledInitState;
pCurLed->ledMask = pCurMap->ledMask;
pCurLed->ledActiveLow = pCurMap->ledActiveLow;
pCurLed->ledMaskFail = pCurMap->ledMaskFail;
pCurLed->ledActiveLowFail = pCurMap->ledActiveLowFail;
switch (pCurLed->ledState)
{
case kLedStateOn:
pCurLed->blinkCountDown = 0; // reset the blink count down
ledOn(pCurLed);
break;
case kLedStateOff:
pCurLed->blinkCountDown = 0; // reset the blink count down
ledOff(pCurLed);
break;
case kLedStateFail:
pCurLed->blinkCountDown = 0; // reset the blink count down
ledOnFail(pCurLed);
break;
case kLedStateBlinkOnce:
pCurLed->blinkCountDown = 1;
needTimer = TRUE;
break;
case kLedStateSlowBlinkContinues:
pCurLed->blinkCountDown = kSlowBlinkCount;
needTimer = TRUE;
break;
case kLedStateFastBlinkContinues:
pCurLed->blinkCountDown = kFastBlinkCount;
needTimer = TRUE;
break;
default:
printk("Invalid state = %d\n", pCurLed->ledState);
}
return( needTimer );
}
#if 0 /* BROKEN */
// Determines if there is at least one interface in bridge mode. Bridge mode
// is determined by the cfm convention of naming bridge interfaces nas17
// through nas24.
static int isBridgedProtocol(void)
{
extern int dev_get(const char *name);
const int firstBridgeId = 17;
const int lastBridgeId = 24;
int i;
int ret = FALSE;
char name[16];
for( i = firstBridgeId; i <= lastBridgeId; i++ )
{
sprintf( name, "nas%d", i );
if( dev_get(name) )
{
ret = TRUE;
break;
}
}
return(ret);
}
#endif
// led ctrl. Maps the ledName to the corresponding ledInfoPtr and perform the led operation
void boardLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
{
PLED_INFO ledInfoPtr;
// do the mapping from virtual to physical led
if( (int) ledName < MAX_VIRT_LEDS )
ledInfoPtr = gpVirtLeds[(int) ledName];
else
ledInfoPtr = NULL;
if (ledInfoPtr == NULL)
return;
if( ledState != kLedStateFail && gLedHwFunc[(int) ledName] )
{
(*gLedHwFunc[(int) ledName]) (ledName, ledState);
ledOffFail(ledInfoPtr);
return;
}
else
if( ledState == kLedStateFail && gLedHwFailFunc[(int) ledName] )
{
(*gLedHwFailFunc[(int) ledName]) (ledName, ledState);
ledOff(ledInfoPtr);
return;
}
#if 0 /* BROKEN */
// Do not blink the WAN Data LED if at least one interface is in bridge mode.
if(gLedOffInBridgeMode == 1 && (ledName == kLedWanData || ledName == kLedPPP))
{
static int BridgedProtocol = -1;
if( BridgedProtocol == -1 )
BridgedProtocol = isBridgedProtocol();
if( BridgedProtocol == TRUE )
return;
}
#endif
// If the state is kLedStateFail and there is not a failure LED defined
// in the board parameters, change the state to kLedStateFastBlinkContinues.
if( ledState == kLedStateFail && ledInfoPtr->ledMaskFail == 0 )
ledState = kLedStateFastBlinkContinues;
switch (ledState)
{
case kLedStateOn:
// First, turn off the complimentary (failure) LED GPIO.
if( ledInfoPtr->ledMaskFail )
ledOffFail(ledInfoPtr);
else
if( gLedHwFailFunc[(int) ledName] )
(*gLedHwFailFunc[(int) ledName]) (ledName, kLedStateOff);
// Next, turn on the specified LED GPIO.
ledOn(ledInfoPtr);
break;
case kLedStateOff:
// First, turn off the complimentary (failure) LED GPIO.
if( ledInfoPtr->ledMaskFail )
ledOffFail(ledInfoPtr);
else
if( gLedHwFailFunc[(int) ledName] )
(*gLedHwFailFunc[(int) ledName]) (ledName, kLedStateOff);
// Next, turn off the specified LED GPIO.
ledOff(ledInfoPtr);
break;
case kLedStateFail:
// First, turn off the complimentary (normal) LED GPIO.
if( ledInfoPtr->ledMask )
ledOff(ledInfoPtr);
else
if( gLedHwFunc[(int) ledName] )
(*gLedHwFunc[(int) ledName]) (ledName, kLedStateOff);
// Next, turn on (red) the specified LED GPIO.
ledOnFail(ledInfoPtr);
break;
case kLedStateBlinkOnce:
// skip blinkOnce if it is already in Slow/Fast blink continues state
if (ledInfoPtr->savedLedState == kLedStateSlowBlinkContinues ||
ledInfoPtr->savedLedState == kLedStateFastBlinkContinues)
;
else
{
if (ledInfoPtr->blinkCountDown == 0) // skip the call if it is 1
{
ledToggle(ledInfoPtr);
ledInfoPtr->blinkCountDown = 1; // it will be reset to 0 when timer expires
ledInfoPtr->ledState = kLedStateBlinkOnce;
ledTimerStart();
}
}
break;
case kLedStateSlowBlinkContinues:
ledInfoPtr->blinkCountDown = kSlowBlinkCount;
ledInfoPtr->ledState = kLedStateSlowBlinkContinues;
ledInfoPtr->savedLedState = kLedStateSlowBlinkContinues;
ledTimerStart();
break;
case kLedStateFastBlinkContinues:
ledInfoPtr->blinkCountDown = kFastBlinkCount;
ledInfoPtr->ledState = kLedStateFastBlinkContinues;
ledInfoPtr->savedLedState = kLedStateFastBlinkContinues;
ledTimerStart();
break;
default:
printk("Invalid led state\n");
}
}
// This function is called for an LED that is controlled by hardware.
void kerSysLedRegisterHwHandler( BOARD_LED_NAME ledName,
HANDLE_LED_FUNC ledHwFunc, int ledFailType )
{
if( (int) ledName < MAX_VIRT_LEDS )
{
if( ledFailType == 1 )
gLedHwFailFunc[(int) ledName] = ledHwFunc;
else
gLedHwFunc[(int) ledName] = ledHwFunc;
}
}

View File

@ -1,559 +0,0 @@
/*
<:copyright-gpl
Copyright 2002 Broadcom Corp. All Rights Reserved.
This program is free software; you can distribute it and/or modify it
under the terms of the GNU General Public License (Version 2) as
published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
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.,
59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
:>
*/
/* Includes. */
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <asm/uaccess.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/if.h>
#include <linux/spinlock.h>
#include <bcm_map_part.h>
#include <board.h>
#include <bcmTag.h>
#include "boardparms.h"
#include "bcm_intr.h"
#include "board.h"
#include "bcm_map_part.h"
static DEFINE_SPINLOCK(board_lock);
/* Typedefs. */
#if defined (NON_CONSECUTIVE_MAC)
// used to be the last octet. Now changed to the first 5 bits of the the forth octet
// to reduced the duplicated MAC addresses.
#define CHANGED_OCTET 3
#define SHIFT_BITS 3
#else
#define CHANGED_OCTET 1
#define SHIFT_BITS 0
#endif
typedef struct
{
unsigned long ulId;
char chInUse;
char chReserved[3];
} MAC_ADDR_INFO, *PMAC_ADDR_INFO;
typedef struct
{
unsigned long ulSdramSize;
unsigned long ulPsiSize;
unsigned long ulNumMacAddrs;
unsigned long ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN];
MAC_ADDR_INFO MacAddrs[1];
} NVRAM_INFO, *PNVRAM_INFO;
typedef struct
{
unsigned long eventmask;
} BOARD_IOC, *PBOARD_IOC;
/*Dyinggasp callback*/
typedef void (*cb_dgasp_t)(void *arg);
typedef struct _CB_DGASP__LIST
{
struct list_head list;
char name[IFNAMSIZ];
cb_dgasp_t cb_dgasp_fn;
void *context;
}CB_DGASP_LIST , *PCB_DGASP_LIST;
static LED_MAP_PAIR LedMapping[] =
{ // led name Initial state physical pin (ledMask)
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0},
{kLedEnd, kLedStateOff, 0, 0, 0, 0} // NOTE: kLedEnd has to be at the end.
};
/* Externs. */
extern struct file fastcall *fget_light(unsigned int fd, int *fput_needed);
extern unsigned int nr_free_pages (void);
extern const char *get_system_type(void);
extern void kerSysFlashInit(void);
extern unsigned long get_nvram_start_addr(void);
extern unsigned long get_scratch_pad_start_addr(void);
extern unsigned long getMemorySize(void);
extern void __init boardLedInit(PLED_MAP_PAIR);
extern void boardLedCtrl(BOARD_LED_NAME, BOARD_LED_STATE);
extern void kerSysLedRegisterHandler( BOARD_LED_NAME ledName,
HANDLE_LED_FUNC ledHwFunc, int ledFailType );
/* Prototypes. */
void __init InitNvramInfo( void );
/* DyingGasp function prototype */
static void __init kerSysDyingGaspMapIntr(void);
static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id);
static void __init kerSysInitDyingGaspHandler( void );
static void __exit kerSysDeinitDyingGaspHandler( void );
/* -DyingGasp function prototype - */
static PNVRAM_INFO g_pNvramInfo = NULL;
static int g_ledInitialized = 0;
static CB_DGASP_LIST *g_cb_dgasp_list_head = NULL;
static int g_wakeup_monitor = 0;
static struct file *g_monitor_file = NULL;
static struct task_struct *g_monitor_task = NULL;
static unsigned int (*g_orig_fop_poll)
(struct file *, struct poll_table_struct *) = NULL;
void kerSysMipsSoftReset(void)
{
if (PERF->RevID == 0x634800A1) {
typedef void (*FNPTR) (void);
FNPTR bootaddr = (FNPTR) FLASH_BASE;
int i;
/* Disable interrupts. */
//cli();
spin_lock_irq(&board_lock);
/* Reset all blocks. */
PERF->BlockSoftReset &= ~BSR_ALL_BLOCKS;
for( i = 0; i < 1000000; i++ )
;
PERF->BlockSoftReset |= BSR_ALL_BLOCKS;
/* Jump to the power on address. */
(*bootaddr) ();
}
else
PERF->pll_control |= SOFT_RESET; // soft reset mips
}
int kerSysGetMacAddress( unsigned char *pucaMacAddr, unsigned long ulId )
{
int nRet = 0;
PMAC_ADDR_INFO pMai = NULL;
PMAC_ADDR_INFO pMaiFreeNoId = NULL;
PMAC_ADDR_INFO pMaiFreeId = NULL;
unsigned long i = 0, ulIdxNoId = 0, ulIdxId = 0, shiftedIdx = 0;
/* CMO -- Fix le problème avec les adresses mac que l'on n'arrive pas
* * à relire plusieurs fois */
/* inv_xde */
#if 0
if (boot_loader_type == BOOT_CFE)
memcpy( pucaMacAddr, g_pNvramInfo->ucaBaseMacAddr,
NVRAM_MAC_ADDRESS_LEN );
else {
#endif
pucaMacAddr[0] = 0x00;
pucaMacAddr[1] = 0x07;
pucaMacAddr[2] = 0x3A;
pucaMacAddr[3] = 0xFF;
pucaMacAddr[4] = 0xFF;
pucaMacAddr[5] = 0xFF;
#if 0
}
#endif
return nRet;
} /* kerSysGetMacAddr */
int kerSysReleaseMacAddress( unsigned char *pucaMacAddr )
{
int nRet = -EINVAL;
unsigned long ulIdx = 0;
int idx = (pucaMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET] -
g_pNvramInfo->ucaBaseMacAddr[NVRAM_MAC_ADDRESS_LEN - CHANGED_OCTET]);
// if overflow 255 (negitive), add 256 to have the correct index
if (idx < 0)
idx += 256;
ulIdx = (unsigned long) (idx >> SHIFT_BITS);
if( ulIdx < g_pNvramInfo->ulNumMacAddrs )
{
PMAC_ADDR_INFO pMai = &g_pNvramInfo->MacAddrs[ulIdx];
if( pMai->chInUse == 1 )
{
pMai->chInUse = 0;
nRet = 0;
}
}
return( nRet );
} /* kerSysReleaseMacAddr */
int kerSysGetSdramSize( void )
{
if (boot_loader_type == BOOT_CFE) {
return( (int) g_pNvramInfo->ulSdramSize );
}
else {
printk("kerSysGetSdramSize : 0x%08X\n", (int)getMemorySize() + 0x00040000);
return((int)getMemorySize() + 0x00040000);
}
} /* kerSysGetSdramSize */
void kerSysLedCtrl(BOARD_LED_NAME ledName, BOARD_LED_STATE ledState)
{
if (g_ledInitialized)
boardLedCtrl(ledName, ledState);
}
unsigned int kerSysMonitorPollHook( struct file *f, struct poll_table_struct *t)
{
int mask = (*g_orig_fop_poll) (f, t);
if( g_wakeup_monitor == 1 && g_monitor_file == f )
{
/* If g_wakeup_monitor is non-0, the user mode application needs to
* return from a blocking select function. Return POLLPRI which will
* cause the select to return with the exception descriptor set.
*/
mask |= POLLPRI;
g_wakeup_monitor = 0;
}
return( mask );
}
/* Put the user mode application that monitors link state on a run queue. */
void kerSysWakeupMonitorTask( void )
{
g_wakeup_monitor = 1;
if( g_monitor_task )
wake_up_process( g_monitor_task );
}
//<<JUNHON, 2004/09/15, get reset button status , tim hou , 05/04/12
int kerSysGetResetHold(void)
{
unsigned short gpio;
if( BpGetPressAndHoldResetGpio( &gpio ) == BP_SUCCESS )
{
unsigned long gpio_mask = GPIO_NUM_TO_MASK(gpio);
volatile unsigned long *gpio_reg = &GPIO->GPIOio;
if( (gpio & ~BP_ACTIVE_MASK) >= 32 )
{
gpio_mask = GPIO_NUM_TO_MASK_HIGH(gpio);
gpio_reg = &GPIO->GPIOio_high;
}
//printk("gpio=%04x,gpio_mask=%04x,gpio_reg=%04x\n",gpio,gpio_mask,*gpio_reg);
if(*gpio_reg & gpio_mask) //press down
return RESET_BUTTON_UP;
}
return RESET_BUTTON_PRESSDOWN;
}
//<<JUNHON, 2004/09/15
/***************************************************************************
* Dying gasp ISR and functions.
***************************************************************************/
#define KERSYS_DBG printk
#if defined(CONFIG_BCM96345)
#define CYCLE_PER_US 70
#elif defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)
/* The BCM6348 cycles per microsecond is really variable since the BCM6348
* MIPS speed can vary depending on the PLL settings. However, an appoximate
* value of 120 will still work OK for the test being done.
*/
#define CYCLE_PER_US 120
#endif
#define DG_GLITCH_TO (100*CYCLE_PER_US)
static void __init kerSysDyingGaspMapIntr()
{
unsigned long ulIntr;
#if defined(CONFIG_BCM96348) || defined(_BCM96348_) || defined(CONFIG_BCM96338) || defined(_BCM96338_)
if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) {
BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, INTERRUPT_ID_DG);
BcmHalInterruptEnable( INTERRUPT_ID_DG );
}
#elif defined(CONFIG_BCM96345) || defined(_BCM96345_)
if( BpGetAdslDyingGaspExtIntr( &ulIntr ) == BP_SUCCESS ) {
ulIntr += INTERRUPT_ID_EXTERNAL_0;
BcmHalMapInterrupt((FN_HANDLER)kerSysDyingGaspIsr, 0, ulIntr);
BcmHalInterruptEnable( ulIntr );
}
#endif
}
void kerSysSetWdTimer(ulong timeUs)
{
TIMER->WatchDogDefCount = timeUs * (FPERIPH/1000000);
TIMER->WatchDogCtl = 0xFF00;
TIMER->WatchDogCtl = 0x00FF;
}
ulong kerSysGetCycleCount(void)
{
ulong cnt;
#ifdef _WIN32_WCE
cnt = 0;
#else
__asm volatile("mfc0 %0, $9":"=d"(cnt));
#endif
return(cnt);
}
static Bool kerSysDyingGaspCheckPowerLoss(void)
{
ulong clk0;
ulong ulIntr;
ulIntr = 0;
clk0 = kerSysGetCycleCount();
UART->Data = 'D';
UART->Data = '%';
UART->Data = 'G';
#if defined(CONFIG_BCM96345)
BpGetAdslDyingGaspExtIntr( &ulIntr );
do {
ulong clk1;
clk1 = kerSysGetCycleCount(); /* time cleared */
/* wait a little to get new reading */
while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2)
;
} while ((0 == (PERF->ExtIrqCfg & (1 << (ulIntr + EI_STATUS_SHFT)))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO));
if (PERF->ExtIrqCfg & (1 << (ulIntr + EI_STATUS_SHFT))) { /* power glitch */
BcmHalInterruptEnable( ulIntr + INTERRUPT_ID_EXTERNAL_0);
KERSYS_DBG(" - Power glitch detected. Duration: %ld us\n", (kerSysGetCycleCount() - clk0)/CYCLE_PER_US);
return 0;
}
#elif (defined(CONFIG_BCM96348) || defined(CONFIG_BCM96338)) && !defined(VXWORKS)
do {
ulong clk1;
clk1 = kerSysGetCycleCount(); /* time cleared */
/* wait a little to get new reading */
while ((kerSysGetCycleCount()-clk1) < CYCLE_PER_US*2)
;
} while ((PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET))) && ((kerSysGetCycleCount() - clk0) < DG_GLITCH_TO));
if (!(PERF->IrqStatus & (1 << (INTERRUPT_ID_DG - INTERNAL_ISR_TABLE_OFFSET)))) {
BcmHalInterruptEnable( INTERRUPT_ID_DG );
KERSYS_DBG(" - Power glitch detected. Duration: %ld us\n", (kerSysGetCycleCount() - clk0)/CYCLE_PER_US);
return 0;
}
#endif
return 1;
}
static void kerSysDyingGaspShutdown( void )
{
kerSysSetWdTimer(1000000);
#if defined(CONFIG_BCM96345)
PERF->blkEnables &= ~(EMAC_CLK_EN | USB_CLK_EN | CPU_CLK_EN);
#elif defined(CONFIG_BCM96348)
PERF->blkEnables &= ~(EMAC_CLK_EN | USBS_CLK_EN | USBH_CLK_EN | SAR_CLK_EN);
#endif
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
static irqreturn_t kerSysDyingGaspIsr(int irq, void * dev_id)
#else
static unsigned int kerSysDyingGaspIsr(void)
#endif
{
struct list_head *pos;
CB_DGASP_LIST *tmp, *dsl = NULL;
if (kerSysDyingGaspCheckPowerLoss()) {
/* first to turn off everything other than dsl */
list_for_each(pos, &g_cb_dgasp_list_head->list) {
tmp = list_entry(pos, CB_DGASP_LIST, list);
if(strncmp(tmp->name, "dsl", 3)) {
(tmp->cb_dgasp_fn)(tmp->context);
}else {
dsl = tmp;
}
}
/* now send dgasp */
if(dsl)
(dsl->cb_dgasp_fn)(dsl->context);
/* reset and shutdown system */
kerSysDyingGaspShutdown();
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
return( IRQ_HANDLED );
#else
return( 1 );
#endif
}
static void __init kerSysInitDyingGaspHandler( void )
{
CB_DGASP_LIST *new_node;
if( g_cb_dgasp_list_head != NULL) {
printk("Error: kerSysInitDyingGaspHandler: list head is not null\n");
return;
}
new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL);
memset(new_node, 0x00, sizeof(CB_DGASP_LIST));
INIT_LIST_HEAD(&new_node->list);
g_cb_dgasp_list_head = new_node;
} /* kerSysInitDyingGaspHandler */
static void __exit kerSysDeinitDyingGaspHandler( void )
{
struct list_head *pos;
CB_DGASP_LIST *tmp;
if(g_cb_dgasp_list_head == NULL)
return;
list_for_each(pos, &g_cb_dgasp_list_head->list) {
tmp = list_entry(pos, CB_DGASP_LIST, list);
list_del(pos);
kfree(tmp);
}
kfree(g_cb_dgasp_list_head);
g_cb_dgasp_list_head = NULL;
} /* kerSysDeinitDyingGaspHandler */
void kerSysRegisterDyingGaspHandler(char *devname, void *cbfn, void *context)
{
CB_DGASP_LIST *new_node;
if( g_cb_dgasp_list_head == NULL) {
printk("Error: kerSysRegisterDyingGaspHandler: list head is null\n");
return;
}
if( devname == NULL || cbfn == NULL ) {
printk("Error: kerSysRegisterDyingGaspHandler: register info not enough (%s,%x,%x)\n", devname, (unsigned int)cbfn, (unsigned int)context);
return;
}
new_node= (CB_DGASP_LIST *)kmalloc(sizeof(CB_DGASP_LIST), GFP_KERNEL);
memset(new_node, 0x00, sizeof(CB_DGASP_LIST));
INIT_LIST_HEAD(&new_node->list);
strncpy(new_node->name, devname, IFNAMSIZ);
new_node->cb_dgasp_fn = (cb_dgasp_t)cbfn;
new_node->context = context;
list_add(&new_node->list, &g_cb_dgasp_list_head->list);
printk("dgasp: kerSysRegisterDyingGaspHandler: %s registered \n", devname);
} /* kerSysRegisterDyingGaspHandler */
void kerSysDeregisterDyingGaspHandler(char *devname)
{
struct list_head *pos;
CB_DGASP_LIST *tmp;
if(g_cb_dgasp_list_head == NULL) {
printk("Error: kerSysDeregisterDyingGaspHandler: list head is null\n");
return;
}
if(devname == NULL) {
printk("Error: kerSysDeregisterDyingGaspHandler: devname is null\n");
return;
}
printk("kerSysDeregisterDyingGaspHandler: %s is deregistering\n", devname);
list_for_each(pos, &g_cb_dgasp_list_head->list) {
tmp = list_entry(pos, CB_DGASP_LIST, list);
if(!strcmp(tmp->name, devname)) {
list_del(pos);
kfree(tmp);
printk("kerSysDeregisterDyingGaspHandler: %s is deregistered\n", devname);
return;
}
}
printk("kerSysDeregisterDyingGaspHandler: %s not (de)registered\n", devname);
} /* kerSysDeregisterDyingGaspHandler */
//EXPORT_SYMBOL(kerSysNvRamGet);
EXPORT_SYMBOL(kerSysGetMacAddress);
EXPORT_SYMBOL(kerSysReleaseMacAddress);
EXPORT_SYMBOL(kerSysGetSdramSize);
EXPORT_SYMBOL(kerSysLedCtrl);
EXPORT_SYMBOL(kerSysGetResetHold);
EXPORT_SYMBOL(kerSysLedRegisterHwHandler);
EXPORT_SYMBOL(BpGetBoardIds);
EXPORT_SYMBOL(BpGetSdramSize);
EXPORT_SYMBOL(BpGetPsiSize);
EXPORT_SYMBOL(BpGetEthernetMacInfo);
EXPORT_SYMBOL(BpGetRj11InnerOuterPairGpios);
EXPORT_SYMBOL(BpGetPressAndHoldResetGpio);
EXPORT_SYMBOL(BpGetVoipResetGpio);
EXPORT_SYMBOL(BpGetVoipIntrGpio);
EXPORT_SYMBOL(BpGetPcmciaResetGpio);
EXPORT_SYMBOL(BpGetRtsCtsUartGpios);
EXPORT_SYMBOL(BpGetAdslLedGpio);
EXPORT_SYMBOL(BpGetAdslFailLedGpio);
EXPORT_SYMBOL(BpGetWirelessLedGpio);
EXPORT_SYMBOL(BpGetUsbLedGpio);
EXPORT_SYMBOL(BpGetHpnaLedGpio);
EXPORT_SYMBOL(BpGetWanDataLedGpio);
EXPORT_SYMBOL(BpGetPppLedGpio);
EXPORT_SYMBOL(BpGetPppFailLedGpio);
EXPORT_SYMBOL(BpGetVoipLedGpio);
EXPORT_SYMBOL(BpGetWirelessExtIntr);
EXPORT_SYMBOL(BpGetAdslDyingGaspExtIntr);
EXPORT_SYMBOL(BpGetVoipExtIntr);
EXPORT_SYMBOL(BpGetHpnaExtIntr);
EXPORT_SYMBOL(BpGetHpnaChipSelect);
EXPORT_SYMBOL(BpGetVoipChipSelect);
EXPORT_SYMBOL(BpGetWirelessSesBtnGpio);
EXPORT_SYMBOL(BpGetWirelessSesExtIntr);
EXPORT_SYMBOL(BpGetWirelessSesLedGpio);
EXPORT_SYMBOL(kerSysRegisterDyingGaspHandler);
EXPORT_SYMBOL(kerSysDeregisterDyingGaspHandler);
EXPORT_SYMBOL(kerSysGetCycleCount);
EXPORT_SYMBOL(kerSysSetWdTimer);
EXPORT_SYMBOL(kerSysWakeupMonitorTask);

File diff suppressed because it is too large Load Diff

View File

@ -1,758 +0,0 @@
/*
<:copyright-gpl
Copyright 2003 Broadcom Corp. All Rights Reserved.
This program is free software; you can distribute it and/or modify it
under the terms of the GNU General Public License (Version 2) as
published by the Free Software Foundation.
This program is distributed in the hope it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
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.,
59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
:>
*/
/**************************************************************************
* File Name : boardparms.h
*
* Description: This file contains definitions and function prototypes for
* the BCM63xx board parameter access functions.
*
* Updates : 07/14/2003 Created.
***************************************************************************/
#if !defined(_BOARDPARMS_H)
#define _BOARDPARMS_H
/* Return codes. */
#define BP_SUCCESS 0
#define BP_BOARD_ID_NOT_FOUND 1
#define BP_VALUE_NOT_DEFINED 2
#define BP_BOARD_ID_NOT_SET 3
/* Values for BpGetSdramSize. */
#define BP_MEMORY_8MB_1_CHIP 0
#define BP_MEMORY_16MB_1_CHIP 1
#define BP_MEMORY_32MB_1_CHIP 2
#define BP_MEMORY_64MB_2_CHIP 3
#define BP_MEMORY_32MB_2_CHIP 4
#define BP_MEMORY_16MB_2_CHIP 5
/* Values for EthernetMacInfo PhyType. */
#define BP_ENET_NO_PHY 0
#define BP_ENET_INTERNAL_PHY 1
#define BP_ENET_EXTERNAL_PHY 2
#define BP_ENET_EXTERNAL_SWITCH 3
/* Values for EthernetMacInfo Configuration type. */
#define BP_ENET_CONFIG_MDIO 0 /* Internal PHY, External PHY, Switch+(no GPIO, no SPI, no MDIO Pseudo phy */
#define BP_ENET_CONFIG_GPIO 1 /* Bcm96345GW board + Bcm5325M/E */
#define BP_ENET_CONFIG_MDIO_PSEUDO_PHY 2 /* Bcm96348GW board + Bcm5325E */
#define BP_ENET_CONFIG_SPI_SSB_0 3 /* Bcm96348GW board + Bcm5325M/E */
#define BP_ENET_CONFIG_SPI_SSB_1 4 /* Bcm96348GW board + Bcm5325M/E */
#define BP_ENET_CONFIG_SPI_SSB_2 5 /* Bcm96348GW board + Bcm5325M/E */
#define BP_ENET_CONFIG_SPI_SSB_3 6 /* Bcm96348GW board + Bcm5325M/E */
/* Values for EthernetMacInfo Reverse MII. */
#define BP_ENET_NO_REVERSE_MII 0
#define BP_ENET_REVERSE_MII 1
/* Values for VoIPDSPInfo DSPType. */
#define BP_VOIP_NO_DSP 0
#define BP_VOIP_DSP 1
/* Values for GPIO pin assignments (AH = Active High, AL = Active Low). */
#define BP_ACTIVE_MASK 0x8000
#define BP_ACTIVE_HIGH 0x0000
#define BP_ACTIVE_LOW 0x8000
#define BP_GPIO_0_AH (0 | BP_ACTIVE_HIGH)
#define BP_GPIO_0_AL (0 | BP_ACTIVE_LOW)
#define BP_GPIO_1_AH (1 | BP_ACTIVE_HIGH)
#define BP_GPIO_1_AL (1 | BP_ACTIVE_LOW)
#define BP_GPIO_2_AH (2 | BP_ACTIVE_HIGH)
#define BP_GPIO_2_AL (2 | BP_ACTIVE_LOW)
#define BP_GPIO_3_AH (3 | BP_ACTIVE_HIGH)
#define BP_GPIO_3_AL (3 | BP_ACTIVE_LOW)
#define BP_GPIO_4_AH (4 | BP_ACTIVE_HIGH)
#define BP_GPIO_4_AL (4 | BP_ACTIVE_LOW)
#define BP_GPIO_5_AH (5 | BP_ACTIVE_HIGH)
#define BP_GPIO_5_AL (5 | BP_ACTIVE_LOW)
#define BP_GPIO_6_AH (6 | BP_ACTIVE_HIGH)
#define BP_GPIO_6_AL (6 | BP_ACTIVE_LOW)
#define BP_GPIO_7_AH (7 | BP_ACTIVE_HIGH)
#define BP_GPIO_7_AL (7 | BP_ACTIVE_LOW)
#define BP_GPIO_8_AH (8 | BP_ACTIVE_HIGH)
#define BP_GPIO_8_AL (8 | BP_ACTIVE_LOW)
#define BP_GPIO_9_AH (9 | BP_ACTIVE_HIGH)
#define BP_GPIO_9_AL (9 | BP_ACTIVE_LOW)
#define BP_GPIO_10_AH (10 | BP_ACTIVE_HIGH)
#define BP_GPIO_10_AL (10 | BP_ACTIVE_LOW)
#define BP_GPIO_11_AH (11 | BP_ACTIVE_HIGH)
#define BP_GPIO_11_AL (11 | BP_ACTIVE_LOW)
#define BP_GPIO_12_AH (12 | BP_ACTIVE_HIGH)
#define BP_GPIO_12_AL (12 | BP_ACTIVE_LOW)
#define BP_GPIO_13_AH (13 | BP_ACTIVE_HIGH)
#define BP_GPIO_13_AL (13 | BP_ACTIVE_LOW)
#define BP_GPIO_14_AH (14 | BP_ACTIVE_HIGH)
#define BP_GPIO_14_AL (14 | BP_ACTIVE_LOW)
#define BP_GPIO_15_AH (15 | BP_ACTIVE_HIGH)
#define BP_GPIO_15_AL (15 | BP_ACTIVE_LOW)
#define BP_GPIO_16_AH (16 | BP_ACTIVE_HIGH)
#define BP_GPIO_16_AL (16 | BP_ACTIVE_LOW)
#define BP_GPIO_17_AH (17 | BP_ACTIVE_HIGH)
#define BP_GPIO_17_AL (17 | BP_ACTIVE_LOW)
#define BP_GPIO_18_AH (18 | BP_ACTIVE_HIGH)
#define BP_GPIO_18_AL (18 | BP_ACTIVE_LOW)
#define BP_GPIO_19_AH (19 | BP_ACTIVE_HIGH)
#define BP_GPIO_19_AL (19 | BP_ACTIVE_LOW)
#define BP_GPIO_20_AH (20 | BP_ACTIVE_HIGH)
#define BP_GPIO_20_AL (20 | BP_ACTIVE_LOW)
#define BP_GPIO_21_AH (21 | BP_ACTIVE_HIGH)
#define BP_GPIO_21_AL (21 | BP_ACTIVE_LOW)
#define BP_GPIO_22_AH (22 | BP_ACTIVE_HIGH)
#define BP_GPIO_22_AL (22 | BP_ACTIVE_LOW)
#define BP_GPIO_23_AH (23 | BP_ACTIVE_HIGH)
#define BP_GPIO_23_AL (23 | BP_ACTIVE_LOW)
#define BP_GPIO_24_AH (24 | BP_ACTIVE_HIGH)
#define BP_GPIO_24_AL (24 | BP_ACTIVE_LOW)
#define BP_GPIO_25_AH (25 | BP_ACTIVE_HIGH)
#define BP_GPIO_25_AL (25 | BP_ACTIVE_LOW)
#define BP_GPIO_26_AH (26 | BP_ACTIVE_HIGH)
#define BP_GPIO_26_AL (26 | BP_ACTIVE_LOW)
#define BP_GPIO_27_AH (27 | BP_ACTIVE_HIGH)
#define BP_GPIO_27_AL (27 | BP_ACTIVE_LOW)
#define BP_GPIO_28_AH (28 | BP_ACTIVE_HIGH)
#define BP_GPIO_28_AL (28 | BP_ACTIVE_LOW)
#define BP_GPIO_29_AH (29 | BP_ACTIVE_HIGH)
#define BP_GPIO_29_AL (29 | BP_ACTIVE_LOW)
#define BP_GPIO_30_AH (30 | BP_ACTIVE_HIGH)
#define BP_GPIO_30_AL (30 | BP_ACTIVE_LOW)
#define BP_GPIO_31_AH (31 | BP_ACTIVE_HIGH)
#define BP_GPIO_31_AL (31 | BP_ACTIVE_LOW)
#define BP_GPIO_32_AH (32 | BP_ACTIVE_HIGH)
#define BP_GPIO_32_AL (32 | BP_ACTIVE_LOW)
#define BP_GPIO_33_AH (33 | BP_ACTIVE_HIGH)
#define BP_GPIO_33_AL (33 | BP_ACTIVE_LOW)
#define BP_GPIO_34_AH (34 | BP_ACTIVE_HIGH)
#define BP_GPIO_34_AL (34 | BP_ACTIVE_LOW)
#define BP_GPIO_35_AH (35 | BP_ACTIVE_HIGH)
#define BP_GPIO_35_AL (35 | BP_ACTIVE_LOW)
#define BP_GPIO_36_AH (36 | BP_ACTIVE_HIGH)
#define BP_GPIO_36_AL (36 | BP_ACTIVE_LOW)
/* Values for external interrupt assignments. */
#define BP_EXT_INTR_0 0
#define BP_EXT_INTR_1 1
#define BP_EXT_INTR_2 2
#define BP_EXT_INTR_3 3
/* Values for chip select assignments. */
#define BP_CS_0 0
#define BP_CS_1 1
#define BP_CS_2 2
#define BP_CS_3 3
/* Value for GPIO and external interrupt fields that are not used. */
#define BP_NOT_DEFINED 0xffff
#define BP_HW_DEFINED 0xfff0
#define BP_UNEQUIPPED 0xfff1
/* Maximum size of the board id string. */
#define BP_BOARD_ID_LEN 16
/* Maximum number of Ethernet MACs. */
#define BP_MAX_ENET_MACS 2
/* Maximum number of VoIP DSPs. */
#define BP_MAX_VOIP_DSP 2
/* Wireless Antenna Settings. */
#define BP_WLAN_ANT_MAIN 0
#define BP_WLAN_ANT_AUX 1
#define BP_WLAN_ANT_BOTH 3
#if !defined(__ASSEMBLER__)
/* Information about an Ethernet MAC. If ucPhyType is BP_ENET_NO_PHY,
* then the other fields are not valid.
*/
typedef struct EthernetMacInfo
{
unsigned char ucPhyType; /* BP_ENET_xxx */
unsigned char ucPhyAddress; /* 0 to 31 */
unsigned short usGpioPhySpiSck; /* GPIO pin or not defined */
unsigned short usGpioPhySpiSs; /* GPIO pin or not defined */
unsigned short usGpioPhySpiMosi; /* GPIO pin or not defined */
unsigned short usGpioPhySpiMiso; /* GPIO pin or not defined */
unsigned short usGpioPhyReset; /* GPIO pin or not defined (96348LV) */
unsigned short numSwitchPorts; /* Number of PHY ports */
unsigned short usConfigType; /* Configuration type */
unsigned short usReverseMii; /* Reverse MII */
} ETHERNET_MAC_INFO, *PETHERNET_MAC_INFO;
/* Information about VoIP DSPs. If ucDspType is BP_VOIP_NO_DSP,
* then the other fields are not valid.
*/
typedef struct VoIPDspInfo
{
unsigned char ucDspType;
unsigned char ucDspAddress;
unsigned short usExtIntrVoip;
unsigned short usGpioVoipReset;
unsigned short usGpioVoipIntr;
unsigned short usGpioLedVoip;
unsigned short usCsVoip;
} VOIP_DSP_INFO;
/**************************************************************************
* Name : BpSetBoardId
*
* Description: This function find the BOARD_PARAMETERS structure for the
* specified board id string and assigns it to a global, static
* variable.
*
* Parameters : [IN] pszBoardId - Board id string that is saved into NVRAM.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_FOUND - Error, board id input string does not
* have a board parameters configuration record.
***************************************************************************/
int BpSetBoardId( char *pszBoardId );
/**************************************************************************
* Name : BpGetBoardIds
*
* Description: This function returns all of the supported board id strings.
*
* Parameters : [OUT] pszBoardIds - Address of a buffer that the board id
* strings are returned in. Each id starts at BP_BOARD_ID_LEN
* boundary.
* [IN] nBoardIdsSize - Number of BP_BOARD_ID_LEN elements that
* were allocated in pszBoardIds.
*
* Returns : Number of board id strings returned.
***************************************************************************/
int BpGetBoardIds( char *pszBoardIds, int nBoardIdsSize );
/**************************************************************************
* Name : BpGetEthernetMacInfo
*
* Description: This function returns all of the supported board id strings.
*
* Parameters : [OUT] pEnetInfos - Address of an array of ETHERNET_MAC_INFO
* buffers.
* [IN] nNumEnetInfos - Number of ETHERNET_MAC_INFO elements that
* are pointed to by pEnetInfos.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
***************************************************************************/
int BpGetEthernetMacInfo( PETHERNET_MAC_INFO pEnetInfos, int nNumEnetInfos );
/**************************************************************************
* Name : BpGetSdramSize
*
* Description: This function returns a constant that describees the board's
* SDRAM type and size.
*
* Parameters : [OUT] pulSdramSize - Address of short word that the SDRAM size
* is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
***************************************************************************/
int BpGetSdramSize( unsigned long *pulSdramSize );
/**************************************************************************
* Name : BpGetPsiSize
*
* Description: This function returns the persistent storage size in K bytes.
*
* Parameters : [OUT] pulPsiSize - Address of short word that the persistent
* storage size is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
***************************************************************************/
int BpGetPsiSize( unsigned long *pulPsiSize );
/**************************************************************************
* Name : BpGetRj11InnerOuterPairGpios
*
* Description: This function returns the GPIO pin assignments for changing
* between the RJ11 inner pair and RJ11 outer pair.
*
* Parameters : [OUT] pusInner - Address of short word that the RJ11 inner pair
* GPIO pin is returned in.
* [OUT] pusOuter - Address of short word that the RJ11 outer pair
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, values are returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetRj11InnerOuterPairGpios( unsigned short *pusInner,
unsigned short *pusOuter );
/**************************************************************************
* Name : BpGetPressAndHoldResetGpio
*
* Description: This function returns the GPIO pin assignment for the press
* and hold reset button.
*
* Parameters : [OUT] pusValue - Address of short word that the press and hold
* reset button GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetPressAndHoldResetGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetVoipResetGpio
*
* Description: This function returns the GPIO pin assignment for the VOIP
* Reset operation.
*
* Parameters : [OUT] pusValue - Address of short word that the VOIP reset
* GPIO pin is returned in.
* [IN] dspNum - Address of the DSP to query.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetVoipResetGpio( unsigned char dspNum, unsigned short *pusValue );
/**************************************************************************
* Name : BpGetVoipIntrGpio
*
* Description: This function returns the GPIO pin assignment for VoIP interrupt.
*
* Parameters : [OUT] pusValue - Address of short word that the VOIP interrupt
* GPIO pin is returned in.
* [IN] dspNum - Address of the DSP to query.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetVoipIntrGpio( unsigned char dspNum, unsigned short *pusValue );
/**************************************************************************
* Name : BpGetPcmciaResetGpio
*
* Description: This function returns the GPIO pin assignment for the PCMCIA
* Reset operation.
*
* Parameters : [OUT] pusValue - Address of short word that the PCMCIA reset
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetPcmciaResetGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetUartRtsCtsGpios
*
* Description: This function returns the GPIO pin assignments for RTS and CTS
* UART signals.
*
* Parameters : [OUT] pusRts - Address of short word that the UART RTS GPIO
* pin is returned in.
* [OUT] pusCts - Address of short word that the UART CTS GPIO
* pin is returned in.
*
* Returns : BP_SUCCESS - Success, values are returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetRtsCtsUartGpios( unsigned short *pusRts, unsigned short *pusCts );
/**************************************************************************
* Name : BpGetAdslLedGpio
*
* Description: This function returns the GPIO pin assignment for the ADSL
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the ADSL LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetAdslLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetAdslFailLedGpio
*
* Description: This function returns the GPIO pin assignment for the ADSL
* LED that is used when there is a DSL connection failure.
*
* Parameters : [OUT] pusValue - Address of short word that the ADSL LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetAdslFailLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessLedGpio
*
* Description: This function returns the GPIO pin assignment for the Wireless
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the Wireless LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessAntInUse
*
* Description: This function returns the antennas in use for wireless
*
* Parameters : [OUT] pusValue - Address of short word that the Wireless Antenna
* is in use.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessAntInUse( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessSesBtnGpio
*
* Description: This function returns the GPIO pin assignment for the Wireless
* Ses Button.
*
* Parameters : [OUT] pusValue - Address of short word that the Wireless Ses
* Button GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessSesBtnGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessSesExtIntr
*
* Description: This function returns the external interrupt number for the
* Wireless Ses Button.
*
* Parameters : [OUT] pusValue - Address of short word that the Wireless Ses
* external interrup is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessSesExtIntr( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessSesLedGpio
*
* Description: This function returns the GPIO pin assignment for the Wireless
* Ses Led.
*
* Parameters : [OUT] pusValue - Address of short word that the Wireless Ses
* Led GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessSesLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetUsbLedGpio
*
* Description: This function returns the GPIO pin assignment for the USB
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the USB LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetUsbLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetHpnaLedGpio
*
* Description: This function returns the GPIO pin assignment for the HPNA
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the HPNA LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetHpnaLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWanDataLedGpio
*
* Description: This function returns the GPIO pin assignment for the WAN Data
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the WAN Data LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWanDataLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetPppLedGpio
*
* Description: This function returns the GPIO pin assignment for the PPP
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the PPP LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetPppLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetPppFailLedGpio
*
* Description: This function returns the GPIO pin assignment for the PPP
* LED that is used when there is a PPP connection failure.
*
* Parameters : [OUT] pusValue - Address of short word that the PPP LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetPppFailLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetVoipLedGpio
*
* Description: This function returns the GPIO pin assignment for the VOIP
* LED.
*
* Parameters : [OUT] pusValue - Address of short word that the VOIP LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetVoipLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetBootloaderPowerOnLedGpio
*
* Description: This function returns the GPIO pin assignment for the power
* on LED that is set by the bootloader.
*
* Parameters : [OUT] pusValue - Address of short word that the alarm LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetBootloaderPowerOnLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetBootloaderAlarmLedGpio
*
* Description: This function returns the GPIO pin assignment for the alarm
* LED that is set by the bootloader.
*
* Parameters : [OUT] pusValue - Address of short word that the alarm LED
* GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetBootloaderAlarmLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetBootloaderResetCfgLedGpio
*
* Description: This function returns the GPIO pin assignment for the reset
* configuration LED that is set by the bootloader.
*
* Parameters : [OUT] pusValue - Address of short word that the reset
* configuration LED GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetBootloaderResetCfgLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetBootloaderStopLedGpio
*
* Description: This function returns the GPIO pin assignment for the break
* into bootloader LED that is set by the bootloader.
*
* Parameters : [OUT] pusValue - Address of short word that the break into
* bootloader LED GPIO pin is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetBootloaderStopLedGpio( unsigned short *pusValue );
/**************************************************************************
* Name : BpGetWirelessExtIntr
*
* Description: This function returns the Wireless external interrupt number.
*
* Parameters : [OUT] pulValue - Address of short word that the wireless
* external interrupt number is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetWirelessExtIntr( unsigned long *pulValue );
/**************************************************************************
* Name : BpGetAdslDyingGaspExtIntr
*
* Description: This function returns the ADSL Dying Gasp external interrupt
* number.
*
* Parameters : [OUT] pulValue - Address of short word that the ADSL Dying Gasp
* external interrupt number is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetAdslDyingGaspExtIntr( unsigned long *pulValue );
/**************************************************************************
* Name : BpGetVoipExtIntr
*
* Description: This function returns the VOIP external interrupt number.
*
* Parameters : [OUT] pulValue - Address of short word that the VOIP
* external interrupt number is returned in.
* [IN] dspNum - Address of the DSP to query.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetVoipExtIntr( unsigned char dspNum, unsigned long *pulValue );
/**************************************************************************
* Name : BpGetHpnaExtIntr
*
* Description: This function returns the HPNA external interrupt number.
*
* Parameters : [OUT] pulValue - Address of short word that the HPNA
* external interrupt number is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetHpnaExtIntr( unsigned long *pulValue );
/**************************************************************************
* Name : BpGetHpnaChipSelect
*
* Description: This function returns the HPNA chip select number.
*
* Parameters : [OUT] pulValue - Address of short word that the HPNA
* chip select number is returned in.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetHpnaChipSelect( unsigned long *pulValue );
/**************************************************************************
* Name : BpGetVoipChipSelect
*
* Description: This function returns the VOIP chip select number.
*
* Parameters : [OUT] pulValue - Address of short word that the VOIP
* chip select number is returned in.
* [IN] dspNum - Address of the DSP to query.
*
* Returns : BP_SUCCESS - Success, value is returned.
* BP_BOARD_ID_NOT_SET - Error, BpSetBoardId has not been called.
* BP_VALUE_NOT_DEFINED - At least one return value is not defined
* for the board.
***************************************************************************/
int BpGetVoipChipSelect( unsigned char dspNum, unsigned long *pulValue );
#endif /* __ASSEMBLER__ */
#endif /* _BOARDPARMS_H */

View File

@ -0,0 +1,86 @@
/*
* $Id$
*
* Copyright (C) 2007 OpenWrt.org
* Copyright (C) 2007 Gabor Juhos <juhosg@freemail.hu>
* Copyright (C) 2007 Florian Fainelli <florian@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/types.h>
#include <linux/autoconf.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/bootinfo.h>
#include <asm/addrspace.h>
#include <asm/string.h>
#include <asm/mach-bcm963xx/bootloaders.h>
static char *boot_loader_names[BOOT_LOADER_LAST+1] = {
[BOOT_LOADER_UNKNOWN] = "Unknown",
[BOOT_LOADER_CFE] = "CFE",
[BOOT_LOADER_REDBOOT] = "RedBoot"
};
/* boot loaders specific definitions */
#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE from other bootloaders */
int boot_loader_type;
/*
* Boot loader detection routines
*/
static int __init detect_cfe(void)
{
/*
* This method only works, when we are booted directly from the CFE.
*/
uint32_t cfe_handle = (uint32_t) fw_arg0;
uint32_t cfe_a1_val = (uint32_t) fw_arg1;
uint32_t cfe_entry = (uint32_t) fw_arg2;
uint32_t cfe_seal = (uint32_t) fw_arg3;
/* Check for CFE by finding the CFE magic number */
if (cfe_seal != CFE_EPTSEAL)
/* We are not booted from CFE */
return 0;
/* cfe_a1_val must be 0, because only one CPU present in the ADM5120 SoC */
if (cfe_a1_val != 0)
return 0;
/* The cfe_handle, and the cfe_entry must be kernel mode addresses */
if ((cfe_handle < KSEG0) || (cfe_entry < KSEG0))
return 0;
return 1;
}
static int __init detect_redboot(void)
{
/* On Inventel Livebox, the boot loader is passed as a command line argument, check for it */
if (!strncmp(arcs_cmdline, "boot_loader=RedBoot", 19))
return 1;
return 0;
}
void __init detect_bootloader(void)
{
if (detect_cfe()) {
boot_loader_type = BOOT_LOADER_CFE;
printk("Boot loader is : %s\n", boot_loader_names[boot_loader_type]);
}
if (detect_redboot()) {
boot_loader_type = BOOT_LOADER_REDBOOT;
}
else
boot_loader_type = BOOT_LOADER_UNKNOWN;
}
EXPORT_SYMBOL(boot_loader_type);

View File

@ -35,6 +35,8 @@
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/signal.h> #include <asm/signal.h>
#include <6348_map_part.h>
#include <6348_intr.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <bcm_intr.h> #include <bcm_intr.h>

View File

@ -25,119 +25,49 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/mach-bcm963xx/bootloaders.h>
#include <asm/mach-bcm963xx/6348_map_part.h>
#include <bcm_map_part.h> #include "../cfe/cfe_private.h"
#include <board.h>
#include "boardparms.h"
#include "softdsl/AdslCoreDefs.h"
extern void __init detect_bootloader(void);
//char arcs_cmdline[CL_SIZE] __initdata = {0};
/* inv_xde */
int boot_loader_type;
int prom_argc;
char **prom_argv, **prom_envp;
extern int do_syslog(int, char *, int);
extern void serial_init(void); extern void serial_init(void);
extern void __init InitNvramInfo( void ); extern int boot_loader_type;
extern void kerSysFlashInit( void );
extern unsigned long get_nvram_start_addr(void);
void __init create_root_nfs_cmdline( char *cmdline );
#define MACH_BCM MACH_BCM96348 #define MACH_BCM MACH_BCM96348
const char *get_system_type(void) const char *get_system_type(void)
{ {
/*PNVRAM_DATA pNvramData = (PNVRAM_DATA) get_nvram_start_addr(); return "Broadcom BCM963xx";
return( pNvramData->szBoardId );*/
return "brcm63xx";
} }
unsigned long getMemorySize(void)
{
unsigned long ulSdramType = BOARD_SDRAM_TYPE;
unsigned long ulSdramSize;
switch( ulSdramType )
{
case BP_MEMORY_16MB_1_CHIP:
case BP_MEMORY_16MB_2_CHIP:
ulSdramSize = 16 * 1024 * 1024;
break;
case BP_MEMORY_32MB_1_CHIP:
case BP_MEMORY_32MB_2_CHIP:
ulSdramSize = 32 * 1024 * 1024;
break;
case BP_MEMORY_64MB_2_CHIP:
ulSdramSize = 64 * 1024 * 1024;
break;
default:
ulSdramSize = 8 * 1024 * 1024;
break;
}
if (boot_loader_type == BOOT_CFE)
return ulSdramSize;
else
// assume that there is one contiguous memory map
return boot_mem_map.map[0].size;
}
/* --------------------------------------------------------------------------
Name: prom_init
-------------------------------------------------------------------------- */
void __init prom_init(void) void __init prom_init(void)
{ {
extern ulong r4k_interval;
serial_init(); serial_init();
prom_argc = fw_arg0;
prom_argv = (char **) fw_arg1;
prom_envp = (char **) fw_arg2;
if ((prom_argv > 0x80000000) && (prom_argv < 0x82000000)) {
strncpy(arcs_cmdline, prom_argv[1], CL_SIZE);
}
if (strncmp(arcs_cmdline, "boot_loader=RedBoot", 19) != 0) {
boot_loader_type = BOOT_CFE;
}
else {
boot_loader_type = BOOT_REDBOOT;
}
do_syslog(8, NULL, 8);
printk( "%s prom init\n", get_system_type() ); printk( "%s prom init\n", get_system_type() );
PERF->IrqMask = 0; PERF->IrqMask = 0;
arcs_cmdline[0] = '\0'; detect_bootloader();
if (boot_loader_type == BOOT_CFE) if (boot_loader_type == BOOT_LOADER_CFE) {
add_memory_region(0, (getMemorySize() - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM); cfe_setup(fw_arg0, fw_arg1, fw_arg2, fw_arg3);
add_memory_region(0, (boot_mem_map.map[0].size - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
}
else else
add_memory_region(0, (0x01000000 - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM); add_memory_region(0, (0x01000000 - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
mips_machgroup = MACH_GROUP_BRCM; mips_machgroup = MACH_GROUP_BRCM;
mips_machtype = MACH_BCM; mips_machtype = MACH_BCM;
BpSetBoardId("96348GW-10");
} }
/* --------------------------------------------------------------------------
Name: prom_free_prom_memory
Abstract:
-------------------------------------------------------------------------- */
void __init prom_free_prom_memory(void) void __init prom_free_prom_memory(void)
{ {
/* We do not have any memory to free */
} }

View File

@ -37,6 +37,7 @@
#include <asm/mc146818rtc.h> #include <asm/mc146818rtc.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <6348_map_part.h>
#include <board.h> #include <board.h>
#define SER63XX_DEFAULT_BAUD 115200 #define SER63XX_DEFAULT_BAUD 115200
@ -54,7 +55,7 @@
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
void __init serial_init(void) void __init serial_init(void)
{ {
UINT32 tmpVal = SER63XX_DEFAULT_BAUD; u32 tmpVal = SER63XX_DEFAULT_BAUD;
ULONG clockFreqHz; ULONG clockFreqHz;
#if defined(CONFIG_BCM96345) #if defined(CONFIG_BCM96345)

View File

@ -32,6 +32,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/bcache.h> #include <asm/bcache.h>
@ -39,9 +40,12 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/gdb-stub.h> #include <asm/gdb-stub.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/mach-bcm963xx/bootloaders.h>
extern void brcm_time_init(void); extern void brcm_time_init(void);
extern unsigned long getMemorySize(void); extern int boot_loader_type;
#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) #if defined(CONFIG_BCM96348) && defined(CONFIG_PCI)
#include <linux/pci.h> #include <linux/pci.h>
@ -373,13 +377,16 @@ static int mpi_DetectPcCard(void)
static int mpi_init(void) static int mpi_init(void)
{ {
unsigned long data; unsigned long data;
unsigned int chipid; unsigned int chipid, chiprev, sdramsize;
unsigned int chiprev;
unsigned int sdramsize;
printk("Broadcom BCM963xx MPI\n");
chipid = (PERF->RevID & 0xFFFF0000) >> 16; chipid = (PERF->RevID & 0xFFFF0000) >> 16;
chiprev = (PERF->RevID & 0xFF); chiprev = (PERF->RevID & 0xFF);
sdramsize = getMemorySize();
if (boot_loader_type == BOOT_LOADER_CFE)
sdramsize = boot_mem_map.map[0].size;
else
sdramsize = 0x01000000;
/* /*
* Init the pci interface * Init the pci interface
*/ */
@ -456,68 +463,16 @@ static int mpi_init(void)
} }
#endif #endif
static int __init brcm63xx_setup(void) void __init plat_mem_setup(void)
{ {
extern int panic_timeout;
_machine_restart = brcm_machine_restart; _machine_restart = brcm_machine_restart;
_machine_halt = brcm_machine_halt; _machine_halt = brcm_machine_halt;
pm_power_off = brcm_machine_halt; pm_power_off = brcm_machine_halt;
board_time_init = brcm_time_init; board_time_init = brcm_time_init;
panic_timeout = 5;
#if defined(CONFIG_BCM96348) && defined(CONFIG_PCI) #if defined(CONFIG_BCM96348) && defined(CONFIG_PCI)
/* mpi initialization */ /* mpi initialization */
mpi_init(); mpi_init();
#endif #endif
return 0;
} }
void __init plat_mem_setup(void)
{
brcm63xx_setup();
}
/***************************************************************************
* C++ New and delete operator functions
***************************************************************************/
/* void *operator new(unsigned int sz) */
void *_Znwj(unsigned int sz)
{
return( kmalloc(sz, GFP_KERNEL) );
}
/* void *operator new[](unsigned int sz)*/
void *_Znaj(unsigned int sz)
{
return( kmalloc(sz, GFP_KERNEL) );
}
/* placement new operator */
/* void *operator new (unsigned int size, void *ptr) */
void *ZnwjPv(unsigned int size, void *ptr)
{
return ptr;
}
/* void operator delete(void *m) */
void _ZdlPv(void *m)
{
kfree(m);
}
/* void operator delete[](void *m) */
void _ZdaPv(void *m)
{
kfree(m);
}
EXPORT_SYMBOL(_Znwj);
EXPORT_SYMBOL(_Znaj);
EXPORT_SYMBOL(ZnwjPv);
EXPORT_SYMBOL(_ZdlPv);
EXPORT_SYMBOL(_ZdaPv);

View File

@ -1,2 +0,0 @@
#define ADSL_SDRAM_IMAGE_SIZE (384*1024)

View File

@ -35,6 +35,8 @@
#include <asm/div64.h> #include <asm/div64.h>
#include <asm/time.h> #include <asm/time.h>
#include <6348_map_part.h>
#include <6348_intr.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <bcm_intr.h> #include <bcm_intr.h>
@ -54,7 +56,7 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */
static inline unsigned long __init calculateCpuSpeed(void) static inline unsigned long __init calculateCpuSpeed(void)
{ {
UINT32 pllStrap = PERF->PllStrap; u32 pllStrap = PERF->PllStrap;
int n1 = (pllStrap & PLL_N1_MASK) >> PLL_N1_SHFT; int n1 = (pllStrap & PLL_N1_MASK) >> PLL_N1_SHFT;
int n2 = (pllStrap & PLL_N2_MASK) >> PLL_N2_SHFT; int n2 = (pllStrap & PLL_N2_MASK) >> PLL_N2_SHFT;
int m1cpu = (pllStrap & PLL_M1_CPU_MASK) >> PLL_M1_CPU_SHFT; int m1cpu = (pllStrap & PLL_M1_CPU_MASK) >> PLL_M1_CPU_SHFT;

View File

@ -0,0 +1,5 @@
#
# Makefile for the Broadcom Common Firmware Environment support
#
obj-y += cfe.o

View File

@ -0,0 +1,533 @@
/*
* 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;
}

View File

@ -0,0 +1,176 @@
/*
* 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_ */

View File

@ -23,6 +23,8 @@
#include <bcmpci.h> #include <bcmpci.h>
#include <bcm_intr.h> #include <bcm_intr.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <6348_intr.h>
#include <6348_map_part.h>
static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE); static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE);

View File

@ -24,6 +24,8 @@
#include <bcm_intr.h> #include <bcm_intr.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <6348_intr.h>
#include <6348_map_part.h>
#include <bcmpci.h> #include <bcmpci.h>
#include <linux/delay.h> #include <linux/delay.h>

View File

@ -1,277 +1,474 @@
/* /*
* $Id$ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2006 Florian Fainelli <florian@openwrt.org> * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
* Mike Albon <malbon@openwrt.org> * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
* Copyright (C) $Date$ $Author$
* *
* This program is free software; you can redistribute it and/or modify * original functions for finding root filesystem from Mike Baker
* 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 program is distributed in the hope that it will be useful, * This program is free software; you can redistribute it and/or modify it
* but WITHOUT ANY WARRANTY; without even the implied warranty of * under the terms of the GNU General Public License as published by the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Free Software Foundation; either version 2 of the License, or (at your
* GNU General Public License for more details. * option) any later version.
* *
* You should have received a copy of the GNU General Public License * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* along with this program; if not, write to the Free Software * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 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.
*
* Copyright 2001-2003, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* Flash mapping for BCM963XX boards
*/ */
/* This is the BCM963xx flash map driver, in its actual state it only supports BCM96348 devices
* this driver is able to manage both bootloader we found on these boards : CFE and RedBoot
*
* RedBoot :
* - this bootloader allows us to parse partitions and therefore deduce the MTD partition table
*
* CFE :
* - CFE partitionning can be detected as for BCM947xx devices
*
*/
#include <asm/io.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mtd/map.h> #include <linux/wait.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/vmalloc.h> #endif
#include <board.h> #include <linux/squashfs_fs.h>
#include <linux/jffs2.h>
#include <linux/crc32.h>
#include <asm/io.h>
#define WINDOW_ADDR 0x1FC00000 /* Real address of the flash */ #include <asm/mach-bcm963xx/bootloaders.h>
#define WINDOW_SIZE 0x400000 /* Size of flash */
#define BUSWIDTH 2 /* Buswidth */
#define EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
#define IMAGE_LEN 10 /* Length of Length Field */
#define ADDRESS_LEN 12 /* Length of Address field */
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
extern int boot_loader_type; /* For RedBoot / CFE detection */ extern int boot_loader_type;
extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin); extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
static struct mtd_partition *parsed_parts; static struct mtd_partition *parsed_parts;
static void __exit bcm963xx_mtd_cleanup(void);
static struct mtd_info *bcm963xx_mtd_info; #define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_VERSION 1
#define TRX_MAX_LEN 0x3A0000
#define TRX_NO_HEADER 1 /* Do not write TRX header */
#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
#define TRX_MAX_OFFSET 3
struct trx_header {
u32 magic; /* "HDR0" */
u32 len; /* Length of file including header */
u32 crc32; /* 32-bit CRC from flag_version to end of file */
u32 flag_version; /* 0:15 flags, 16:31 version */
u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
};
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
#define NVRAM_SPACE 0x8000
#define WINDOW_ADDR 0x1FC00000
#define WINDOW_SIZE 0x400000
#define BUSWIDTH 2
#define EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
static struct mtd_info *bcm963xx_mtd;
static struct map_info bcm963xx_map = { static struct map_info bcm963xx_map = {
.name = "bcm963xx", .name = "Physically mapped flash",
.size = WINDOW_SIZE, .size = WINDOW_SIZE,
.bankwidth = BUSWIDTH, .bankwidth = BUSWIDTH,
.phys = WINDOW_ADDR, .phys = WINDOW_ADDR,
}; };
#ifdef CONFIG_MTD_PARTITIONS
int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition **pparts)
{
int nrparts = 2, curpart = 0; // CFE and NVRAM always present.
struct bcm963xx_cfe_map {
unsigned char tagVersion[4]; // Version of the image tag
unsigned char sig_1[20]; // Company Line 1
unsigned char sig_2[14]; // Company Line 2
unsigned char chipid[6]; // Chip this image is for
unsigned char boardid[16]; // Board name
unsigned char bigEndian[2]; // Map endianness -- 1 BE 0 LE
unsigned char totalLength[IMAGE_LEN]; //Total length of image
unsigned char cfeAddress[ADDRESS_LEN]; // Address in memory of CFE
unsigned char cfeLength[IMAGE_LEN]; // Size of CFE
unsigned char rootAddress[ADDRESS_LEN]; // Address in memory of rootfs
unsigned char rootLength[IMAGE_LEN]; // Size of rootfs
unsigned char kernelAddress[ADDRESS_LEN]; // Address in memory of kernel
unsigned char kernelLength[IMAGE_LEN]; // Size of kernel
unsigned char dualImage[2]; // Unused at present
unsigned char inactiveFlag[2]; // Unused at present
unsigned char reserved1[74]; // Reserved area not in use
unsigned char imageCRC[4]; // CRC32 of images
unsigned char reserved2[16]; // Unused at present
unsigned char headerCRC[4]; // CRC32 of header excluding tagVersion
unsigned char reserved3[16]; // Unused at present
} *buf;
struct mtd_partition *parts;
int ret;
size_t retlen;
unsigned int rootfsaddr, kerneladdr, spareaddr;
unsigned int rootfslen, kernellen, sparelen, totallen;
int namelen = 0;
int i;
// Allocate memory for buffer
buf = vmalloc(sizeof(struct bcm963xx_cfe_map));
if (!buf)
return -ENOMEM;
// Get the tag
ret = master->read(master,master->erasesize,sizeof(struct bcm963xx_cfe_map), &retlen, (void *)buf);
if (retlen != sizeof(struct bcm963xx_cfe_map)){
vfree(buf);
return -EIO;
};
printk("bcm963xx: CFE boot tag found with version %s and board type %s.\n",buf->tagVersion,buf->boardid);
// Get the values and calculate
sscanf(buf->rootAddress,"%u", &rootfsaddr);
rootfsaddr = rootfsaddr - EXTENDED_SIZE;
sscanf(buf->rootLength, "%u", &rootfslen);
sscanf(buf->kernelAddress, "%u", &kerneladdr);
kerneladdr = kerneladdr - EXTENDED_SIZE;
sscanf(buf->kernelLength, "%u", &kernellen);
sscanf(buf->totalLength, "%u", &totallen);
spareaddr = ROUNDUP(totallen,master->erasesize) + master->erasesize;
sparelen = master->size - spareaddr - master->erasesize;
// Determine number of partitions
namelen = 8;
if (rootfslen > 0){
nrparts++;
namelen =+ 6;
};
if (kernellen > 0){
nrparts++;
namelen =+ 6;
};
if (sparelen > 0){
nrparts++;
namelen =+ 6;
};
// Ask kernel for more memory.
parts = kmalloc(sizeof(*parts)*nrparts+10*nrparts, GFP_KERNEL);
if (!parts){
vfree(buf);
return -ENOMEM;
};
memset(parts,0,sizeof(*parts)*nrparts+10*nrparts);
// Start building partition list
parts[curpart].name = "CFE";
parts[curpart].offset = 0;
parts[curpart].size = master->erasesize;
curpart++;
if (kernellen > 0){
parts[curpart].name = "Kernel";
parts[curpart].offset = kerneladdr;
parts[curpart].size = kernellen;
curpart++;
};
if (rootfslen > 0){
parts[curpart].name = "Rootfs";
parts[curpart].offset = rootfsaddr;
parts[curpart].size = rootfslen;
curpart++;
};
if (sparelen > 0){
parts[curpart].name = "OpenWrt";
parts[curpart].offset = spareaddr;
parts[curpart].size = sparelen;
curpart++;
};
parts[curpart].name = "NVRAM";
parts[curpart].offset = master->size - master->erasesize;
parts[curpart].size = master->erasesize;
for (i = 0; i < nrparts; i++) {
printk("bcm963xx: Partition %d is %s offset %x and length %x\n", i, parts[i].name, parts[i].offset, parts[i].size);
}
*pparts = parts;
vfree(buf);
return nrparts;
};
static struct mtd_partition bcm963xx_parts[] = { static struct mtd_partition bcm963xx_parts[] = {
{ name: "bootloader", size: 0, offset: 0, mask_flags: MTD_WRITEABLE }, { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
{ name: "rootfs", size: 0, offset: 0}, { name: "linux", offset: 0, size: 0, },
{ name: "jffs2", size: 5 * 0x10000, offset: 57*0x10000} { name: "rootfs", offset: 0, size: 0, },
{ name: "nvram", offset: 0, size: 0, },
{ name: "OpenWrt", offset: 0, size: 0, },
{ name: NULL, },
}; };
static int bcm963xx_parts_size = sizeof(bcm963xx_parts) / sizeof(bcm963xx_parts[0]); static int __init
find_cfe_size(struct mtd_info *mtd, size_t size)
static int bcm963xx_detect_cfe(struct mtd_info *master)
{ {
int idoffset = 0x4e0; struct trx_header *trx;
static char idstring[8] = "CFE1CFE1"; unsigned char buf[512];
char buf[8]; int off;
int ret; size_t len;
size_t retlen; int blocksize;
trx = (struct trx_header *) buf;
blocksize = mtd->erasesize;
if (blocksize < 0x10000)
blocksize = 0x10000;
for (off = (128*1024); off < size; off += blocksize) {
memset(buf, 0xe5, sizeof(buf));
/*
* Read into buffer
*/
if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
len != sizeof(buf))
continue;
/* found a TRX header */
if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
goto found;
}
}
printk(KERN_NOTICE
"%s: Couldn't find bootloader size\n",
mtd->name);
return -1;
found:
printk(KERN_NOTICE "bootloader size: %d\n", off);
return off;
ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
printk("bcm963xx: Read Signature value of %s\n", buf);
return strcmp(idstring,buf);
} }
static int __init bcm963xx_mtd_init(void) /*
* Copied from mtdblock.c
*
* Cache stuff...
*
* Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors
* and to speed things up, we locally cache a whole flash sector while it is
* being written to until a different sector is required.
*/
static void erase_callback(struct erase_info *done)
{ {
printk("bcm963xx: 0x%08x at 0x%08x\n", WINDOW_SIZE, WINDOW_ADDR); wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
bcm963xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); wake_up(wait_q);
}
if (!bcm963xx_map.virt) { static int erase_write (struct mtd_info *mtd, unsigned long pos,
printk("bcm963xx: Failed to ioremap\n"); int len, const char *buf)
{
struct erase_info erase;
DECLARE_WAITQUEUE(wait, current);
wait_queue_head_t wait_q;
size_t retlen;
int ret;
/*
* First, let's erase the flash block.
*/
init_waitqueue_head(&wait_q);
erase.mtd = mtd;
erase.callback = erase_callback;
erase.addr = pos;
erase.len = len;
erase.priv = (u_long)&wait_q;
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wait_q, &wait);
ret = mtd->erase(mtd, &erase);
if (ret) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&wait_q, &wait);
printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
"on \"%s\" failed\n",
pos, len, mtd->name);
return ret;
}
schedule(); /* Wait for erase to finish. */
remove_wait_queue(&wait_q, &wait);
/*
* Next, writhe data to flash.
*/
ret = mtd->write (mtd, pos, len, &retlen, buf);
if (ret)
return ret;
if (retlen != len)
return -EIO; return -EIO;
} return 0;
}
simple_map_init(&bcm963xx_map);
bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
if (bcm963xx_mtd_info) {
bcm963xx_mtd_info->owner = THIS_MODULE;
//if (boot_loader_type == BOOT_CFE) static int __init
if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
{ {
int parsed_nr_parts = 0; struct trx_header trx, *trx2;
char * part_type; unsigned char buf[512], *block;
printk("bcm963xx: CFE bootloader detected\n"); int off, blocksize;
//add_mtd_device(bcm963xx_mtd_info); u32 i, crc = ~0;
//add_mtd_partitions(bcm963xx_mtd_info, bcm963xx_parts, bcm963xx_parts_size); size_t len;
if (parsed_nr_parts == 0) { struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
int ret = parse_cfe_partitions(bcm963xx_mtd_info, &parsed_parts);
if (ret > 0) { blocksize = mtd->erasesize;
part_type = "CFE"; if (blocksize < 0x10000)
parsed_nr_parts = ret; blocksize = 0x10000;
for (off = (128*1024); off < size; off += blocksize) {
memset(&trx, 0xe5, sizeof(trx));
/*
* Read into buffer
*/
if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
len != sizeof(trx))
continue;
/* found a TRX header */
if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
part->offset = le32_to_cpu(trx.offsets[2]) ? :
le32_to_cpu(trx.offsets[1]);
part->size = le32_to_cpu(trx.len);
part->size -= part->offset;
part->offset += off;
goto found;
} }
} }
add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts);
printk(KERN_NOTICE
"%s: Couldn't find root filesystem\n",
mtd->name);
return -1;
found:
if (part->size == 0)
return 0;
if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0;
if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
/* Update the squashfs partition size based on the superblock info */
part->size = sb->bytes_used;
len = part->offset + part->size;
len += (mtd->erasesize - 1);
len &= ~(mtd->erasesize - 1);
part->size = len - part->offset;
} else if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
/* Move the squashfs outside of the trx */
part->size = 0;
} else {
printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
return 0; return 0;
} }
else
{ if (trx.len != part->offset + part->size - off) {
/* Update the trx offsets and length */
trx.len = part->offset + part->size - off;
/* Update the trx crc32 */
for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0;
crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
}
trx.crc32 = crc;
/* read first eraseblock from the trx */
block = kmalloc(mtd->erasesize, GFP_KERNEL);
trx2 = (struct trx_header *) block;
if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
printk("Error accessing the first trx eraseblock\n");
return 0;
}
printk("Updating TRX offsets and length:\n");
printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
/* Write updated trx header to the flash */
memcpy(block, &trx, sizeof(trx));
if (mtd->unlock)
mtd->unlock(mtd, off, mtd->erasesize);
erase_write(mtd, off, mtd->erasesize, block);
if (mtd->sync)
mtd->sync(mtd);
kfree(block);
printk("Done\n");
}
return part->size;
}
struct mtd_partition * __init
init_mtd_partitions(struct mtd_info *mtd, size_t size)
{
int cfe_size;
if ((cfe_size = find_cfe_size(mtd,size)) < 0)
return NULL;
/* boot loader */
bcm963xx_parts[0].offset = 0;
bcm963xx_parts[0].size = cfe_size;
/* nvram */
if (cfe_size != 384 * 1024) {
bcm963xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
bcm963xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
} else {
/* nvram (old 128kb config partition on netgear wgt634u) */
bcm963xx_parts[3].offset = bcm963xx_parts[0].size;
bcm963xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
}
/* linux (kernel and rootfs) */
if (cfe_size != 384 * 1024) {
bcm963xx_parts[1].offset = bcm963xx_parts[0].size;
bcm963xx_parts[1].size = bcm963xx_parts[3].offset -
bcm963xx_parts[1].offset;
} else {
/* do not count the elf loader, which is on one block */
bcm963xx_parts[1].offset = bcm963xx_parts[0].size +
bcm963xx_parts[3].size + mtd->erasesize;
bcm963xx_parts[1].size = size -
bcm963xx_parts[0].size -
(2*bcm963xx_parts[3].size) -
mtd->erasesize;
}
/* find and size rootfs */
if (find_root(mtd,size,&bcm963xx_parts[2])==0) {
/* entirely jffs2 */
bcm963xx_parts[4].name = NULL;
bcm963xx_parts[2].size = size - bcm963xx_parts[2].offset -
bcm963xx_parts[3].size;
} else {
/* legacy setup */
/* calculate leftover flash, and assign it to the jffs2 partition */
if (cfe_size != 384 * 1024) {
bcm963xx_parts[4].offset = bcm963xx_parts[2].offset +
bcm963xx_parts[2].size;
if ((bcm963xx_parts[4].offset % mtd->erasesize) > 0) {
bcm963xx_parts[4].offset += mtd->erasesize -
(bcm963xx_parts[4].offset % mtd->erasesize);
}
bcm963xx_parts[4].size = bcm963xx_parts[3].offset -
bcm963xx_parts[4].offset;
} else {
bcm963xx_parts[4].offset = bcm963xx_parts[2].offset +
bcm963xx_parts[2].size;
if ((bcm963xx_parts[4].offset % mtd->erasesize) > 0) {
bcm963xx_parts[4].offset += mtd->erasesize -
(bcm963xx_parts[4].offset % mtd->erasesize);
}
bcm963xx_parts[4].size = size - bcm963xx_parts[3].size -
bcm963xx_parts[4].offset;
}
}
return bcm963xx_parts;
}
#endif
int __init init_bcm963xx_map(void)
{
size_t size;
int ret = 0;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
int i;
#endif
printk("BCM963xx flash init: 0x%08x 0x%08x\n", WINDOW_ADDR, WINDOW_SIZE);
bcm963xx_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
if (!bcm963xx_map.virt) {
printk("Failed to ioremap\n");
return -EIO;
}
simple_map_init(&bcm963xx_map);
if (!(bcm963xx_mtd = do_map_probe("cfi_probe", &bcm963xx_map))) {
printk("Failed to do_map_probe\n");
iounmap((void *)bcm963xx_map.virt);
return -ENXIO;
}
bcm963xx_mtd->owner = THIS_MODULE;
size = bcm963xx_mtd->size;
printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR);
#ifdef CONFIG_MTD_PARTITIONS
if (boot_loader_type == BOOT_LOADER_CFE) {
parts = init_mtd_partitions(bcm963xx_mtd, size);
for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(bcm963xx_mtd, parts, i);
if (ret) {
printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
goto fail;
}
}
else {
int parsed_nr_parts = 0; int parsed_nr_parts = 0;
char * part_type; char * part_type;
if (bcm963xx_mtd_info->size > 0x00400000) { if (bcm963xx_mtd->size > 0x00400000) {
printk("Support for extended flash memory size : 0x%08X ; ONLY 64MBIT SUPPORT\n", bcm963xx_mtd_info->size); printk("Support for extended flash memory size : 0x%08X ; ONLY 64MBIT SUPPORT\n", bcm963xx_mtd->size);
bcm963xx_map.virt = (unsigned long)(EXTENDED_SIZE); bcm963xx_map.virt = (unsigned long)EXTENDED_SIZE;
} }
#ifdef CONFIG_MTD_REDBOOT_PARTS #ifdef CONFIG_MTD_REDBOOT_PARTS
if (parsed_nr_parts == 0) { if (parsed_nr_parts == 0) {
int ret = parse_redboot_partitions(bcm963xx_mtd_info, &parsed_parts, 0); int ret = parse_redboot_partitions(bcm963xx_mtd, &parsed_parts, 0);
if (ret > 0) { if (ret > 0) {
part_type = "RedBoot"; part_type = "RedBoot";
parsed_nr_parts = ret; parsed_nr_parts = ret;
} }
} }
#endif #endif
add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts); add_mtd_partitions(bcm963xx_mtd, parsed_parts, parsed_nr_parts);
#endif
}
return 0; return 0;
}
}
iounmap(bcm963xx_map.virt);
return -ENXIO;
}
static void __exit bcm963xx_mtd_cleanup(void) fail:
{ if (bcm963xx_mtd)
if (bcm963xx_mtd_info) { map_destroy(bcm963xx_mtd);
del_mtd_partitions(bcm963xx_mtd_info); if (bcm963xx_map.virt)
map_destroy(bcm963xx_mtd_info); iounmap((void *)bcm963xx_map.virt);
}
if (bcm963xx_map.virt) {
iounmap(bcm963xx_map.virt);
bcm963xx_map.virt = 0; bcm963xx_map.virt = 0;
} return ret;
} }
module_init(bcm963xx_mtd_init); void __exit cleanup_bcm963xx_map(void)
module_exit(bcm963xx_mtd_cleanup); {
#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(bcm963xx_mtd);
#endif
map_destroy(bcm963xx_mtd);
iounmap((void *)bcm963xx_map.virt);
}
MODULE_LICENSE("GPL"); module_init(init_bcm963xx_map);
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org> Mike Albon <malbon@openwrt.org>"); module_exit(cleanup_bcm963xx_map);

View File

@ -44,6 +44,8 @@
#include <board.h> #include <board.h>
#include <bcm_map_part.h> #include <bcm_map_part.h>
#include <bcm_intr.h> #include <bcm_intr.h>
#include <6348_map_part.h>
#include <6348_intr.h>
static DEFINE_SPINLOCK(bcm963xx_serial_lock); static DEFINE_SPINLOCK(bcm963xx_serial_lock);

View File

@ -0,0 +1,189 @@
/*
* 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_API_H_
#define LINUX_CFE_API_H_
#include <linux/types.h>
#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */
#define CFE_MI_AVAILABLE 1 /* memory is available */
#define CFE_FLG_WARMSTART 0x00000001
#define CFE_FLG_FULL_ARENA 0x00000001
#define CFE_FLG_ENV_PERMANENT 0x00000001
#define CFE_CPU_CMD_START 1
#define CFE_CPU_CMD_STOP 0
#define CFE_STDHANDLE_CONSOLE 0
#define CFE_DEV_NETWORK 1
#define CFE_DEV_DISK 2
#define CFE_DEV_FLASH 3
#define CFE_DEV_SERIAL 4
#define CFE_DEV_CPU 5
#define CFE_DEV_NVRAM 6
#define CFE_DEV_CLOCK 7
#define CFE_DEV_OTHER 8
#define CFE_DEV_MASK 0x0F
#define CFE_CACHE_FLUSH_D 1
#define CFE_CACHE_INVAL_I 2
#define CFE_CACHE_INVAL_D 4
#define CFE_CACHE_INVAL_L2 8
#define CFE_FWI_64BIT 0x00000001
#define CFE_FWI_32BIT 0x00000002
#define CFE_FWI_RELOC 0x00000004
#define CFE_FWI_UNCACHED 0x00000008
#define CFE_FWI_MULTICPU 0x00000010
#define CFE_FWI_FUNCSIM 0x00000020
#define CFE_FWI_RTLSIM 0x00000040
struct cfe_fwinfo {
s64 version; /* major, minor, eco version */
s64 totalmem; /* total installed mem */
s64 flags; /* various flags */
s64 boardid; /* board ID */
s64 bootarea_va; /* VA of boot area */
s64 bootarea_pa; /* PA of boot area */
s64 bootarea_size; /* size of boot area */
};
/* The public CFE API */
int cfe_present(void); /* Check if we booted from CFE. Returns bool */
int cfe_getticks(s64 *ticks);
int cfe_close(int handle);
int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1);
int cfe_cpu_stop(int cpu);
int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
int cfe_enumdev(int idx, char *name, int namelen);
int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
u64 *type);
int cfe_exit(int warm, int status);
int cfe_flushcache(int flags);
int cfe_getdevinfo(char *name);
int cfe_getenv(char *name, char *dest, int destlen);
int cfe_getfwinfo(struct cfe_fwinfo *info);
int cfe_getstdhandle(int handletype);
int cfe_inpstat(int handle);
int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
int length, int *retlen, u64 offset);
int cfe_open(char *name);
int cfe_read(int handle, unsigned char *buffer, int length);
int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length);
int cfe_setenv(char *name, char *val);
int cfe_write(int handle, unsigned char *buffer, int length);
int cfe_writeblk(int handle, s64 offset, unsigned char *buffer,
int length);
/* High level API */
/* Print some information to CFE's console (most likely serial line) */
int cfe_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
int cfe_vprintk(const char *fmt, va_list args);
/* Error codes returned by the low API functions */
#define CFE_ISERR(errcode) (errcode < 0)
#define CFE_OK 0
#define CFE_ERR -1 /* generic error */
#define CFE_ERR_INV_COMMAND -2
#define CFE_ERR_EOF -3
#define CFE_ERR_IOERR -4
#define CFE_ERR_NOMEM -5
#define CFE_ERR_DEVNOTFOUND -6
#define CFE_ERR_DEVOPEN -7
#define CFE_ERR_INV_PARAM -8
#define CFE_ERR_ENVNOTFOUND -9
#define CFE_ERR_ENVREADONLY -10
#define CFE_ERR_NOTELF -11
#define CFE_ERR_NOT32BIT -12
#define CFE_ERR_WRONGENDIAN -13
#define CFE_ERR_BADELFVERS -14
#define CFE_ERR_NOTMIPS -15
#define CFE_ERR_BADELFFMT -16
#define CFE_ERR_BADADDR -17
#define CFE_ERR_FILENOTFOUND -18
#define CFE_ERR_UNSUPPORTED -19
#define CFE_ERR_HOSTUNKNOWN -20
#define CFE_ERR_TIMEOUT -21
#define CFE_ERR_PROTOCOLERR -22
#define CFE_ERR_NETDOWN -23
#define CFE_ERR_NONAMESERVER -24
#define CFE_ERR_NOHANDLES -25
#define CFE_ERR_ALREADYBOUND -26
#define CFE_ERR_CANNOTSET -27
#define CFE_ERR_NOMORE -28
#define CFE_ERR_BADFILESYS -29
#define CFE_ERR_FSNOTAVAIL -30
#define CFE_ERR_INVBOOTBLOCK -31
#define CFE_ERR_WRONGDEVTYPE -32
#define CFE_ERR_BBCHECKSUM -33
#define CFE_ERR_BOOTPROGCHKSUM -34
#define CFE_ERR_LDRNOTAVAIL -35
#define CFE_ERR_NOTREADY -36
#define CFE_ERR_GETMEM -37
#define CFE_ERR_SETMEM -38
#define CFE_ERR_NOTCONN -39
#define CFE_ERR_ADDRINUSE -40
#endif /* LINUX_CFE_API_H_ */

View File

@ -0,0 +1,6 @@
#define ADSL_SDRAM_IMAGE_SIZE (384*1024)
#define BOOT_LOADER_UNKNOWN 0
#define BOOT_LOADER_CFE 1
#define BOOT_LOADER_REDBOOT 2
#define BOOT_LOADER_LAST 2

View File

@ -17,17 +17,32 @@ LOADER_MAKEOPTS= \
KERNEL_ENTRY=$(KERNEL_ENTRY) \ KERNEL_ENTRY=$(KERNEL_ENTRY) \
RAMSIZE=$(RAMSIZE) RAMSIZE=$(RAMSIZE)
define trxalign/jffs2-128k
-a 0x20000
endef
define trxalign/jffs2-64k
-a 0x10000
endef
define trxalign/squashfs
-a 1024
endef
define Build/Clean define Build/Clean
$(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader $(LOADER_MAKEOPTS) clean $(MAKE) -C lzma-loader clean
endef endef
define Image/Prepare define Image/Prepare
cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
$(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader $(LOADER_MAKEOPTS) clean compile rm -f $(KDIR)/loader.gz
$(MAKE) -C lzma-loader \
BUILD_DIR="$(KDIR)" \
TARGET="$(KDIR)" \
clean install
echo -ne "\\x00" >> $(KDIR)/loader.gz
endef endef
define Image/Build define Image/Build
cp $(KDIR)/vmlinux $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).img $(STAGING_DIR)/bin/trx -o $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).trx -f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma $(call trxalign/$(1)) -f $(KDIR)/root.$(1)
endef endef
$(eval $(call BuildImage)) $(eval $(call BuildImage))

View File

@ -0,0 +1,34 @@
#
# Copyright (C) 2006 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id$
include $(TOPDIR)/rules.mk
PKG_NAME := lzma-loader
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
$(PKG_BUILD_DIR)/.prepared:
mkdir $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
touch $@
$(PKG_BUILD_DIR)/loader.gz: $(PKG_BUILD_DIR)/.prepared
$(MAKE) -C $(PKG_BUILD_DIR) CC="$(TARGET_CC)" \
LD="$(TARGET_CROSS)ld" CROSS_COMPILE="$(TARGET_CROSS)"
download:
prepare: $(PKG_BUILD_DIR)/.prepared
compile: $(PKG_BUILD_DIR)/loader.gz
install:
ifneq ($(TARGET),)
install: compile
$(CP) $(PKG_BUILD_DIR)/loader.gz $(PKG_BUILD_DIR)/loader.elf $(TARGET)/
endif
clean:
rm -rf $(PKG_BUILD_DIR)

View File

@ -0,0 +1,663 @@
/*
LzmaDecode.c
LZMA Decoder
LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaDecode.h"
#ifndef Byte
#define Byte unsigned char
#endif
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
typedef struct _CRangeDecoder
{
Byte *Buffer;
Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback;
int Result;
#endif
int ExtraBytes;
} CRangeDecoder;
Byte RangeDecoderReadByte(CRangeDecoder *rd)
{
if (rd->Buffer == rd->BufferLim)
{
#ifdef _LZMA_IN_CB
UInt32 size;
rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
rd->BufferLim = rd->Buffer + size;
if (size == 0)
#endif
{
rd->ExtraBytes = 1;
return 0xFF;
}
}
return (*rd->Buffer++);
}
/* #define ReadByte (*rd->Buffer++) */
#define ReadByte (RangeDecoderReadByte(rd))
void RangeDecoderInit(CRangeDecoder *rd,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback
#else
Byte *stream, UInt32 bufferSize
#endif
)
{
int i;
#ifdef _LZMA_IN_CB
rd->InCallback = inCallback;
rd->Buffer = rd->BufferLim = 0;
#else
rd->Buffer = stream;
rd->BufferLim = stream + bufferSize;
#endif
rd->ExtraBytes = 0;
rd->Code = 0;
rd->Range = (0xFFFFFFFF);
for(i = 0; i < 5; i++)
rd->Code = (rd->Code << 8) | ReadByte;
}
#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
{
RC_INIT_VAR
UInt32 result = 0;
int i;
for (i = numTotalBits; i > 0; i--)
{
/* UInt32 t; */
range >>= 1;
result <<= 1;
if (code >= range)
{
code -= range;
result |= 1;
}
/*
t = (code - range) >> 31;
t &= 1;
code -= range & (t - 1);
result = (result + result) | (1 - t);
*/
RC_NORMALIZE
}
RC_FLUSH_VAR
return result;
}
int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
{
UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
if (rd->Code < bound)
{
rd->Range = bound;
*prob += (kBitModelTotal - *prob) >> kNumMoveBits;
if (rd->Range < kTopValue)
{
rd->Code = (rd->Code << 8) | ReadByte;
rd->Range <<= 8;
}
return 0;
}
else
{
rd->Range -= bound;
rd->Code -= bound;
*prob -= (*prob) >> kNumMoveBits;
if (rd->Range < kTopValue)
{
rd->Code = (rd->Code << 8) | ReadByte;
rd->Range <<= 8;
}
return 1;
}
}
#define RC_GET_BIT2(prob, mi, A0, A1) \
UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
if (code < bound) \
{ A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
else \
{ A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
RC_NORMALIZE
#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
int mi = 1;
int i;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
for(i = numLevels; i > 0; i--)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + mi;
RC_GET_BIT(prob, mi)
#else
mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
#endif
}
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return mi - (1 << numLevels);
}
int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
int mi = 1;
int i;
int symbol = 0;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
for(i = 0; i < numLevels; i++)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + mi;
RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
#else
int bit = RangeDecoderBitDecode(probs + mi, rd);
mi = mi + mi + bit;
symbol |= (bit << i);
#endif
}
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
{
int symbol = 1;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
do
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + symbol;
RC_GET_BIT(prob, symbol)
#else
symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
#endif
}
while (symbol < 0x100);
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
{
int symbol = 1;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
do
{
int bit;
int matchBit = (matchByte >> 7) & 1;
matchByte <<= 1;
#ifdef _LZMA_LOC_OPT
{
CProb *prob = probs + ((1 + matchBit) << 8) + symbol;
RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
}
#else
bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd);
symbol = (symbol << 1) | bit;
#endif
if (matchBit != bit)
{
while (symbol < 0x100)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + symbol;
RC_GET_BIT(prob, symbol)
#else
symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
#endif
}
break;
}
}
while (symbol < 0x100);
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
{
if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
return RangeDecoderBitTreeDecode(p + LenLow +
(posState << kLenNumLowBits), kLenNumLowBits, rd);
if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
(posState << kLenNumMidBits), kLenNumMidBits, rd);
return kLenNumLowSymbols + kLenNumMidSymbols +
RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
}
#define kNumStates 12
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
#ifdef _LZMA_OUT_READ
typedef struct _LzmaVarState
{
CRangeDecoder RangeDecoder;
Byte *Dictionary;
UInt32 DictionarySize;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 Reps[4];
int lc;
int lp;
int pb;
int State;
int PreviousIsMatch;
int RemainLen;
} LzmaVarState;
int LzmaDecoderInit(
unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
unsigned char *dictionary, UInt32 dictionarySize,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback
#else
unsigned char *inStream, UInt32 inSize
#endif
)
{
LzmaVarState *vs = (LzmaVarState *)buffer;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
UInt32 i;
if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
return LZMA_RESULT_NOT_ENOUGH_MEM;
vs->Dictionary = dictionary;
vs->DictionarySize = dictionarySize;
vs->DictionaryPos = 0;
vs->GlobalPos = 0;
vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
vs->lc = lc;
vs->lp = lp;
vs->pb = pb;
vs->State = 0;
vs->PreviousIsMatch = 0;
vs->RemainLen = 0;
dictionary[dictionarySize - 1] = 0;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
RangeDecoderInit(&vs->RangeDecoder,
#ifdef _LZMA_IN_CB
inCallback
#else
inStream, inSize
#endif
);
return LZMA_RESULT_OK;
}
int LzmaDecode(unsigned char *buffer,
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
LzmaVarState *vs = (LzmaVarState *)buffer;
CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
CRangeDecoder rd = vs->RangeDecoder;
int state = vs->State;
int previousIsMatch = vs->PreviousIsMatch;
Byte previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << (vs->pb)) - 1;
UInt32 literalPosMask = (1 << (vs->lp)) - 1;
int lc = vs->lc;
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
if (len == -1)
{
*outSizeProcessed = 0;
return LZMA_RESULT_OK;
}
while(len > 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
#else
int LzmaDecode(
Byte *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
unsigned char *inStream, UInt32 inSize,
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
CProb *p = (CProb *)buffer;
CRangeDecoder rd;
UInt32 i;
int state = 0;
int previousIsMatch = 0;
Byte previousByte = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
UInt32 nowPos = 0;
UInt32 posStateMask = (1 << pb) - 1;
UInt32 literalPosMask = (1 << lp) - 1;
int len = 0;
if (bufferSize < numProbs * sizeof(CProb))
return LZMA_RESULT_NOT_ENOUGH_MEM;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
RangeDecoderInit(&rd,
#ifdef _LZMA_IN_CB
inCallback
#else
inStream, inSize
#endif
);
#endif
*outSizeProcessed = 0;
while(nowPos < outSize)
{
int posState = (int)(
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& posStateMask);
#ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
{
CProb *probs = p + Literal + (LZMA_LIT_SIZE *
(((
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
if (previousIsMatch)
{
Byte matchByte;
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
#else
matchByte = outStream[nowPos - rep0];
#endif
previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
previousIsMatch = 0;
}
else
previousByte = LzmaLiteralDecode(probs, &rd);
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
}
else
{
previousIsMatch = 1;
if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
{
if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
{
if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
{
#ifdef _LZMA_OUT_READ
UInt32 pos;
#endif
if (
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
== 0)
return LZMA_RESULT_DATA_ERROR;
state = state < 7 ? 9 : 11;
#ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
continue;
}
}
else
{
UInt32 distance;
if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
distance = rep1;
else
{
if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
distance = rep2;
else
{
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
state = state < 7 ? 8 : 11;
}
else
{
int posSlot;
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < 7 ? 7 : 10;
len = LzmaLenDecode(p + LenCoder, &rd, posState);
posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits), kNumPosSlotBits, &rd);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
if (posSlot < kEndPosModelIndex)
{
rep0 += RangeDecoderReverseBitTreeDecode(
p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
}
else
{
rep0 += RangeDecoderDecodeDirectBits(&rd,
numDirectBits - kNumAlignBits) << kNumAlignBits;
rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
}
}
else
rep0 = posSlot;
rep0++;
}
if (rep0 == (UInt32)(0))
{
/* it's for stream version */
len = -1;
break;
}
if (rep0 > nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
{
return LZMA_RESULT_DATA_ERROR;
}
len += kMatchMinLen;
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
len--;
}
while(len > 0 && nowPos < outSize);
}
}
#ifdef _LZMA_OUT_READ
vs->RangeDecoder = rd;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + nowPos;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->PreviousIsMatch = previousIsMatch;
vs->RemainLen = len;
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -0,0 +1,100 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMADECODE_H
#define __LZMADECODE_H
/* #define _LZMA_IN_CB */
/* Use callback for input data */
/* #define _LZMA_OUT_READ */
/* Use read function for output data */
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_LOC_OPT */
/* Enable local speed optimizations inside code */
#ifndef UInt32
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
#else
#define UInt32 unsigned int
#endif
#endif
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb unsigned short
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_RESULT_NOT_ENOUGH_MEM 2
#ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback
{
int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize);
} ILzmaInCallback;
#endif
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
/*
bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
bufferSize += 100 in case of _LZMA_OUT_READ
by default CProb is unsigned short,
but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int)
*/
#ifdef _LZMA_OUT_READ
int LzmaDecoderInit(
unsigned char *buffer, UInt32 bufferSize,
int lc, int lp, int pb,
unsigned char *dictionary, UInt32 dictionarySize,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback
#else
unsigned char *inStream, UInt32 inSize
#endif
);
#endif
int LzmaDecode(
unsigned char *buffer,
#ifndef _LZMA_OUT_READ
UInt32 bufferSize,
int lc, int lp, int pb,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
unsigned char *inStream, UInt32 inSize,
#endif
#endif
unsigned char *outStream, UInt32 outSize,
UInt32 *outSizeProcessed);
#endif

View File

@ -0,0 +1,77 @@
#
# Makefile for Broadcom BCM947XX boards
#
# Copyright 2001-2003, Broadcom Corporation
# All Rights Reserved.
#
# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
#
# Copyright 2004 Manuel Novoa III <mjn3@codepoet.org>
# Modified to support bzip'd kernels.
# Of course, it would be better to integrate bunzip capability into CFE.
#
# Copyright 2005 Oleg I. Vdovikin <oleg@cs.msu.su>
# Cleaned up, modified for lzma support, removed from kernel
#
TEXT_START := 0x80001000
BZ_TEXT_START := 0x80300000
OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \
-ffunction-sections -pipe -mlong-calls -fno-common \
-mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap
CFLAGS += -DLOADADDR=$(TEXT_START) -D_LZMA_IN_CB
ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -DBZ_TEXT_START=$(BZ_TEXT_START)
SEDFLAGS := s/BZ_TEXT_START/$(BZ_TEXT_START)/;s/TEXT_START/$(TEXT_START)/
OBJECTS := head.o data.o
all: loader.gz loader.elf
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
install:
loader.gz: loader
gzip -nc9 $< > $@
loader.elf: loader.o
cp $< $@
loader: loader.o
$(OBJCOPY) $< $@
loader.o: loader.lds $(OBJECTS)
$(LD) -static --gc-sections -no-warn-mismatch -T loader.lds -o $@ $(OBJECTS)
loader.lds: loader.lds.in Makefile
@sed "$(SEDFLAGS)" < $< > $@
data.o: data.lds decompress.image
$(LD) -no-warn-mismatch -T data.lds -r -o $@ -b binary decompress.image -b elf32-tradlittlemips
data.lds:
@echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > $@
decompress.image: decompress
$(OBJCOPY) $< $@
decompress: decompress.lds decompress.o LzmaDecode.o
$(LD) -static --gc-sections -no-warn-mismatch -T decompress.lds -o $@ decompress.o LzmaDecode.o
decompress.lds: decompress.lds.in Makefile
@sed "$(SEDFLAGS)" < $< > $@
mrproper: clean
clean:
rm -f loader.gz loader decompress *.lds *.o *.image

View File

@ -0,0 +1,55 @@
/*
* LZMA compressed kernel decompressor for bcm947xx boards
*
* Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
The code is intended to decompress kernel, being compressed using lzma utility
build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory
decompressor code expects that your .trx file consist of three partitions:
1) decompressor itself (this is gziped code which pmon/cfe will extract and run
on boot-up instead of real kernel)
2) LZMA compressed kernel (both streamed and regular modes are supported now)
3) Root filesystem
Please be sure to apply the following patch for use this new trx layout (it will
allow using both new and old trx files for root filesystem lookup code)
--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:24:27.503322896 +0300
+++ linux/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:29:05.237100944 +0300
@@ -221,7 +221,9 @@
/* Try looking at TRX header for rootfs offset */
if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
bcm947xx_parts[1].offset = off;
- if (le32_to_cpu(trx->offsets[1]) > off)
+ if (le32_to_cpu(trx->offsets[2]) > off)
+ off = le32_to_cpu(trx->offsets[2]);
+ else if (le32_to_cpu(trx->offsets[1]) > off)
off = le32_to_cpu(trx->offsets[1]);
continue;
}
Revision history:
0.02 Initial release
0.03 Added Mineharu Takahara <mtakahar@yahoo.com> patch to pass actual
output size to decoder (stream mode compressed input is not
a requirement anymore)
0.04 Reordered functions using lds script

View File

@ -0,0 +1,175 @@
/*
* LZMA compressed kernel decompressor for bcm947xx boards
*
* Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* Please note, this was code based on the bunzip2 decompressor code
* by Manuel Novoa III (mjn3@codepoet.org), although the only thing left
* is an idea and part of original vendor code
*
*
* 12-Mar-2005 Mineharu Takahara <mtakahar@yahoo.com>
* pass actual output size to decoder (stream mode
* compressed input is not a requirement anymore)
*
* 24-Apr-2005 Oleg I. Vdovikin
* reordered functions using lds script, removed forward decl
*
*/
#include "LzmaDecode.h"
#define BCM4710_FLASH 0x1fc00000 /* Flash */
#define KSEG0 0x80000000
#define KSEG1 0xa0000000
#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1)
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define cache_unroll(base,op) \
__asm__ __volatile__( \
".set noreorder;\n" \
".set mips3;\n" \
"cache %1, (%0);\n" \
".set mips0;\n" \
".set reorder\n" \
: \
: "r" (base), \
"i" (op));
static __inline__ void blast_icache(unsigned long size, unsigned long lsize)
{
unsigned long start = KSEG0;
unsigned long end = (start + size);
while(start < end) {
cache_unroll(start,Index_Invalidate_I);
start += lsize;
}
}
static __inline__ void blast_dcache(unsigned long size, unsigned long lsize)
{
unsigned long start = KSEG0;
unsigned long end = (start + size);
while(start < end) {
cache_unroll(start,Index_Writeback_Inv_D);
start += lsize;
}
}
#define TRX_MAGIC 0x30524448 /* "HDR0" */
struct trx_header {
unsigned int magic; /* "HDR0" */
unsigned int len; /* Length of file including header */
unsigned int crc32; /* 32-bit CRC from flag_version to end of file */
unsigned int flag_version; /* 0:15 flags, 16:31 version */
unsigned int offsets[3]; /* Offsets of partitions from start of header */
};
/* beyound the image end, size not known in advance */
extern unsigned char workspace[];
unsigned int offset;
unsigned char *data;
/* flash access should be aligned, so wrapper is used */
/* read byte from the flash, all accesses are 32-bit aligned */
static int read_byte(void *object, unsigned char **buffer, UInt32 *bufferSize)
{
static unsigned int val;
if (((unsigned int)offset % 4) == 0) {
val = *(unsigned int *)data;
data += 4;
}
*bufferSize = 1;
*buffer = ((unsigned char *)&val) + (offset++ & 3);
return LZMA_RESULT_OK;
}
static __inline__ unsigned char get_byte(void)
{
unsigned char *buffer;
UInt32 fake;
return read_byte(0, &buffer, &fake), *buffer;
}
/* should be the first function */
void entry(unsigned long icache_size, unsigned long icache_lsize,
unsigned long dcache_size, unsigned long dcache_lsize)
{
unsigned int i; /* temp value */
unsigned int lc; /* literal context bits */
unsigned int lp; /* literal pos state bits */
unsigned int pb; /* pos state bits */
unsigned int osize; /* uncompressed size */
ILzmaInCallback callback;
callback.Read = read_byte;
/* look for trx header, 32-bit data access */
for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH));
((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536);
/* compressed kernel is in the partition 0 or 1 */
if (((struct trx_header *)data)->offsets[1] > 65536)
data += ((struct trx_header *)data)->offsets[0];
else
data += ((struct trx_header *)data)->offsets[1];
offset = 0;
/* lzma args */
i = get_byte();
lc = i % 9, i = i / 9;
lp = i % 5, pb = i / 5;
/* skip rest of the LZMA coder property */
for (i = 0; i < 4; i++)
get_byte();
/* read the lower half of uncompressed size in the header */
osize = ((unsigned int)get_byte()) +
((unsigned int)get_byte() << 8) +
((unsigned int)get_byte() << 16) +
((unsigned int)get_byte() << 24);
/* skip rest of the header (upper half of uncompressed size) */
for (i = 0; i < 4; i++)
get_byte();
/* decompress kernel */
if (LzmaDecode(workspace, ~0, lc, lp, pb, &callback,
(unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK)
{
blast_dcache(dcache_size, dcache_lsize);
blast_icache(icache_size, icache_lsize);
/* Jump to load address */
((void (*)(void)) LOADADDR)();
}
}

View File

@ -0,0 +1,20 @@
OUTPUT_ARCH(mips)
ENTRY(entry)
SECTIONS {
. = BZ_TEXT_START;
.text : {
*(.text.entry)
*(.text)
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
workspace = .;
}

View File

@ -0,0 +1,155 @@
/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su) */
/* cache manipulation adapted from Broadcom code */
/* idea taken from original bunzip2 decompressor code */
/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org) */
/* Licensed under the linux kernel's version of the GPL.*/
#include <asm/asm.h>
#include <asm/regdef.h>
#define KSEG0 0x80000000
#define C0_CONFIG $16
#define C0_TAGLO $28
#define C0_TAGHI $29
#define CONF1_DA_SHIFT 7 /* D$ associativity */
#define CONF1_DA_MASK 0x00000380
#define CONF1_DA_BASE 1
#define CONF1_DL_SHIFT 10 /* D$ line size */
#define CONF1_DL_MASK 0x00001c00
#define CONF1_DL_BASE 2
#define CONF1_DS_SHIFT 13 /* D$ sets/way */
#define CONF1_DS_MASK 0x0000e000
#define CONF1_DS_BASE 64
#define CONF1_IA_SHIFT 16 /* I$ associativity */
#define CONF1_IA_MASK 0x00070000
#define CONF1_IA_BASE 1
#define CONF1_IL_SHIFT 19 /* I$ line size */
#define CONF1_IL_MASK 0x00380000
#define CONF1_IL_BASE 2
#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */
#define CONF1_IS_MASK 0x01c00000
#define CONF1_IS_BASE 64
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
.text
LEAF(startup)
.set noreorder
/* Copy decompressor code to the right place */
li t2, BZ_TEXT_START
add a0, t2, 0
la a1, code_start
la a2, code_stop
$L1:
lw t0, 0(a1)
sw t0, 0(a0)
add a1, 4
add a0, 4
blt a1, a2, $L1
nop
/* At this point we need to invalidate dcache and */
/* icache before jumping to new code */
1: /* Get cache sizes */
.set mips32
mfc0 s0,C0_CONFIG,1
.set mips0
li s1,CONF1_DL_MASK
and s1,s0
beq s1,zero,nodc
nop
srl s1,CONF1_DL_SHIFT
li t0,CONF1_DL_BASE
sll s1,t0,s1 /* s1 has D$ cache line size */
li s2,CONF1_DA_MASK
and s2,s0
srl s2,CONF1_DA_SHIFT
addiu s2,CONF1_DA_BASE /* s2 now has D$ associativity */
li t0,CONF1_DS_MASK
and t0,s0
srl t0,CONF1_DS_SHIFT
li s3,CONF1_DS_BASE
sll s3,s3,t0 /* s3 has D$ sets per way */
multu s2,s3 /* sets/way * associativity */
mflo t0 /* total cache lines */
multu s1,t0 /* D$ linesize * lines */
mflo s2 /* s2 is now D$ size in bytes */
/* Initilize the D$: */
mtc0 zero,C0_TAGLO
mtc0 zero,C0_TAGHI
li t0,KSEG0 /* Just an address for the first $ line */
addu t1,t0,s2 /* + size of cache == end */
.set mips3
1: cache Index_Writeback_Inv_D,0(t0)
.set mips0
bne t0,t1,1b
addu t0,s1
nodc:
/* Now we get to do it all again for the I$ */
move s3,zero /* just in case there is no icache */
move s4,zero
li t0,CONF1_IL_MASK
and t0,s0
beq t0,zero,noic
nop
srl t0,CONF1_IL_SHIFT
li s3,CONF1_IL_BASE
sll s3,t0 /* s3 has I$ cache line size */
li t0,CONF1_IA_MASK
and t0,s0
srl t0,CONF1_IA_SHIFT
addiu s4,t0,CONF1_IA_BASE /* s4 now has I$ associativity */
li t0,CONF1_IS_MASK
and t0,s0
srl t0,CONF1_IS_SHIFT
li s5,CONF1_IS_BASE
sll s5,t0 /* s5 has I$ sets per way */
multu s4,s5 /* sets/way * associativity */
mflo t0 /* s4 is now total cache lines */
multu s3,t0 /* I$ linesize * lines */
mflo s4 /* s4 is cache size in bytes */
/* Initilize the I$: */
mtc0 zero,C0_TAGLO
mtc0 zero,C0_TAGHI
li t0,KSEG0 /* Just an address for the first $ line */
addu t1,t0,s4 /* + size of cache == end */
.set mips3
1: cache Index_Invalidate_I,0(t0)
.set mips0
bne t0,t1,1b
addu t0,s3
noic:
move a0,s3 /* icache line size */
move a1,s4 /* icache size */
move a2,s1 /* dcache line size */
jal t2
move a3,s2 /* dcache size */
.set reorder
END(startup)

View File

@ -0,0 +1,17 @@
OUTPUT_ARCH(mips)
ENTRY(startup)
SECTIONS {
. = TEXT_START;
.text : {
*(.text)
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}

View File

@ -1,45 +1,55 @@
diff -urN linux-2.6.19/arch/mips/Kconfig linux-2.6.19.new/arch/mips/Kconfig diff -urN linux-2.6.19/arch/mips/Kconfig linux-2.6.19.new/arch/mips/Kconfig
--- linux-2.6.19/arch/mips/Kconfig 2006-11-29 22:57:37.000000000 +0100 --- linux-2.6.19/arch/mips/Kconfig 2006-11-29 22:57:37.000000000 +0100
+++ linux-2.6.19.new/arch/mips/Kconfig 2006-12-16 18:46:31.000000000 +0100 +++ linux-2.6.19.new/arch/mips/Kconfig 2006-12-16 18:46:31.000000000 +0100
@@ -12,6 +12,15 @@ @@ -4,6 +4,10 @@
# Horrible source of confusion. Die, die, die ...
select EMBEDDED
+config CFE
+ bool
+ # Common Firmware Environment
+
mainmenu "Linux/MIPS Kernel Configuration"
menu "Machine selection"
@@ -12,6 +12,18 @@
prompt "System type" prompt "System type"
default SGI_IP22 default SGI_IP22
+config BCM963XX +config BCM963XX
+ bool "Support for the Broadcom boards" + bool "Support for Broadcom BCM963xx SoC"
+ select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R1
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select IRQ_CPU + select IRQ_CPU
+ select CFE
+ help + help
+ This is a fmaily of boards based on the Broadcom MIPS32 + This is a fmaily of boards based on the Broadcom MIPS32
+ +
config MIPS_MTX1 config MIPS_MTX1
bool "4G Systems MTX-1 board" bool "4G Systems MTX-1 board"
select DMA_NONCOHERENT select DMA_NONCOHERENT
@@ -766,6 +775,7 @@
endchoice
+source "arch/mips/bcm963xx/Kconfig"
source "arch/mips/ddb5xxx/Kconfig"
source "arch/mips/gt64120/ev64120/Kconfig"
source "arch/mips/jazz/Kconfig"
diff -urN linux-2.6.19/arch/mips/Makefile linux-2.6.19.new/arch/mips/Makefile diff -urN linux-2.6.19/arch/mips/Makefile linux-2.6.19.new/arch/mips/Makefile
--- linux-2.6.19/arch/mips/Makefile 2006-12-16 17:36:29.000000000 +0100 --- linux-2.6.19/arch/mips/Makefile 2006-12-16 17:36:29.000000000 +0100
+++ linux-2.6.19.new/arch/mips/Makefile 2006-12-16 18:46:31.000000000 +0100 +++ linux-2.6.19.new/arch/mips/Makefile 2006-12-16 18:46:31.000000000 +0100
@@ -158,6 +158,15 @@ @@ -158,6 +158,19 @@
# #
# #
+# Broadcom board +# Broadcom BCM963xx SoC
+# +#
+core-$(CONFIG_BCM963XX) += arch/mips/bcm963xx/ +core-$(CONFIG_BCM963XX) += arch/mips/bcm963xx/
+cflags-$(CONFIG_BCM963XX) += -Iinclude/asm-mips/mach-bcm963xx +cflags-$(CONFIG_BCM963XX) += -Iinclude/asm-mips/mach-bcm963xx
+cflags-$(CONFIG_BCM963XX) += -Iarch/mips/bcm963xx/include
+load-$(CONFIG_BCM963XX) += 0xffffffff80010000 +load-$(CONFIG_BCM963XX) += 0xffffffff80010000
+ +
+ +
+#
+# Common Firmware Environment
+#
+core-$(CONFIG_CFE) += arch/mips/cfe/
+
+# +#
# Acer PICA 61, Mips Magnum 4000 and Olivetti M700. # Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
# #
@ -105,7 +115,7 @@ diff -urN linux-2.6.19/arch/mips/mm/c-r4k.c linux-2.6.19.new/arch/mips/mm/c-r4k.
+ if (c->cputype == CPU_BCM6338 || c->cputype == CPU_BCM6345 || c->cputype == CPU_BCM6348) + if (c->cputype == CPU_BCM6338 || c->cputype == CPU_BCM6345 || c->cputype == CPU_BCM6348)
+ { + {
+ printk("brcm mips: enabling icache and dcache...\n"); + printk("bcm963xx: enabling icache and dcache...\n");
+ /* Enable caches */ + /* Enable caches */
+ write_c0_diag(read_c0_diag() | 0xC0000000); + write_c0_diag(read_c0_diag() | 0xC0000000);
+ } + }
@ -133,7 +143,7 @@ diff -urN linux-2.6.19/arch/mips/pci/Makefile linux-2.6.19.new/arch/mips/pci/Mak
obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o
obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
+obj-$(CONFIG_BCM_PCI) += fixup-bcm96348.o pci-bcm96348.o ops-bcm96348.o +obj-$(CONFIG_BCM963XX) += fixup-bcm96348.o pci-bcm96348.o ops-bcm96348.o
# #
# These are still pretty much in the old state, watch, go blind. # These are still pretty much in the old state, watch, go blind.
@ -144,7 +154,7 @@ diff -urN linux-2.6.19/drivers/serial/Makefile linux-2.6.19.new/drivers/serial/M
obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
+obj-$(CONFIG_BCM_SERIAL) += bcm63xx_cons.o +obj-$(CONFIG_BCM963XX) += bcm63xx_cons.o
diff -urN linux-2.6.19/include/asm-mips/bootinfo.h linux-2.6.19.new/include/asm-mips/bootinfo.h diff -urN linux-2.6.19/include/asm-mips/bootinfo.h linux-2.6.19.new/include/asm-mips/bootinfo.h
--- linux-2.6.19/include/asm-mips/bootinfo.h 2006-11-29 22:57:37.000000000 +0100 --- linux-2.6.19/include/asm-mips/bootinfo.h 2006-11-29 22:57:37.000000000 +0100
+++ linux-2.6.19.new/include/asm-mips/bootinfo.h 2006-12-16 18:46:31.000000000 +0100 +++ linux-2.6.19.new/include/asm-mips/bootinfo.h 2006-12-16 18:46:31.000000000 +0100