aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c
blob: 3a350e90a14a2d892c16cb8782d09e219d92554a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 *  Atheros PB42 board support
 *
 *  Copyright (C) 2008-2012 Gabor Juhos <juhosg@openwrt.org>
 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 */

#include <asm/mach-ath79/ath79.h>

#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-m25p80.h"
#include "dev-usb.h"
#include "machtypes.h"
#include "pci.h"

#define PB42_KEYS_POLL_INTERVAL		20	/* msecs */
#define PB42_KEYS_DEBOUNCE_INTERVAL	(3 * PB42_KEYS_POLL_INTERVAL)

#define PB42_GPIO_BTN_SW4	8
#define PB42_GPIO_BTN_SW5	3

static struct gpio_keys_button pb42_gpio_keys[] __initdata = {
	{
		.desc		= "sw4",
		.type		= EV_KEY,
		.code		= BTN_0,
		.debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL,
		.gpio		= PB42_GPIO_BTN_SW4,
		.active_low	= 1,
	}, {
		.desc		= "sw5",
		.type		= EV_KEY,
		.code		= BTN_1,
		.debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL,
		.gpio		= PB42_GPIO_BTN_SW5,
		.active_low	= 1,
	}
};

static const char *pb42_part_probes[] = {
	"RedBoot",
	NULL,
};

static struct flash_platform_data pb42_flash_data = {
	.part_probes	= pb42_part_probes,
};

#define PB42_WAN_PHYMASK	BIT(20)
#define PB42_LAN_PHYMASK	(BIT(16) | BIT(17) | BIT(18) | BIT(19))
#define PB42_MDIO_PHYMASK	(PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)

static void __init pb42_init(void)
{
	ath79_register_m25p80(&pb42_flash_data);

	ath79_register_mdio(0, ~PB42_MDIO_PHYMASK);

	ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0);
	ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
	ath79_eth0_data.phy_mask = PB42_WAN_PHYMASK;

	ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1);
	ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
	ath79_eth1_data.speed = SPEED_100;
	ath79_eth1_data.duplex = DUPLEX_FULL;

	ath79_register_eth(0);
	ath79_register_eth(1);

	ath79_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL,
					ARRAY_SIZE(pb42_gpio_keys),
					pb42_gpio_keys);

	ath79_register_pci();
}

MIPS_MACHINE(ATH79_MACH_PB42, "PB42", "Atheros PB42", pb42_init);
87' href='#n487'>487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
#!/usr/bin/env bash
#
# Licensed under the terms of the GNU GPL License version 2 or later.
#
# Author: Jason Wu <jason.hy.wu@gmail.com>
# with modifications for multi-DTB-same-image by:
# Mathew McBride <matt@traverse.com.au>
#
# U-Boot firmware supports the booting of images in the Flattened Image
# Tree (FIT) format.  The FIT format uses a device tree structure to
# describe a kernel image, device tree blob, ramdisk, etc.  This script
# creates an Image Tree Source (.its file) which can be passed to the
# 'mkimage' utility to generate an Image Tree Blob (.itb file).  The .itb
# file can then be booted by U-Boot (or other bootloaders which support
# FIT images).  See doc/uImage.FIT/howto.txt in U-Boot source code for
# additional information on FIT images.
#
# This tools supports:
#   - multi-configuration
#   - multi-image support - multiple kernel/fdt/ramdsik
#   - per image configuration:
#     - hash algorithm and generated required subnodes
#     - compression
#     - signature and generated required subnodes
#
set -e

# image config limit
MAX_IMG=50
# conf config limit
MAX_CONF=10

# declare main data array
declare -a img_array
declare -a conf_array

# initialize array with empty values
for (( index=1; index<=$MAX_IMG; index++ )); do
	declare -a img$index
	for i in {0..13}; do
		eval img${index}[$i]=""
	done
done

for (( index=1; index<=$MAX_CONF; index++ )); do
	declare -a conf$index
	for i in {0..9}; do
		eval conf${index}[$i]=""
	done
done

# imgX array index information
#	0: type of image - kernel, fdt, ramdsik
#	1: image location
#	2: image index
#	3: loadaddr of image
#	4: entrypoint of image
#	5: compression
#	6: hash algorithm
#	7: part of the configuration
#	8: Human friend name for the image
#	9: key file name
#	10: signature
# 	11: conf friendly name

