Commit 5d898a00 authored by Shaohui Xie's avatar Shaohui Xie Committed by Andy Fleming

powerpc/CoreNet: add tool to support pbl image build.

Provides a tool to build boot Image for PBL(Pre boot loader) which is
used on Freescale CoreNet SoCs, PBL can be used to load some instructions
and/or data for pre-initialization. The default output image is u-boot.pbl,
for more details please refer to doc/README.pblimage.
Signed-off-by: 's avatarShaohui Xie <Shaohui.Xie@freescale.com>
Signed-off-by: 's avatarAndy Fleming <afleming@freescale.com>
parent 461632bd
......@@ -422,6 +422,11 @@ $(obj)u-boot.kwb: $(obj)u-boot.bin
$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@
$(obj)u-boot.pbl: $(obj)u-boot.bin
$(obj)tools/mkimage -n $(CONFIG_PBLRCW_CONFIG) \
-R $(CONFIG_PBLPBI_CONFIG) -T pblimage \
-d $< $@
$(obj)u-boot.sha1: $(obj)u-boot.bin
$(obj)tools/ubsha1 $(obj)u-boot.bin
......@@ -782,6 +787,7 @@ clobber: tidy
$(obj)cscope.* $(obj)*.*~
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL-y)
@rm -f $(obj)u-boot.kwb
@rm -f $(obj)u-boot.pbl
@rm -f $(obj)u-boot.imx
@rm -f $(obj)u-boot.ubl
@rm -f $(obj)u-boot.ais
......
#
# Copyright 2012 Freescale Semiconductor, Inc.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# 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., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
#
# Refer docs/README.pblimage for more details about how-to configure
# and create PBL boot image
#
#PBI commands
#Initialize CPC1 as 1MB SRAM
09010000 00200400
09138000 00000000
091380c0 00000100
09010100 00000000
09010104 fff0000b
09010f00 08000000
09010000 80000000
#Configure LAW for CPC1
09000d00 00000000
09000d04 fff00000
09000d08 81000013
09000010 00000000
09000014 ff000000
09000018 81000000
#Initialize eSPI controller, default configuration is slow for eSPI to
#load data, this configuration comes from u-boot eSPI driver.
09110000 80000403
09110020 2d170008
09110024 00100008
09110028 00100008
0911002c 00100008
#Flush PBL data
09138000 00000000
091380c0 00000000
#
# Default RCW for P3041DS.
#
#PBL preamble and RCW header
aa55aa55 010e0100
#64 bytes RCW data
12600000 00000000 241C0000 00000000
D8984A01 03002000 58000000 41000000
00000000 00000000 00000000 10070000
00000000 00000000 00000000 00000000
#
# Default RCW for P4080DS.
#
#PBL preamble and RCW header
aa55aa55 010e0100
#64 bytes RCW data
105a0000 00000000 1e1e181e 0000cccc
58400000 3c3c2000 58000000 e1000000
00000000 00000000 00000000 008b6000
00000000 00000000 00000000 00000000
#
# Default RCW for P5020DS.
#
#PBL preamble and RCW header
aa55aa55 010e0100
#64 bytes RCW data
0C540000 00000000 1E120000 00000000
D8984A01 03002000 58000000 41000000
00000000 00000000 00000000 10070000
00000000 00000000 00000000 00000000
......@@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_INVALID, NULL, "Invalid Image", },
{ IH_TYPE_MULTI, "multi", "Multi-File Image", },
{ IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",},
{ IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",},
{ IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", },
{ IH_TYPE_SCRIPT, "script", "Script", },
{ IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
......
------------------------------------------------------------------
Freescale PBL(pre-boot loader) Boot Image generation using mkimage
------------------------------------------------------------------
The CoreNet SoC's can boot directly from eSPI FLASH, SD/MMC and
NAND, etc. These SoCs use PBL to load RCW and/or pre-initialization
instructions. For more details refer section 5 Pre-boot loader
specifications of reference manual P3041RM/P4080RM/P5020RM at link:
http://www.freescale.com/webapp/search/Serp.jsp?Reference+Manuals
Building PBL Boot Image and boot steps
--------------------------------------
1. Building PBL Boot Image.
The default Image is u-boot.pbl.
For eSPI boot(available on P3041/P4080/P5020):
To build the eSPI boot image:
make <board_name>_SPIFLASH_config
make u-boot.pbl
For SD boot(available on P3041/P4080/P5020):
To build the SD boot image:
make <board_name>_SDCARD_config
make u-boot.pbl
For Nand boot(available on P3041/P5020):
To build the NAND boot image:
make <board_name>_NAND_config
make u-boot.pbl
2. pblimage support available with mkimage utility will generate Freescale PBL
boot image that can be flashed on the board eSPI flash, SD/MMC and NAND.
Following steps describe it in detail.
1). Boot from eSPI flash
Write u-boot.pbl to eSPI flash from offset 0x0.
for ex in u-boot:
=>tftp 100000 u-boot.pbl
=>sf probe 0
=>sf erase 0 100000
=>sf write 100000 0 $filesize
Change SW1[1:5] = off off on off on.
2). Boot from SD/MMC
Write u-boot.pbl to SD/MMC from offset 0x1000.
for ex in u-boot:
=>tftp 100000 u-boot.pbl
=>mmcinfo
=>mmc write 100000 8 441
Change SW1[1:5] = off off on on off.
3). Boot from Nand
Write u-boot.pbl to Nand from offset 0x0.
for ex in u-boot:
=>tftp 100000 u-boot.pbl
=>nand info
=>nand erase 0 100000
=>nand write 100000 0 $filesize
Change SW1[1:5] = off on off off on
Change SW7[1:4] = on off off on
Board specific configuration file specifications:
------------------------------------------------
1. Configuration files rcw.cfg and pbi.cfg must present in the
board/freescale/corenet_ds/, rcw.cfg is for RCW, pbi.cfg is for
PBI instructions. File name must not be changed since they are used
in Makefile.
2. These files can have empty lines and lines starting with "#" as first
character to put comments
Typical example of rcw.cfg file:
-----------------------------------
#PBL preamble and RCW header
aa55aa55 010e0100
#64 bytes RCW data
4c580000 00000000 18185218 0000cccc
40464000 3c3c2000 58000000 61000000
00000000 00000000 00000000 008b6000
00000000 00000000 00000000 00000000
Typical example of pbi.cfg file:
-----------------------------------
#PBI commands
#Initialize CPC1
09010000 00200400
09138000 00000000
091380c0 00000100
09010100 00000000
09010104 fff0000b
09010f00 08000000
09010000 80000000
#Configure LAW for CPC1
09000d00 00000000
09000d04 fff00000
09000d08 81000013
09000010 00000000
09000014 ff000000
09000018 81000000
#Initialize eSPI controller
09110000 80000403
09110020 2d170008
09110024 00100008
09110028 00100008
0911002c 00100008
#Flush PBL data
09138000 00000000
091380c0 00000000
------------------------------------------------
Author: Shaohui Xie<Shaohui.Xie@freescale.com>
......@@ -31,6 +31,14 @@
#ifdef CONFIG_RAMBOOT_PBL
#define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc
#define CONFIG_PBLPBI_CONFIG $(SRCTREE)/board/freescale/corenet_ds/pbi.cfg
#if defined(CONFIG_P3041DS)
#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p3041ds.cfg
#elif defined(CONFIG_P4080DS)
#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p4080ds.cfg
#elif defined(CONFIG_P5020DS)
#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p5020ds.cfg
#endif
#endif
#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
......
......@@ -164,6 +164,7 @@
#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */
#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */
#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
/*
* Compression Types
......
......@@ -92,6 +92,7 @@ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
NOPED_OBJ_FILES-y += aisimage.o
NOPED_OBJ_FILES-y += kwbimage.o
NOPED_OBJ_FILES-y += pblimage.o
NOPED_OBJ_FILES-y += imximage.o
NOPED_OBJ_FILES-y += omapimage.o
NOPED_OBJ_FILES-y += mkenvimage.o
......@@ -208,6 +209,7 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
$(obj)image.o \
$(obj)imximage.o \
$(obj)kwbimage.o \
$(obj)pblimage.o \
$(obj)md5.o \
$(obj)mkimage.o \
$(obj)os_support.o \
......
......@@ -39,6 +39,7 @@ struct mkimage_params params = {
.comp = IH_COMP_GZIP,
.dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,
.imagename = "",
.imagename2 = "",
};
/*
......@@ -150,6 +151,8 @@ main (int argc, char **argv)
int retval = 0;
struct image_type_params *tparams = NULL;
/* Init Freescale PBL Boot image generation/list support */
init_pbl_image_type();
/* Init Kirkwood Boot image generation/list support */
init_kwb_image_type ();
/* Init Freescale imx Boot image generation/list support */
......@@ -250,6 +253,15 @@ main (int argc, char **argv)
usage ();
params.imagename = *++argv;
goto NXTARG;
case 'R':
if (--argc <= 0)
usage();
/*
* This entry is for the second configuration
* file, if only one is not enough.
*/
params.imagename2 = *++argv;
goto NXTARG;
case 's':
params.skipcpy = 1;
break;
......@@ -440,6 +452,9 @@ NXTARG: ;
break;
}
}
} else if (params.type == IH_TYPE_PBLIMAGE) {
/* PBL has special Image format, implements its' own */
pbl_load_uboot(ifd, &params);
} else {
copy_file (ifd, params.datafile, 0);
}
......
......@@ -69,6 +69,7 @@ struct mkimage_params {
unsigned int addr;
unsigned int ep;
char *imagename;
char *imagename2;
char *datafile;
char *imagefile;
char *cmdname;
......@@ -147,6 +148,8 @@ void mkimage_register (struct image_type_params *tparams);
*
* Supported image types init functions
*/
void pbl_load_uboot(int fd, struct mkimage_params *mparams);
void init_pbl_image_type(void);
void init_ais_image_type(void);
void init_kwb_image_type (void);
void init_imx_image_type (void);
......
/*
* Copyright 2012 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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
*/
#define _GNU_SOURCE
#include "mkimage.h"
#include <image.h>
#include "pblimage.h"
/*
* The PBL can load up to 64 bytes at a time, so we split the U-Boot
* image into 64 byte chunks. PBL needs a command for each piece, of
* the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE
* is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit,
* so it starts from 0x81F80000.
*/
static uint32_t next_pbl_cmd = 0x81F80000;
/*
* need to store all bytes in memory for calculating crc32, then write the
* bytes to image file for PBL boot.
*/
static unsigned char mem_buf[600000];
static unsigned char *pmem_buf = mem_buf;
static int pbl_size;
static char *fname = "Unknown";
static int lineno = -1;
static struct pbl_header pblimage_header;
static union
{
char c[4];
unsigned char l;
} endian_test = { {'l', '?', '?', 'b'} };
#define ENDIANNESS ((char)endian_test.l)
static void generate_pbl_cmd(void)
{
uint32_t val = next_pbl_cmd;
next_pbl_cmd += 0x40;
int i;
for (i = 3; i >= 0; i--) {
*pmem_buf++ = (val >> (i * 8)) & 0xff;
pbl_size++;
}
}
static void pbl_fget(size_t size, FILE *stream)
{
unsigned char c;
int c_temp;
while (size && (c_temp = fgetc(stream)) != EOF) {
c = (unsigned char)c_temp;
*pmem_buf++ = c;
pbl_size++;
size--;
}
}
/* load split u-boot with PBI command 81xxxxxx. */
static void load_uboot(FILE *fp_uboot)
{
while (next_pbl_cmd < 0x82000000) {
generate_pbl_cmd();
pbl_fget(64, fp_uboot);
}
}
static void check_get_hexval(char *token)
{
uint32_t hexval;
int i;
if (!sscanf(token, "%x", &hexval)) {
printf("Error:%s[%d] - Invalid hex data(%s)\n", fname,
lineno, token);
exit(EXIT_FAILURE);
}
for (i = 3; i >= 0; i--) {
*pmem_buf++ = (hexval >> (i * 8)) & 0xff;
pbl_size++;
}
}
static void pbl_parser(char *name)
{
FILE *fd = NULL;
char *line = NULL;
char *token, *saveptr1, *saveptr2;
size_t len = 0;
fname = name;
fd = fopen(name, "r");
if (fd == NULL) {
printf("Error:%s - Can't open\n", fname);
exit(EXIT_FAILURE);
}
while ((getline(&line, &len, fd)) > 0) {
lineno++;
token = strtok_r(line, "\r\n", &saveptr1);
/* drop all lines with zero tokens (= empty lines) */
if (token == NULL)
continue;
for (line = token;; line = NULL) {
token = strtok_r(line, " \t", &saveptr2);
if (token == NULL)
break;
/* Drop all text starting with '#' as comments */
if (token[0] == '#')
break;
check_get_hexval(token);
}
}
if (line)
free(line);
fclose(fd);
}
static uint32_t crc_table[256];
static void make_crc_table(void)
{
uint32_t mask;
int i, j;
uint32_t poly; /* polynomial exclusive-or pattern */
/*
* the polynomial used by PBL is 1 + x1 + x2 + x4 + x5 + x7 + x8 + x10
* + x11 + x12 + x16 + x22 + x23 + x26 + x32.
*/
poly = 0x04c11db7;
for (i = 0; i < 256; i++) {
mask = i << 24;
for (j = 0; j < 8; j++) {
if (mask & 0x80000000)
mask = (mask << 1) ^ poly;
else
mask <<= 1;
}
crc_table[i] = mask;
}
}
unsigned long pbl_crc32(unsigned long crc, const char *buf, uint32_t len)
{
uint32_t crc32_val = 0xffffffff;
uint32_t xor = 0x0;
int i;
make_crc_table();
for (i = 0; i < len; i++)
crc32_val = (crc32_val << 8) ^
crc_table[(crc32_val >> 24) ^ (*buf++ & 0xff)];
crc32_val = crc32_val ^ xor;
if (crc32_val < 0) {
crc32_val += 0xffffffff;
crc32_val += 1;
}
return crc32_val;
}
static uint32_t reverse_byte(uint32_t val)
{
uint32_t temp;
unsigned char *p1;
int j;
temp = val;
p1 = (unsigned char *)&temp;
for (j = 3; j >= 0; j--)
*p1++ = (val >> (j * 8)) & 0xff;
return temp;
}
/* write end command and crc command to memory. */
static void add_end_cmd(void)
{
uint32_t pbl_end_cmd[4] = {0x09138000, 0x00000000,
0x091380c0, 0x00000000};
uint32_t crc32_pbl;
int i;
unsigned char *p = (unsigned char *)&pbl_end_cmd;
if (ENDIANNESS == 'l') {
for (i = 0; i < 4; i++)
pbl_end_cmd[i] = reverse_byte(pbl_end_cmd[i]);
}
for (i = 0; i < 16; i++) {
*pmem_buf++ = *p++;
pbl_size++;
}
/* Add PBI CRC command. */
*pmem_buf++ = 0x08;
*pmem_buf++ = 0x13;
*pmem_buf++ = 0x80;
*pmem_buf++ = 0x40;
pbl_size += 4;
/* calculated CRC32 and write it to memory. */
crc32_pbl = pbl_crc32(0, (const char *)mem_buf, pbl_size);
*pmem_buf++ = (crc32_pbl >> 24) & 0xff;
*pmem_buf++ = (crc32_pbl >> 16) & 0xff;
*pmem_buf++ = (crc32_pbl >> 8) & 0xff;
*pmem_buf++ = (crc32_pbl) & 0xff;
pbl_size += 4;
if ((pbl_size % 16) != 0) {
for (i = 0; i < 8; i++) {
*pmem_buf++ = 0x0;
pbl_size++;
}
}
if ((pbl_size % 16 != 0)) {
printf("Error: Bad size of image file\n");
exit(EXIT_FAILURE);
}
}
void pbl_load_uboot(int ifd, struct mkimage_params *params)
{
FILE *fp_uboot;
int size;
/* parse the rcw.cfg file. */
pbl_parser(params->imagename);
/* parse the pbi.cfg file. */
pbl_parser(params->imagename2);
fp_uboot = fopen(params->datafile, "r");
if (fp_uboot == NULL) {
printf("Error: %s open failed\n", params->datafile);
exit(EXIT_FAILURE);
}
load_uboot(fp_uboot);
add_end_cmd();
fclose(fp_uboot);
lseek(ifd, 0, SEEK_SET);
size = pbl_size;
if (write(ifd, (const void *)&mem_buf, size) != size) {
fprintf(stderr, "Write error on %s: %s\n",
params->imagefile, strerror(errno));
exit(EXIT_FAILURE);
}
}
static int pblimage_check_image_types(uint8_t type)
{
if (type == IH_TYPE_PBLIMAGE)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
static int pblimage_verify_header(unsigned char *ptr, int image_size,
struct mkimage_params *params)
{
struct pbl_header *pbl_hdr = (struct pbl_header *) ptr;
/* Only a few checks can be done: search for magic numbers */
if (ENDIANNESS == 'l') {
if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
return -FDT_ERR_BADSTRUCTURE;
if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER))
return -FDT_ERR_BADSTRUCTURE;
} else {
if (pbl_hdr->preamble != RCW_PREAMBLE)
return -FDT_ERR_BADSTRUCTURE;
if (pbl_hdr->rcwheader != RCW_HEADER)
return -FDT_ERR_BADSTRUCTURE;
}
return 0;
}
static void pblimage_print_header(const void *ptr)
{
printf("Image Type: Freescale PBL Boot Image\n");
}
static void pblimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct mkimage_params *params)
{
/*nothing need to do, pbl_load_uboot takes care of whole file. */
}
/* pblimage parameters */
static struct image_type_params pblimage_params = {
.name = "Freescale PBL Boot Image support",
.header_size = sizeof(struct pbl_header),
.hdr = (void *)&pblimage_header,
.check_image_type = pblimage_check_image_types,
.verify_header = pblimage_verify_header,
.print_header = pblimage_print_header,
.set_header = pblimage_set_header,
};
void init_pbl_image_type(void)
{
pbl_size = 0;
mkimage_register(&pblimage_params);
}
/*
* Copyright 2012 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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
*/
#ifndef PBLIMAGE_H
#define PBLIMAGE_H
#define RCW_BYTES 64
#define RCW_PREAMBLE 0xaa55aa55
#define RCW_HEADER 0x010e0100
struct pbl_header {
uint32_t preamble;
uint32_t rcwheader;
uint8_t rcw_data[RCW_BYTES];
};
#endif /* PBLIMAGE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment