blob: d97bd1027850a3005e5e88514d464124857361e8 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <byteswap.h>
#include <stdint.h>
#include <stdbool.h>
#include <getopt.h>
#include <limits.h>
#include <arpa/inet.h>
#include <assert.h>
#include "io.h"
void *ahb_reg_map;
void *ahb_flash_map;
uint32_t ahb_flash_base, ahb_flash_size;
void *gpio_ctrl;
int ast_copy_to_ahb(uint32_t reg, const void *src, uint32_t len)
{
if (reg < ahb_flash_base ||
(reg + len) > (ahb_flash_base + ahb_flash_size))
return -1;
reg -= ahb_flash_base;
if (((reg | (unsigned long)src | len) & 3) == 0) {
while(len > 3) {
uint32_t val = *(uint32_t *)src;
writel(val, ahb_flash_map + reg);
src += 4;
reg += 4;
len -= 4;
}
}
while(len--) {
uint8_t val = *(uint8_t *)src;
writeb(val, ahb_flash_map + reg++);
src += 1;
}
return 0;
}
int ast_copy_from_ahb(void *dst, uint32_t reg, uint32_t len)
{
if (reg < ahb_flash_base ||
(reg + len) > (ahb_flash_base + ahb_flash_size))
return -1;
reg -= ahb_flash_base;
if (((reg | (unsigned long)dst | len) & 3) == 0) {
while(len > 3) {
*(uint32_t *)dst = readl(ahb_flash_map + reg);
dst += 4;
reg += 4;
len -= 4;
}
}
while(len--) {
*(uint8_t *)dst = readb(ahb_flash_map + reg++);
dst += 1;
}
return 0;
}
/*
* GPIO stuff to be replaced by higher level accessors for
* controlling the flash write lock via sysfs
*/
static inline uint32_t gpio_ctl_readl(uint32_t offset)
{
return readl(gpio_ctrl + offset);
}
static inline void gpio_ctl_writel(uint32_t val, uint32_t offset)
{
writel(val, gpio_ctrl + offset);
}
bool set_wrprotect(bool protect)
{
uint32_t reg;
bool was_protected;
reg = gpio_ctl_readl(0x20);
was_protected = !!(reg & 0x00004000);
if (protect)
reg |= 0x00004000; /* GPIOF[6] value */
else
reg &= ~0x00004000; /* GPIOF[6] value */
gpio_ctl_writel(reg, 0x20);
reg = gpio_ctl_readl(0x24);
reg |= 0x00004000; /* GPIOF[6] direction */
gpio_ctl_writel(reg, 0x24);
return was_protected;
}
void open_devs(bool use_lpc, bool bmc_flash)
{
int fd;
(void)use_lpc;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {
perror("can't open /dev/mem");
exit(1);
}
ahb_reg_map = mmap(0, AHB_REGS_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, AHB_REGS_BASE);
if (ahb_reg_map == MAP_FAILED) {
perror("can't map AHB registers /dev/mem");
exit(1);
}
gpio_ctrl = mmap(0, GPIO_CTRL_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, GPIO_CTRL_BASE);
if (gpio_ctrl == MAP_FAILED) {
perror("can't map GPIO control via /dev/mem");
exit(1);
}
ahb_flash_base = bmc_flash ? BMC_FLASH_BASE : PNOR_FLASH_BASE;
ahb_flash_size = bmc_flash ? BMC_FLASH_SIZE : PNOR_FLASH_SIZE;
ahb_flash_map = mmap(0, ahb_flash_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, ahb_flash_base);
if (ahb_flash_map == MAP_FAILED) {
perror("can't map flash via /dev/mem");
exit(1);
}
}