# confX array index information
#	0: conf number
#	1: kernel conf
#	2: fdt conf
#	3: rootfs conf
#	4: kernel key file
#	5: fdt key file
#	6: rootfs key file
#	7: kernel sign_algorithm
#	8: fdt sign_algorithm
#	9: rootfs sign_algorithm
#	10: conf friendly name

usage() {
	echo "Usage: `basename $0` -A arch -v version -o its_file" \
		"-k kernel -a addr -e entry [-C none] [-h sha1] [-c conf]"
	echo -e "Example1:\n\tkernel image ker_img1 with no compression +"
	echo -e "\tsha1 hash + fdt dtb1 with sha1 and crc32 hash for conf 1"
	echo -e "\t $ `basename $0` -A arm -v 4.4 \ "
	echo -e "\t      -k ker_img1 -C none -h sha1 -e 0x8000 -a 0x8000 -c 1 \ "
	echo -e "\t      -d dtb1 -h sha1 -h crc32 -c 1\n"
	echo "General settings:"
	echo -e "\t-A ==> set architecture to 'arch'"
	echo -e "\t-v ==> set kernel version to 'version'"
	echo -e "\t-o ==> create output file 'its_file' [optional]"
	echo "Input image type:"
	echo -e "\t-k ==> kernel image 'kernel'"
	echo -e "\t-d ==> Device Tree Blob 'dtb'"
	echo -e "\t-r ==> ramdisk image 'ramdisk"
	echo "Per image configurations:"
	echo -e "\t-C ==> set compression type 'comp'"
	echo -e "\t-c ==> set image config (multiple -c allowed)"
	echo -e "\t-a ==> set load address to 'addr' (hex)"
	echo -e "\t-e ==> set entry point to 'entry' (hex)"
	echo -e "\t-D ==> human friendly 'name' (one word only)"
	echo -e "\t-h ==> set hash algorithm (multiple -h allowed)"
	echo -e "\t-s ==> set signature for given config image"
	echo -e "\t-K ==> set key file for given config image"
	exit 1
}

array_check()
{
	local a=999
	local max_a=0
	local max_i=0

	if echo $1 | grep -q img; then
		max_a=$MAX_IMG
		max_i=13
		let a=$(echo $1 | awk -F "img" '{print $2}')
	elif echo $1 | grep -q conf; then
		max_a=$MAX_CONF
		max_i=10
		let a=$(echo $1 | awk -F "conf" '{print $2}')
	fi
	if [ ${a} -lt 0 -o ${a} -gt ${max_a} -o \
		${2} -lt 0 -o ${2} -gt ${max_i} ]; then
		echo "WARNING: Invalid array name, skipping!!!"
		return 255
	fi
}

#
# $1:	array name
# $2:	index
# $3:	value
# $4:	append operation
#
array_put()
{
	# check if array is declared
	array_check $1 $2 || return 0
	if [ -z "$4" ]; then
		eval $1[$2]=$3
	else
		eval $1[$2]=\"\${$1[$2]} $3\"
	fi
}

#
# $1:	array name
# $2:	index
#
array_get()
{
	local val
	eval val=\${$1[$2]}
	echo $val
}

