Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / blaze / ui_mem_cmds.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: ui_mem_cmds.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
/*
* Copyright (C) 2001 Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "@(#)1.19 07/11/19 ui_mem_cmds.cc"
#include <sys/types.h>
#include <sys/mman.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <libelf.h>
#include <sys/dkio.h>
#include <sys/dklabel.h>
#include <sys/vtoc.h>
#include "types.h"
#include "mem.h"
#include "system.h"
#include "dr.h"
#include "ui.h"
typedef void* TM_OPAQUE_DATA;
#include "tracemod.h"
#include "blaze_globals.h"
#include "ui_utils.h"
#include "fileutil.h"
///////////////////////////////////////////////////////////////////////
void load_elf64(char *filename, uint64_t base_pa, uint64_t base_va);
static void load_elf64_section(Elf64_Shdr *shdr, Elf_Scn *scn,
uint64_t base_pa, uint64_t base_va);
///////////////////////////////////////////////////////////////////////
extern bool_t schizo_rom_match (uint64_t paddr);
extern bool_t schizo_rom_store (uint32_t cpu_id, uint64_t paddr, uint32_t size, uint64_t *buf);
///////////////////////////////////////////////////////////////////////
int load_cmd(char *cp, void *)
{
char *filename;
char *token;
uint64_t base_pa;
uint64_t base_va;
cp = ui_parsew(cp, &token);
base_pa = strtoll(token, (char**)NULL, 16);
cp = ui_parsew(cp, &filename);
cp = ui_parsew(cp, &token);
base_va = strtoll(token, (char**)NULL, 16);
load_elf64(filename, base_pa, base_va);
return UI_CMD_DONE;
}
void load_elf64(char *filename, uint64_t base_pa, uint64_t base_va)
{
int fd;
Elf *elf;
Elf64_Ehdr *ehdr;
Elf_Scn *scn;
Elf64_Shdr *shdr;
Elf_Data *data;
u_int cnt;
/* Open the input file */
fd = SYSTEM_open(filename, O_RDONLY);
if (fd == -1) {
ui->error("<%s> not found \n", filename);
exit (0);
}
/* Obtain the ELF descriptor */
(void) elf_version(EV_CURRENT);
if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
ui->error("%s\n", elf_errmsg(elf_errno()));
exit(0);
}
/* Obtain the .shstrtab data buffer */
if (((ehdr = elf64_getehdr(elf)) == NULL) ||
((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) ||
((data = elf_getdata(scn, NULL)) == NULL)) {
ui->error("%s\n", elf_errmsg(elf_errno()));
exit(0);
}
/* Traverse input filename, looking for relevant sections */
for (cnt = 1, scn = NULL; scn = elf_nextscn(elf, scn); cnt++) {
if ((shdr = elf64_getshdr(scn)) == NULL) {
ui->error("%s\n", elf_errmsg(elf_errno()));
exit(0);
}
if (strcmp((char *)data->d_buf+shdr->sh_name,
".text") == 0) {
load_elf64_section(shdr, scn, base_pa, base_va);
} else if (strcmp((char *)data->d_buf+shdr->sh_name,
".rodata") == 0) {
load_elf64_section(shdr, scn, base_pa, base_va);
} else if (strcmp((char *)data->d_buf+shdr->sh_name,
".rodata1") == 0) {
load_elf64_section(shdr, scn, base_pa, base_va);
} else if (strcmp((char *)data->d_buf+shdr->sh_name,
".data") == 0) {
load_elf64_section(shdr, scn, base_pa, base_va);
} else if (strcmp((char *)data->d_buf+shdr->sh_name,
".data1") == 0) {
load_elf64_section(shdr, scn, base_pa, base_va);
}
}
elf_end(elf);
close(fd);
}
///////////////////////////////////////////////////////////////
static void load_elf64_section(Elf64_Shdr *shdr, Elf_Scn *scn,
uint64_t base_pa, uint64_t base_va)
{
uint64_t offset;
Elf_Data *data;
if ((data = elf_getdata(scn, NULL)) == NULL) {
ui->error("%s\n", elf_errmsg(elf_errno()));
exit(0);
}
offset = shdr->sh_addr - base_va;
memwrite8u_blk_nl(mm1, base_pa + offset, (const unsigned char *)data->d_buf,
data->d_size);
}
///////////////////////////////////////////////////////////////
#ifdef NIAGARA
bool_t load_mem_image(const char * file)
{
FILE * fp = fopen (file, "r");
if (fp == NULL) {
ui->perror(file);
return FALSE;
}
char s[512];
uint64_t pa = 0;
while(fgets(s, 512, fp) != NULL) {
if (s[0] == '@') {
pa = strtoull(s+1, NULL, 16);
continue;
}
char * last_s;
char * token = strtok_r(s, " \t\n", &last_s);
if (token == NULL) continue;
do {
uint64_t v = strtoull(token, NULL, 16);
if (schizo_rom_match(pa)) {
schizo_rom_store (0, pa, 8, &v);
} else {
memwrite64u_nl(mm1, pa, v);
}
pa += 8;
token = strtok_r(NULL, " \t\n", &last_s);
} while(token != NULL);
}
return true;
} // bool_t load_mem_image(char * file)
bool_t load_bin_image (char *file, uint64_t addr, uint64_t size, uint64_t seg_size, int zero_pad, int create_lbl)
{
bool_t is_ni_rom = FALSE;
uint64_t tmppa, buf=0;
int bytes_read =0;
is_ni_rom = schizo_rom_match (addr);
if (is_ni_rom) { // If it is rom, it is special
ui->output("ni rom: addr = 0x%llx, size = 0x%llx, seg_size = 0x%llx\n", addr, size, seg_size);
buf = 0;
tmppa = addr;
for (int i= 0; i<seg_size/8; i++) {
schizo_rom_store (0, tmppa, 8, &buf);
tmppa +=8;
}
FILE * Ffp = fopen (file, "r");
for (int i=0; i< size/8; i++) {
bytes_read += fread (&buf, sizeof(uint64_t), 1, Ffp);
schizo_rom_store (0, addr, 8, &buf);
addr +=8;
}
buf = 0;
while (size - bytes_read++) {
schizo_rom_store (0, addr++, 1, &buf);
}
ui->output("total bytes to rom_store 0x%x\n", bytes_read);
} else /* not ni rom */ {
FILE * fp = fopen (file, "r");
char s[512]; // char *ps;
uint64_t pa, buf, last_pa = 0;
uint8_t *buf8;
int ret_size = 0;
int bytes_read =0;
AddrPair *ap = NULL;
memT *msp;
if (fp == NULL) {
ui->perror (file);
return FALSE;
}
buf8 = (uint8_t *)malloc(size);
assert(buf8);
bytes_read += fread(buf8, sizeof(uint8_t), size, fp);
memwrite8u_blk_nl(mm1, addr, (const unsigned char *)buf8, (int)size);
if (create_lbl) {
ui->error("create_lbl not supported in this version. Please use v4.49 or prior\n");
exit(1);
}
} // ni-rom or phys RAM?
}
#endif //// NIAGARA