[Skiboot] [RFC, PATCH 3/3] core/flash: Move flash NVRAM handling to new flash module
Jeremy Kerr
jk at ozlabs.org
Fri Feb 6 22:09:19 AEDT 2015
Since we want to prevent conflicts between PNOR and NVRAM, this change
moves the flash-nvram handling out of flash-nvram.c and into the generic
flash module. This way, the OPAL_FLASH_{READ,WRITE,ERASE} API won't
conflict with the OPAL_*_NVRAM api.
To do this, we use the flash_register function to look for an "NVRAM"
partition. If one is found, it is automatically registered as the system
NVRAM backend.
We also change the rhesus and astmbc platforms to use the common flash
code.
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
---
core/Makefile.inc | 2
core/flash-nvram.c | 76 --------------------------
core/flash.c | 107 ++++++++++++++++++++++++++++++++++++--
include/skiboot.h | 3 -
platforms/astbmc/pnor.c | 41 ++------------
platforms/rhesus/rhesus.c | 39 +------------
6 files changed, 116 insertions(+), 152 deletions(-)
diff --git a/core/Makefile.inc b/core/Makefile.inc
index 1a4e466..590780f 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -5,7 +5,7 @@ CORE_OBJS = relocate.o console.o stack.o init.o chip.o mem_region.o
CORE_OBJS += malloc.o lock.o cpu.o utils.o fdt.o opal.o interrupts.o
CORE_OBJS += timebase.o opal-msg.o pci.o pci-opal.o fast-reboot.o
CORE_OBJS += device.o exceptions.o trace.o affinity.o vpd.o
-CORE_OBJS += hostservices.o platform.o nvram.o flash-nvram.o hmi.o
+CORE_OBJS += hostservices.o platform.o nvram.o hmi.o
CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
CORE_OBJS += timer.o i2c.o rtc.o flash.o
CORE=core/built-in.o
diff --git a/core/flash-nvram.c b/core/flash-nvram.c
deleted file mode 100644
index 7e261b1..0000000
--- a/core/flash-nvram.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2013-2014 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 <device.h>
-#include <console.h>
-#include <opal.h>
-#include <platform.h>
-#include <libflash/libflash.h>
-
-static struct flash_chip *fl_nv_chip;
-static uint32_t fl_nv_start, fl_nv_size;
-
-static int flash_nvram_info(uint32_t *total_size)
-{
- if (!fl_nv_chip)
- return OPAL_HARDWARE;
- *total_size = fl_nv_size;
- return OPAL_SUCCESS;
-}
-
-static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
-{
- int rc;
-
- if ((src + len) > fl_nv_size) {
- prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n",
- src, len);
- return OPAL_PARAMETER;
- }
- rc = flash_read(fl_nv_chip, fl_nv_start + src, dst, len);
- if (rc)
- return rc;
- nvram_read_complete(true);
- return 0;
-}
-
-static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
-{
- /* TODO: When we have async jobs for PRD, turn this into one */
-
- if ((dst + len) > fl_nv_size) {
- prerror("FLASH_NVRAM: write out of bound (0x%x,0x%x)\n",
- dst, len);
- return OPAL_PARAMETER;
- }
- return flash_smart_write(fl_nv_chip, fl_nv_start + dst, src, len);
-}
-
-int flash_nvram_init(struct flash_chip *chip, uint32_t start, uint32_t size)
-{
- fl_nv_chip = chip;
- fl_nv_start = start;
- fl_nv_size = size;
-
- platform.nvram_info = flash_nvram_info;
- platform.nvram_start_read = flash_nvram_start_read;
- platform.nvram_write = flash_nvram_write;
-
- return 0;
-}
-
diff --git a/core/flash.c b/core/flash.c
index e68b41e..d41eb01 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -37,6 +37,105 @@ static struct flash *system_flash;
/* Using a single lock as we only have one flash at present. */
static struct lock flash_lock;
+/* nvram-on-flash support */
+static struct flash *nvram_flash;
+static u32 nvram_offset, nvram_size;
+
+static int flash_nvram_info(uint32_t *total_size)
+{
+ int rc = OPAL_HARDWARE;
+
+ lock(&flash_lock);
+ if (nvram_flash) {
+ *total_size = nvram_size;
+ rc = OPAL_SUCCESS;
+ }
+ unlock(&flash_lock);
+
+ return rc;
+}
+
+static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
+{
+ int rc;
+
+ lock(&flash_lock);
+
+ if (!nvram_flash) {
+ rc = OPAL_HARDWARE;
+ goto out;
+ }
+
+ if ((src + len) > nvram_size) {
+ prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n",
+ src, len);
+ rc = OPAL_PARAMETER;
+ goto out;
+ }
+
+ rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len);
+
+out:
+ unlock(&flash_lock);
+ if (!rc)
+ nvram_read_complete(true);
+ return rc;
+}
+
+static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
+{
+ int rc;
+
+ lock(&flash_lock);
+
+ /* TODO: When we have async jobs for PRD, turn this into one */
+
+ if ((dst + len) > nvram_size) {
+ prerror("FLASH_NVRAM: write out of bound (0x%x,0x%x)\n",
+ dst, len);
+ rc = OPAL_PARAMETER;
+ goto out;
+ }
+ rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, len);
+
+out:
+ unlock(&flash_lock);
+ return rc;
+}
+
+static int flash_nvram_probe(struct flash *flash, struct ffs_handle *ffs)
+{
+ uint32_t start, size, part;
+ int rc;
+
+ prlog(PR_INFO, "FLASH: probing for NVRAM\n");
+
+ rc = ffs_lookup_part(ffs, "NVRAM", &part);
+ if (rc) {
+ prlog(PR_WARNING, "FLASH: no NVRAM partition found\n");
+ return OPAL_HARDWARE;
+ }
+
+ rc = ffs_part_info(ffs, part, NULL,
+ &start, &size, NULL);
+ if (rc) {
+ prlog(PR_ERR, "FLASH: Can't parse ffs info for NVRAM\n");
+ return OPAL_HARDWARE;
+ }
+
+ nvram_flash = flash;
+ nvram_offset = start;
+ nvram_size = size;
+
+ platform.nvram_info = flash_nvram_info;
+ platform.nvram_start_read = flash_nvram_start_read;
+ platform.nvram_write = flash_nvram_write;
+
+ return 0;
+}
+
+/* core flash support */
+
static void flash_add_dt_partition_node(struct dt_node *flash_node, char *name,
uint32_t start, uint32_t size)
{
@@ -124,11 +223,13 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
ffs = NULL;
}
- if (is_system_flash && !system_flash)
- system_flash = flash;
-
flash_add_dt_node(flash, i, ffs);
+ if (is_system_flash && !system_flash) {
+ system_flash = flash;
+ flash_nvram_probe(flash, ffs);
+ }
+
ffs_close(ffs);
unlock(&flash_lock);
diff --git a/include/skiboot.h b/include/skiboot.h
index dbc2057..e04b0cf 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -205,9 +205,6 @@ extern bool flash_load_resource(enum resource_id id, void *buf, size_t *len);
extern void nvram_init(void);
extern void nvram_read_complete(bool success);
-/* NVRAM on flash helper */
-extern int flash_nvram_init(struct flash_chip *chip, uint32_t start,
- uint32_t size);
/* UART stuff */
extern void uart_irq(void);
extern void uart_setup_linux_passthrough(void);
diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
index c56ac63..57ab657 100644
--- a/platforms/astbmc/pnor.c
+++ b/platforms/astbmc/pnor.c
@@ -24,16 +24,13 @@
#include "astbmc.h"
-static struct spi_flash_ctrl *pnor_ctrl;
-static struct flash_chip *pnor_chip;
-static struct ffs_handle *pnor_ffs;
-
int pnor_init(void)
{
- uint32_t nv_part, nv_start, nv_size;
+ struct spi_flash_ctrl *pnor_ctrl;
+ struct flash_chip *pnor_chip;
int rc;
- /* Open controller, flash and ffs */
+ /* Open controller and flash */
rc = ast_sf_open(AST_SF_TYPE_PNOR, &pnor_ctrl);
if (rc) {
prerror("PLAT: Failed to open PNOR flash controller\n");
@@ -44,42 +41,16 @@ int pnor_init(void)
prerror("PLAT: Failed to open init PNOR driver\n");
goto fail;
}
- rc = ffs_open_flash(pnor_chip, 0, 0, &pnor_ffs);
- if (rc) {
- prerror("PLAT: Failed to parse FFS partition map\n");
- goto fail;
- }
- /*
- * Grab NVRAM and initialize the flash_nvram module
- *
- * Note: Ignore actual size for now ... some images have
- * it setup incorrectly.
- */
- rc = ffs_lookup_part(pnor_ffs, "NVRAM", &nv_part);
- if (rc) {
- prerror("PLAT: No NVRAM partition in PNOR\n");
- return OPAL_HARDWARE;
- }
- rc = ffs_part_info(pnor_ffs, nv_part, NULL,
- &nv_start, &nv_size, NULL);
- if (rc) {
- prerror("PLAT: Failed to get NVRAM partition info\n");
- return OPAL_HARDWARE;
- }
- flash_nvram_init(pnor_chip, nv_start, nv_size);
+ rc = flash_register(pnor_chip, true);
+ if (!rc)
+ return 0;
- return 0;
fail:
- if (pnor_ffs)
- ffs_close(pnor_ffs);
- pnor_ffs = NULL;
if (pnor_chip)
flash_exit(pnor_chip);
- pnor_chip = NULL;
if (pnor_ctrl)
ast_sf_close(pnor_ctrl);
- pnor_ctrl = NULL;
return rc;
}
diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
index 8385a0c..50769cf 100644
--- a/platforms/rhesus/rhesus.c
+++ b/platforms/rhesus/rhesus.c
@@ -38,10 +38,6 @@
#define RHESUS_BOARD_REVISION3 EC_GPIO_PORT_E, 4
#define RHESUS_BOARD_REVISION4 EC_GPIO_PORT_E, 1
-static struct spi_flash_ctrl *pnor_ctrl;
-static struct flash_chip *pnor_chip;
-static struct ffs_handle *pnor_ffs;
-
/*
* IO accessors for the EC driver
@@ -121,7 +117,8 @@ static int64_t rhesus_power_down(uint64_t request __unused)
static int rhesus_pnor_init(void)
{
- uint32_t nv_part, nv_start, nv_size;
+ struct spi_flash_ctrl *pnor_ctrl;
+ struct flash_chip *pnor_chip;
int rc;
/* Open controller, flash and ffs */
@@ -135,42 +132,16 @@ static int rhesus_pnor_init(void)
prerror("PLAT: Failed to open init PNOR driver\n");
goto fail;
}
- rc = ffs_open_flash(pnor_chip, 0, 0, &pnor_ffs);
- if (rc) {
- prerror("PLAT: Failed to parse FFS partition map\n");
- goto fail;
- }
- /*
- * Grab NVRAM and initialize the flash_nvram module
- *
- * Note: Ignore actual size for now ... some images have
- * it setup incorrectly.
- */
- rc = ffs_lookup_part(pnor_ffs, "NVRAM", &nv_part);
- if (rc) {
- prerror("PLAT: No NVRAM partition in PNOR\n");
- return OPAL_HARDWARE;
- }
- rc = ffs_part_info(pnor_ffs, nv_part, NULL,
- &nv_start, &nv_size, NULL);
- if (rc) {
- prerror("PLAT: Failed to get NVRAM partition info\n");
- return OPAL_HARDWARE;
- }
- flash_nvram_init(pnor_chip, nv_start, nv_size);
+ rc = flash_register(pnor_chip, true);
+ if (!rc)
+ return 0;
- return 0;
fail:
- if (pnor_ffs)
- ffs_close(pnor_ffs);
- pnor_ffs = NULL;
if (pnor_chip)
flash_exit(pnor_chip);
- pnor_chip = NULL;
if (pnor_ctrl)
sfc_close(pnor_ctrl);
- pnor_ctrl = NULL;
return rc;
}
More information about the Skiboot
mailing list