aboutsummaryrefslogtreecommitdiff
path: root/libc/string
diff options
context:
space:
mode:
authorClaudio Carvalho <cclaudio@linux.vnet.ibm.com>2016-09-28 05:01:03 -0300
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-10-05 14:42:26 +1100
commit26a1d0c487d6b61afb0a338189d98c91bb481ee9 (patch)
tree773b093c58dc954b37a728790e0507407bdd127d /libc/string
parent6ef40b5999aad01379daf19689d264f9e3d518d7 (diff)
downloadskiboot-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.inc9
-rw-r--r--libc/string/memcpy_from_ci.c47
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;
+}