#include "config.h" #include "libopenbios/bindings.h" #include "libc/byteorder.h" #include "libopenbios/ofmem.h" #define NO_QEMU_PROTOS #include "arch/common/fw_cfg.h" #if !defined(CONFIG_SPARC64) static volatile uint16_t *fw_cfg_cmd; static volatile uint8_t *fw_cfg_data; static void fw_cfg_read_bytes(char *buf, unsigned int nbytes) { unsigned int i; for (i = 0; i < nbytes; i++) buf[i] = *fw_cfg_data; } void fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) { *fw_cfg_cmd = cmd; fw_cfg_read_bytes(buf, nbytes); } #else // XXX depends on PCI bus location, should be removed static void fw_cfg_read_bytes(char *buf, unsigned int nbytes) { unsigned int i; for (i = 0; i < nbytes; i++) buf[i] = inb(CONFIG_FW_CFG_ADDR + 1); } void fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) { outw(cmd, CONFIG_FW_CFG_ADDR); fw_cfg_read_bytes(buf, nbytes); } #endif uint64_t fw_cfg_read_i64(uint16_t cmd) { uint64_t buf; fw_cfg_read(cmd, (char *)&buf, sizeof(uint64_t)); return __le64_to_cpu(buf); } uint32_t fw_cfg_read_i32(uint16_t cmd) { uint32_t buf; fw_cfg_read(cmd, (char *)&buf, sizeof(uint32_t)); return __le32_to_cpu(buf); } uint16_t fw_cfg_read_i16(uint16_t cmd) { uint16_t buf; fw_cfg_read(cmd, (char *)&buf, sizeof(uint16_t)); return __le16_to_cpu(buf); } uint32_t fw_cfg_find_file(const char *filename, uint16_t *select, uint32_t *size) { FWCfgFile f; unsigned int i; uint32_t buf, count; /* Unusually all FW_CFG_FILE_DIR fields are BE */ fw_cfg_read(FW_CFG_FILE_DIR, (char *)&buf, sizeof(uint32_t)); count = __be32_to_cpu(buf); for (i = 0; i < count; i++) { fw_cfg_read_bytes((char *)&f, sizeof(f)); if (!strcmp(f.name, filename)) { *select = __be16_to_cpu(f.select); *size = __be32_to_cpu(f.size); return -1; } } return 0; } char * fw_cfg_read_file(const char *filename, uint32_t *size) { uint16_t cmd; uint32_t nbytes; char *buf; if (fw_cfg_find_file(filename, &cmd, &nbytes)) { buf = malloc(nbytes); fw_cfg_read(cmd, buf, nbytes); *size = nbytes; return buf; } return NULL; } // // ( fname fnamelen -- buf buflen -1 | 0 ) // void forth_fw_cfg_read_file(void) { char *filename = pop_fstr_copy(); char *buffer; uint32_t size; buffer = fw_cfg_read_file(filename, &size); if (buffer) { PUSH(pointer2cell(buffer)); PUSH(size); PUSH(-1); return; } PUSH(0); } void fw_cfg_init(void) { #if defined(CONFIG_SPARC32) fw_cfg_cmd = (void *)ofmem_map_io(CONFIG_FW_CFG_ADDR, 2); fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2; #elif defined(CONFIG_SPARC64) // Nothing for the port version #elif defined(CONFIG_PPC) fw_cfg_cmd = (void *)CONFIG_FW_CFG_ADDR; fw_cfg_data = (void *)(CONFIG_FW_CFG_ADDR + 2); #endif }