/* Sample test code for 34K Cores
*/
/*
Unpublished work (c) MIPS Technologies, Inc. All rights reserved. Unpublished rights reserved
under the copyright laws of the United States of America and other countries.
This code is confidential and proprietary to MIPS Technologies, Inc. ("MIPS Technologies") and
may be disclosed only as permitted in writing by MIPS Technologies or an authorized third party.
Any copying, reproducing, modifying, use or disclosure of this code (in whole or in part) that is
not expressly permitted in writing by MIPS Technologies or an authorized third party is strictly
prohibited. At a minimum, this code is protected under trade secret, unfair competition, and
copyright laws. Violations thereof may result in criminal penalties and fines.
MIPS Technologies reserves the right to change this code to improve function, design or
otherwise. MIPS Technologies does not assume any liability arising out of the application or use
of this code, or of any error or omission in such code. Any warranties, whether express, statutory,
implied or otherwise, including but not limited to the implied warranties of merchantability or
fitness for a particular purpose, are excluded. Except as expressly provided in any written license
agreement from MIPS Technologies or an authorized third party, the furnishing of this code does
not give recipient any license to any intellectual property rights, including any patent rights, that
cover this code.
This code shall not be exported, reexported, transferred, or released, directly or indirectly, in
violation of the law of any country or international law, regulation, treaty, Executive Order,
statute, amendments or supplements thereto. Should a conflict arise regarding the export,
reexport, transfer, or release of this code, the laws of the United States of America shall be
the governing law.
This code may only be disclosed to the United States government ("Government"), or to
Government users, with prior written consent from MIPS Technologies or an authorized third
party. This code constitutes one or more of the following: commercial computer software,
commercial computer software documentation or other commercial items. If the user of this
code, or any related documentation of any kind, including related technical data or manuals, is an
agency, department, or other entity of the Government, the use, duplication, reproduction, release,
modification, disclosure, or transfer of this code, or any related documentation of any kind, is
restricted in accordance with Federal Acquisition Regulation 12.212 for civilian agencies and
Defense Federal Acquisition Regulation Supplement 227.7202 for military agencies. The use of
this code by the Government is further restricted in accordance with the terms of the license
agreement(s) and/or applicable contract terms and conditions covering this code from MIPS
Technologies or an authorized third party.
*/
// Terminology
// VPE: (virtual processing element): Core functionality necessary to support privileged execution (OS.)
// TC: (thread context): Core functionality necessary to support a thread of execution.
// CPU: A core vpe/tc pair.
#include <mips/m32c0.h>
// Defines
#define MALTA_CHAR(index) *((volatile unsigned int*) (0xbf000418 + ((index) * 8)))
// Global variables.
// volatile unsigned int rom_start, ram_start, ram_end;
volatile int ready[8] ;
volatile int boot_count[8] = { 1, 2, 3, 4, 5, 6, 7, 8};
volatile unsigned int *rom_start, ram_start, ram_end;
// Global variables initialized in the assembler
// extern unsigned int rom_start, ram_start, ram_end;
#ifdef SECONDCOPY
int copy_rom_2_spram();
#endif
int do_display(unsigned int);
//
// main(): Synchronized run of shared test code coordinated by cpu0.
//
int main(unsigned int vpe_num, unsigned int num_vpe_this_core) {
int i, j, k ;
int num_cpus = 0 ;
int temp;
// End timing of boot for this "cpu".
asm volatile ("mfc0 %[temp], $9": [temp] "=r"(temp) :) ;
boot_count[vpe_num] = temp ;
// VPE0 synchronizes test code execution.
if (vpe_num == 0) {
#ifdef SECONDCOPY
copy_rom_2_spram();
#endif
// Wait for other VPEs to indicate they are ready.
for (i = 1; i < num_vpe_this_core; i++) {
MALTA_CHAR(vpe_num) = 'W' ; // 'W' for Waiting.
while (!ready[i]) ; // Busy wait for all VPEs to be ready.
}
} else {
// Other VPEs indicate ready and wait...
MALTA_CHAR(vpe_num) = 'r' ; // display 'r' for ready.
ready[vpe_num] = 1 ;
}
// Put test code here:
MALTA_CHAR(vpe_num) = 't' ; // 't' for test.
do_display(vpe_num);
return 0 ;
}
#ifdef SECONDCOPY
#define CACHE_OP(op,addr) \
__asm__ volatile( \
"cache %0,0(%1) \n" \
: \
:"i"(op),"r"((unsigned char*)(addr)))
int copy_rom_2_spram(){
unsigned int data_word, config0, spram_index, errctl, errctl_save;
// now start the copy
// rom_start, ram_start, ram_end are initialized in common/copy_c2_SPram.S to
// address defines in the linker file
// rom_start is the starting code address in ROM
// ram_start is the first instruction address in ram where the code should be copied to
// ram_end is the end instruction address of the code section in ram
// Need to compute the position within the ISPram to write first instructions to
// Here it is assumed that the code starts at the first location of ISPram
// add s1, zero, zero
spram_index = (ram_start & ~0xf0000000);
// # Set err control register SPR bit so cache instructions will
// # be directed to the Scratch Pad registers
// mfc0 s0_save_C0_ERRCTL, C0_ERRCTL
errctl = _m32c0_mfc0(C0_ERRCTL, 0);
// move s1, s0_save_C0_ERRCTL # make copy so we can restore C0_ERRCTL
errctl_save = errctl;
// ins s1, v0_all_ones, 28, 1
errctl = (errctl | (1 << 28));
// mtc0 s1,C0_ERRCTL
_m32c0_mtc0(C0_ERRCTL, 0, errctl);
// get endian mode bit 15 of the config0 register already in $8
// ext v1, v1, 15, 1
// blez v1, next_Iram_wordLE
// nop
config0 = mips32_getconfig0();
if((config0 | CFG0_BE) == config0) {
// bne ram_start, ram_end, next_Iram_wordBE
while(ram_start < ram_end){
// next_Iram_wordBE:
// lw data_word, 0(rom_start)
data_word = *rom_start;
// mtc0 data_word,C0_DATAHI
_m32c0_mtc0(C0_TAGHI, 1, data_word);
// addiu rom_start, 4
rom_start += 1;
// lw data_word, 0(rom_start)
data_word = *rom_start;
// mtc0 data_word, C0_DATALO
_m32c0_mtc0(C0_TAGLO, 1, data_word);
// cache 0xc,0(spram_index)
CACHE_OP(0xc, spram_index);
// addiu spram_index, 8
spram_index += 8;
// addiu ram_start, 8
ram_start += 8;
// addiu rom_start, 4
rom_start += 1;
}
}
else {
// bne ram_start, ram_end, next_Iram_wordBE
while(ram_start < ram_end){
// next_Iram_wordLE:
// lw data_word, 0(rom_start)
data_word = *rom_start;
// mtc0 data_word,C0_DATALO
_m32c0_mtc0(C0_TAGLO, 1, data_word);
// addiu rom_start, 4
rom_start += 1;
// lw data_word, 0(rom_start)
data_word = *rom_start;
// mtc0 data_word, C0_DATAHI
_m32c0_mtc0(C0_TAGHI, 1, data_word);
// cache 0xc,0(spram_index)
CACHE_OP(0xc, spram_index);
// addiu spram_index, 8
spram_index += 8;
// addiu ram_start, 8
ram_start += 8;
// addiu rom_start, 4
rom_start += 1;
}
}
// # restore C0_ERRCTL
// mtc0 s0_save_C0_ERRCTL,C0_ERRCTL
_m32c0_mtc0(C0_ERRCTL, 0, errctl_save);
return(1);
}
#endif