parse_args() {
	local i=-1 k=-1 d=-1 r=-1
	while getopts ":A:a:C:c:D:d:e:h:k:K:o:v:r:s:n:" OPTION; do
		case $OPTION in
			A ) ARCH=$OPTARG;;
			a ) array_put img$i 3 $OPTARG;;
			C ) value_sanity_chk compression $OPTARG;
				array_put img$i 5 $OPTARG;;
			c ) array_put img$i 7 $OPTARG append;;
			D ) array_put img$i 8 $OPTARG;;
			d ) i=$(($i + 1));
				d=$(($d + 1));
				img_array[$i]=img$i;
				array_put img$i 0 fdt;
				array_put img$i 1 $OPTARG;
				array_put img$i 2 $d;
				;;
			e ) array_put img$i 4 $OPTARG;;
			h ) value_sanity_chk hash $OPTARG;
				array_put img$i 6 $OPTARG append;;
			k ) i=$(($i + 1));
				k=$(($k + 1));
				img_array[$i]=img$i;
				array_put img$i 0 "kernel";
				array_put img$i 1 $OPTARG;
				array_put img$i 2 $k;
				;;
			K ) array_put img$i 9 $OPTARG;;
			n ) array_put img$i 11 $OPTARG;;
			o ) OUTPUT=$OPTARG;;
			v ) VERSION=$OPTARG;;
			r ) i=$(($i + 1));
				r=$(($r + 1));
				img_array[$i]=img$i;
				array_put img$i 0 "ramdisk";
				array_put img$i 1 $OPTARG;
				array_put img$i 2 $r;
				;;
			s ) value_sanity_chk signature $OPTARG;
				array_put img$i 10 $OPTARG;
				;;
			* ) echo "Invalid option passed to '$0' (options:$@)"
			usage;;
		esac
	done
	[ -n "${OUTPUT}" ] || OUTPUT=fitimage.its
	[ -n "${VERSION}" ] || VERSION="Unknown"
	[ -n "${ARCH}" ] || ARCH=arm
}

#
# sanity check for signature, compression and hash
#
value_sanity_chk()
{
	local valid=""
	case $1 in
		signature) valid="sha-1,rsa-2048 sha-256,rsa-2048 sha-256,rsa-4096";;
		compression) valid="gzip bzip2 none";;
		hash) valid="sha1 md5 crc32";;
	esac
	if ! echo $valid | grep -q "$2"; then
		echo "Error: Invalid $1 provided '$2'"
		echo "Valid options are: $valid"
		exit 255
	fi
}

#
# Emit the fitImage section bits
#
# $1: Section bit type: fitstart   - its header
#                       imagestart - image section start
#                       confstart  - configuration section start
#                       sectend    - section end
#                       fitend     - fitimage end
# $2: optional variable for confstart section
#
emit_its() {
	case $1 in
	fitstart)
		cat << EOF > ${OUTPUT}
/dts-v1/;

/ {
	description = "U-Boot fitImage for ${VERSION} kernel";
	#address-cells = <1>;
EOF
	;;
	imagestart)
		echo -e "\n\timages {" >> ${OUTPUT};;
	confstart)
#		echo -e "\tconfigurations {\n\t\tdefault = \"conf@${2:-0}\";" \
	echo -e "\tconfigurations {\n" \
			>> ${OUTPUT};;
	sectend)
		echo -e "\t};" >> ${OUTPUT};;
	fitend)
		echo -e "};" >> ${OUTPUT};;
	esac
}

