diff options
author | Claudio Carvalho <cclaudio@linux.vnet.ibm.com> | 2016-09-28 05:01:03 -0300 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-10-05 14:42:26 +1100 |
commit | 26a1d0c487d6b61afb0a338189d98c91bb481ee9 (patch) | |
tree | 773b093c58dc954b37a728790e0507407bdd127d /libc/string | |
parent | 6ef40b5999aad01379daf19689d264f9e3d518d7 (diff) | |
download | skiboot-26a1d0c487d6b61afb0a338189d98c91bb481ee9.zip skiboot-26a1d0c487d6b61afb0a338189d98c91bb481ee9.tar.gz skiboot-26a1d0c487d6b61afb0a338189d98c91bb481ee9.tar.bz2 |
libc/string: add memcpy_from_ci()
This adds memcpy_from_ci, a cache inhibited version of memcpy, required
by secure boot. The secure boot verification code is stored in a secure
ROM and the logic that contains the ROM within the processor is
implemented in a way that it only responds to CI (cache inhibited)
operations. Due to performance issues we copy the verification code from
the secure ROM to RAM and we use memcpy_ci for that.
What makes memcpy_ci vs ordinary memcpy?
memcpy copies data like in the example below and the compiler translates that
to load instructions that are not cache inhibited (e.g. lbzx - load byte and
zero indexed). In other words, the data is cached.
a[i] = b[i]
memcpy_ci copies data using the cache inhibited version of load instructions:
in_8() and in_be32(), both defined in include/io.h. These functions use lbzcix
and lwzcix assembly instructions, respectively. In this case, the data is not
cached as required by the logic that contains the ROM.
*((uint8_t*) destp) = in_8((uint8_t*)srcp);
*((uint32_t*) destp) = in_be32((uint32_t*)srcp)
Signed-off-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libc/string')
-rw-r--r-- | libc/string/Makefile.inc | 9 | ||||
-rw-r--r-- | libc/string/memcpy_from_ci.c | 47 |
2 files changed, 52 insertions, 4 deletions
diff --git a/libc/string/Makefile.inc b/libc/string/Makefile.inc index 3b7c8ce..fb2f037 100644 --- a/libc/string/Makefile.inc +++ b/libc/string/Makefile.inc @@ -1,5 +1,5 @@ # ***************************************************************************** -# * Copyright (c) 2004, 2008 IBM Corporation +# * Copyright (c) 2004, 2016 IBM Corporation # * All rights reserved. # * This program and the accompanying materials # * are made available under the terms of the BSD License @@ -12,9 +12,10 @@ SUBDIRS += $(LIBCDIR)/string -STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o strncmp.o \ - strncpy.o strstr.o memset.o memcpy.o memmove.o memchr.o \ - memcmp.o strcasecmp.o strncasecmp.o strtok.o strdup.o +STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o \ + strncmp.o strncpy.o strstr.o memset.o memcpy.o memcpy_from_ci.o \ + memmove.o memchr.o memcmp.o strcasecmp.o strncasecmp.o \ + strtok.o strdup.o STRING = $(LIBCDIR)/string/built-in.o $(STRING): $(STRING_OBJS:%=$(LIBCDIR)/string/%) diff --git a/libc/string/memcpy_from_ci.c b/libc/string/memcpy_from_ci.c new file mode 100644 index 0000000..02affa3 --- /dev/null +++ b/libc/string/memcpy_from_ci.c @@ -0,0 +1,47 @@ +/* Copyright 2013-2016 IBM Corp + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <ccan/short_types/short_types.h> +#include <io.h> + +void* memcpy_from_ci(void *destpp, const void *srcpp, size_t len) +{ + const size_t block = sizeof(uint64_t); + unsigned long int destp = (long int) destpp; + unsigned long int srcp = (long int) srcpp; + + /* Copy as many blocks as possible if srcp is block aligned */ + if ((srcp % block) == 0) { + while ((len - block) > -1) { + *((uint64_t*) destp) = in_be64((uint64_t*)srcp); + srcp += block; + destp += block; + len -= block; + } + } + /* + * Byte-by-byte copy if srcp is not block aligned or len is/becomes + * less than one block + */ + while (len > 0) { + *((uint8_t*) destp) = in_8((uint8_t*)srcp); + srcp += 1; + destp += 1; + len--; + } + return destpp; +} |