00001
00038 #include <hugemem.h>
00039 #include <assert.h>
00040
00041
00042 #if defined(CONFIG_HAVE_HUGEMEM) || defined(__DOXYGEN__)
00043 # if defined(__GNUC__) || defined(__DOXYGEN__)
00044 uint_fast16_t hugemem_read16(const hugemem_ptr_t from)
00045 {
00046 uint16_t value;
00047
00048 asm(
00049 "movw r30, %A1 \n\t"
00050 "out %2, %C1 \n\t"
00051 "ld %A0, Z+ \n\t"
00052 "ld %B0, Z \n\t"
00053 "out %2, __zero_reg__ \n\t"
00054 : "=r"(value)
00055 : "r"(from), "i"(CPU_REG(RAMPZ))
00056 : "r30", "r31"
00057 );
00058
00059 return value;
00060 }
00061
00062 uint_fast32_t hugemem_read32(const hugemem_ptr_t from)
00063 {
00064 uint32_t value;
00065
00066 asm(
00067 "movw r30, %A1 \n\t"
00068 "out %2, %C1 \n\t"
00069 "ld %A0, Z+ \n\t"
00070 "ld %B0, Z+ \n\t"
00071 "ld %C0, Z+ \n\t"
00072 "ld %D0, Z \n\t"
00073 "out %2, __zero_reg__ \n\t"
00074 : "=r"(value)
00075 : "r"(from), "i"(CPU_REG(RAMPZ))
00076 : "r30", "r31"
00077 );
00078
00079 return value;
00080 }
00081
00082 void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size)
00083 {
00084
00085 assert(((uint32_t)to + size) <= 0x10000);
00086
00087 if (size > 0) {
00088 asm volatile(
00089 "movw r30, %A2 \n\t"
00090 "out %3, %C2 \n\t"
00091 "get_%=: \n\t"
00092 "ld __tmp_reg__, Z+ \n\t"
00093 "st X+, __tmp_reg__ \n\t"
00094 "sbiw %A1, 1 \n\t"
00095 "brne get_%= \n\t"
00096 "out %3, __zero_reg__ \n\t"
00097 : "+x"(to), "+w"(size)
00098 : "r"(from), "i"(CPU_REG(RAMPZ))
00099 : "r30", "r31"
00100 );
00101 }
00102 }
00103
00104 void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val)
00105 {
00106 asm(
00107 "movw r30, %A0 \n\t"
00108 "out %2, %C0 \n\t"
00109 "st Z+, %A1 \n\t"
00110 "st Z, %B1 \n\t"
00111 "out %2, __zero_reg__ \n\t"
00112 :
00113 : "r"(to), "r"(val), "i"(CPU_REG(RAMPZ))
00114 : "r30", "r31"
00115 );
00116 }
00117
00118 void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val)
00119 {
00120 asm(
00121 "movw r30, %A0 \n\t"
00122 "out %2, %C0 \n\t"
00123 "st Z+, %A1 \n\t"
00124 "st Z+, %B1 \n\t"
00125 "st Z+, %C1 \n\t"
00126 "st Z, %D1 \n\t"
00127 "out %2, __zero_reg__ \n\t"
00128 :
00129 : "r"(to), "r"(val), "i"(CPU_REG(RAMPZ))
00130 : "r30", "r31"
00131 );
00132 }
00133
00134 void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size)
00135 {
00136
00137 assert(((uint32_t)from + size) <= 0x10000);
00138
00139 if (size > 0) {
00140 asm volatile(
00141 "movw r30, %A2 \n\t"
00142 "out %3, %C2 \n\t"
00143 "put_%=: \n\t"
00144 "ld __tmp_reg__, X+ \n\t"
00145 "st Z+, __tmp_reg__ \n\t"
00146 "sbiw %A1, 1 \n\t"
00147 "brne put_%= \n\t"
00148 "out %3, __zero_reg__ \n\t"
00149 : "+x"(from), "+w"(size)
00150 : "r"(to), "i"(CPU_REG(RAMPZ))
00151 : "r30", "r31"
00152 );
00153 }
00154 }
00155 # endif
00156
00157 # ifdef __ICCAVR__
00158 void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size)
00159 {
00160 uint8_t *to_ptr;
00161 uint8_t __huge *from_ptr;
00162
00163
00164 assert(((uint32_t)to + size) <= 0x10000);
00165
00166 to_ptr = (uint8_t *)to;
00167 from_ptr = (uint8_t __huge *)from;
00168
00169 for (; size > 0; size--) {
00170 *to_ptr++ = *from_ptr++;
00171 }
00172 }
00173
00174 void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size)
00175 {
00176 uint8_t __huge *to_ptr;
00177 uint8_t *from_ptr;
00178
00179
00180 assert(((uint32_t)from + size) <= 0x10000);
00181
00182 to_ptr = (uint8_t __huge *)to;
00183 from_ptr = (uint8_t *)from;
00184
00185 for (; size > 0; size--) {
00186 *to_ptr++ = *from_ptr++;
00187 }
00188 }
00189 # endif
00190 #endif