114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org) 314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * This program is free software; you can redistribute it and/or 514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * modify it under the terms of the GNU General Public License 614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * as published by the Free Software Foundation; either version 714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 2 of the License, or (at your option) any later version. 814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Todo: - add support for the OF persistent properties 1014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 114b16f8e2d6d64249f0ed3ca7fe2a319d0dde2719Paul Gortmaker#include <linux/export.h> 1214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/kernel.h> 1314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/stddef.h> 1414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/string.h> 1514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/nvram.h> 1614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/init.h> 1714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/delay.h> 1814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/errno.h> 1914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/adb.h> 2014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/pmu.h> 2114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/bootmem.h> 2214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/completion.h> 2314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/spinlock.h> 2414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/sections.h> 2514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/io.h> 2614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/prom.h> 2714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/machdep.h> 2814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/nvram.h> 2914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 300ebfff1491ef85d41ddf9c633834838be144f69fBenjamin Herrenschmidt#include "pmac.h" 310ebfff1491ef85d41ddf9c633834838be144f69fBenjamin Herrenschmidt 3214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define DEBUG 3314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 3414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef DEBUG 3514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define DBG(x...) printk(x) 3614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#else 3714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define DBG(x...) 3814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif 3914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ 4114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define CORE99_SIGNATURE 0x5a 4314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define CORE99_ADLER_START 0x14 4414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* On Core99, nvram is either a sharp, a micron or an AMD flash */ 4614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_STATUS_DONE 0x80 4735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras#define SM_FLASH_STATUS_ERR 0x38 4835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 4914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 5014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_ERASE_SETUP 0x20 5114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_RESET 0xff 5214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_WRITE_SETUP 0x40 5314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_CLEAR_STATUS 0x50 5414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#define SM_FLASH_CMD_READ_STATUS 0x70 5514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 5614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* CHRP NVRAM header */ 5714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstruct chrp_header { 5814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u8 signature; 5914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u8 cksum; 6014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u16 len; 6114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras char name[12]; 6214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u8 data[0]; 6314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras}; 6414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 6514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstruct core99_header { 6614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct chrp_header hdr; 6714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u32 adler; 6814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u32 generation; 6914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u32 reserved[2]; 7014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras}; 7114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 7214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 7314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Read and write the non-volatile RAM on PowerMacs and CHRP machines. 7414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 7514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int nvram_naddrs; 76af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwellstatic volatile unsigned char __iomem *nvram_data; 7735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasstatic int is_core_99; 7814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int core99_bank = 0; 7914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int nvram_partitions[3]; 8035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras// XXX Turn that into a sem 817d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixnerstatic DEFINE_RAW_SPINLOCK(nv_lock); 8214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 8314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int (*core99_write_bank)(int bank, u8* datas); 8414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int (*core99_erase_bank)(int bank); 8514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 8614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic char *nvram_image; 8714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 8814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 8914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic unsigned char core99_nvram_read_byte(int addr) 9014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 9114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (nvram_image == NULL) 9214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0xff; 9314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return nvram_image[addr]; 9414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 9514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 9614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void core99_nvram_write_byte(int addr, unsigned char val) 9714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 9814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (nvram_image == NULL) 9914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return; 10014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_image[addr] = val; 10114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 10214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 10335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasstatic ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index) 10435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras{ 10535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int i; 10635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 10735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (nvram_image == NULL) 10835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -ENODEV; 10935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (*index > NVRAM_SIZE) 11035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return 0; 11135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 11235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras i = *index; 11335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (i + count > NVRAM_SIZE) 11435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras count = NVRAM_SIZE - i; 11535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 11635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras memcpy(buf, &nvram_image[i], count); 11735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras *index = i + count; 11835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return count; 11935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras} 12035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 12135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasstatic ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index) 12235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras{ 12335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int i; 12435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 12535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (nvram_image == NULL) 12635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -ENODEV; 12735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (*index > NVRAM_SIZE) 12835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return 0; 12935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 13035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras i = *index; 13135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (i + count > NVRAM_SIZE) 13235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras count = NVRAM_SIZE - i; 13335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 13435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras memcpy(&nvram_image[i], buf, count); 13535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras *index = i + count; 13635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return count; 13735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras} 13835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 13935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasstatic ssize_t core99_nvram_size(void) 14035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras{ 14135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (nvram_image == NULL) 14235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -ENODEV; 14335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return NVRAM_SIZE; 14435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras} 14535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 14635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras#ifdef CONFIG_PPC32 147af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwellstatic volatile unsigned char __iomem *nvram_addr; 14835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasstatic int nvram_mult; 14914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 15014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic unsigned char direct_nvram_read_byte(int addr) 15114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 15214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]); 15314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 15414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 15514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void direct_nvram_write_byte(int addr, unsigned char val) 15614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 15714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val); 15814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 15914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 16014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 16114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic unsigned char indirect_nvram_read_byte(int addr) 16214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 16314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned char val; 16414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long flags; 16514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 1667d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_lock_irqsave(&nv_lock, flags); 16714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(nvram_addr, addr >> 5); 16814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras val = in_8(&nvram_data[(addr & 0x1f) << 4]); 1697d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_unlock_irqrestore(&nv_lock, flags); 17014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 17114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return val; 17214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 17314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 17414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void indirect_nvram_write_byte(int addr, unsigned char val) 17514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 17614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long flags; 17714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 1787d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_lock_irqsave(&nv_lock, flags); 17914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(nvram_addr, addr >> 5); 18014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(&nvram_data[(addr & 0x1f) << 4], val); 1817d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_unlock_irqrestore(&nv_lock, flags); 18214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 18314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 18414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 18514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef CONFIG_ADB_PMU 18614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 18714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void pmu_nvram_complete(struct adb_request *req) 18814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 18914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (req->arg) 19014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras complete((struct completion *)req->arg); 19114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 19214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 19314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic unsigned char pmu_nvram_read_byte(int addr) 19414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 19514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct adb_request req; 1966e9a4738c9fadb7cbdcabc1e3b415159f3741ed9Peter Zijlstra DECLARE_COMPLETION_ONSTACK(req_complete); 19714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 19814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; 19914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM, 20014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras (addr >> 8) & 0xff, addr & 0xff)) 20114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0xff; 20214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (system_state == SYSTEM_RUNNING) 20314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras wait_for_completion(&req_complete); 20414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras while (!req.complete) 20514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pmu_poll(); 20614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return req.reply[0]; 20714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 20814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 20914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void pmu_nvram_write_byte(int addr, unsigned char val) 21014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 21114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct adb_request req; 2126e9a4738c9fadb7cbdcabc1e3b415159f3741ed9Peter Zijlstra DECLARE_COMPLETION_ONSTACK(req_complete); 21314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 21414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; 21514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM, 21614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras (addr >> 8) & 0xff, addr & 0xff, val)) 21714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return; 21814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (system_state == SYSTEM_RUNNING) 21914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras wait_for_completion(&req_complete); 22014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras while (!req.complete) 22114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras pmu_poll(); 22214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 22314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 22414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif /* CONFIG_ADB_PMU */ 22535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras#endif /* CONFIG_PPC32 */ 22614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 22714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic u8 chrp_checksum(struct chrp_header* hdr) 22814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 22914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u8 *ptr; 23014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u16 sum = hdr->signature; 23114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++) 23214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras sum += *ptr; 23314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras while (sum > 0xFF) 23414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras sum = (sum & 0xFF) + (sum>>8); 23514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return sum; 23614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 23714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 23814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic u32 core99_calc_adler(u8 *buffer) 23914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 24014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int cnt; 24114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u32 low, high; 24214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 24314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras buffer += CORE99_ADLER_START; 24414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras low = 1; 24514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras high = 0; 24614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) { 24714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((cnt % 5000) == 0) { 24814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras high %= 65521UL; 24914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras high %= 65521UL; 25014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 25114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras low += buffer[cnt]; 25214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras high += low; 25314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 25414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras low %= 65521UL; 25514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras high %= 65521UL; 25614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 25714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return (high << 16) | low; 25814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 25914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 26014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic u32 core99_check(u8* datas) 26114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 26214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct core99_header* hdr99 = (struct core99_header*)datas; 26314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 26414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (hdr99->hdr.signature != CORE99_SIGNATURE) { 26514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("Invalid signature\n"); 26614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 26714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 26814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) { 26914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("Invalid checksum\n"); 27014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 27114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 27214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (hdr99->adler != core99_calc_adler(datas)) { 27314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("Invalid adler\n"); 27414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 27514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 27614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return hdr99->generation; 27714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 27814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 27914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int sm_erase_bank(int bank) 28014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 2812d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita int stat; 28214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long timeout; 28314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 284af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwell u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; 28514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 28614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); 28714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 28814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_ERASE_SETUP); 28914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_ERASE_CONFIRM); 29014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras timeout = 0; 29114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras do { 29214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (++timeout > 1000000) { 29335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n"); 29414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 29514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 29614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_READ_STATUS); 29714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras stat = in_8(base); 29814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } while (!(stat & SM_FLASH_STATUS_DONE)); 29914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 30014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_CLEAR_STATUS); 30114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_RESET); 30214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 3032d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita if (memchr_inv(base, 0xff, NVRAM_SIZE)) { 3042d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n"); 3052d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita return -ENXIO; 3062d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita } 30714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 30814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 30914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 31014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int sm_write_bank(int bank, u8* datas) 31114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 31214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int i, stat = 0; 31314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long timeout; 31414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 315af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwell u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; 31614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 31714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); 31814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 31914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (i=0; i<NVRAM_SIZE; i++) { 32014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+i, SM_FLASH_CMD_WRITE_SETUP); 32114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 32214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+i, datas[i]); 32314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras timeout = 0; 32414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras do { 32514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (++timeout > 1000000) { 32614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n"); 32714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 32814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 32914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_READ_STATUS); 33014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras stat = in_8(base); 33114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } while (!(stat & SM_FLASH_STATUS_DONE)); 33214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (!(stat & SM_FLASH_STATUS_DONE)) 33314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 33414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 33514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_CLEAR_STATUS); 33614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, SM_FLASH_CMD_RESET); 3372d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita if (memcmp(base, datas, NVRAM_SIZE)) { 3382d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n"); 3392d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita return -ENXIO; 3402d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita } 34114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 34214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 34314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 34414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int amd_erase_bank(int bank) 34514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 3462d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita int stat = 0; 34714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long timeout; 34814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 349af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwell u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; 35014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 35114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: AMD Erasing bank %d...\n", bank); 35214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 35314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Unlock 1 */ 35414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x555, 0xaa); 35514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 35614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Unlock 2 */ 35714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x2aa, 0x55); 35814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 35914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 36014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Sector-Erase */ 36114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x555, 0x80); 36214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 36314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x555, 0xaa); 36414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 36514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x2aa, 0x55); 36614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 36714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, 0x30); 36814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 36914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 37014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras timeout = 0; 37114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras do { 37214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (++timeout > 1000000) { 37314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk(KERN_ERR "nvram: AMD flash erase timeout !\n"); 37414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 37514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 37614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras stat = in_8(base) ^ in_8(base); 37714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } while (stat != 0); 37814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 37914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Reset */ 38014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, 0xf0); 38114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 3822d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita 3832d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita if (memchr_inv(base, 0xff, NVRAM_SIZE)) { 3842d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita printk(KERN_ERR "nvram: AMD flash erase failed !\n"); 3852d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita return -ENXIO; 3862d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita } 38714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 38814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 38914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 39014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic int amd_write_bank(int bank, u8* datas) 39114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 39214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int i, stat = 0; 39314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long timeout; 39414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 395af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwell u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; 39614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 39714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: AMD Writing bank %d...\n", bank); 39814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 39914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (i=0; i<NVRAM_SIZE; i++) { 40014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Unlock 1 */ 40114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x555, 0xaa); 40214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 40314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Unlock 2 */ 40414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x2aa, 0x55); 40514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 40614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 40714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Write single word */ 40814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+0x555, 0xa0); 40914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 41014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base+i, datas[i]); 41114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 41214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras timeout = 0; 41314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras do { 41414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (++timeout > 1000000) { 41514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk(KERN_ERR "nvram: AMD flash write timeout !\n"); 41614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 41714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 41814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras stat = in_8(base) ^ in_8(base); 41914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } while (stat != 0); 42014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (stat != 0) 42114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras break; 42214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 42314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 42414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* Reset */ 42514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras out_8(base, 0xf0); 42614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras udelay(1); 42714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4282d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita if (memcmp(base, datas, NVRAM_SIZE)) { 4292d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita printk(KERN_ERR "nvram: AMD flash write failed !\n"); 4302d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita return -ENXIO; 4312d4b971287cbce16585acda4b76308faa8da0950Akinobu Mita } 43214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 43314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 43414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 43514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void __init lookup_partitions(void) 43614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 43714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras u8 buffer[17]; 43814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras int i, offset; 43914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct chrp_header* hdr; 44014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 44114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (pmac_newworld) { 44214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_OF] = -1; 44314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_XPRAM] = -1; 44414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_NR] = -1; 44514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr = (struct chrp_header *)buffer; 44614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 44714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras offset = 0; 44814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras buffer[16] = 0; 44914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras do { 45014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras for (i=0;i<16;i++) 45135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras buffer[i] = ppc_md.nvram_read_val(offset+i); 45214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (!strcmp(hdr->name, "common")) 45314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_OF] = offset + 0x10; 45414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (!strcmp(hdr->name, "APL,MacOS75")) { 45514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10; 45614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_NR] = offset + 0x110; 45714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 45814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras offset += (hdr->len * 0x10); 45914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } while(offset < NVRAM_SIZE); 46014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else { 46114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_OF] = 0x1800; 46214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_XPRAM] = 0x1300; 46314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_partitions[pmac_nvram_NR] = 0x1400; 46414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 46514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]); 46614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]); 46714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]); 46814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 46914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 47014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasstatic void core99_nvram_sync(void) 47114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 47214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct core99_header* hdr99; 47314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long flags; 47414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 47514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (!is_core_99 || !nvram_data || !nvram_image) 47614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return; 47714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 4787d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_lock_irqsave(&nv_lock, flags); 47914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE, 48014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras NVRAM_SIZE)) 48114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras goto bail; 48214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 48314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras DBG("Updating nvram...\n"); 48414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 48514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr99 = (struct core99_header*)nvram_image; 48614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr99->generation++; 48714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr99->hdr.signature = CORE99_SIGNATURE; 48814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr); 48914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras hdr99->adler = core99_calc_adler(nvram_image); 49014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras core99_bank = core99_bank ? 0 : 1; 49114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (core99_erase_bank) 49214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (core99_erase_bank(core99_bank)) { 49314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk("nvram: Error erasing bank %d\n", core99_bank); 49414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras goto bail; 49514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 49614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (core99_write_bank) 49714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (core99_write_bank(core99_bank, nvram_image)) 49814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk("nvram: Error writing bank %d\n", core99_bank); 49914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras bail: 5007d725bdc1b25b9c4ff7c14e43d0d0d6c3d677727Thomas Gleixner raw_spin_unlock_irqrestore(&nv_lock, flags); 50114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 50214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef DEBUG 50314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras mdelay(2000); 50414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif 50514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 50614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 507cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidtstatic int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) 50835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras{ 50935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int i; 51035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras u32 gen_bank0, gen_bank1; 51135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 51235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (nvram_naddrs < 1) { 51335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras printk(KERN_ERR "nvram: no address\n"); 51435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -EINVAL; 51535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras } 51635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras nvram_image = alloc_bootmem(NVRAM_SIZE); 51735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (nvram_image == NULL) { 51835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras printk(KERN_ERR "nvram: can't allocate ram image\n"); 51935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -ENOMEM; 52035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras } 521cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_data = ioremap(addr, NVRAM_SIZE*2); 52235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras nvram_naddrs = 1; /* Make sure we get the correct case */ 52335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 52435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras DBG("nvram: Checking bank 0...\n"); 52535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 52635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras gen_bank0 = core99_check((u8 *)nvram_data); 52735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE); 52835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0; 52935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 53035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1); 53135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras DBG("nvram: Active bank is: %d\n", core99_bank); 53235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 53335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras for (i=0; i<NVRAM_SIZE; i++) 53435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE]; 53535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 53635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_read_val = core99_nvram_read_byte; 53735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_write_val = core99_nvram_write_byte; 53835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_read = core99_nvram_read; 53935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_write = core99_nvram_write; 54035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_size = core99_nvram_size; 54135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras ppc_md.nvram_sync = core99_nvram_sync; 5423d1229d6ae92ed1994f4411b8493327ef8f4b76fMichael Ellerman ppc_md.machine_shutdown = core99_nvram_sync; 54335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras /* 54435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras * Maybe we could be smarter here though making an exclusive list 54535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras * of known flash chips is a bit nasty as older OF didn't provide us 54635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras * with a useful "compatible" entry. A solution would be to really 54735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras * identify the chip using flash id commands and base ourselves on 54835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras * a list of known chips IDs 54935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras */ 55055b61fec22caa3e7872caea6c4100fc75cb8f49bStephen Rothwell if (of_device_is_compatible(dp, "amd-0137")) { 55135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras core99_erase_bank = amd_erase_bank; 55235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras core99_write_bank = amd_write_bank; 55335499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras } else { 55435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras core99_erase_bank = sm_erase_bank; 55535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras core99_write_bank = sm_write_bank; 55635499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras } 55735499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return 0; 55835499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras} 55935499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras 56035499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerrasint __init pmac_nvram_init(void) 56114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 56214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras struct device_node *dp; 563cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt struct resource r1, r2; 564cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt unsigned int s1 = 0, s2 = 0; 56535499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int err = 0; 56614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 56714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_naddrs = 0; 56814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 569cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt dp = of_find_node_by_name(NULL, "nvram"); 57014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (dp == NULL) { 57114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras printk(KERN_ERR "Can't find NVRAM device\n"); 57235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return -ENODEV; 57314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 574cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt 575cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt /* Try to obtain an address */ 576cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt if (of_address_to_resource(dp, 0, &r1) == 0) { 577cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_naddrs = 1; 57828f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches s1 = resource_size(&r1); 579cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt if (of_address_to_resource(dp, 1, &r2) == 0) { 580cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_naddrs = 2; 58128f65c11f2ffb3957259dece647a24f8ad2e241bJoe Perches s2 = resource_size(&r2); 582cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt } 583cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt } 584cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt 58555b61fec22caa3e7872caea6c4100fc75cb8f49bStephen Rothwell is_core_99 = of_device_is_compatible(dp, "nvram,flash"); 586cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt if (is_core_99) { 587cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt err = core99_nvram_setup(dp, r1.start); 588cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt goto bail; 589cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt } 590cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt 59135499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras#ifdef CONFIG_PPC32 592e8222502ee6157e2713da9e0792c21f4ad458d50Benjamin Herrenschmidt if (machine_is(chrp) && nvram_naddrs == 1) { 593cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_data = ioremap(r1.start, s1); 59414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_mult = 1; 59514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_read_val = direct_nvram_read_byte; 59614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_write_val = direct_nvram_write_byte; 59714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else if (nvram_naddrs == 1) { 598cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_data = ioremap(r1.start, s1); 599cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE; 60014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_read_val = direct_nvram_read_byte; 60114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_write_val = direct_nvram_write_byte; 60214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else if (nvram_naddrs == 2) { 603cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_addr = ioremap(r1.start, s1); 604cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt nvram_data = ioremap(r2.start, s2); 60514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_read_val = indirect_nvram_read_byte; 60614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_write_val = indirect_nvram_write_byte; 60714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { 60814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#ifdef CONFIG_ADB_PMU 60914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras nvram_naddrs = -1; 61014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_read_val = pmu_nvram_read_byte; 61114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_write_val = pmu_nvram_write_byte; 61214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#endif /* CONFIG_ADB_PMU */ 613cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt } else { 61435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras printk(KERN_ERR "Incompatible type of NVRAM\n"); 615cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt err = -ENXIO; 61614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 617cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt#endif /* CONFIG_PPC32 */ 618cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidtbail: 619cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt of_node_put(dp); 620cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt if (err == 0) 621cc5d0189b9ba95260857a5018a1c2fef90008507Benjamin Herrenschmidt lookup_partitions(); 62235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras return err; 62314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 62414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 62514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasint pmac_get_partition(int partition) 62614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 62714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return nvram_partitions[partition]; 62814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 62914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 63014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasu8 pmac_xpram_read(int xpaddr) 63114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 63235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int offset = pmac_get_partition(pmac_nvram_XPRAM); 63314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 63435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) 63514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0xff; 63614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 63714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return ppc_md.nvram_read_val(xpaddr + offset); 63814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 63914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 64014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasvoid pmac_xpram_write(int xpaddr, u8 data) 64114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 64235499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras int offset = pmac_get_partition(pmac_nvram_XPRAM); 64314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 64435499c0195e46f479cf6ac16ad8d3f394b5fcc10Paul Mackerras if (offset < 0 || xpaddr < 0 || xpaddr > 0x100) 64514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return; 64614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 64714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras ppc_md.nvram_write_val(xpaddr + offset, data); 64814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 64914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 65014cf11af6cf608eb8c23e989ddb17a715ddce109Paul MackerrasEXPORT_SYMBOL(pmac_get_partition); 65114cf11af6cf608eb8c23e989ddb17a715ddce109Paul MackerrasEXPORT_SYMBOL(pmac_xpram_read); 65214cf11af6cf608eb8c23e989ddb17a715ddce109Paul MackerrasEXPORT_SYMBOL(pmac_xpram_write); 653