diff --git a/Makefile b/Makefile index f64a700..f71e6c5 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,8 @@ tlb_helpers.o \ std.o \ bl_common.o \ - platform_helpers.o + platform_helpers.o \ + io_storage.o ARCH ?= aarch64 @@ -120,7 +121,9 @@ BL2_LINKERFILE := $(addprefix ${BUILD_BL2}/,${BL2_LINKERFILE}) BL31_LINKERFILE := $(addprefix ${BUILD_BL31}/,${BL31_LINKERFILE}) + INCLUDES += -Ilib/include/ \ + -Idrivers/io \ -Iinclude/${ARCH}/ \ -Iinclude/ \ -Iarch/system/gic \ diff --git a/drivers/io/io_driver.h b/drivers/io/io_driver.h new file mode 100644 index 0000000..82dbbf1 --- /dev/null +++ b/drivers/io/io_driver.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + */ + +#ifndef __IO_DRIVER_H__ +#define __IO_DRIVER_H__ + +#include "platform.h" /* For MAX_IO_DEVICES */ + + +/* Generic IO entity structure,representing an accessible IO construct on the + * device, such as a file */ +struct io_entity { + io_dev_handle dev_handle; + uintptr_t info; +}; + + +/* Device info structure, providing device-specific functions and a means of + * adding driver-specific state */ +struct io_dev_info { + struct io_dev_funcs *funcs; + uintptr_t info; +}; + + +/* Structure used to create a connection to a type of device */ +struct io_dev_connector { + /* dev_open opens a connection to a particular device driver */ + int (*dev_open)(void *spec, struct io_dev_info **dev_info); +}; + + +/* Structure to hold device driver function pointers */ +struct io_dev_funcs { + io_type (*type)(void); + int (*open)(struct io_dev_info *dev_info, const void *spec, + struct io_entity *entity); + int (*seek)(struct io_entity *entity, int mode, ssize_t offset); + int (*size)(struct io_entity *entity, size_t *length); + int (*read)(struct io_entity *entity, void *buffer, size_t length, + size_t *length_read); + int (*write)(struct io_entity *entity, const void *buffer, + size_t length, size_t *length_written); + int (*close)(struct io_entity *entity); + int (*dev_init)(struct io_dev_info *dev_info, const void *init_params); + int (*dev_close)(struct io_dev_info *dev_info); +}; + + +/* IO platform data - used to track devices registered for a specific + * platform */ +struct io_plat_data { + struct io_dev_info *devices[MAX_IO_DEVICES]; + unsigned int dev_count; +}; + + +/* Operations intended to be performed during platform initialisation */ + +/* Initialise the IO layer */ +void io_init(struct io_plat_data *data); + +/* Register a device driver */ +int io_register_device(struct io_dev_info *dev_info); + +#endif /* __IO_DRIVER_H__ */ diff --git a/include/io_storage.h b/include/io_storage.h new file mode 100644 index 0000000..71f5d26 --- /dev/null +++ b/include/io_storage.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + */ + +#ifndef __IO_H__ +#define __IO_H__ + +#include +#include /* For ssize_t */ + + +/* Device type which can be used to enable policy decisions about which device + * to access */ +typedef enum { + IO_TYPE_INVALID, + IO_TYPE_SEMIHOSTING, + IO_TYPE_BLOCK, + IO_TYPE_MAX +} io_type; + + +/* Modes used when seeking data on a supported device */ +typedef enum { + IO_SEEK_INVALID, + IO_SEEK_SET, + IO_SEEK_END, + IO_SEEK_CUR, + IO_SEEK_MAX +} io_seek_mode; + + +/* Connector type, providing a means of identifying a device to open */ +struct io_dev_connector; + +/* Device handle, providing a client with access to a specific device */ +typedef struct io_dev_info *io_dev_handle; + +/* IO handle, providing a client with access to a specific source of data from + * a device */ +typedef struct io_entity *io_handle; + + +/* File specification - used to refer to data on a device supporting file-like + * entities */ +typedef struct { + const char *path; + unsigned int mode; +} io_file_spec; + + +/* Block specification - used to refer to data on a device supporting + * block-like entities */ +typedef struct { + unsigned long offset; + size_t length; +} io_block_spec; + + +/* Access modes used when accessing data on a device */ +#define IO_MODE_INVALID (0) +#define IO_MODE_RO (1 << 0) +#define IO_MODE_RW (1 << 1) + + +/* Return codes reported by 'io_*' APIs */ +#define IO_SUCCESS (0) +#define IO_FAIL (-1) +#define IO_NOT_SUPPORTED (-2) +#define IO_RESOURCES_EXHAUSTED (-3) + + +/* Open a connection to a device */ +int io_dev_open(struct io_dev_connector *dev_con, void *dev_spec, + io_dev_handle *dev_handle); + + +/* Initialise a device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(io_dev_handle dev_handle, const void *init_params); + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(io_dev_handle dev_handle); + + +/* Synchronous operations */ +int io_open(io_dev_handle dev_handle, const void *spec, io_handle *handle); + +int io_seek(io_handle handle, io_seek_mode mode, ssize_t offset); + +int io_size(io_handle handle, size_t *length); + +int io_read(io_handle handle, void *buffer, size_t length, size_t *length_read); + +int io_write(io_handle handle, const void *buffer, size_t length, + size_t *length_written); + +int io_close(io_handle handle); + + +#endif /* __IO_H__ */ diff --git a/include/stdlib/string.h b/include/stdlib/string.h index 221de03..00a5dcd 100644 --- a/include/stdlib/string.h +++ b/include/stdlib/string.h @@ -56,7 +56,9 @@ void *memset(void *, int, size_t); char *strchr(const char *, int) __pure; +int strcmp(const char *, const char *) __pure; size_t strlen(const char *) __pure; +int strncmp(const char *, const char *, size_t) __pure; __END_DECLS diff --git a/lib/io_storage.c b/lib/io_storage.c new file mode 100644 index 0000000..aeb8edb --- /dev/null +++ b/lib/io_storage.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + */ + + +#include +#include +#include "io_storage.h" +#include "io_driver.h" + + +#define MAX_DEVICES(plat_data) \ + (sizeof((plat_data)->devices)/sizeof((plat_data)->devices[0])) + + +/* Storage for a fixed maximum number of IO entities, definable by platform */ +static struct io_entity entity_pool[MAX_IO_HANDLES]; + +/* Simple way of tracking used storage - each entry is NULL or a pointer to an + * entity */ +static struct io_entity *entity_map[MAX_IO_HANDLES]; + +/* Track number of allocated entities */ +static unsigned int entity_count; + + +/* Used to keep a reference to platform-specific data */ +static struct io_plat_data *platform_data; + + +#if DEBUG /* Extra validation functions only used in debug builds */ + +/* Return a boolean value indicating whether a device connector is valid */ +static int is_valid_dev_connector(const struct io_dev_connector *dev_con) +{ + int result = (dev_con != NULL) && (dev_con->dev_open != NULL); + return result; +} + + +/* Return a boolean value indicating whether a device handle is valid */ +static int is_valid_dev(io_dev_handle handle) +{ + const struct io_dev_info *dev = handle; + int result = (dev != NULL) && (dev->funcs != NULL) && + (dev->funcs->type != NULL) && + (dev->funcs->type() < IO_TYPE_MAX); + return result; +} + + +/* Return a boolean value indicating whether an IO entity is valid */ +static int is_valid_entity(io_handle handle) +{ + const struct io_entity *entity = handle; + int result = (entity != NULL) && (is_valid_dev(entity->dev_handle)); + return result; +} + + +/* Return a boolean value indicating whether a seek mode is valid */ +static int is_valid_seek_mode(io_seek_mode mode) +{ + return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX)); +} + +#endif /* End of debug-only validation functions */ + + +/* Open a connection to a specific device */ +static int dev_open(const struct io_dev_connector *dev_con, void *dev_spec, + struct io_dev_info **dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + assert(is_valid_dev_connector(dev_con)); + + result = dev_con->dev_open(dev_spec, dev_info); + return result; +} + + +/* Set a handle to track an entity */ +static void set_handle(io_handle *handle, struct io_entity *entity) +{ + assert(handle != NULL); + *handle = entity; +} + + +/* Locate an entity in the pool, specified by address */ +static int find_first_entity(struct io_entity *entity, unsigned int *index_out) +{ + int result = IO_FAIL; + for (int index = 0; index < MAX_IO_HANDLES; ++index) { + if (entity_map[index] == entity) { + result = IO_SUCCESS; + *index_out = index; + break; + } + } + return result; +} + + +/* Allocate an entity from the pool and return a pointer to it */ +static int allocate_entity(struct io_entity **entity) +{ + int result = IO_FAIL; + assert(entity != NULL); + + if (entity_count < MAX_IO_HANDLES) { + unsigned int index = 0; + result = find_first_entity(NULL, &index); + assert(result == IO_SUCCESS); + *entity = entity_map[index] = &entity_pool[index]; + ++entity_count; + } else + result = IO_RESOURCES_EXHAUSTED; + + return result; +} + + +/* Release an entity back to the pool */ +static int free_entity(struct io_entity *entity) +{ + int result = IO_FAIL; + unsigned int index = 0; + assert(entity != NULL); + + result = find_first_entity(entity, &index); + if (result == IO_SUCCESS) { + entity_map[index] = NULL; + --entity_count; + } + + return result; +} + + +/* Exported API */ + + +/* Initialise the IO layer */ +void io_init(struct io_plat_data *data) +{ + assert(data != NULL); + platform_data = data; +} + + +/* Register a device driver */ +int io_register_device(struct io_dev_info *dev_info) +{ + int result = IO_FAIL; + assert(dev_info != NULL); + assert(platform_data != NULL); + + unsigned int dev_count = platform_data->dev_count; + + if (dev_count < MAX_DEVICES(platform_data)) { + platform_data->devices[dev_count] = dev_info; + platform_data->dev_count++; + result = IO_SUCCESS; + } else { + result = IO_RESOURCES_EXHAUSTED; + } + + return result; +} + + +/* Open a connection to an IO device */ +int io_dev_open(struct io_dev_connector *dev_con, void *dev_spec, + io_dev_handle *handle) +{ + int result = IO_FAIL; + assert(handle != NULL); + + result = dev_open(dev_con, dev_spec, handle); + return result; +} + + +/* Initialise an IO device explicitly - to permit lazy initialisation or + * re-initialisation */ +int io_dev_init(struct io_dev_info *dev_handle, const void *init_params) +{ + int result = IO_FAIL; + assert(dev_handle != NULL); + assert(is_valid_dev(dev_handle)); + + struct io_dev_info *dev = dev_handle; + + if (dev->funcs->dev_init != NULL) { + result = dev->funcs->dev_init(dev, init_params); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + return result; +} + + +/* TODO: Consider whether an explicit "shutdown" API should be included */ + +/* Close a connection to a device */ +int io_dev_close(io_dev_handle dev_handle) +{ + int result = IO_FAIL; + assert(dev_handle != NULL); + assert(is_valid_dev(dev_handle)); + + struct io_dev_info *dev = dev_handle; + + if (dev->funcs->dev_close != NULL) { + result = dev->funcs->dev_close(dev); + } else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + + return result; +} + + +/* Synchronous operations */ + + +/* Open an IO entity */ +int io_open(io_dev_handle dev_handle, const void *spec, io_handle *handle) +{ + int result = IO_FAIL; + assert((spec != NULL) && (handle != NULL)); + assert(is_valid_dev(dev_handle)); + + struct io_dev_info *dev = dev_handle; + struct io_entity *entity; + + result = allocate_entity(&entity); + + if (result == IO_SUCCESS) { + assert(dev->funcs->open != NULL); + result = dev->funcs->open(dev, spec, entity); + + if (result == IO_SUCCESS) { + entity->dev_handle = dev_handle; + set_handle(handle, entity); + } else + free_entity(entity); + } + return result; +} + + +/* Seek to a specific position in an IO entity */ +int io_seek(io_handle handle, io_seek_mode mode, ssize_t offset) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && is_valid_seek_mode(mode)); + + struct io_entity *entity = handle; + + struct io_dev_info *dev = entity->dev_handle; + + if (dev->funcs->seek != NULL) + result = dev->funcs->seek(entity, mode, offset); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Determine the length of an IO entity */ +int io_size(io_handle handle, size_t *length) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (length != NULL)); + + struct io_entity *entity = handle; + + struct io_dev_info *dev = entity->dev_handle; + + if (dev->funcs->size != NULL) + result = dev->funcs->size(entity, length); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Read data from an IO entity */ +int io_read(io_handle handle, void *buffer, size_t length, size_t *length_read) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != NULL)); + + struct io_entity *entity = handle; + + struct io_dev_info *dev = entity->dev_handle; + + if (dev->funcs->read != NULL) + result = dev->funcs->read(entity, buffer, length, length_read); + else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Write data to an IO entity */ +int io_write(io_handle handle, const void *buffer, size_t length, + size_t *length_written) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle) && (buffer != NULL)); + + struct io_entity *entity = handle; + + struct io_dev_info *dev = entity->dev_handle; + + if (dev->funcs->write != NULL) { + result = dev->funcs->write(entity, buffer, length, + length_written); + } else + result = IO_NOT_SUPPORTED; + + return result; +} + + +/* Close an IO entity */ +int io_close(io_handle handle) +{ + int result = IO_FAIL; + assert(is_valid_entity(handle)); + + struct io_entity *entity = handle; + + struct io_dev_info *dev = entity->dev_handle; + + if (dev->funcs->close != NULL) + result = dev->funcs->close(entity); + else { + /* Absence of registered function implies NOP here */ + result = IO_SUCCESS; + } + /* Ignore improbable free_entity failure */ + (void)free_entity(entity); + + return result; +} diff --git a/lib/stdlib/std.c b/lib/stdlib/std.c index ee308b0..4608754 100644 --- a/lib/stdlib/std.c +++ b/lib/stdlib/std.c @@ -29,7 +29,7 @@ */ -// Include the various implemented functions +/* Include the various implemented functions */ #include "abort.c" #include "assert.c" #include "mem.c" @@ -37,5 +37,7 @@ #include "putchar.c" #include "puts.c" #include "strchr.c" +#include "strcmp.c" #include "strlen.c" +#include "strncmp.c" #include "subr_prf.c" diff --git a/lib/stdlib/strcmp.c b/lib/stdlib/strcmp.c new file mode 100644 index 0000000..1d26f2b --- /dev/null +++ b/lib/stdlib/strcmp.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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. + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include +#include + +/* + * Compare strings. + */ +int +strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == '\0') + return 0; + return *(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1); +} diff --git a/lib/stdlib/strncmp.c b/lib/stdlib/strncmp.c new file mode 100644 index 0000000..f45f4a2 --- /dev/null +++ b/lib/stdlib/strncmp.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 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. + */ + +/* + * Portions copyright (c) 2014, ARM Limited and Contributors. + * All rights reserved. + */ + +#include +#include + +int +strncmp(const char *s1, const char *s2, size_t n) +{ + + if (n == 0) + return 0; + do { + if (*s1 != *s2++) + return (*(const unsigned char *)s1 - + *(const unsigned char *)(s2 - 1)); + if (*s1++ == '\0') + break; + } while (--n != 0); + return 0; +} diff --git a/plat/fvp/platform.h b/plat/fvp/platform.h index 797e008..1b0a736 100644 --- a/plat/fvp/platform.h +++ b/plat/fvp/platform.h @@ -61,6 +61,8 @@ PLATFORM_CLUSTER0_CORE_COUNT) #define PLATFORM_MAX_CPUS_PER_CLUSTER 4 #define PRIMARY_CPU 0x0 +#define MAX_IO_DEVICES 1 +#define MAX_IO_HANDLES 4 /* Constants for accessing platform configuration */ #define CONFIG_GICD_ADDR 0 @@ -212,7 +214,7 @@ /******************************************************************************* * BL2 specific defines. ******************************************************************************/ -#define BL2_BASE 0x0402D000 +#define BL2_BASE 0x0402C000 /******************************************************************************* * BL31 specific defines.