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 */