From 0ad10f26c94a86a0c9c3970e53f9a9f6a744055d Mon Sep 17 00:00:00 2001 From: "Nikunj A. Dadhania" Date: Tue, 16 Oct 2012 11:49:51 +0530 Subject: SLOF: Support PAPR NVRAM RTAS calls BenH still need to ACK this though. From: Nikunj A. Dadhania * Determines size of the flash using device tree. * Provides nvram access functions for RTAS_NVRAM * Allocates temporary buffer of nvram in SLOF code and use that in C. (sbrk not available) * NVRAM_LENGTH is used at various places, make sure it is well guarded and also use dynamically determined size once an RTAS-NVRAM is found. * Use NVRAM_LENGTH as a variable in case of RTAS_NVRAM, not very elegant though Signed-off-by: Nikunj A. Dadhania -- Changelog from v1: * #define cleanups suggested by Thomas/Benh * Fix makefile which missed passing $FLAG for building llfw * renamed vio-nvram.fs as rtas-nvram.fs --- lib/libnvram/nvram.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'lib/libnvram/nvram.c') diff --git a/lib/libnvram/nvram.c b/lib/libnvram/nvram.c index 048ec0f..2cb83dc 100644 --- a/lib/libnvram/nvram.c +++ b/lib/libnvram/nvram.c @@ -12,6 +12,7 @@ #include "cache.h" #include "nvram.h" +#include "../libhvcall/libhvcall.h" #include #include @@ -20,9 +21,38 @@ #include #include +#ifdef RTAS_NVRAM +static uint32_t fetch_token; +static uint32_t store_token; +static uint32_t NVRAM_LENGTH; +static char *nvram_buffer; /* use buffer allocated by SLOF code */ +#else #ifndef NVRAM_LENGTH #define NVRAM_LENGTH 0x10000 #endif +/* + * This is extremely ugly, but still better than implementing + * another sbrk() around it. + */ +static char nvram_buffer[NVRAM_LENGTH]; +#endif + +static uint8_t nvram_buffer_locked=0x00; + +void nvram_init(uint32_t _fetch_token, uint32_t _store_token, + long _nvram_length, void* nvram_addr) +{ +#ifdef RTAS_NVRAM + fetch_token = _fetch_token; + store_token = _store_token; + NVRAM_LENGTH = _nvram_length; + nvram_buffer = nvram_addr; + + printf("\nNVRAM: size=%d, fetch=%x, store=%x\n", + NVRAM_LENGTH, fetch_token, store_token); +#endif +} + void asm_cout(long Character,long UART,long NVRAM); @@ -48,6 +78,46 @@ static volatile uint8_t nvram[NVRAM_LENGTH]; /* FAKE */ *pos = data; \ } +#elif defined(RTAS_NVRAM) + +static inline void nvram_fetch(unsigned int offset, void *buf, unsigned int len) +{ + struct hv_rtas_call rtas = { + .token = fetch_token, + .nargs = 3, + .nrets = 2, + .argret = { offset, (uint32_t)(unsigned long)buf, len }, + }; + h_rtas(&rtas); +} + +static inline void nvram_store(unsigned int offset, void *buf, unsigned int len) +{ + struct hv_rtas_call rtas = { + .token = store_token, + .nargs = 3, + .nrets = 2, + .argret = { offset, (uint32_t)(unsigned long)buf, len }, + }; + h_rtas(&rtas); +} + +#define nvram_access(type,size,name) \ + type nvram_read_##name(unsigned int offset) \ + { \ + type val; \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return 0; \ + nvram_fetch(offset, &val, size / 8); \ + return val; \ + } \ + void nvram_write_##name(unsigned int offset, type data) \ + { \ + if (offset > (NVRAM_LENGTH - sizeof(type))) \ + return; \ + nvram_store(offset, &data, size / 8); \ + } + #else /* DISABLE_NVRAM */ static volatile uint8_t *nvram = (volatile uint8_t *)SB_NVRAM_adr; @@ -83,12 +153,7 @@ nvram_access(uint16_t, 16, word) nvram_access(uint32_t, 32, dword) nvram_access(uint64_t, 64, qword) -/* - * This is extremely ugly, but still better than implementing - * another sbrk() around it. - */ -static char nvram_buffer[NVRAM_LENGTH]; -static uint8_t nvram_buffer_locked=0x00; + /** * This function is a minimal abstraction for our temporary @@ -184,7 +249,7 @@ static char * get_partition_name(int offset) for (i=0; i<12; i++) name[i]=nvram_read_byte(offset+4+i); - // DEBUG("name: \"%s\"\n", name); + DEBUG("name: \"%s\"\n", name); return name; } @@ -217,7 +282,7 @@ static int calc_used_nvram_space(void) } len=get_partition_len(walk); - // DEBUG("... part len=%x, %x\n", len, len*16); + DEBUG("... part len=%x, %x\n", len, len*16); if(!len) { /* If there's a partition type but no len, bail out. @@ -546,6 +611,13 @@ void reset_nvram(void) void nvram_debug(void) { +#ifndef RTAS_NVRAM printf("\nNVRAM_BASE: %p\n", nvram); printf("NVRAM_LEN: 0x%x\n", NVRAM_LENGTH); +#endif +} + +unsigned int get_nvram_size(void) +{ + return NVRAM_LENGTH; } -- cgit v1.1