diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc
index 8a78fb6..217f3fc 100644
--- a/libstb/Makefile.inc
+++ b/libstb/Makefile.inc
@@ -4,7 +4,7 @@ LIBSTB_DIR = libstb
 
 SUBDIRS += $(LIBSTB_DIR)
 
-LIBSTB_SRCS = container.c rom.c tpm_chip.c stb.c
+LIBSTB_SRCS = container.c tpm_chip.c stb.c
 LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o)
 LIBSTB = $(LIBSTB_DIR)/built-in.o
 
diff --git a/libstb/container.h b/libstb/container.h
index c125bc1..1233e7e 100644
--- a/libstb/container.h
+++ b/libstb/container.h
@@ -19,7 +19,9 @@
 
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <ccan/endian/endian.h>
+#include <ccan/short_types/short_types.h>
 
 #define SECURE_BOOT_HEADERS_SIZE	4096
 #define SHA256_DIGEST_LENGTH		32
diff --git a/libstb/cvc/c1vc.c b/libstb/cvc/c1vc.c
index 0ac0d8a..04ebc89 100644
--- a/libstb/cvc/c1vc.c
+++ b/libstb/cvc/c1vc.c
@@ -19,120 +19,51 @@
 #include <string.h>
 #include <skiboot.h>
 #include "../status_codes.h"
-#include "../rom.h"
+#include "../container.h"
 #include "c1vc.h"
 
-#define DRIVER_NAME	"c1vc"
-
-#define SECURE_ROM_MEMORY_SIZE		(16 * 1024)
-#define SECURE_ROM_XSCOM_ADDRESS	0x02020017
-
 /*
- *  From the source code of the ROM code
- */
-#define SECURE_ROM_SHA512_OFFSET	0x20
-#define SECURE_ROM_VERIFY_OFFSET	0x30
-
-static const char *compat = "ibm,secureboot-v1";
-static void *securerom_addr = NULL;
-static sha2_hash_t *hw_key_hash = NULL;
-
-/*
- * Assembly interfaces to call into ROM code.
- * func_ptr is the ROM code function address, followed
- * by additional parameters as necessary
+ * Assembly interfaces to call into the Container v1 Verification Code.
+ * func_ptr: C1VC base address + offset
  */
 ROM_response __c1vc_verify(void *func_ptr, ROM_container_raw *container,
 			   ROM_hw_params *params);
 void __c1vc_sha512(void *func_ptr, const uint8_t *data, size_t len,
 		   uint8_t *digest);
 
-static int c1vc_verify(void *container)
+int c1vc_verify(void *func_addr, const char *name, void *container,
+		const void *hw_key_hash, size_t hw_key_hash_size)
 {
 	ROM_hw_params hw_params;
 	ROM_response rc;
 
 	memset(&hw_params, 0, sizeof(ROM_hw_params));
-	memcpy(&hw_params.hw_key_hash, hw_key_hash, sizeof(sha2_hash_t));
-	rc = __c1vc_verify(securerom_addr + SECURE_ROM_VERIFY_OFFSET,
-			   (ROM_container_raw*) container, &hw_params);
+	memcpy(&hw_params.hw_key_hash, hw_key_hash, hw_key_hash_size);
+	rc = __c1vc_verify(func_addr, (ROM_container_raw*) container, &hw_params);
 	if (rc != ROM_DONE) {
 		/*
-		 * Verify failed. hw_params.log indicates what checking has
-		 * failed. This will abort the boot process.
+		 * Container verification failed, the boot process will probably
+		 * be halted by the caller.
+		 *
+		 * The value returned in params.log indicates what checking has
+		 * failed and it is one of the return codes defined in
+		 * /hostboot/src/include/securerom/status_codes.H
 		 */
-		prlog(PR_ERR, "ROM: %s failed (rc=%d, hw_params.log=0x%llx)\n",
-		      __func__, rc, be64_to_cpu(hw_params.log));
+		prerror("STB: %s verification FAILED (rc=%d, hw_params.log=0x%llx)\n",
+			name, rc, be64_to_cpu(hw_params.log));
 		return STB_VERIFY_FAILED;
 	}
 	return 0;
 }
 
-static void c1vc_sha512(const uint8_t *data, size_t len, uint8_t *digest)
+void c1vc_sha512(void *func_addr, const uint8_t *data, size_t len,
+		 uint8_t *digest)
 {
 	memset(digest, 0, sizeof(sha2_hash_t));
-	__c1vc_sha512(securerom_addr + SECURE_ROM_SHA512_OFFSET,
-		      data, len, digest);
+	__c1vc_sha512(func_addr, data, len, digest);
 }
 
