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
|
#ifndef CACHERACER_H
#define CACHERACER_H
void __start(int core_id, unsigned char payload);
/** Memory Layout
*
* Memory layout differs from CS 3410. Here, we have 64MB of memory,
* addressable in the range 0x00000000 to 0x04000000. Each player sees
* their half of memory as starting at 0x00000000. Player 2 is mapped
* in reverse, i.e. their 0x00000000 is Player 1's 0x03FFFFFC. Memory
* is byte-addressed.
*
* The linker script places code beginning at 0x400. Up to 0x00100000
* is read-only memory containing game data. Beginning at 0x00100000
* are the stacks, spaced 1 MB apart. Thus the layout is
*
* 0x00000000 - 0x00100000: Read-only memory
* 0x00100000 - 0x02000000: Your half of read-write memory
* TODO: are the below addresses correct?
* 0x02000000 - 0x03EFFFFC: Opponent's half of read-write memory
* 0x03EFFFFC - 0x04000000: Opponent's read-only memory
*/
#define PLAYER_RO_SEGMENT_SIZE 0x00100000
#define PLAYER_STACK_SIZE 0x00100000
#define HOME_START 0x00000000
#define HOME_RW_START PLAYER_RO_SEGMENT_SIZE
#define HOME_DATA_START (PLAYER_RO_SEGMENT_SIZE + 4 * PLAYER_STACK_SIZE)
#define HOME_RW ((void *) HOME_RW_START)
#define HOME_DATA ((void *) HOME_DATA_START)
/** Cache Layout
*
* Each team is given a shared direct-mapped cache with 2 blocks; each
* block contains 64 words (256 bytes) of memory.
*/
#define CACHE_NUM_BLOCKS 2
/** Definitions of global data */
#define TAUNT_SIZE 228
struct player_status {
unsigned int cache_tags[CACHE_NUM_BLOCKS];
unsigned int cache_fetch_tags[CACHE_NUM_BLOCKS];
unsigned int cycles_left;
unsigned int score;
unsigned char payload;
unsigned char pad0, pad1, pad2;
signed char taunt[TAUNT_SIZE];
} __attribute__ ((packed));
/** Pointers to global structures */
#define HOME_STATUS ((struct player_status*) (HOME_RW_START - sizeof(struct player_status)))
__attribute__ ((unused, noinline)) static void prints(char *fmt) {
__asm__ __volatile__ (
"ADDI a1, %0, 0\n\t"
"ADDI a0, zero, 22\n\t"
"SCALL\n\t"
:
: "r" (fmt)
);
}
__attribute__ ((unused, noinline)) static void printi(int i) {
__asm__ __volatile__ (
"ADDI a1, %0, 0\n\t"
"ADDI a0, zero, 23\n\t"
"SCALL\n\t"
:
: "r" (i)
);
}
__attribute__ ((unused, noinline)) static void sneak_attack() {
__asm__ __volatile__ (
"ADDI a0, zero, 24\n\t"
"SCALL"
);
}
#endif
|