| #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); | |
| } | |
| } |