2 * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3 * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/system.h>
10 #include <asm/openrisc_exc.h>
12 static volatile int illegal_instruction
;
14 static void illegal_instruction_handler(void)
16 ulong
*epcr
= (ulong
*)mfspr(SPR_EPCR_BASE
);
18 /* skip over the illegal instruction */
19 mtspr(SPR_EPCR_BASE
, (ulong
)(++epcr
));
20 illegal_instruction
= 1;
23 static void checkinstructions(void)
25 ulong ra
= 1, rb
= 1, rc
;
27 exception_install_handler(EXC_ILLEGAL_INSTR
,
28 illegal_instruction_handler
);
30 illegal_instruction
= 0;
31 asm volatile("l.mul %0,%1,%2" : "=r" (rc
) : "r" (ra
), "r" (rb
));
32 printf(" Hardware multiplier: %s\n",
33 illegal_instruction
? "no" : "yes");
35 illegal_instruction
= 0;
36 asm volatile("l.div %0,%1,%2" : "=r" (rc
) : "r" (ra
), "r" (rb
));
37 printf(" Hardware divider: %s\n",
38 illegal_instruction
? "no" : "yes");
40 exception_free_handler(EXC_ILLEGAL_INSTR
);
45 ulong upr
= mfspr(SPR_UPR
);
46 ulong vr
= mfspr(SPR_VR
);
47 ulong iccfgr
= mfspr(SPR_ICCFGR
);
48 ulong dccfgr
= mfspr(SPR_DCCFGR
);
49 ulong immucfgr
= mfspr(SPR_IMMUCFGR
);
50 ulong dmmucfgr
= mfspr(SPR_DMMUCFGR
);
51 ulong cpucfgr
= mfspr(SPR_CPUCFGR
);
52 uint ver
= (vr
& SPR_VR_VER
) >> 24;
53 uint rev
= vr
& SPR_VR_REV
;
58 printf("CPU: OpenRISC-%x00 (rev %d) @ %d MHz\n",
59 ver
, rev
, (CONFIG_SYS_CLK_FREQ
/ 1000000));
61 if (upr
& SPR_UPR_DCP
) {
62 block_size
= (dccfgr
& SPR_DCCFGR_CBS
) ? 32 : 16;
63 ways
= 1 << (dccfgr
& SPR_DCCFGR_NCW
);
64 printf(" D-Cache: %d bytes, %d bytes/line, %d way(s)\n",
65 checkdcache(), block_size
, ways
);
67 printf(" D-Cache: no\n");
70 if (upr
& SPR_UPR_ICP
) {
71 block_size
= (iccfgr
& SPR_ICCFGR_CBS
) ? 32 : 16;
72 ways
= 1 << (iccfgr
& SPR_ICCFGR_NCW
);
73 printf(" I-Cache: %d bytes, %d bytes/line, %d way(s)\n",
74 checkicache(), block_size
, ways
);
76 printf(" I-Cache: no\n");
79 if (upr
& SPR_UPR_DMP
) {
80 sets
= 1 << ((dmmucfgr
& SPR_DMMUCFGR_NTS
) >> 2);
81 ways
= (dmmucfgr
& SPR_DMMUCFGR_NTW
) + 1;
82 printf(" DMMU: %d sets, %d way(s)\n",
85 printf(" DMMU: no\n");
88 if (upr
& SPR_UPR_IMP
) {
89 sets
= 1 << ((immucfgr
& SPR_IMMUCFGR_NTS
) >> 2);
90 ways
= (immucfgr
& SPR_IMMUCFGR_NTW
) + 1;
91 printf(" IMMU: %d sets, %d way(s)\n",
94 printf(" IMMU: no\n");
97 printf(" MAC unit: %s\n",
98 (upr
& SPR_UPR_MP
) ? "yes" : "no");
99 printf(" Debug unit: %s\n",
100 (upr
& SPR_UPR_DUP
) ? "yes" : "no");
101 printf(" Performance counters: %s\n",
102 (upr
& SPR_UPR_PCUP
) ? "yes" : "no");
103 printf(" Power management: %s\n",
104 (upr
& SPR_UPR_PMP
) ? "yes" : "no");
105 printf(" Interrupt controller: %s\n",
106 (upr
& SPR_UPR_PICP
) ? "yes" : "no");
107 printf(" Timer: %s\n",
108 (upr
& SPR_UPR_TTP
) ? "yes" : "no");
109 printf(" Custom unit(s): %s\n",
110 (upr
& SPR_UPR_CUP
) ? "yes" : "no");
112 printf(" Supported instructions:\n");
113 printf(" ORBIS32: %s\n",
114 (cpucfgr
& SPR_CPUCFGR_OB32S
) ? "yes" : "no");
115 printf(" ORBIS64: %s\n",
116 (cpucfgr
& SPR_CPUCFGR_OB64S
) ? "yes" : "no");
117 printf(" ORFPX32: %s\n",
118 (cpucfgr
& SPR_CPUCFGR_OF32S
) ? "yes" : "no");
119 printf(" ORFPX64: %s\n",
120 (cpucfgr
& SPR_CPUCFGR_OF64S
) ? "yes" : "no");
127 int cleanup_before_linux(void)
129 disable_interrupts();
133 extern void __reset(void);
135 int do_reset(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
137 disable_interrupts();
138 /* Code the jump to __reset here as the compiler is prone to
139 emitting a bad jump instruction if the function is in flash */
140 __asm__("l.movhi r1,hi(__reset); \
141 l.ori r1,r1,lo(__reset); \
143 /* not reached, __reset does not return */