vloaduc.c revision 72313efb
1bdcaa8d0Smrg/* 2bdcaa8d0Smrg * includes 3bdcaa8d0Smrg */ 4bdcaa8d0Smrg 5bdcaa8d0Smrg#ifdef HAVE_CONFIG_H 6bdcaa8d0Smrg#include "config.h" 7bdcaa8d0Smrg#endif 8bdcaa8d0Smrg 9bdcaa8d0Smrg#include "rendition.h" 10bdcaa8d0Smrg#include "v1kregs.h" 11bdcaa8d0Smrg#include "v1krisc.h" 12bdcaa8d0Smrg#include "vloaduc.h" 13bdcaa8d0Smrg#include "vos.h" 14bdcaa8d0Smrg 15bdcaa8d0Smrg#include <sys/types.h> 16bdcaa8d0Smrg#include <sys/stat.h> 17bdcaa8d0Smrg#include <fcntl.h> 18bdcaa8d0Smrg#include <stdio.h> 1972313efbSmrg#include <unistd.h> 20bdcaa8d0Smrg#ifdef HAVE_ELF_H 21bdcaa8d0Smrg#include <elf.h> 22bdcaa8d0Smrg#endif 23bdcaa8d0Smrg#ifdef HAVE_ELF_ABI_H 24bdcaa8d0Smrg#include <elf_abi.h> 25bdcaa8d0Smrg#endif 26bdcaa8d0Smrg 27bdcaa8d0Smrg/* 28bdcaa8d0Smrg * defines 29bdcaa8d0Smrg */ 30bdcaa8d0Smrg 31bdcaa8d0Smrg#ifdef X_LITTLE_ENDIAN 32bdcaa8d0Smrg 33bdcaa8d0Smrg/* maybe swap word */ 34bdcaa8d0Smrg#define SW32(x) lswapl(x) 35bdcaa8d0Smrg#define SW16(x) lswaps(x) 36bdcaa8d0Smrg#else /* BIG_ENDIAN */ 37bdcaa8d0Smrg#define SW32(x) (x) 38bdcaa8d0Smrg#define SW16(x) (x) 39bdcaa8d0Smrg#endif /* #ifdef LITTLE_ENDIAN */ 40bdcaa8d0Smrg 41bdcaa8d0Smrg 42bdcaa8d0Smrg 43bdcaa8d0Smrg/* 44bdcaa8d0Smrg * local function prototypes 45bdcaa8d0Smrg */ 46bdcaa8d0Smrgstatic void loadSection2board(ScrnInfoPtr pScreenInfo, int fd, 47bdcaa8d0Smrg Elf32_Shdr *shdr); 48bdcaa8d0Smrgstatic void loadSegment2board(ScrnInfoPtr pScreenInfo, int fd, 49bdcaa8d0Smrg Elf32_Phdr *phdr); 50bdcaa8d0Smrgstatic int seek_and_read_hdr(int fd, void *ptr, long int offset, 51bdcaa8d0Smrg int size, int cnt); 52bdcaa8d0Smrgstatic void mmve(ScrnInfoPtr pScreenInfo, vu32 size, vu8 *data, vu32 phys_addr); 53bdcaa8d0Smrg 54bdcaa8d0Smrg 55bdcaa8d0Smrg 56bdcaa8d0Smrg/* 57bdcaa8d0Smrg * functions 58bdcaa8d0Smrg */ 59bdcaa8d0Smrg 60bdcaa8d0Smrg/* 61bdcaa8d0Smrg * int verite_load_ucfile(ScrnInfoPtr pScreenInfo, char *file_name) 62bdcaa8d0Smrg * 63bdcaa8d0Smrg * Loads verite elf file microcode file in |name| onto the board. 64bdcaa8d0Smrg * NOTE: Assumes the ucode loader is already running on the board! 65bdcaa8d0Smrg * 66bdcaa8d0Smrg * Returns the program's entry point, on error -1; 67bdcaa8d0Smrg */ 68bdcaa8d0Smrgint 69bdcaa8d0Smrgverite_load_ucfile(ScrnInfoPtr pScreenInfo, char *file_name) 70bdcaa8d0Smrg{ 71bdcaa8d0Smrg /* renditionPtr pRendition = RENDITIONPTR(pScreenInfo); */ 72bdcaa8d0Smrg 73bdcaa8d0Smrg int num; 74bdcaa8d0Smrg int sz; 75bdcaa8d0Smrg int fd; 76bdcaa8d0Smrg Elf32_Phdr *pphdr, *orig_pphdr=NULL; 77bdcaa8d0Smrg Elf32_Shdr *pshdr, *orig_pshdr=NULL; 78bdcaa8d0Smrg Elf32_Ehdr ehdr ; 79bdcaa8d0Smrg 80bdcaa8d0Smrg#ifdef DEBUG 81bdcaa8d0Smrg ErrorF("RENDITION: Loading microcode %s\n", file_name); 82bdcaa8d0Smrg#endif 83bdcaa8d0Smrg 84bdcaa8d0Smrg /* Stop the RISC if it happends to run */ 85bdcaa8d0Smrg v1k_stop (pScreenInfo); 86bdcaa8d0Smrg 87bdcaa8d0Smrg /* open file and read ELF-header */ 88bdcaa8d0Smrg if (-1 == (fd=open(file_name, O_RDONLY, 0))) { 89bdcaa8d0Smrg ErrorF("RENDITION: Cannot open microcode %s\n", file_name); 90bdcaa8d0Smrg return -1; 91bdcaa8d0Smrg } 92bdcaa8d0Smrg 93bdcaa8d0Smrg if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) { 94bdcaa8d0Smrg ErrorF("RENDITION: Cannot read microcode header %s\n", file_name); 95bdcaa8d0Smrg return -1; 96bdcaa8d0Smrg } 97bdcaa8d0Smrg if (0 != strncmp((char *)&ehdr.e_ident[1], "ELF", 3)) { 98bdcaa8d0Smrg ErrorF("RENDITION: Microcode header in %s is corrupt\n", file_name); 99bdcaa8d0Smrg return -1; 100bdcaa8d0Smrg } 101bdcaa8d0Smrg 102bdcaa8d0Smrg /* read in the program header(s) */ 103bdcaa8d0Smrg sz=SW16(ehdr.e_phentsize); 104bdcaa8d0Smrg num=SW16(ehdr.e_phnum); 105bdcaa8d0Smrg if (0!=sz && 0!=num) { 106bdcaa8d0Smrg orig_pphdr=pphdr=(Elf32_Phdr *)xalloc(sz*num); 107bdcaa8d0Smrg if (!pphdr) { 108bdcaa8d0Smrg ErrorF("RENDITION: Cannot allocate global memory (1)\n"); 109bdcaa8d0Smrg close(fd); 110bdcaa8d0Smrg return -1; 111bdcaa8d0Smrg } 112bdcaa8d0Smrg 113bdcaa8d0Smrg if (seek_and_read_hdr(fd, pphdr, SW32(ehdr.e_phoff), sz, num)) { 114bdcaa8d0Smrg ErrorF("RENDITION: Error reading microcode (1)\n"); 115bdcaa8d0Smrg close(fd); 116bdcaa8d0Smrg return -1; 117bdcaa8d0Smrg } 118bdcaa8d0Smrg 119bdcaa8d0Smrg orig_pshdr=pshdr=(Elf32_Shdr *)0; 120bdcaa8d0Smrg } 121bdcaa8d0Smrg else { 122bdcaa8d0Smrg orig_pphdr=pphdr=(Elf32_Phdr *)0; 123bdcaa8d0Smrg 124bdcaa8d0Smrg /* read in the section header(s) */ 125bdcaa8d0Smrg sz=SW16(ehdr.e_shentsize); 126bdcaa8d0Smrg num=SW16(ehdr.e_shnum); 127bdcaa8d0Smrg if (0!=sz && 0!=num) { 128bdcaa8d0Smrg orig_pshdr=pshdr=(Elf32_Shdr *)xalloc(sz*num); 129bdcaa8d0Smrg if (!pshdr) { 130bdcaa8d0Smrg ErrorF("RENDITION: Cannot allocate global memory (2)\n"); 131bdcaa8d0Smrg close(fd); 132bdcaa8d0Smrg return -1; 133bdcaa8d0Smrg } 134bdcaa8d0Smrg 135bdcaa8d0Smrg if (seek_and_read_hdr(fd, pshdr, SW32(ehdr.e_shoff), sz, num)) { 136bdcaa8d0Smrg ErrorF("RENDITION: Error reading microcode (2)\n"); 137bdcaa8d0Smrg close(fd); 138bdcaa8d0Smrg return -1; 139bdcaa8d0Smrg } 140bdcaa8d0Smrg } 141bdcaa8d0Smrg else 142bdcaa8d0Smrg pshdr=(Elf32_Shdr *)0; 143bdcaa8d0Smrg } 144bdcaa8d0Smrg 145bdcaa8d0Smrg if (pphdr) { 146bdcaa8d0Smrg do { 147bdcaa8d0Smrg if (SW32(pphdr->p_type) == PT_LOAD) 148bdcaa8d0Smrg loadSegment2board(pScreenInfo, fd, pphdr); 149bdcaa8d0Smrg pphdr=(Elf32_Phdr *)(((char *)pphdr)+sz); 150bdcaa8d0Smrg } while (--num); 151bdcaa8d0Smrg xfree(orig_pphdr); 152bdcaa8d0Smrg } 153bdcaa8d0Smrg else { 154bdcaa8d0Smrg do { 155bdcaa8d0Smrg if (SW32(pshdr->sh_size) && (SW32(pshdr->sh_flags) & SHF_ALLOC) 156bdcaa8d0Smrg && ((SW32(pshdr->sh_type)==SHT_PROGBITS) 157bdcaa8d0Smrg || (SW32(pshdr->sh_type)==SHT_NOBITS))) 158bdcaa8d0Smrg loadSection2board(pScreenInfo, fd, pshdr); 159bdcaa8d0Smrg pshdr=(Elf32_Shdr *)(((char *)pshdr)+sz); 160bdcaa8d0Smrg } while (--num) ; 161bdcaa8d0Smrg xfree(orig_pshdr); 162bdcaa8d0Smrg } 163bdcaa8d0Smrg close(fd); 164bdcaa8d0Smrg 165bdcaa8d0Smrg return SW32(ehdr.e_entry); 166bdcaa8d0Smrg} 167bdcaa8d0Smrg 168bdcaa8d0Smrg 169bdcaa8d0Smrg 170bdcaa8d0Smrg/* 171bdcaa8d0Smrg * local functions 172bdcaa8d0Smrg */ 173bdcaa8d0Smrg 174bdcaa8d0Smrgstatic void 175bdcaa8d0SmrgloadSection2board(ScrnInfoPtr pScreenInfo, int fd, Elf32_Shdr *shdr) 176bdcaa8d0Smrg{ 177bdcaa8d0Smrg /* renditionPtr pRendition = RENDITIONPTR(pScreenInfo); */ 178bdcaa8d0Smrg ErrorF("vlib: loadSection2board not implemented yet!\n"); 179bdcaa8d0Smrg} 180bdcaa8d0Smrg 181bdcaa8d0Smrg 182bdcaa8d0Smrg 183bdcaa8d0Smrgstatic void 184bdcaa8d0SmrgloadSegment2board(ScrnInfoPtr pScreenInfo, int fd, Elf32_Phdr *phdr) 185bdcaa8d0Smrg{ 186bdcaa8d0Smrg /* renditionPtr pRendition = RENDITIONPTR(pScreenInfo); */ 187bdcaa8d0Smrg vu8 *data; 188bdcaa8d0Smrg vu32 offset=SW32(phdr->p_offset); 189bdcaa8d0Smrg vu32 size=SW32(phdr->p_filesz); 190bdcaa8d0Smrg vu32 physAddr=SW32(phdr->p_paddr); 191bdcaa8d0Smrg 192bdcaa8d0Smrg if (lseek(fd, offset, SEEK_SET) != offset) { 193bdcaa8d0Smrg ErrorF("RENDITION: Failure in loadSegmentToBoard, offset %lx\n", 194bdcaa8d0Smrg (unsigned long)offset); 195bdcaa8d0Smrg return; 196bdcaa8d0Smrg } 197bdcaa8d0Smrg 198bdcaa8d0Smrg data=(vu8 *)xalloc(size); 199bdcaa8d0Smrg if (NULL == data){ 200bdcaa8d0Smrg ErrorF("RENDITION: GlobalAllocPtr couldn't allocate %lx bytes", 201bdcaa8d0Smrg (unsigned long)size); 202bdcaa8d0Smrg return; 203bdcaa8d0Smrg } 204bdcaa8d0Smrg 205bdcaa8d0Smrg if (read(fd, data, size) != size){ 206bdcaa8d0Smrg ErrorF("RENDITION: verite_readfile Failure, couldn't read %lx bytes ", 207bdcaa8d0Smrg (unsigned long)size); 208bdcaa8d0Smrg return; 209bdcaa8d0Smrg } 210bdcaa8d0Smrg 211bdcaa8d0Smrg mmve(pScreenInfo, size, data, physAddr); 212bdcaa8d0Smrg 213bdcaa8d0Smrg xfree(data); 214bdcaa8d0Smrg} 215bdcaa8d0Smrg 216bdcaa8d0Smrg 217bdcaa8d0Smrg 218bdcaa8d0Smrgstatic int 219bdcaa8d0Smrgseek_and_read_hdr(int fd, void *ptr, long int offset, int size, 220bdcaa8d0Smrg int cnt) 221bdcaa8d0Smrg{ 222bdcaa8d0Smrg if (lseek(fd, offset, SEEK_SET) != offset) 223bdcaa8d0Smrg return 1 ; 224bdcaa8d0Smrg 225bdcaa8d0Smrg if (size*cnt != read(fd, ptr, size*cnt)) 226bdcaa8d0Smrg return 2 ; 227bdcaa8d0Smrg 228bdcaa8d0Smrg return 0 ; 229bdcaa8d0Smrg} 230bdcaa8d0Smrg 231bdcaa8d0Smrg 232bdcaa8d0Smrg 233bdcaa8d0Smrgstatic void 234bdcaa8d0Smrgmmve(ScrnInfoPtr pScreenInfo, vu32 size, vu8 *data, vu32 phys_addr) 235bdcaa8d0Smrg{ 236bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 237bdcaa8d0Smrg vu8 memend; 238bdcaa8d0Smrg vu32 *dataout; 239bdcaa8d0Smrg vu8 *vmb=pRendition->board.vmem_base; 240bdcaa8d0Smrg 241bdcaa8d0Smrg /* swap bytes 3<>0, 2<>1 */ 242bdcaa8d0Smrg memend=verite_in8(pRendition->board.io_base+MEMENDIAN); 243bdcaa8d0Smrg verite_out8(pRendition->board.io_base+MEMENDIAN, MEMENDIAN_END); 244bdcaa8d0Smrg 245bdcaa8d0Smrg dataout=(vu32 *)data; 246bdcaa8d0Smrg 247bdcaa8d0Smrg /* If RISC happends to be running, be sure it is stopped */ 248bdcaa8d0Smrg v1k_stop(pScreenInfo); 249bdcaa8d0Smrg 250bdcaa8d0Smrg while (size > 0) { 251bdcaa8d0Smrg verite_write_memory32(vmb, phys_addr, *dataout); 252bdcaa8d0Smrg phys_addr+=4; 253bdcaa8d0Smrg dataout++; 254bdcaa8d0Smrg size-=4; 255bdcaa8d0Smrg } 256bdcaa8d0Smrg 257bdcaa8d0Smrg verite_out8(pRendition->board.io_base+MEMENDIAN, memend); 258bdcaa8d0Smrg} 259bdcaa8d0Smrg 260bdcaa8d0Smrg/* 261bdcaa8d0Smrg * end of file vloaduc.c 262bdcaa8d0Smrg */ 263