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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/*
* (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
* (C) Copyright 2011, Julius Baxter <julius@opencores.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/system.h>
#include <asm/openrisc_exc.h>
static volatile int illegal_instruction;
static void illegal_instruction_handler(void)
{
ulong *epcr = (ulong *)mfspr(SPR_EPCR_BASE);
/* skip over the illegal instruction */
mtspr(SPR_EPCR_BASE, (ulong)(++epcr));
illegal_instruction = 1;
}
static void checkinstructions(void)
{
ulong ra = 1, rb = 1, rc;
exception_install_handler(EXC_ILLEGAL_INSTR,
illegal_instruction_handler);
illegal_instruction = 0;
asm volatile("l.mul %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
printf(" Hardware multiplier: %s\n",
illegal_instruction ? "no" : "yes");
illegal_instruction = 0;
asm volatile("l.div %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
printf(" Hardware divider: %s\n",
illegal_instruction ? "no" : "yes");
exception_free_handler(EXC_ILLEGAL_INSTR);
}
int checkcpu(void)
{
ulong upr = mfspr(SPR_UPR);
ulong vr = mfspr(SPR_VR);
ulong iccfgr = mfspr(SPR_ICCFGR);
ulong dccfgr = mfspr(SPR_DCCFGR);
ulong immucfgr = mfspr(SPR_IMMUCFGR);
ulong dmmucfgr = mfspr(SPR_DMMUCFGR);
ulong cpucfgr = mfspr(SPR_CPUCFGR);
uint ver = (vr & SPR_VR_VER) >> 24;
uint rev = vr & SPR_VR_REV;
uint block_size;
uint ways;
uint sets;
printf("CPU: OpenRISC-%x00 (rev %d) @ %d MHz\n",
ver, rev, (CONFIG_SYS_CLK_FREQ / 1000000));
if (upr & SPR_UPR_DCP) {
block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
printf(" D-Cache: %d bytes, %d bytes/line, %d way(s)\n",
checkdcache(), block_size, ways);
} else {
printf(" D-Cache: no\n");
}
if (upr & SPR_UPR_ICP) {
block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
printf(" I-Cache: %d bytes, %d bytes/line, %d way(s)\n",
checkicache(), block_size, ways);
} else {
printf(" I-Cache: no\n");
}
if (upr & SPR_UPR_DMP) {
sets = 1 << ((dmmucfgr & SPR_DMMUCFGR_NTS) >> 2);
ways = (dmmucfgr & SPR_DMMUCFGR_NTW) + 1;
printf(" DMMU: %d sets, %d way(s)\n",
sets, ways);
} else {
printf(" DMMU: no\n");
}
if (upr & SPR_UPR_IMP) {
sets = 1 << ((immucfgr & SPR_IMMUCFGR_NTS) >> 2);
ways = (immucfgr & SPR_IMMUCFGR_NTW) + 1;
printf(" IMMU: %d sets, %d way(s)\n",
sets, ways);
} else {
printf(" IMMU: no\n");
}
printf(" MAC unit: %s\n",
(upr & SPR_UPR_MP) ? "yes" : "no");
printf(" Debug unit: %s\n",
(upr & SPR_UPR_DUP) ? "yes" : "no");
printf(" Performance counters: %s\n",
(upr & SPR_UPR_PCUP) ? "yes" : "no");
printf(" Power management: %s\n",
(upr & SPR_UPR_PMP) ? "yes" : "no");
printf(" Interrupt controller: %s\n",
(upr & SPR_UPR_PICP) ? "yes" : "no");
printf(" Timer: %s\n",
(upr & SPR_UPR_TTP) ? "yes" : "no");
printf(" Custom unit(s): %s\n",
(upr & SPR_UPR_CUP) ? "yes" : "no");
printf(" Supported instructions:\n");
printf(" ORBIS32: %s\n",
(cpucfgr & SPR_CPUCFGR_OB32S) ? "yes" : "no");
printf(" ORBIS64: %s\n",
(cpucfgr & SPR_CPUCFGR_OB64S) ? "yes" : "no");
printf(" ORFPX32: %s\n",
(cpucfgr & SPR_CPUCFGR_OF32S) ? "yes" : "no");
printf(" ORFPX64: %s\n",
(cpucfgr & SPR_CPUCFGR_OF64S) ? "yes" : "no");
checkinstructions();
return 0;
}
int cleanup_before_linux(void)
{
disable_interrupts();
return 0;
}
extern void __reset(void);
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
disable_interrupts();
/* Code the jump to __reset here as the compiler is prone to
emitting a bad jump instruction if the function is in flash */
__asm__("l.movhi r1,hi(__reset); \
l.ori r1,r1,lo(__reset); \
l.jr r1");
/* not reached, __reset does not return */
return 0;
}
|