#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
}
#endif
#include "physmem.hh"
#include "rcs_print.hh"
PHYSMEM_HANDLE::PHYSMEM_HANDLE()
{
size = 0;
offset = 0;
temp_buf = NULL;
local_address = (LOCAL_ADDRESS_TYPE) NULL;
physical_address = 0;
using_bit3 = 0;
isvalid = 1;
total_bytes_moved = 0;
enable_byte_counting = 0;
}
PHYSMEM_HANDLE::PHYSMEM_HANDLE(unsigned long _physical_address,
long _address_code, long _size)
{
temp_buf = NULL;
physical_address = _physical_address;
size = _size;
address_code = _address_code;
local_address = (LOCAL_ADDRESS_TYPE) NULL;
isvalid = 1;
offset = 0;
using_bit3 = 0;
if (0 == physical_address) {
local_address = (LOCAL_ADDRESS_TYPE) NULL;
return;
}
local_address = (LOCAL_ADDRESS_TYPE) physical_address;
}
PHYSMEM_HANDLE::~PHYSMEM_HANDLE()
{
}
void
PHYSMEM_HANDLE::set_to_ptr(void *_ptr, long _size)
{
local_address = (LOCAL_ADDRESS_TYPE) _ptr;
size = _size;
offset = 0;
}
static int physmem_read_local_address_is_null_error_print_count = 0;
int PHYSMEM_HANDLE::read(void *_to, long _read_size)
{
if (NULL == _to) {
rcs_print_error("PHYSMEM_HANDLE::read _to = NULL.\n");
return (-1);
}
if (_read_size + offset > size || offset < 0) {
rcs_print_error
("PHYSMEM_HANDLE: Can't read %ld bytes at offset %ld from buffer of size %ld.\n",
_read_size, offset, size);
return (-1);
}
if (enable_byte_counting) {
total_bytes_moved += _read_size;
}
if (NULL != local_address) {
char *from;
from = ((char *) local_address) + offset;
if (_read_size == 2) {
short *sfrom = (short *) from;
short sval;
sval = *sfrom;
short *sto = (short *) _to;
*sto = sval;
} else {
memcpy(_to, from, _read_size);
}
return (0);
}
if (!(physmem_read_local_address_is_null_error_print_count % 100000)) {
rcs_print_error
("PHYSMEM_HANDLE: Cannot read from physical memory when local address is NULL.\n");
rcs_print_error("(This error has occurred %d times.)\n",
physmem_read_local_address_is_null_error_print_count + 1);
}
physmem_read_local_address_is_null_error_print_count++;
return (-1);
}
static int physmem_write_local_address_is_null_error_print_count = 0;
int PHYSMEM_HANDLE::write(void *_from, long _write_size)
{
if (NULL == _from) {
rcs_print_error("PHYSMEM_HANDLE:write _from = NULL\n");
return -1;
}
if (_write_size + offset > size || offset < 0) {
rcs_print_error
("PHYSMEM_HANDLE: Can't write %ld bytes at offset %ld from buffer of size %ld.\n",
_write_size, offset, size);
return (-1);
}
if (enable_byte_counting) {
total_bytes_moved += _write_size;
}
if (NULL != local_address) {
char *to;
to = ((char *) local_address) + offset;
if (_write_size == 2) {
short *sto = (short *) to;
short sval = *(short *) _from;
*sto = sval;
} else {
memcpy(to, _from, _write_size);
}
return (0);
}
if (!(physmem_write_local_address_is_null_error_print_count % 100000)) {
rcs_print_error
("PHYSMEM_HANDLE: Cannot write to physical memory when local address is NULL.\n");
rcs_print_error("(This error has occurred %d times.)\n",
physmem_write_local_address_is_null_error_print_count + 1);
}
physmem_write_local_address_is_null_error_print_count++;
return (-1);
}
void PHYSMEM_HANDLE::memsetf(long _memset_offset, char _byte,
long _memset_size)
{
if (_memset_size + _memset_offset > size) {
return;
}
if (NULL != local_address) {
char *temp_addr;
temp_addr = ((char *) local_address) + _memset_offset;
memset(temp_addr, _byte, _memset_size);
return;
} else {
if (NULL == temp_buf) {
temp_buf = (char *) malloc(size);
}
if (NULL != temp_buf) {
if (_memset_size + _memset_offset <= size) {
memset(temp_buf, _byte, _memset_size);
unsigned long old_offset;
old_offset = offset;
offset = _memset_offset;
write(temp_buf, _memset_size);
offset = old_offset;
} else {
memset(temp_buf, _byte, size - _memset_offset);
unsigned long old_offset;
old_offset = offset;
offset = _memset_offset;
write(temp_buf, size - offset);
offset = old_offset;
}
}
}
}
int PHYSMEM_HANDLE::clear_memory()
{
if (NULL != local_address) {
memset(local_address, 0, size);
return (0);
} else {
if (NULL == temp_buf) {
temp_buf = (char *) malloc(size);
}
if (NULL == temp_buf) {
return (-1);
}
memset(temp_buf, 0, size);
unsigned long old_offset;
old_offset = offset;
offset = 0;
if (-1 == write(temp_buf, size)) {
offset = old_offset;
return (-1);
}
offset = old_offset;
}
return (0);
}
int PHYSMEM_HANDLE::valid()
{
return isvalid;
}