aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32')
-rw-r--r--arch/cris/arch-v32/lib/nand_init.S178
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.c103
-rw-r--r--arch/cris/arch-v32/mach-a3/vcs_hook.h58
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.c100
-rw-r--r--arch/cris/arch-v32/mach-fs/vcs_hook.h42
5 files changed, 481 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/lib/nand_init.S b/arch/cris/arch-v32/lib/nand_init.S
new file mode 100644
index 00000000000..d671fed451c
--- /dev/null
+++ b/arch/cris/arch-v32/lib/nand_init.S
@@ -0,0 +1,178 @@
1##=============================================================================
2##
3## nand_init.S
4##
5## The bootrom copies data from the NAND flash to the internal RAM but
6## due to a bug/feature we can only trust the 256 first bytes. So this
7## code copies more data from NAND flash to internal RAM. Obvioulsy this
8## code must fit in the first 256 bytes so alter with care.
9##
10## Some notes about the bug/feature for future reference:
11## The bootrom copies the first 127 KB from NAND flash to internal
12## memory. The problem is that it does a bytewise copy. NAND flashes
13## does autoincrement on the address so for a 16-bite device each
14## read/write increases the address by two. So the copy loop in the
15## bootrom will discard every second byte. This is solved by inserting
16## zeroes in every second byte in the first erase block.
17##
18## The bootrom also incorrectly assumes that it can read the flash
19## linear with only one read command but the flash will actually
20## switch between normal area and spare area if you do that so we
21## can't trust more than the first 256 bytes.
22##
23##=============================================================================
24
25#include <arch/hwregs/asm/reg_map_asm.h>
26#include <arch/hwregs/asm/gio_defs_asm.h>
27#include <arch/hwregs/asm/pinmux_defs_asm.h>
28#include <arch/hwregs/asm/bif_core_defs_asm.h>
29#include <arch/hwregs/asm/config_defs_asm.h>
30
31;; There are 8-bit NAND flashes and 16-bit NAND flashes.
32;; We need to treat them slightly different.
33#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
34#define PAGE_SIZE 256
35#else
36#error 2
37#define PAGE_SIZE 512
38#endif
39#define ERASE_BLOCK 16384
40
41;; GPIO pins connected to NAND flash
42#define CE 4
43#define CLE 5
44#define ALE 6
45#define BY 7
46
47;; Address space for NAND flash
48#define NAND_RD_ADDR 0x90000000
49#define NAND_WR_ADDR 0x94000000
50
51#define READ_CMD 0x00
52
53;; Readability macros
54#define CSP_MASK \
55 REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
56 REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
57#define CSP_VAL \
58 REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
59 REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
60
61;;----------------------------------------------------------------------------
62;; Macros to set/clear GPIO bits
63
64.macro SET x
65 or.b (1<<\x),$r9
66 move.d $r9, [$r2]
67.endm
68
69.macro CLR x
70 and.b ~(1<<\x),$r9
71 move.d $r9, [$r2]
72.endm
73
74;;----------------------------------------------------------------------------
75
76nand_boot:
77 ;; Check if nand boot was selected
78 move.d REG_ADDR(config, regi_config, r_bootsel), $r0
79 move.d [$r0], $r0
80 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
81 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
82 bne normal_boot ; No NAND boot
83 nop
84
85copy_nand_to_ram:
86 ;; copy_nand_to_ram
87 ;; Arguments
88 ;; r10 - destination
89 ;; r11 - source offset
90 ;; r12 - size
91 ;; r13 - Address to jump to after completion
92 ;; Note : r10-r12 are clobbered on return
93 ;; Registers used:
94 ;; r0 - NAND_RD_ADDR
95 ;; r1 - NAND_WR_ADDR
96 ;; r2 - reg_gio_rw_pa_dout
97 ;; r3 - reg_gio_r_pa_din
98 ;; r4 - tmp
99 ;; r5 - byte counter within a page
100 ;; r6 - reg_pinmux_rw_pa
101 ;; r7 - reg_gio_rw_pa_oe
102 ;; r8 - reg_bif_core_rw_grp3_cfg
103 ;; r9 - reg_gio_rw_pa_dout shadow
104 move.d 0x90000000, $r0
105 move.d 0x94000000, $r1
106 move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
107 move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
108 move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
109 move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
110 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
111
112#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
113 lsrq 1, $r11
114#endif
115 ;; Set up GPIO
116 move.d [$r2], $r9
117 move.d [$r7], $r4
118 or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
119 move.d $r4, [$r7]
120
121 ;; Set up bif
122 move.d [$r8], $r4
123 and.d CSP_MASK, $r4
124 or.d CSP_VAL, $r4
125 move.d $r4, [$r8]
126
1271: ;; Copy one page
128 CLR CE
129 SET CLE
130 moveq READ_CMD, $r4
131 move.b $r4, [$r1]
132 moveq 20, $r4
1332: bne 2b
134 subq 1, $r4
135 CLR CLE
136 SET ALE
137 clear.w [$r1] ; Column address = 0
138 move.d $r11, $r4
139 lsrq 8, $r4
140 move.b $r4, [$r1] ; Row address
141 lsrq 8, $r4
142 move.b $r4, [$r1] ; Row address
143 moveq 20, $r4
1442: bne 2b
145 subq 1, $r4
146 CLR ALE
1472: move.d [$r3], $r4
148 and.d 1 << BY, $r4
149 beq 2b
150 movu.w PAGE_SIZE, $r5
1512: ; Copy one byte/word
152#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
153 move.w [$r0], $r4
154#else
155 move.b [$r0], $r4
156#endif
157 subq 1, $r5
158 bne 2b
159#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
160 move.w $r4, [$r10+]
161 subu.w PAGE_SIZE*2, $r12
162#else
163 move.b $r4, [$r10+]
164 subu.w PAGE_SIZE, $r12
165#endif
166 bpl 1b
167 addu.w PAGE_SIZE, $r11
168
169 ;; End of copy
170 jump $r13
171 nop
172
173 ;; This will warn if the code above is too large. If you consider
174 ;; to remove this you don't understand the bug/feature.
175 .org 256
176 .org ERASE_BLOCK
177
178normal_boot:
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.c b/arch/cris/arch-v32/mach-a3/vcs_hook.c
new file mode 100644
index 00000000000..58b1a5469fd
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/vcs_hook.c
@@ -0,0 +1,103 @@
1/*
2 * Simulator hook mechanism
3 */
4
5#include "vcs_hook.h"
6#include <asm/io.h>
7#include <stdarg.h>
8
9#define HOOK_TRIG_ADDR 0xb7000000
10#define HOOK_MEM_BASE_ADDR 0xce000000
11
12static volatile unsigned *hook_base;
13
14#define HOOK_DATA(offset) hook_base[offset]
15#define VHOOK_DATA(offset) hook_base[offset]
16#define HOOK_TRIG(funcid) \
17 do { \
18 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19 } while (0)
20#define HOOK_DATA_BYTE(offset) ((unsigned char *)hook_base)[offset]
21
22static void hook_init(void)
23{
24 static int first = 1;
25 if (first) {
26 first = 0;
27 hook_base = ioremap(HOOK_MEM_BASE_ADDR, 8192);
28 }
29}
30
31static unsigned hook_trig(unsigned id)
32{
33 unsigned ret;
34
35 /* preempt_disable(); */
36
37 /* Dummy read from mem to make sure data has propagated to memory
38 * before trigging */
39 ret = *hook_base;
40
41 /* trigger hook */
42 HOOK_TRIG(id);
43
44 /* wait for call to finish */
45 while (VHOOK_DATA(0) > 0) ;
46
47 /* extract return value */
48
49 ret = VHOOK_DATA(1);
50
51 return ret;
52}
53
54int hook_call(unsigned id, unsigned pcnt, ...)
55{
56 va_list ap;
57 int i;
58 unsigned ret;
59
60 hook_init();
61
62 HOOK_DATA(0) = id;
63
64 va_start(ap, pcnt);
65 for (i = 1; i <= pcnt; i++)
66 HOOK_DATA(i) = va_arg(ap, unsigned);
67 va_end(ap);
68
69 ret = hook_trig(id);
70
71 return ret;
72}
73
74int hook_call_str(unsigned id, unsigned size, const char *str)
75{
76 int i;
77 unsigned ret;
78
79 hook_init();
80
81 HOOK_DATA(0) = id;
82 HOOK_DATA(1) = size;
83
84 for (i = 0; i < size; i++)
85 HOOK_DATA_BYTE(8 + i) = str[i];
86 HOOK_DATA_BYTE(8 + i) = 0;
87
88 ret = hook_trig(id);
89
90 return ret;
91}
92
93void print_str(const char *str)
94{
95 int i;
96 /* find null at end of string */
97 for (i = 1; str[i]; i++) ;
98 hook_call(hook_print_str, i, str);
99}
100
101void CPU_WATCHDOG_TIMEOUT(unsigned t)
102{
103}
diff --git a/arch/cris/arch-v32/mach-a3/vcs_hook.h b/arch/cris/arch-v32/mach-a3/vcs_hook.h
new file mode 100644
index 00000000000..8b73d0e8392
--- /dev/null
+++ b/arch/cris/arch-v32/mach-a3/vcs_hook.h
@@ -0,0 +1,58 @@
1/*
2 * Simulator hook call mechanism
3 */
4
5#ifndef __hook_h__
6#define __hook_h__
7
8int hook_call(unsigned id, unsigned pcnt, ...);
9int hook_call_str(unsigned id, unsigned size, const char *str);
10
11enum hook_ids {
12 hook_debug_on = 1,
13 hook_debug_off,
14 hook_stop_sim_ok,
15 hook_stop_sim_fail,
16 hook_alloc_shared,
17 hook_ptr_shared,
18 hook_free_shared,
19 hook_file2shared,
20 hook_cmp_shared,
21 hook_print_params,
22 hook_sim_time,
23 hook_stop_sim,
24 hook_kick_dog,
25 hook_dog_timeout,
26 hook_rand,
27 hook_srand,
28 hook_rand_range,
29 hook_print_str,
30 hook_print_hex,
31 hook_cmp_offset_shared,
32 hook_fill_random_shared,
33 hook_alloc_random_data,
34 hook_calloc_random_data,
35 hook_print_int,
36 hook_print_uint,
37 hook_fputc,
38 hook_init_fd,
39 hook_sbrk,
40 hook_print_context_descr,
41 hook_print_data_descr,
42 hook_print_group_descr,
43 hook_fill_shared,
44 hook_sl_srand,
45 hook_sl_rand_irange,
46 hook_sl_rand_urange,
47 hook_sl_sh_malloc_aligned,
48 hook_sl_sh_calloc_aligned,
49 hook_sl_sh_alloc_random_data,
50 hook_sl_sh_file2mem,
51 hook_sl_vera_mbox_handle,
52 hook_sl_vera_mbox_put,
53 hook_sl_vera_mbox_get,
54 hook_sl_system,
55 hook_sl_sh_hexdump
56};
57
58#endif
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.c b/arch/cris/arch-v32/mach-fs/vcs_hook.c
new file mode 100644
index 00000000000..b11594ae0cb
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.c
@@ -0,0 +1,100 @@
1/*
2 * Call simulator hook. This is the part running in the
3 * simulated program.
4 */
5
6#include "vcs_hook.h"
7#include <stdarg.h>
8#include <arch-v32/hwregs/reg_map.h>
9#include <arch-v32/hwregs/intr_vect_defs.h>
10
11#define HOOK_TRIG_ADDR 0xb7000000 /* hook cvlog model reg address */
12#define HOOK_MEM_BASE_ADDR 0xa0000000 /* csp4 (shared mem) base addr */
13
14#define HOOK_DATA(offset) ((unsigned *)HOOK_MEM_BASE_ADDR)[offset]
15#define VHOOK_DATA(offset) ((volatile unsigned *)HOOK_MEM_BASE_ADDR)[offset]
16#define HOOK_TRIG(funcid) \
17 do { \
18 *((unsigned *) HOOK_TRIG_ADDR) = funcid; \
19 } while (0)
20#define HOOK_DATA_BYTE(offset) ((unsigned char *)HOOK_MEM_BASE_ADDR)[offset]
21
22int hook_call(unsigned id, unsigned pcnt, ...)
23{
24 va_list ap;
25 unsigned i;
26 unsigned ret;
27#ifdef USING_SOS
28 PREEMPT_OFF_SAVE();
29#endif
30
31 /* pass parameters */
32 HOOK_DATA(0) = id;
33
34 /* Have to make hook_print_str a special case since we call with a
35 * parameter of byte type. Should perhaps be a separate
36 * hook_call. */
37
38 if (id == hook_print_str) {
39 int i;
40 char *str;
41
42 HOOK_DATA(1) = pcnt;
43
44 va_start(ap, pcnt);
45 str = (char *)va_arg(ap, unsigned);
46
47 for (i = 0; i != pcnt; i++)
48 HOOK_DATA_BYTE(8 + i) = str[i];
49
50 HOOK_DATA_BYTE(8 + i) = 0; /* null byte */
51 } else {
52 va_start(ap, pcnt);
53 for (i = 1; i <= pcnt; i++)
54 HOOK_DATA(i) = va_arg(ap, unsigned);
55 va_end(ap);
56 }
57
58 /* read from mem to make sure data has propagated to memory before
59 * trigging */
60 ret = *((volatile unsigned *)HOOK_MEM_BASE_ADDR);
61
62 /* trigger hook */
63 HOOK_TRIG(id);
64
65 /* wait for call to finish */
66 while (VHOOK_DATA(0) > 0) ;
67
68 /* extract return value */
69
70 ret = VHOOK_DATA(1);
71
72#ifdef USING_SOS
73 PREEMPT_RESTORE();
74#endif
75 return ret;
76}
77
78unsigned hook_buf(unsigned i)
79{
80 return (HOOK_DATA(i));
81}
82
83void print_str(const char *str)
84{
85 int i;
86 /* find null at end of string */
87 for (i = 1; str[i]; i++) ;
88 hook_call(hook_print_str, i, str);
89}
90
91void CPU_KICK_DOG(void)
92{
93 (void)hook_call(hook_kick_dog, 0);
94}
95
96void CPU_WATCHDOG_TIMEOUT(unsigned t)
97{
98 (void)hook_call(hook_dog_timeout, 1, t);
99}
100
diff --git a/arch/cris/arch-v32/mach-fs/vcs_hook.h b/arch/cris/arch-v32/mach-fs/vcs_hook.h
new file mode 100644
index 00000000000..c000b9fece4
--- /dev/null
+++ b/arch/cris/arch-v32/mach-fs/vcs_hook.h
@@ -0,0 +1,42 @@
1/*
2 * Call simulator hook functions
3 */
4
5#ifndef HOOK_H
6#define HOOK_H
7
8int hook_call(unsigned id, unsigned pcnt, ...);
9
10enum hook_ids {
11 hook_debug_on = 1,
12 hook_debug_off,
13 hook_stop_sim_ok,
14 hook_stop_sim_fail,
15 hook_alloc_shared,
16 hook_ptr_shared,
17 hook_free_shared,
18 hook_file2shared,
19 hook_cmp_shared,
20 hook_print_params,
21 hook_sim_time,
22 hook_stop_sim,
23 hook_kick_dog,
24 hook_dog_timeout,
25 hook_rand,
26 hook_srand,
27 hook_rand_range,
28 hook_print_str,
29 hook_print_hex,
30 hook_cmp_offset_shared,
31 hook_fill_random_shared,
32 hook_alloc_random_data,
33 hook_calloc_random_data,
34 hook_print_int,
35 hook_print_uint,
36 hook_fputc,
37 hook_init_fd,
38 hook_sbrk
39
40};
41
42#endif