1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/* This file is an implementation of the functions
defined in mips_mem.h. It is designed to be
linked against something which needs an implementation
of a RAM device following that memory mapping
interface.
*/
#include "mips_mem.h"
#include <stdio.h>
#include <stdlib.h>
struct mips_mem_provider
{
uint32_t length;
uint32_t blockSize;
uint8_t *data;
};
extern "C" mips_mem_h mips_mem_create_ram(
uint32_t cbMem, //!< Total number of bytes of ram
uint32_t blockSize //!< Granularity in bytes
){
uint8_t *data=(uint8_t*)malloc(cbMem);
if(data==0)
return 0;
struct mips_mem_provider *mem=(struct mips_mem_provider*)malloc(sizeof(struct mips_mem_provider));
if(mem==0){
free(data);
return 0;
}
mem->length=cbMem;
mem->blockSize=blockSize;
mem->data=data;
return mem;
}
static mips_error mips_mem_read_write(
bool write,
mips_mem_h mem,
uint32_t address,
uint32_t length,
uint8_t *dataOut
)
{
if(mem==0)
return mips_ErrorInvalidHandle;
if(0 != (address%mem->blockSize) ){
return mips_ExceptionInvalidAlignment;
}
if(0 != ((address+length)%mem->blockSize)){
return mips_ExceptionInvalidAlignment;
}
if((address+length) > mem->length){ // A subtle bug here, maybe?
return mips_ExceptionInvalidAddress;
}
if(write){
for(unsigned i=0; i<length; i++){
mem->data[address+i]=dataOut[i];
}
}else{
for(unsigned i=0; i<length; i++){
dataOut[i]=mem->data[address+i];
}
}
return mips_Success;
}
mips_error mips_mem_read(
mips_mem_h mem, //!< Handle to target memory
uint32_t address, //!< Byte address to start transaction at
uint32_t length, //!< Number of bytes to transfer
uint8_t *dataOut //!< Receives the target bytes
)
{
return mips_mem_read_write(
false, // we want to read
mem,
address,
length,
dataOut
);
}
mips_error mips_mem_write(
mips_mem_h mem, //! Handle to target memory
uint32_t address, //! Byte address to start transaction at
uint32_t length, //! Number of bytes to transfer
const uint8_t *dataIn //! Receives the target bytes
)
{
return mips_mem_read_write(
true, // we want to write
mem,
address,
length,
(uint8_t*)dataIn
);
}
void mips_mem_free(mips_mem_h mem)
{
if(mem){
free(mem->data);
mem->data=0;
free(mem);
}
}
|