diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/system.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/firmware/system.c b/firmware/system.c index 757fe9e651..693c4a1434 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -27,12 +27,15 @@ | |||
27 | 27 | ||
28 | void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); | 28 | void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); |
29 | 29 | ||
30 | void ddma_wait_idle(void) __attribute__ ((section (".icode"))); | ||
30 | void ddma_wait_idle(void) | 31 | void ddma_wait_idle(void) |
31 | { | 32 | { |
32 | do { | 33 | do { |
33 | } while ((DDMACOM & 3) != 0); | 34 | } while ((DDMACOM & 3) != 0); |
34 | } | 35 | } |
35 | 36 | ||
37 | void ddma_transfer(int dir, int mem, long intAddr, long extAddr, int num) | ||
38 | __attribute__ ((section (".icode"))); | ||
36 | void ddma_transfer(int dir, int mem, long intAddr, long extAddr, int num) { | 39 | void ddma_transfer(int dir, int mem, long intAddr, long extAddr, int num) { |
37 | int irq = set_irq_level(1); | 40 | int irq = set_irq_level(1); |
38 | ddma_wait_idle(); | 41 | ddma_wait_idle(); |
@@ -52,6 +55,31 @@ void ddma_transfer(int dir, int mem, long intAddr, long extAddr, int num) { | |||
52 | set_irq_level(irq); | 55 | set_irq_level(irq); |
53 | } | 56 | } |
54 | 57 | ||
58 | static void ddma_wait_idle_noicode(void) | ||
59 | { | ||
60 | do { | ||
61 | } while ((DDMACOM & 3) != 0); | ||
62 | } | ||
63 | |||
64 | static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr, int num) { | ||
65 | int irq = set_irq_level(1); | ||
66 | ddma_wait_idle_noicode(); | ||
67 | long externalAddress = (long) extAddr; | ||
68 | long internalAddress = (long) intAddr; | ||
69 | /* HW wants those two in word units. */ | ||
70 | num /= 2; | ||
71 | externalAddress /= 2; | ||
72 | |||
73 | DDMACFG = (dir << 1) | (mem << 2); | ||
74 | DDMAIADR = internalAddress; | ||
75 | DDMAEADR = externalAddress; | ||
76 | DDMANUM = num; | ||
77 | DDMACOM |= 0x4; /* start */ | ||
78 | |||
79 | ddma_wait_idle_noicode(); /* wait for completion */ | ||
80 | set_irq_level(irq); | ||
81 | } | ||
82 | |||
55 | /* Some linker-defined symbols */ | 83 | /* Some linker-defined symbols */ |
56 | extern int icodecopy; | 84 | extern int icodecopy; |
57 | extern int icodesize; | 85 | extern int icodesize; |
@@ -86,7 +114,7 @@ void system_init(void) | |||
86 | /************************ | 114 | /************************ |
87 | * Copy .icode section to icram | 115 | * Copy .icode section to icram |
88 | */ | 116 | */ |
89 | ddma_transfer(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); | 117 | ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize); |
90 | 118 | ||
91 | 119 | ||
92 | /*************************** | 120 | /*************************** |