-static void c1vc_cleanup(void) {
-	if (securerom_addr)
-		free(securerom_addr);
-	hw_key_hash = NULL;
-}
-
-static struct container_verification_code c1vc = {
-	.name    = DRIVER_NAME,
-	.verify  = c1vc_verify,
-	.sha512  = c1vc_sha512,
-	.cleanup = c1vc_cleanup,
-};
-
-void c1vc_probe(const struct dt_node *node)
+void __attrconst c1vc_cleanup(void)
 {
-	/* This xscom register has the Secure ROM code base address */
-	const uint32_t reg_addr = SECURE_ROM_XSCOM_ADDRESS;
-	uint64_t reg_data;
-	struct proc_chip *chip;
-	const char* hash_algo;
-
-	if (!dt_node_is_compatible(node, compat)) {
-		prlog(PR_DEBUG, "ROM: %s node is not compatible\n",
-		      node->name);
-		return;
-	}
-	/*
-	 * secureboot-v1 defines containers with sha512 hashes
-	 */
-	hash_algo = dt_prop_get(node, "hash-algo");
-	if (strcmp(hash_algo, "sha512")) {
-		/**
-		 * @fwts-label ROMHashAlgorithmInvalid
-		 * @fwts-advice Hostboot creates the ibm,secureboot node and
-		 * the hash-algo property. Check that the ibm,secureboot node
-		 * layout has not changed.
-		 */
-		prlog(PR_ERR, "ROM: hash-algo=%s not expected\n", hash_algo);
-		return;
-	}
-	hw_key_hash = (sha2_hash_t*) dt_prop_get(node, "hw-key-hash");
-	securerom_addr = malloc(SECURE_ROM_MEMORY_SIZE);
-	assert(securerom_addr);
-	/*
-	 * 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_from_ci to do that.
-	 */
-	chip = next_chip(NULL);
-	xscom_read(chip->id, reg_addr, &reg_data);
-	memcpy_from_ci(securerom_addr, (void*) reg_data,
-		       SECURE_ROM_MEMORY_SIZE);
-	/*
-	 * Skiboot runs with IR (Instruction Relocation) &
-	 * DR (Data Relocation) off, so there is no need to either MMIO
-	 * the ROM code or set the memory region as executable.
-         * skiboot accesses the physical memory directly. Real mode.
-	 */
-	rom_set_driver(&c1vc);
+	return;
 }
diff --git a/libstb/cvc/c1vc.h b/libstb/cvc/c1vc.h
index f0d2a3d..fd5588b 100644
--- a/libstb/cvc/c1vc.h
+++ b/libstb/cvc/c1vc.h
@@ -17,8 +17,15 @@
 #ifndef __C1VC_H
 #define __C1VC_H
 
-#include <device.h>
+#include <compiler.h>
+#include <stdint.h>
 
-extern void c1vc_probe(const struct dt_node *node);
+int c1vc_verify(void *func_addr, const char *name, void *container,
+		const void *hw_key_hash, size_t hw_key_hash_size);
+
+void c1vc_sha512(void *func_addr, const uint8_t *data, size_t len,
+		 uint8_t *digest);
+
+void __attrconst c1vc_cleanup(void);
 
 #endif /* __C1VC_H */
diff --git a/libstb/cvc/c1vc_mbedtls.c b/libstb/cvc/c1vc_mbedtls.c
index 4cf8e13..f677a68 100644
--- a/libstb/cvc/c1vc_mbedtls.c
+++ b/libstb/cvc/c1vc_mbedtls.c
@@ -14,21 +14,22 @@
  * limitations under the License.
  */
 
-#include <chip.h>
 #include <string.h>
-#include <skiboot.h>
-#include "../rom.h"
 #include "../mbedtls/sha512.h"
+#include "../container.h"
 #include "c1vc_mbedtls.h"
 
-static sha2_hash_t *hw_key_hash = NULL;
-
-static int c1vc_mbedtls_verify(void *container __unused)
+int __attrconst c1vc_mbedtls_verify(void *func_addr __unused,
+				    const char* name __unused,
+				    void *container __unused,
+				    const void *hw_key_hash __unused,
+				    size_t hw_key_hash_size __unused)
 {
 	return -100;
 }
 
