Copy some software code from the original Milkymist SoC.
[litex.git] / software / libbase / system.c
1 /*
2 * Milkymist SoC (Software)
3 * Copyright (C) 2007, 2008, 2009, 2012 Sebastien Bourdeauducq
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <irq.h>
19 #include <uart.h>
20 #include <hw/sysctl.h>
21
22 #include <system.h>
23
24 void flush_cpu_icache(void)
25 {
26 asm volatile(
27 "wcsr ICC, r0\n"
28 "nop\n"
29 "nop\n"
30 "nop\n"
31 "nop\n"
32 );
33 }
34
35 void flush_cpu_dcache(void)
36 {
37 asm volatile(
38 "wcsr DCC, r0\n"
39 "nop\n"
40 );
41 }
42
43 __attribute__((noreturn)) void reboot(void)
44 {
45 uart_sync();
46 irq_setmask(0);
47 irq_enable(0);
48 CSR_SYSTEM_ID = 1; /* Writing to CSR_SYSTEM_ID causes a system reset */
49 while(1);
50 }
51
52 static void icap_write(int val, unsigned int w)
53 {
54 while(!(CSR_ICAP & ICAP_READY));
55 if(!val)
56 w |= ICAP_CE|ICAP_WRITE;
57 CSR_ICAP = w;
58 }
59
60 __attribute__((noreturn)) void reconf(void)
61 {
62 uart_sync();
63 irq_setmask(0);
64 irq_enable(0);
65 icap_write(0, 0xffff); /* dummy word */
66 icap_write(0, 0xffff); /* dummy word */
67 icap_write(0, 0xffff); /* dummy word */
68 icap_write(0, 0xffff); /* dummy word */
69 icap_write(1, 0xaa99); /* sync word part 1 */
70 icap_write(1, 0x5566); /* sync word part 2 */
71 icap_write(1, 0x30a1); /* write to command register */
72 icap_write(1, 0x0000); /* null command */
73 icap_write(1, 0x30a1); /* write to command register */
74 icap_write(1, 0x000e); /* reboot command */
75 icap_write(1, 0x2000); /* NOP */
76 icap_write(1, 0x2000); /* NOP */
77 icap_write(1, 0x2000); /* NOP */
78 icap_write(1, 0x2000); /* NOP */
79 icap_write(0, 0x1111); /* NULL */
80 icap_write(0, 0xffff); /* dummy word */
81 while(1);
82 }