#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 /** Traps */ #define WRITE_TRAP 0xE0 #define AREA_TRAP 0xE4 /** 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