#
# Emit kernel image node
#
emit_kernel() {
	local image=${1}
	local count=${2:-${MAX_IMG}}
	local loaddaddr=${3:-0x8000}
	local entrypoint=${4:-0x8000}
	local compresson=${5:-none}
	local checksum=${6:-sha1}
	local name=${7}

	[ -z "${name}" ] || name=" ${name}"
	cat << EOF >> ${OUTPUT}
		kernel@${count} {
			description = "Linux Kernel${name}";
			data = /incbin/("${image}");
			type = "kernel";
			arch = "${ARCH}";
			os = "linux";
			compression = "${compresson}";
			load = <${loaddaddr}>;
			entry = <${entrypoint}>;
EOF
	emit_cksum ${checksum}

	if [ -z "$SIGN_IN_CONF" ] ; then
		emit_signature "$9" "" "" "$8" "" ""
	fi

	echo "		};" >> ${OUTPUT}
}

#
# Emit fdt node
#
emit_fdt() {
	local image=${1}
	local count=${2:-${MAX_IMG}}
	local compresson=${3:-none}
	local checksum=${4:-sha1}
	local name=${5}
	local loadaddr=${6}

	[ -z "${name}" ] || name=" ${name}"
	cat << EOF >> ${OUTPUT}
		fdt@${count} {
			description = "Flattened Device Tree blob${name}";
			data = /incbin/("${image}");
			type = "flat_dt";
			arch = "${ARCH}";
			load = <${loadaddr}>;
			compression = "none";
EOF
	emit_cksum ${checksum}
	if [ -z "$SIGN_IN_CONF" ] ; then
		emit_signature "" "$7" "" "" "$6" ""
	fi
	echo "		};" >> ${OUTPUT}
}

#
# Emit ramdisk node
#
emit_ramdisk() {
	local image=${1}
	local count=${2:-${MAX_IMG}}
	local compresson=${3:-none}
	local checksum=${4:-sha1}
	local name=${5}

	[ -z "${name}" ] || name=" ${name}"
	cat << EOF >> ${OUTPUT}
		ramdisk@${count} {
			description = "ramdisk${name}";
			data = /incbin/("${image}");
			type = "ramdisk";
			arch = "${ARCH}";
			os = "linux";
			compression = "${compresson}";
EOF
	emit_cksum ${checksum}
	if [ -z "$SIGN_IN_CONF" ] ; then
		emit_signature "" "" "$7" "" "" "$6"
	fi
	echo "		};" >> ${OUTPUT}
}

#
# Emit check sum sub node
#
emit_cksum() {
	csum_list=$@
	count=1
	for csum in ${csum_list}; do
		cat << EOF >> ${OUTPUT}
			hash@${count} {
				algo = "${csum}";
			};
EOF
		count=`expr ${count} + 1`
	done
}

#
# Emit signature sub node
#
emit_signature() {
	local kernel=$1
	local fdt=$2
	local rootfs=$3
	local kernel_key=$4
	local fdt_key=$5
	local rootfs_key=$6
	local imgs=""
	local count=0
	local chk_list="" algo="" algos="" i=""

	for i in kernel fdt rootfs; do
		eval algo=\$$i
		eval key=\$${i}_key
		[ -n "$algo" ] || continue
		if ! echo "$algos" | grep -q $algo; then
			if [ -z "$algos" ]; then
				algos=$algo
			else
				algos="${algos} $algo"
			fi
		fi
		if ! echo "$keys" | grep -q $key; then
			if [ -z "$keys" ]; then
				keys=$key
			else
				keys="${keys} $key"
			fi
		fi
	done

	for algo in $algos; do
		for key in $keys; do
			img=""
			for i in kernel fdt rootfs; do
				eval tmp_algo=\$$i
				eval tmp_key=\$${i}_key
				[ "$tmp_algo" == "$algo" ] || continue
				[ "$tmp_key" == "$key" ] || continue
				if [ -z "$img" ]; then
					img=$i
				else
					img=${img},$i
				fi
			done

			[ -n "$img" ] || continue
			cat << EOF >> ${OUTPUT}
			signature@${count} {
				algo = "${algo}";
				key-name-hint = "${key}";
EOF
			if [ -n "$SIGN_IN_CONF" ] ; then
				echo "			sign-images = \"$img\";" >> ${OUTPUT}
			fi
			echo "			};" >> ${OUTPUT}

			count=`expr ${count} + 1`
		done
	done
}

#
# Emit config sub nodes
#
emit_config() {
	local conf_csum="sha1"

	config_name="conf@${1}"
	if [ ! -z "${11}" ]; then
		config_name="${11}"
	fi 
	if [ -z "${2}" ]; then
		echo "Error: config has no kernel img, skipping conf node!"
		return 0
	fi

	# Test if we have any DTBs at all
	if [ -z "${3}" ] ; then
		conf_desc="Boot Linux kernel"
		fdt_line=""
	else
		conf_desc="Boot Linux kernel with FDT blob"
		fdt_line="
			fdt = \"fdt@${3}\";"
	fi

	# Test if we have any ROOTFS at all
	if [ -n "${4}" ] ; then
		conf_desc="$conf_desc + ramdisk"
		fdt_line="${fdt_line}
			ramdisk = \"ramdisk@${4}\";"
	fi

	kernel_line="kernel = \"kernel@${2}\";"

	cat << EOF >> ${OUTPUT}
		${config_name} {
			description = "${conf_desc}";
			${kernel_line}${fdt_line}
			hash@1 {
				algo = "${conf_csum}";
			};
EOF
	if [ -n "$SIGN_IN_CONF" ] ; then
		emit_signature "$5" "$6" "$7" "$8" "$9" "${10}"
	fi

	echo "		};" >> ${OUTPUT}
}

#
# remove prefix space
#
remove_prefix_space()
{
	echo "$@" | sed "s:^ ::g"
}

#
# generate image nodes and its subnodes
#
emit_image_nodes()
{
	local t img_c img_i img_index chk
	local img_type img_path img_count img_loadadr img_entrypoint \
		img_compression img_hash img_conf img_name img_key img_sign \
		img_index

	emit_its imagestart
	for t in "kernel" "fdt" "ramdisk"; do
		img_index=0
		for a in ${img_array[@]}; do
			img_type=$(array_get $a 0)
			img_path=$(array_get $a 1)
			img_count=$(array_get $a 2)
			img_loadadr=$(array_get $a 3)
			img_entrypoint=$(array_get $a 4)
			img_compression=$(array_get $a 5)
			img_hash=$(array_get $a 6)
			img_conf=$(array_get $a 7)
			img_name=$(array_get $a 8)
			img_key=$(array_get $a 9)
			img_sign=$(array_get $a 10)
			img_cname=$(array_get $a 11)
			
			img_conf=$(remove_prefix_space $img_conf)
			img_hash=$(remove_prefix_space $img_hash)

			[ "${img_type}" == $t ] || continue
			# generate sub nodes
			eval chk=\$DEF_$t
			[ -n "${chk}" ] || eval DEF_$t=$img_count
			case $t in
				kernel) emit_kernel "$img_path" "$img_count" \
					"$img_loadadr" "$img_entrypoint" \
					"$img_compression" "$img_hash" \
					"$img_name" "$img_key" "$img_sign";;
				fdt) emit_fdt "$img_path" "$img_count" \
					"$img_compression" "$img_hash" \
					"$img_name" "$img_loadadr" "$img_key" "$img_sign"  ;;

				ramdisk) emit_ramdisk "$img_path" "$img_count" \
					"$img_compression" "$img_hash" \
					"$img_name" "$img_key" "$img_sign";;
			esac

			# set up configuration data
			for img_c in $img_conf; do
				img_i=""
				#set up default configuration if its not set
				[ -n "$DEF_CONFIG" ] || DEF_CONFIG=$img_c
				[ -z "${img_c}" ] || conf_array[$img_c]=conf$img_c
				array_put conf$img_c 0 ${img_c}
				case $t in
					kernel) img_i=1;;
					fdt) img_i=2;;
					ramdisk) img_i=3;;
				esac
				array_put conf$img_c $img_i $img_index
				array_put conf$img_c $(($img_i + 3)) ${img_sign}
				array_put conf$img_c $(($img_i + 6)) ${img_key}
				array_put conf$img_c 10 $img_cname
			done
			img_index=$((img_index + 1))
		done
	done
	emit_its sectend
}

