aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-03-06 14:18:45 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-06 14:18:45 +1100
commitdaa340ae58bbf774628d87505b2696e6f63f75d1 (patch)
tree757209560a71e40cffbe92a3e779232d4a0b5574 /core
parent6cf8b663e7d7cb1e827b6d9c90e694ea583f6f87 (diff)
parent9a3f68b499e686ff3b543633f59192890f6c740b (diff)
downloadskiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.zip
skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.gz
skiboot-daa340ae58bbf774628d87505b2696e6f63f75d1.tar.bz2
Merge branch 'openpower'
Diffstat (limited to 'core')
-rw-r--r--core/flash.c58
-rw-r--r--core/init.c5
-rw-r--r--core/ipmi.c9
3 files changed, 66 insertions, 6 deletions
diff --git a/core/flash.c b/core/flash.c
index 37827b3..f2d7501 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -26,6 +26,7 @@
struct flash {
bool registered;
+ bool busy;
struct flash_chip *chip;
uint32_t size;
uint32_t block_size;
@@ -42,12 +43,39 @@ static struct lock flash_lock;
static struct flash *nvram_flash;
static u32 nvram_offset, nvram_size;
+bool flash_reserve(void)
+{
+ bool rc = false;
+
+ if (!try_lock(&flash_lock))
+ return false;
+
+ if (!system_flash->busy) {
+ system_flash->busy = true;
+ rc = true;
+ }
+ unlock(&flash_lock);
+
+ return rc;
+}
+
+void flash_release(void)
+{
+ lock(&flash_lock);
+ system_flash->busy = false;
+ unlock(&flash_lock);
+}
+
static int flash_nvram_info(uint32_t *total_size)
{
- int rc = OPAL_HARDWARE;
+ int rc;
lock(&flash_lock);
- if (nvram_flash) {
+ if (!nvram_flash) {
+ rc = OPAL_HARDWARE;
+ } else if (nvram_flash->busy) {
+ rc = OPAL_BUSY;
+ } else {
*total_size = nvram_size;
rc = OPAL_SUCCESS;
}
@@ -60,13 +88,19 @@ static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
{
int rc;
- lock(&flash_lock);
+ if (!try_lock(&flash_lock))
+ return OPAL_BUSY;
if (!nvram_flash) {
rc = OPAL_HARDWARE;
goto out;
}
+ if (nvram_flash->busy) {
+ rc = OPAL_BUSY;
+ goto out;
+ }
+
if ((src + len) > nvram_size) {
prerror("FLASH_NVRAM: read out of bound (0x%x,0x%x)\n",
src, len);
@@ -87,7 +121,13 @@ static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
{
int rc;
- lock(&flash_lock);
+ if (!try_lock(&flash_lock))
+ return OPAL_BUSY;
+
+ if (nvram_flash->busy) {
+ rc = OPAL_BUSY;
+ goto out;
+ }
/* TODO: When we have async jobs for PRD, turn this into one */
@@ -235,6 +275,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
flash = &flashes[i];
flash->registered = true;
+ flash->busy = false;
flash->chip = chip;
flash->size = size;
flash->block_size = block_size;
@@ -286,6 +327,12 @@ static int64_t opal_flash_op(enum flash_op op, uint64_t id, uint64_t offset,
return OPAL_BUSY;
flash = &flashes[id];
+
+ if (flash->busy) {
+ rc = OPAL_BUSY;
+ goto err;
+ }
+
if (!flash->registered) {
rc = OPAL_PARAMETER;
goto err;
@@ -493,6 +540,9 @@ bool flash_load_resource(enum resource_id id, uint32_t subid,
flash = system_flash;
+ if (flash->busy)
+ goto out_unlock;
+
for (i = 0, name = NULL; i < ARRAY_SIZE(part_name_map); i++) {
if (part_name_map[i].id == id) {
name = part_name_map[i].name;
diff --git a/core/init.c b/core/init.c
index ac61c37..1fd8d2e 100644
--- a/core/init.c
+++ b/core/init.c
@@ -43,6 +43,7 @@
#include <centaur.h>
#include <libfdt/libfdt.h>
#include <timer.h>
+#include <ipmi.h>
#include <ipmi.h>
@@ -374,6 +375,8 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
load_initramfs();
+ ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
+
if (!is_reboot) {
/* We wait for the nvram read to complete here so we can
* grab stuff from there such as the kernel arguments
@@ -668,6 +671,8 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu)
/* Add OPAL timer related properties */
late_init_timers();
+ ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
+
/*
* These last few things must be done as late as possible
* because they rely on various other things having been setup,
diff --git a/core/ipmi.c b/core/ipmi.c
index 6c1179f..78a54de 100644
--- a/core/ipmi.c
+++ b/core/ipmi.c
@@ -156,9 +156,14 @@ static void ipmi_get_message_flags_complete(struct ipmi_msg *msg)
/* Once we see an interrupt we assume the payload has
* booted. We disable the wdt and let the OS setup its own
- * wdt. */
- if (flags & IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT)
+ * wdt.
+ *
+ * This is also where we consider the OS to be booted, so we set
+ * the boot count sensor */
+ if (flags & IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT) {
ipmi_wdt_stop();
+ ipmi_set_boot_count();
+ }
/* Message available in the event buffer? Queue a Read Event command
* to retrieve it. The flag is cleared by performing a read */