-static void c1vc_mbedtls_sha512(const uint8_t *data, size_t len, uint8_t *digest)
+void c1vc_mbedtls_sha512(void *func_addr __unused,
+			 const uint8_t *data, size_t len, uint8_t *digest)
 {
 	mbedtls_sha512_context ctx;
 	mbedtls_sha512_init(&ctx);
@@ -39,38 +40,7 @@ static void c1vc_mbedtls_sha512(const uint8_t *data, size_t len, uint8_t *digest
 	mbedtls_sha512_free(&ctx);
 }
 
-static void c1vc_mbedtls_cleanup(void)
+void __attrconst c1vc_mbedtls_cleanup(void)
 {
 	return;
 }
-
-static struct container_verification_code c1vc = {
-	.name    = "software",
-	.verify  = c1vc_mbedtls_verify,
-	.sha512  = c1vc_mbedtls_sha512,
-	.cleanup = c1vc_mbedtls_cleanup
-};
-
-void c1vc_mbedtls_probe(const struct dt_node *node)
-{
-	const char* hash_algo;
-
-	if (!dt_node_is_compatible(node, "ibm,secureboot-v1-softrom")) {
-		return;
-	}
-
-	hash_algo = dt_prop_get(node, "hash-algo");
-	if (strcmp(hash_algo, "sha512")) {
-		/**
-		 * @fwts-label ROMHashAlgorithmInvalid
-		 * @fwts-advice Hostboot creates the ibm,secureboot node and
-		 * the hash-algo property. Check that the ibm,secureboot node
-		 * layout has not changed.
-		 */
-		prlog(PR_ERR, "ROM: hash-algo=%s not expected\n", hash_algo);
-		return;
-	}
-	hw_key_hash = (sha2_hash_t*) dt_prop_get(node, "hw-key-hash");
-
-	rom_set_driver(&c1vc);
-}
diff --git a/libstb/cvc/c1vc_mbedtls.h b/libstb/cvc/c1vc_mbedtls.h
index 9027138..f24e940 100644
--- a/libstb/cvc/c1vc_mbedtls.h
+++ b/libstb/cvc/c1vc_mbedtls.h
@@ -17,8 +17,18 @@
 #ifndef __C1VC_MBEDTLS_H
 #define __C1VC_MBEDTLS_H
 
-#include <device.h>
+#include <compiler.h>
+#include <stdint.h>
 
-extern void c1vc_mbedtls_probe(const struct dt_node *node);
+int __attrconst c1vc_mbedtls_verify(void *func_addr __unused,
+				    const char* name __unused,
+				    void *container __unused,
+				    const void *hw_key_hash __unused,
+				    size_t hw_key_hash_size __unused);
+
+void c1vc_mbedtls_sha512(void *func_addr __unused,
+			 const uint8_t *data, size_t len, uint8_t *digest);
+
+void __attrconst c1vc_mbedtls_cleanup(void);
 
 #endif /* __C1VC_MBEDTLS_H */
diff --git a/libstb/rom.c b/libstb/rom.c
deleted file mode 100644
index 04ab364..0000000
--- a/libstb/rom.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 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 <skiboot.h>
-#include "rom.h"
-#include "cvc/c1vc.h"
-#include "cvc/c1vc_mbedtls.h"
-
-static struct container_verification_code *c1vc = NULL;
-
-struct container_verification_code* rom_init(const struct dt_node *node __unused)
-{
-	if (c1vc)
-		goto end;
-
-	/* CVC drivers supported */
-	c1vc_probe(node);
-
-	if (!c1vc)
-		c1vc_mbedtls_probe(node);
-
-	if (!c1vc)
-		prlog(PR_NOTICE, "ROM: no rom driver found\n");
-end:
-	return c1vc;
-}
-
-void rom_set_driver(struct container_verification_code *driver)
-{
-	if (c1vc) {
-		/**
-		 * @fwts-label ROMAlreadyRegistered
-		 * @fwts-advice ibm,secureboot already registered. Check if
-		 * rom_init called twice or the same driver is probed twice
-		 */
-		prlog(PR_WARNING, "ROM: %s driver already registered\n",
-		      c1vc->name);
-		return;
-	}
-	c1vc = driver;
-	prlog(PR_NOTICE, "ROM: %s driver registered\n", c1vc->name);
-}
diff --git a/libstb/rom.h b/libstb/rom.h
deleted file mode 100644
index 972a19b..0000000
--- a/libstb/rom.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* 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.
- */
-
-#ifndef __ROM_H
-#define __ROM_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include "container.h"
-
-struct container_verification_code {
-	const char* name;
-	int  (*verify)(void *container);
-	void (*sha512)(const uint8_t *data, size_t len, uint8_t *digest);
-	void (*cleanup)(void);
-};
-
-/*
- * Load a compatible driver to access the functions of the
- * verification code flashed in the secure ROM
- */
-extern struct container_verification_code* rom_init(const struct dt_node *node);
-
-/*
- * Set the rom driver that will be used
- */
-extern void rom_set_driver(struct container_verification_code *driver);
-
-#endif /* __ROM_H */
diff --git a/libstb/stb.c b/libstb/stb.c
index a238378..ee5771a 100644
--- a/libstb/stb.c
+++ b/libstb/stb.c
@@ -20,19 +20,35 @@
 #include <string.h>
 #include <stdio.h>
 #include <nvram.h>
+#include <chip.h>
+#include <xscom.h>
 #include "stb.h"
 #include "status_codes.h"
 #include "container.h"
-#include "rom.h"
 #include "tpm_chip.h"
+#include "cvc/c1vc.h"
+#include "cvc/c1vc_mbedtls.h"
 
 /* For debugging only */
 //#define STB_DEBUG
 
-static bool secure_mode = false;
-static bool trusted_mode = false;
+struct container_verification_code {
+	const char *name;
+	uint64_t verify_addr;
+	uint64_t sha512_addr;
+	void (*sha512)(void *func_addr, const uint8_t *data, size_t len,
+		       uint8_t *digest);
+	int (*verify)(void *func_addr, const char *name, void *container,
+		      const void *hw_key_hash, size_t hw_key_hash_size);
+	void (*cleanup)(void);
+};
 
 static struct container_verification_code *c1vc = NULL;
+static void *secure_rom_mem = NULL;
+static const void* hw_key_hash = NULL;
+static size_t hw_key_hash_size;
+static bool secure_mode = false;
+static bool trusted_mode = false;
 
 /*
  * This maps a PCR for each resource we can measure. The PCR number is
@@ -88,9 +104,102 @@ static void sb_enforce(void)
 	abort();
 }
 
+static int c1vc_mbedtls_init(struct dt_node *node)
+{
+	const char* hash_algo;
+
+	hash_algo = dt_prop_get(node, "hash-algo");
+	if (strcmp(hash_algo, "sha512")) {
+		/**
+		 * @fwts-label HashAlgoInvalidSoftrom
+		 * @fwts-advice Hash algorithm invalid, secureboot containers
+		 * version 1 requires sha512. If you're running the latest POWER
+		 * firmware, so probably there is a bug in mambo tcl script that
+		 * creates the hash-algo property.
+		 */
+		prerror("STB: %s FAILED, hash-algo=%s not supported\n",
+			__func__, hash_algo);
+		return -1;
+	}
+	hw_key_hash_size = SHA512_DIGEST_LENGTH;
+	hw_key_hash = dt_prop_get_def_size(node, "hw-key-hash", NULL,
+					   &hw_key_hash_size);
+
+	c1vc = malloc(sizeof(struct container_verification_code));
+	assert(c1vc);
+	c1vc->sha512_addr = 0;
+	c1vc->sha512 = c1vc_mbedtls_sha512;
+	c1vc->verify_addr = 0;
+	c1vc->verify = c1vc_mbedtls_verify;
+	c1vc->cleanup = c1vc_mbedtls_cleanup;
+	c1vc->name = "c1vc_mbedtls";
+
+	prlog(PR_INFO, "STB: 'ibm,secureboot-v1-softrom' initialized\n");
+	return 0;
+}
+
+#define SECURE_ROM_MEMORY_SIZE		(16 * 1024)
+#define SECURE_ROM_XSCOM_ADDRESS	0x02020017
+
+#define SECURE_ROM_SHA512_OFFSET	0x20
+#define SECURE_ROM_VERIFY_OFFSET	0x30
+
+static int c1vc_rom_init(struct dt_node *parent)
+{
+	const uint32_t reg_addr = SECURE_ROM_XSCOM_ADDRESS;
+	uint64_t reg_data;
+	struct proc_chip *chip;
+	const char* hash_algo;
+
+	hash_algo = dt_prop_get(parent, "hash-algo");
+	if (strcmp(hash_algo, "sha512")) {
+		/**
+		 * @fwts-label HashAlgoInvalid
+		 * @fwts-advice Hash algorithm invalid, secureboot containers
+		 * version 1 requires sha512. If you're running the latest POWER
+		 * firmware, so probably there is a bug in the device tree
+		 * received from hostboot.
+		 */
+		prerror("STB: %s FAILED, hash-algo=%s not supported\n", __func__,
+			hash_algo);
+		return -1;
+	}
+	hw_key_hash_size = SHA512_DIGEST_LENGTH;
+	hw_key_hash = dt_prop_get_def_size(parent, "hw-key-hash", NULL,
+					   &hw_key_hash_size);
+
+	c1vc = malloc(sizeof(struct container_verification_code));
+	assert(c1vc);
+	secure_rom_mem = malloc(SECURE_ROM_MEMORY_SIZE);
+	assert(secure_rom_mem);
+	/*
+	 * 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. We use memcpy_from_ci() to do that.
+	 */
+	chip = next_chip(NULL);
+	xscom_read(chip->id, reg_addr, &reg_data);
+	memcpy_from_ci(secure_rom_mem, (void*) reg_data,
+		       SECURE_ROM_MEMORY_SIZE);
+
+	c1vc->sha512_addr = (uint64_t) secure_rom_mem + SECURE_ROM_SHA512_OFFSET;
+	c1vc->sha512 = c1vc_sha512;
+
+	c1vc->verify_addr = (uint64_t) secure_rom_mem + SECURE_ROM_VERIFY_OFFSET;
+	c1vc->verify = c1vc_verify;
+
+	c1vc->cleanup = c1vc_cleanup;
+	c1vc->name = "c1vc";
+
+	prlog(PR_INFO, "STB: 'ibm,secureboot-v1' initialized\n");
+	return 0;
+}
+
 void stb_init(void)
 {
 	struct dt_node *node;
+	int rc = -1;
 
 	node = dt_find_by_path(dt_root, "/ibm,secureboot");
 	if (!node) {
@@ -118,13 +227,36 @@ void stb_init(void)
 
 	if (!secure_mode && !trusted_mode)
 		return;
-	c1vc = rom_init(node);
-	if (secure_mode && !c1vc) {
-		prlog(PR_EMERG, "STB: compatible romcode driver not found\n");
-		sb_enforce();
+
+	if (dt_node_is_compatible(node, "ibm,secureboot-v1")) {
+		rc = c1vc_rom_init(node);
+	} else if (dt_node_is_compatible(node, "ibm,secureboot-v1-softrom")) {
+		rc = c1vc_mbedtls_init(node);
+	} else {
+		/**
+		 * @fwts-label SecureBootNotCompatible
+		 * @fwts-advice Compatible secureboot driver not found. If you
+		 * are running the latest skiboot version, probably there is a
+		 * problem when the /ibm,secureboot/compatible property is
+		 * created.
+		 */
+		prerror("STB: secureboot init FAILED, '%s' node not compatible (BUG).\n",
+			node->name);
+		goto enforce;
 	}
+
+	/* cvc init failed? */
+	if (rc)
+		goto enforce;
+
 	if (trusted_mode)
 		tpm_init();
+	return;
+
+enforce:
+	if (secure_mode)
+		sb_enforce();
+	return;
 }
 
 int stb_final(void)
@@ -228,8 +360,9 @@ int tb_measure(enum resource_id id, void *buf, size_t len)
 			abort();
 		}
 
-		c1vc->sha512((void*) buf + SECURE_BOOT_HEADERS_SIZE,
-				   len - SECURE_BOOT_HEADERS_SIZE, digest);
+		c1vc->sha512((void*) c1vc->sha512_addr,
+			     buf + SECURE_BOOT_HEADERS_SIZE,
+			     len - SECURE_BOOT_HEADERS_SIZE, digest);
 
 		prlog(PR_INFO, "STB: %s sha512 hash re-calculated\n", name);
 		if (memcmp(digestp, digest, TPM_ALG_SHA256_SIZE) != 0) {
@@ -243,7 +376,7 @@ int tb_measure(enum resource_id id, void *buf, size_t len)
 				abort();
 		}
 	} else {
-		c1vc->sha512(buf, len, digest);
+		c1vc->sha512((void*) c1vc->sha512_addr, buf, len, digest);
 		prlog(PR_INFO, "STB: %s sha512 hash calculated\n", name);
 	}
 
@@ -288,7 +421,8 @@ int sb_verify(enum resource_id id, void *buf, size_t len)
 		      __func__, id, buf, len);
 		sb_enforce();
 	}
-	if (c1vc->verify(buf)) {
+	if (c1vc->verify((void*) c1vc->verify_addr, name, buf,
+			 hw_key_hash, hw_key_hash_size)) {
 		prlog(PR_EMERG, "STB: %s failed: resource %s, "
 		      "eyecatcher 0x%016llx\n", __func__, name,
 		      *((uint64_t*)buf));
