aboutsummaryrefslogtreecommitdiff
path: root/devkit/cacheracer.h
blob: 7e9aa8cb05359be5dcf6832cc46b41bef51c7fae (plain)
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