#
# generate configuration node and its subnodes
#
emit_configuration_nodes ()
{
	local count kernel fdt ramdisk ker_file fdt_file rfs_file ker_sign \
		fdt_sign rfs_sign
	emit_its confstart $DEF_CONFIG
	for a in ${conf_array[@]}; do
		count=$(array_get $a 0)
		kernel=$(array_get $a 1)
		fdt=$(array_get $a 2)
		ramdisk=$(array_get $a 3)
		er_file=$(array_get $a 4)
		fdt_file=$(array_get $a 5)
		rfs_file=$(array_get $a 6)
		ker_sign=$(array_get $a 7)
		fdt_sign=$(array_get $a 8)
		rfs_sign=$(array_get $a 9)
		cname=$(array_get $a 10)
		emit_config "$count" "$kernel" "$fdt" "$ramdisk" "$ker_file" \
			"$fdt_file" "$rfs_file" "$ker_sign" "$fdt_sign" \
			"$rfs_sign" "${cname}"
	done
	if [ -z "${DEF_CONFIG}" ]; then
		emit_config "0" "$DEF_kernel" "$DEF_fdt" "$DEF_ramdisk"
	fi
	emit_its sectend
}

# Set to none empty to create signature sub node under images node
SIGN_IN_CONF=${SIGN_IN_CONF:-""}
# Set to default config used
DEF_CONFIG=${DEF_CONFIG:-""}

parse_args $@

emit_its fitstart
emit_image_nodes
emit_configuration_nodes
emit_its fitend