1.1 --- a/conf/landfall-examples/mips-x1600-info.list Mon Nov 13 01:20:09 2023 +0100
1.2 +++ b/conf/landfall-examples/mips-x1600-info.list Tue Nov 14 00:02:42 2023 +0100
1.3 @@ -13,3 +13,4 @@
1.4 module ned
1.5 module ex_x1600_info
1.6 module piano-3.raw
1.7 +module P8021407-crop-240x240.data
2.1 --- a/pkg/devices/lib/spi/include/spi-gpio.h Mon Nov 13 01:20:09 2023 +0100
2.2 +++ b/pkg/devices/lib/spi/include/spi-gpio.h Tue Nov 14 00:02:42 2023 +0100
2.3 @@ -21,6 +21,7 @@
2.4
2.5 #pragma once
2.6
2.7 +#include <l4/re/c/dma_space.h>
2.8 #include <stdint.h>
2.9
2.10
2.11 @@ -58,10 +59,16 @@
2.12
2.13 uint32_t send(uint32_t bytes, const uint8_t data[]);
2.14
2.15 - uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[]);
2.16 + uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[],
2.17 + uint8_t char_size, bool big_endian);
2.18
2.19 uint32_t send_units(uint32_t bytes, const uint8_t data[], uint8_t unit_size,
2.20 - uint8_t char_size);
2.21 + uint8_t char_size, bool big_endian);
2.22 +
2.23 + uint32_t transfer(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr,
2.24 + uint32_t count, uint8_t unit_size, uint8_t char_size,
2.25 + l4_addr_t desc_vaddr = 0,
2.26 + l4re_dma_space_dma_addr_t desc_paddr = 0);
2.27 };
2.28
2.29 #endif /* __cplusplus */
2.30 @@ -81,9 +88,20 @@
2.31 uint32_t spi_gpio_send(void *channel, uint32_t bytes, const uint8_t data[]);
2.32
2.33 uint32_t spi_gpio_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
2.34 - const int dc[]);
2.35 + const int dc[], uint8_t char_size, int big_endian);
2.36
2.37 uint32_t spi_gpio_send_units(void *channel, uint32_t bytes, const uint8_t data[],
2.38 - uint8_t unit_size, uint8_t char_size);
2.39 + uint8_t unit_size, uint8_t char_size, int big_endian);
2.40 +
2.41 +uint32_t spi_gpio_transfer(void *channel, l4_addr_t vaddr,
2.42 + l4re_dma_space_dma_addr_t paddr,
2.43 + uint32_t count, uint8_t unit_size,
2.44 + uint8_t char_size);
2.45 +
2.46 +uint32_t spi_gpio_transfer_descriptor(void *channel, l4_addr_t vaddr,
2.47 + l4re_dma_space_dma_addr_t paddr,
2.48 + uint32_t count, uint8_t unit_size,
2.49 + uint8_t char_size, l4_addr_t desc_vaddr,
2.50 + l4re_dma_space_dma_addr_t desc_paddr);
2.51
2.52 EXTERN_C_END
3.1 --- a/pkg/devices/lib/spi/include/spi-hybrid.h Mon Nov 13 01:20:09 2023 +0100
3.2 +++ b/pkg/devices/lib/spi/include/spi-hybrid.h Tue Nov 14 00:02:42 2023 +0100
3.3 @@ -22,6 +22,7 @@
3.4
3.5 #pragma once
3.6
3.7 +#include <l4/re/c/dma_space.h>
3.8 #include <stdint.h>
3.9
3.10
3.11 @@ -53,10 +54,16 @@
3.12
3.13 uint32_t send(uint32_t bytes, const uint8_t data[]);
3.14
3.15 - uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[]);
3.16 + uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[],
3.17 + uint8_t char_size, bool big_endian);
3.18
3.19 uint32_t send_units(uint32_t bytes, const uint8_t data[],
3.20 - uint8_t unit_size, uint8_t char_size);
3.21 + uint8_t unit_size, uint8_t char_size, bool big_endian);
3.22 +
3.23 + uint32_t transfer(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr,
3.24 + uint32_t count, uint8_t unit_size, uint8_t char_size,
3.25 + l4_addr_t desc_vaddr = 0,
3.26 + l4re_dma_space_dma_addr_t desc_paddr = 0);
3.27 };
3.28
3.29 #endif /* __cplusplus */
3.30 @@ -79,9 +86,19 @@
3.31 uint32_t spi_hybrid_send(void *channel, uint32_t bytes, const uint8_t data[]);
3.32
3.33 uint32_t spi_hybrid_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
3.34 - const int dc[]);
3.35 + const int dc[], uint8_t char_size, int big_endian);
3.36
3.37 uint32_t spi_hybrid_send_units(void *channel, uint32_t bytes, const uint8_t data[],
3.38 - uint8_t unit_size, uint8_t char_size);
3.39 + uint8_t unit_size, uint8_t char_size, int big_endian);
3.40 +
3.41 +uint32_t spi_hybrid_transfer(void *channel, l4_addr_t vaddr,
3.42 + l4re_dma_space_dma_addr_t paddr, uint32_t count,
3.43 + uint8_t unit_size, uint8_t char_size);
3.44 +
3.45 +uint32_t spi_hybrid_transfer_descriptor(void *channel, l4_addr_t vaddr,
3.46 + l4re_dma_space_dma_addr_t paddr,
3.47 + uint32_t count, uint8_t unit_size,
3.48 + uint8_t char_size, l4_addr_t desc_vaddr,
3.49 + l4re_dma_space_dma_addr_t desc_paddr);
3.50
3.51 EXTERN_C_END
4.1 --- a/pkg/devices/lib/spi/include/spi-jz4780.h Mon Nov 13 01:20:09 2023 +0100
4.2 +++ b/pkg/devices/lib/spi/include/spi-jz4780.h Tue Nov 14 00:02:42 2023 +0100
4.3 @@ -67,15 +67,16 @@
4.4
4.5 virtual uint32_t send(uint32_t bytes, const uint8_t data[]);
4.6
4.7 - virtual uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[]);
4.8 + virtual uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[],
4.9 + uint8_t char_size, bool big_endian);
4.10
4.11 uint32_t send_units(uint32_t bytes, const uint8_t data[], uint8_t unit_size,
4.12 - uint8_t char_size);
4.13 + uint8_t char_size, bool big_endian);
4.14
4.15 /* DMA operations. */
4.16
4.17 - uint32_t transfer(l4re_dma_space_dma_addr_t paddr, uint32_t count,
4.18 - uint8_t unit_size, uint8_t char_size,
4.19 + uint32_t transfer(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr,
4.20 + uint32_t count, uint8_t unit_size, uint8_t char_size,
4.21 l4_addr_t desc_vaddr = 0,
4.22 l4re_dma_space_dma_addr_t desc_paddr = 0);
4.23 };
4.24 @@ -110,15 +111,17 @@
4.25 uint32_t jz4780_spi_send(void *channel, uint32_t bytes, const uint8_t data[]);
4.26
4.27 uint32_t jz4780_spi_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
4.28 - const int dc[]);
4.29 + const int dc[], uint8_t char_size, int big_endian);
4.30
4.31 uint32_t jz4780_spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],
4.32 - uint8_t unit_size, uint8_t char_size);
4.33 + uint8_t unit_size, uint8_t char_size, int big_endian);
4.34
4.35 -uint32_t jz4780_spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
4.36 - uint32_t count, uint8_t unit_size, uint8_t char_size);
4.37 +uint32_t jz4780_spi_transfer(void *channel, l4_addr_t vaddr,
4.38 + l4re_dma_space_dma_addr_t paddr, uint32_t count,
4.39 + uint8_t unit_size, uint8_t char_size);
4.40
4.41 -uint32_t jz4780_spi_transfer_descriptor(void *channel, l4re_dma_space_dma_addr_t paddr,
4.42 +uint32_t jz4780_spi_transfer_descriptor(void *channel, l4_addr_t vaddr,
4.43 + l4re_dma_space_dma_addr_t paddr,
4.44 uint32_t count, uint8_t unit_size,
4.45 uint8_t char_size, l4_addr_t desc_vaddr,
4.46 l4re_dma_space_dma_addr_t desc_paddr);
5.1 --- a/pkg/devices/lib/spi/include/spi.h Mon Nov 13 01:20:09 2023 +0100
5.2 +++ b/pkg/devices/lib/spi/include/spi.h Tue Nov 14 00:02:42 2023 +0100
5.3 @@ -21,8 +21,11 @@
5.4
5.5 #pragma once
5.6
5.7 +
5.8 +
5.9 #ifdef __cplusplus
5.10
5.11 +#include <l4/re/c/dma_space.h>
5.12 #include <stdint.h>
5.13
5.14 /* SPI channel abstractions. */
5.15 @@ -33,10 +36,17 @@
5.16 virtual uint32_t send(uint32_t bytes, const uint8_t data[]) = 0;
5.17
5.18 virtual uint32_t send_dc(uint32_t bytes, const uint8_t data[],
5.19 - const int dc[]) = 0;
5.20 + const int dc[], uint8_t char_size,
5.21 + bool big_endian) = 0;
5.22
5.23 virtual uint32_t send_units(uint32_t bytes, const uint8_t data[],
5.24 - uint8_t unit_size, uint8_t char_size) = 0;
5.25 + uint8_t unit_size, uint8_t char_size,
5.26 + bool big_endian) = 0;
5.27 +
5.28 + virtual uint32_t transfer(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr,
5.29 + uint32_t count, uint8_t unit_size, uint8_t char_size,
5.30 + l4_addr_t desc_vaddr = 0,
5.31 + l4re_dma_space_dma_addr_t desc_paddr = 0) = 0;
5.32 };
5.33
5.34 class Spi_control_base
6.1 --- a/pkg/devices/lib/spi/src/gpio.cc Mon Nov 13 01:20:09 2023 +0100
6.2 +++ b/pkg/devices/lib/spi/src/gpio.cc Tue Nov 14 00:02:42 2023 +0100
6.3 @@ -19,7 +19,9 @@
6.4 * Boston, MA 02110-1301, USA
6.5 */
6.6
6.7 +#include <l4/devices/byteorder.h>
6.8 #include <l4/devices/spi-gpio.h>
6.9 +#include <stdlib.h> /* NOTE: required by calloc/free */
6.10 #include <time.h>
6.11
6.12
6.13 @@ -58,18 +60,19 @@
6.14
6.15 uint32_t Spi_gpio::send(uint32_t bytes, const uint8_t data[])
6.16 {
6.17 - return send_dc(bytes, data, NULL);
6.18 + return send_dc(bytes, data, NULL, 8, false);
6.19 }
6.20
6.21 -/* Send a byte sequence with accompanying data/command indicators. */
6.22 +/* Send a byte sequence with accompanying data/command indicators. Bytes are
6.23 + grouped into character units, with each unit holding a value with the given
6.24 + byte ordering. */
6.25
6.26 uint32_t Spi_gpio::send_dc(uint32_t bytes, const uint8_t data[],
6.27 - const int dc[])
6.28 + const int dc[], uint8_t char_size, bool big_endian)
6.29 {
6.30 struct timespec ts;
6.31 - uint8_t mask;
6.32 - int bit;
6.33 - uint32_t byte;
6.34 + uint32_t offset, char_unit;
6.35 + uint8_t char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1;
6.36
6.37 if (_frequency)
6.38 {
6.39 @@ -83,27 +86,34 @@
6.40 _clock_device->set(_clock_pin, 1);
6.41 _data_device->set(_data_pin, 0);
6.42
6.43 + if ((_control_device != NULL) && (_control_pin >= 0) && (dc != NULL))
6.44 + _control_device->set(_control_pin, dc[0] ? 1 : 0);
6.45 +
6.46 /* Enter the transmission state. */
6.47
6.48 _enable_device->set(_enable_pin, 0);
6.49
6.50 /* Clock data using the clock and data outputs. */
6.51
6.52 - for (byte = 0; byte < bytes; byte++)
6.53 + for (offset = 0, char_unit = 0; offset < bytes; offset += char_unit_size, char_unit++)
6.54 {
6.55 - mask = 0x80;
6.56 + uint32_t mask, value = get_stored_value(&data[offset], char_unit_size, big_endian);
6.57 +
6.58 + /* Set the control level, if appropriate. */
6.59
6.60 - for (bit = 0; bit < 8; bit++)
6.61 + if ((_control_device != NULL) && (_control_pin >= 0) && (dc != NULL))
6.62 + _control_device->set(_control_pin, dc[char_unit] ? 1 : 0);
6.63 +
6.64 + mask = 1 << (char_size - 1);
6.65 +
6.66 + for (uint8_t bit = 0; bit < char_size; bit++)
6.67 {
6.68 /* NOTE: Data presented on falling clock level and sampled on rising clock
6.69 level. This is SPI mode 3, or 0 given that the enable level is
6.70 driven low immediately before the first bit is presented. */
6.71
6.72 _clock_device->set(_clock_pin, 0);
6.73 - _data_device->set(_data_pin, data[byte] & mask ? 1 : 0);
6.74 -
6.75 - if ((_control_device != NULL) && (_control_pin >= 0) && (dc != NULL))
6.76 - _control_device->set(_control_pin, dc[byte] ? 1 : 0);
6.77 + _data_device->set(_data_pin, value & mask ? 1 : 0);
6.78
6.79 if (_frequency)
6.80 nanosleep(&ts, NULL);
6.81 @@ -122,45 +132,44 @@
6.82 return bytes;
6.83 }
6.84
6.85 -/* Send a number of units, each holding a value in a big endian arrangement
6.86 - limited to the given character size, with any bit immediately above the
6.87 - character portion of the unit indicating the data/command level. */
6.88 +/* Send a number of units, each holding a value limited to the given character
6.89 + size, with any bit immediately above the character portion of the unit
6.90 + indicating the data/command level. */
6.91
6.92 uint32_t Spi_gpio::send_units(uint32_t bytes, const uint8_t data[],
6.93 - uint8_t unit_size, uint8_t char_size)
6.94 + uint8_t unit_size, uint8_t char_size,
6.95 + bool big_endian)
6.96 {
6.97 - /* Obtain the data/command values for each unit. */
6.98 + uint32_t char_units = bytes / unit_size;
6.99 + uint8_t char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1;
6.100
6.101 - uint32_t chars = bytes / unit_size;
6.102 - int dc[chars];
6.103 -
6.104 + /* Obtain the data/command values for each unit. */
6.105 /* Obtain the actual character bytes to be sent. */
6.106
6.107 - int char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1;
6.108 - uint8_t char_data[char_unit_size * chars];
6.109 + /* NOTE: Work around stack allocation limitations in L4Re. We would want to
6.110 + use a static allocation as follows:
6.111 +
6.112 + int dc[char_units];
6.113 + uint8_t char_data[char_unit_size * char_units];
6.114 + */
6.115 +
6.116 + int *dc = (int *) calloc(char_units, sizeof(int));
6.117 + uint8_t *char_data = (uint8_t *) calloc(char_units, char_unit_size);
6.118
6.119 /* Traverse the byte sequence, extracting data/command bits for each unit. */
6.120
6.121 - for (uint32_t offset = 0, unit = 0, char_offset = 0; unit < chars;
6.122 - offset += unit_size, unit++, char_offset += char_unit_size)
6.123 + for (uint32_t offset = 0, char_unit = 0, char_offset = 0; char_unit < char_units;
6.124 + offset += unit_size, char_unit++, char_offset += char_unit_size)
6.125 {
6.126 /* Obtain the unit value. */
6.127
6.128 - uint32_t value = 0;
6.129 -
6.130 - for (uint8_t byte = 0; byte < unit_size; byte++)
6.131 - value = (value << 8) | data[offset + byte];
6.132 + uint32_t value = get_stored_value(&data[offset], unit_size, big_endian);
6.133
6.134 /* The unit size must be greater than the character size for data/command
6.135 bits to be present. */
6.136
6.137 - if (unit_size * 8 <= char_size)
6.138 - dc[unit] = 0;
6.139 -
6.140 - /* Extract the data/command level. */
6.141 -
6.142 - else
6.143 - dc[unit] = value & (1 << char_size) ? 1 : 0;
6.144 + if (unit_size * 8 > char_size)
6.145 + dc[char_unit] = value & (1 << char_size) ? 1 : 0;
6.146
6.147 /* Obtain the actual character data from the input data, discarding the most
6.148 significant bytes beyond the character and masking out any remaining
6.149 @@ -168,14 +177,38 @@
6.150
6.151 value = value & ((1 << char_size) - 1);
6.152
6.153 - for (uint8_t byte = char_unit_size; byte != 0; byte--)
6.154 - {
6.155 - char_data[char_offset + byte - 1] = value & 0xff;
6.156 - value >>= 8;
6.157 - }
6.158 + set_stored_value(value, &char_data[char_offset], char_unit_size, big_endian);
6.159 }
6.160
6.161 - return send_dc(chars, char_data, dc);
6.162 + /* Discard the data/command values if they will not be used. */
6.163 +
6.164 + uint32_t result = send_dc(char_units * char_unit_size, char_data,
6.165 + (unit_size * 8 <= char_size) ? NULL : dc,
6.166 + char_size, big_endian);
6.167 +
6.168 + /* NOTE: Working around allocation limitations with dc... */
6.169 +
6.170 + free(dc);
6.171 + free(char_data);
6.172 + return result;
6.173 +}
6.174 +
6.175 +/* Perform a transfer, ignoring any DMA-specific parameters. */
6.176 +
6.177 +uint32_t Spi_gpio::transfer(l4_addr_t vaddr,
6.178 + l4re_dma_space_dma_addr_t paddr,
6.179 + uint32_t count, uint8_t unit_size,
6.180 + uint8_t char_size,
6.181 + l4_addr_t desc_vaddr,
6.182 + l4re_dma_space_dma_addr_t desc_paddr)
6.183 +{
6.184 + (void) paddr; (void) desc_vaddr; (void) desc_paddr;
6.185 +
6.186 + /* Assume little endian data is being transferred, being the native data
6.187 + representation. */
6.188 +
6.189 + return send_units(count, (const uint8_t *) vaddr, unit_size, char_size,
6.190 + false);
6.191 }
6.192
6.193
6.194 @@ -201,13 +234,34 @@
6.195 }
6.196
6.197 uint32_t spi_gpio_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
6.198 - const int dc[])
6.199 + const int dc[], uint8_t char_size, int big_endian)
6.200 {
6.201 - return static_cast<Spi_gpio *>(channel)->send_dc(bytes, data, dc);
6.202 + return static_cast<Spi_gpio *>(channel)->send_dc(bytes, data, dc, char_size,
6.203 + big_endian);
6.204 }
6.205
6.206 uint32_t spi_gpio_send_units(void *channel, uint32_t bytes, const uint8_t data[],
6.207 - uint8_t unit_size, uint8_t char_size)
6.208 + uint8_t unit_size, uint8_t char_size, int big_endian)
6.209 {
6.210 - return static_cast<Spi_gpio *>(channel)->send_units(bytes, data, unit_size, char_size);
6.211 + return static_cast<Spi_gpio *>(channel)->send_units(bytes, data, unit_size,
6.212 + char_size, big_endian);
6.213 }
6.214 +
6.215 +uint32_t spi_gpio_transfer(void *channel, l4_addr_t vaddr,
6.216 + l4re_dma_space_dma_addr_t paddr,
6.217 + uint32_t count, uint8_t unit_size,
6.218 + uint8_t char_size)
6.219 +{
6.220 + return static_cast<Spi_gpio *>(channel)->transfer(vaddr, paddr, count,
6.221 + unit_size, char_size);
6.222 +}
6.223 +
6.224 +uint32_t spi_gpio_transfer_descriptor(void *channel, l4_addr_t vaddr,
6.225 + l4re_dma_space_dma_addr_t paddr,
6.226 + uint32_t count, uint8_t unit_size,
6.227 + uint8_t char_size, l4_addr_t desc_vaddr,
6.228 + l4re_dma_space_dma_addr_t desc_paddr)
6.229 +{
6.230 + return static_cast<Spi_gpio *>(channel)->transfer(vaddr, paddr, count,
6.231 + unit_size, char_size, desc_vaddr, desc_paddr);
6.232 +}
7.1 --- a/pkg/devices/lib/spi/src/hybrid.cc Mon Nov 13 01:20:09 2023 +0100
7.2 +++ b/pkg/devices/lib/spi/src/hybrid.cc Tue Nov 14 00:02:42 2023 +0100
7.3 @@ -61,19 +61,34 @@
7.4
7.5 /* Send a byte sequence with control information. */
7.6
7.7 -uint32_t Spi_hybrid::send_dc(uint32_t bytes, const uint8_t data[], const int dc[])
7.8 +uint32_t Spi_hybrid::send_dc(uint32_t bytes, const uint8_t data[],
7.9 + const int dc[], uint8_t char_size, bool big_endian)
7.10 {
7.11 - return _channel->send_dc(bytes, data, dc);
7.12 + return _channel->send_dc(bytes, data, dc, char_size, big_endian);
7.13 }
7.14
7.15 /* Send a sequence of units having the given character size. */
7.16
7.17 uint32_t Spi_hybrid::send_units(uint32_t bytes, const uint8_t data[],
7.18 - uint8_t unit_size, uint8_t char_size)
7.19 + uint8_t unit_size, uint8_t char_size,
7.20 + bool big_endian)
7.21 {
7.22 - return _channel->send_units(bytes, data, unit_size, char_size);
7.23 + return _channel->send_units(bytes, data, unit_size, char_size, big_endian);
7.24 }
7.25 -
7.26 +
7.27 +/* Transfer a sequence of units using DMA if available. */
7.28 +
7.29 +uint32_t Spi_hybrid::transfer(l4_addr_t vaddr,
7.30 + l4re_dma_space_dma_addr_t paddr,
7.31 + uint32_t count, uint8_t unit_size,
7.32 + uint8_t char_size,
7.33 + l4_addr_t desc_vaddr,
7.34 + l4re_dma_space_dma_addr_t desc_paddr)
7.35 +{
7.36 + return _channel->transfer(vaddr, paddr, count, unit_size, char_size,
7.37 + desc_vaddr, desc_paddr);
7.38 +}
7.39 +
7.40
7.41
7.42 /* C language interface. */
7.43 @@ -107,13 +122,34 @@
7.44 }
7.45
7.46 uint32_t spi_hybrid_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
7.47 - const int dc[])
7.48 + const int dc[], uint8_t char_size, int big_endian)
7.49 {
7.50 - return static_cast<Spi_hybrid *>(channel)->send_dc(bytes, data, dc);
7.51 + return static_cast<Spi_hybrid *>(channel)->send_dc(bytes, data, dc, char_size,
7.52 + big_endian);
7.53 }
7.54
7.55 uint32_t spi_hybrid_send_units(void *channel, uint32_t bytes, const uint8_t data[],
7.56 - uint8_t unit_size, uint8_t char_size)
7.57 + uint8_t unit_size, uint8_t char_size,
7.58 + int big_endian)
7.59 +{
7.60 + return static_cast<Spi_hybrid *>(channel)->send_units(bytes, data, unit_size,
7.61 + char_size, big_endian);
7.62 +}
7.63 +
7.64 +uint32_t spi_hybrid_transfer(void *channel, l4_addr_t vaddr,
7.65 + l4re_dma_space_dma_addr_t paddr,
7.66 + uint32_t count, uint8_t unit_size,
7.67 + uint8_t char_size)
7.68 {
7.69 - return static_cast<Spi_hybrid *>(channel)->send_units(bytes, data, unit_size, char_size);
7.70 + return static_cast<Spi_hybrid *>(channel)->transfer(vaddr, paddr, count, unit_size, char_size);
7.71 }
7.72 +
7.73 +uint32_t spi_hybrid_transfer_descriptor(void *channel, l4_addr_t vaddr,
7.74 + l4re_dma_space_dma_addr_t paddr,
7.75 + uint32_t count, uint8_t unit_size,
7.76 + uint8_t char_size, l4_addr_t desc_vaddr,
7.77 + l4re_dma_space_dma_addr_t desc_paddr)
7.78 +{
7.79 + return static_cast<Spi_hybrid *>(channel)->transfer(vaddr, paddr, count,
7.80 + unit_size, char_size, desc_vaddr, desc_paddr);
7.81 +}
8.1 --- a/pkg/devices/lib/spi/src/jz4780.cc Mon Nov 13 01:20:09 2023 +0100
8.2 +++ b/pkg/devices/lib/spi/src/jz4780.cc Tue Nov 14 00:02:42 2023 +0100
8.3 @@ -19,8 +19,9 @@
8.4 * Boston, MA 02110-1301, USA
8.5 */
8.6
8.7 +#include <l4/devices/byteorder.h>
8.8 +#include <l4/devices/dma.h>
8.9 #include <l4/devices/spi-jz4780.h>
8.10 -#include <l4/devices/dma.h>
8.11 #include <l4/sys/err.h>
8.12 #include <string.h>
8.13
8.14 @@ -288,29 +289,33 @@
8.15 uint32_t
8.16 Spi_jz4780_channel::send(uint32_t bytes, const uint8_t data[])
8.17 {
8.18 - return send_units(bytes, data, 1, 8);
8.19 + return send_units(bytes, data, 1, 8, false);
8.20 }
8.21
8.22 /* Transfer the given number of bytes from a buffer together with control values. */
8.23
8.24 uint32_t
8.25 Spi_jz4780_channel::send_dc(uint32_t bytes, const uint8_t data[],
8.26 - const int dc[])
8.27 + const int dc[], uint8_t char_size, bool big_endian)
8.28 {
8.29 - configure_transfer(8);
8.30 + configure_transfer(char_size);
8.31
8.32 - uint32_t transferred;
8.33 + uint32_t transferred, char_unit;
8.34 + uint8_t char_unit_size = ((char_size ? char_size - 1 : 0) / 8) + 1;
8.35 + uint32_t char_mask = (1 << char_size) - 1;
8.36
8.37 - for (transferred = 0; transferred < bytes; transferred++)
8.38 + for (transferred = 0, char_unit = 0; transferred < bytes;
8.39 + transferred += char_unit_size, char_unit++)
8.40 {
8.41 + uint32_t value = get_stored_value(&data[transferred], char_unit_size, big_endian);
8.42 +
8.43 /* Relocate the data/command level to bit 16. */
8.44
8.45 - uint32_t command = dc[transferred] ? Ssi_data_gpc_set : Ssi_data_gpc_unset;
8.46 - uint32_t value = data[transferred];
8.47 + uint32_t command = dc[char_unit] ? Ssi_data_gpc_set : Ssi_data_gpc_unset;
8.48
8.49 /* Combine the character with the data/command bit. */
8.50
8.51 - _regs[Ssi_data] = value | command;
8.52 + _regs[Ssi_data] = (value & char_mask) | command;
8.53 }
8.54
8.55 wait_busy();
8.56 @@ -324,7 +329,8 @@
8.57
8.58 uint32_t
8.59 Spi_jz4780_channel::send_units(uint32_t bytes, const uint8_t data[],
8.60 - uint8_t unit_size, uint8_t char_size)
8.61 + uint8_t unit_size, uint8_t char_size,
8.62 + bool big_endian)
8.63 {
8.64 configure_transfer(char_size);
8.65
8.66 @@ -333,10 +339,7 @@
8.67
8.68 for (transferred = 0; transferred < bytes; transferred += unit_size)
8.69 {
8.70 - uint32_t value = 0;
8.71 -
8.72 - for (uint8_t byte = 0; byte < unit_size; byte++)
8.73 - value = (value << 8) | data[transferred + byte];
8.74 + uint32_t value = get_stored_value(&data[transferred], unit_size, big_endian);
8.75
8.76 /* Relocate any command bit to bit 16 for byte characters. */
8.77
8.78 @@ -345,8 +348,7 @@
8.79
8.80 /* Combine the character portion of the unit with the command. */
8.81
8.82 - value = (value & char_mask) | command;
8.83 - _regs[Ssi_data] = value;
8.84 + _regs[Ssi_data] = (value & char_mask) | command;
8.85 }
8.86
8.87 wait_busy();
8.88 @@ -358,12 +360,23 @@
8.89 unit size in bytes and character size in bits. */
8.90
8.91 uint32_t
8.92 -Spi_jz4780_channel::transfer(l4re_dma_space_dma_addr_t paddr,
8.93 +Spi_jz4780_channel::transfer(l4_addr_t vaddr,
8.94 + l4re_dma_space_dma_addr_t paddr,
8.95 uint32_t count, uint8_t unit_size,
8.96 uint8_t char_size,
8.97 l4_addr_t desc_vaddr,
8.98 l4re_dma_space_dma_addr_t desc_paddr)
8.99 {
8.100 + /* Employ a non-DMA transfer if no usable physical address is provided.
8.101 + Assume little endian byte ordering in line with the native value
8.102 + representation. */
8.103 +
8.104 + if (!paddr)
8.105 + return send_units(count, (const uint8_t *) vaddr, unit_size, char_size,
8.106 + false);
8.107 +
8.108 + /* Configure and initiate a DMA transfer with optional descriptor. */
8.109 +
8.110 configure_transfer(char_size);
8.111
8.112 uint32_t transferred = 0;
8.113 @@ -444,31 +457,34 @@
8.114 }
8.115
8.116 uint32_t jz4780_spi_send_dc(void *channel, uint32_t bytes, const uint8_t data[],
8.117 - const int dc[])
8.118 + const int dc[], uint8_t char_size, int big_endian)
8.119 {
8.120 - return static_cast<Spi_jz4780_channel *>(channel)->send_dc(bytes, data, dc);
8.121 + return static_cast<Spi_jz4780_channel *>(channel)->send_dc(bytes, data, dc,
8.122 + char_size, big_endian);
8.123 }
8.124
8.125 uint32_t jz4780_spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],
8.126 - uint8_t unit_size, uint8_t char_size)
8.127 + uint8_t unit_size, uint8_t char_size, int big_endian)
8.128 {
8.129 return static_cast<Spi_jz4780_channel *>(channel)->send_units(bytes, data,
8.130 - unit_size, char_size);
8.131 + unit_size, char_size, big_endian);
8.132 }
8.133
8.134 -uint32_t jz4780_spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
8.135 +uint32_t jz4780_spi_transfer(void *channel, l4_addr_t vaddr,
8.136 + l4re_dma_space_dma_addr_t paddr,
8.137 uint32_t count, uint8_t unit_size,
8.138 uint8_t char_size)
8.139 {
8.140 - return static_cast<Spi_jz4780_channel *>(channel)->transfer(paddr, count,
8.141 - unit_size, char_size);
8.142 + return static_cast<Spi_jz4780_channel *>(channel)->transfer(vaddr, paddr,
8.143 + count, unit_size, char_size);
8.144 }
8.145
8.146 -uint32_t jz4780_spi_transfer_descriptor(void *channel, l4re_dma_space_dma_addr_t paddr,
8.147 +uint32_t jz4780_spi_transfer_descriptor(void *channel, l4_addr_t vaddr,
8.148 + l4re_dma_space_dma_addr_t paddr,
8.149 uint32_t count, uint8_t unit_size,
8.150 uint8_t char_size, l4_addr_t desc_vaddr,
8.151 l4re_dma_space_dma_addr_t desc_paddr)
8.152 {
8.153 - return static_cast<Spi_jz4780_channel *>(channel)->transfer(paddr, count,
8.154 - unit_size, char_size, desc_vaddr, desc_paddr);
8.155 + return static_cast<Spi_jz4780_channel *>(channel)->transfer(vaddr, paddr,
8.156 + count, unit_size, char_size, desc_vaddr, desc_paddr);
8.157 }
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/pkg/devices/util/include/byteorder.h Tue Nov 14 00:02:42 2023 +0100
9.3 @@ -0,0 +1,33 @@
9.4 +/*
9.5 + * Byte ordering utilities.
9.6 + *
9.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
9.8 + *
9.9 + * This program is free software; you can redistribute it and/or
9.10 + * modify it under the terms of the GNU General Public License as
9.11 + * published by the Free Software Foundation; either version 2 of
9.12 + * the License, or (at your option) any later version.
9.13 + *
9.14 + * This program is distributed in the hope that it will be useful,
9.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.17 + * GNU General Public License for more details.
9.18 + *
9.19 + * You should have received a copy of the GNU General Public License
9.20 + * along with this program; if not, write to the Free Software
9.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
9.22 + * Boston, MA 02110-1301, USA
9.23 + */
9.24 +
9.25 +#pragma once
9.26 +
9.27 +#include <l4/sys/compiler.h>
9.28 +#include <stdint.h>
9.29 +
9.30 +EXTERN_C_BEGIN
9.31 +
9.32 +uint32_t get_stored_value(const uint8_t data[], uint8_t bytes, bool big_endian);
9.33 +
9.34 +void set_stored_value(uint32_t value, uint8_t data[], uint8_t bytes, bool big_endian);
9.35 +
9.36 +EXTERN_C_END
10.1 --- a/pkg/devices/util/src/Makefile Mon Nov 13 01:20:09 2023 +0100
10.2 +++ b/pkg/devices/util/src/Makefile Tue Nov 14 00:02:42 2023 +0100
10.3 @@ -4,7 +4,7 @@
10.4 TARGET = libdevice_util.o.a libdevice_util.o.so
10.5 PC_FILENAME := libdevice-util
10.6
10.7 -SRC_CC := dataspace.cc dl.cc dma.cc event-loop.cc memory.cc
10.8 +SRC_CC := byteorder.cc dataspace.cc dl.cc dma.cc event-loop.cc memory.cc
10.9
10.10 PRIVATE_INCDIR += $(PKGDIR)/util/include
10.11
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/pkg/devices/util/src/byteorder.cc Tue Nov 14 00:02:42 2023 +0100
11.3 @@ -0,0 +1,62 @@
11.4 +/*
11.5 + * Byte ordering utilities.
11.6 + *
11.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk>
11.8 + *
11.9 + * This program is free software; you can redistribute it and/or
11.10 + * modify it under the terms of the GNU General Public License as
11.11 + * published by the Free Software Foundation; either version 2 of
11.12 + * the License, or (at your option) any later version.
11.13 + *
11.14 + * This program is distributed in the hope that it will be useful,
11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.17 + * GNU General Public License for more details.
11.18 + *
11.19 + * You should have received a copy of the GNU General Public License
11.20 + * along with this program; if not, write to the Free Software
11.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
11.22 + * Boston, MA 02110-1301, USA
11.23 + */
11.24 +
11.25 +#include "byteorder.h"
11.26 +
11.27 +
11.28 +
11.29 +uint32_t get_stored_value(const uint8_t data[], uint8_t bytes, bool big_endian)
11.30 +{
11.31 + uint32_t value = 0;
11.32 +
11.33 + if (big_endian)
11.34 + {
11.35 + for (uint8_t byte = 0; byte < bytes; byte++)
11.36 + value = (value << 8) | data[byte];
11.37 + }
11.38 + else
11.39 + {
11.40 + for (uint8_t byte = bytes; byte; byte--)
11.41 + value = (value << 8) | data[byte - 1];
11.42 + }
11.43 +
11.44 + return value;
11.45 +}
11.46 +
11.47 +void set_stored_value(uint32_t value, uint8_t data[], uint8_t bytes, bool big_endian)
11.48 +{
11.49 + if (big_endian)
11.50 + {
11.51 + for (uint8_t byte = bytes; byte; byte--)
11.52 + {
11.53 + data[byte - 1] = value & 0xff;
11.54 + value >>= 8;
11.55 + }
11.56 + }
11.57 + else
11.58 + {
11.59 + for (uint8_t byte = 0; byte < bytes; byte++)
11.60 + {
11.61 + data[byte] = value & 0xff;
11.62 + value >>= 8;
11.63 + }
11.64 + }
11.65 +}
12.1 --- a/pkg/landfall-examples/hw_info/common.h Mon Nov 13 01:20:09 2023 +0100
12.2 +++ b/pkg/landfall-examples/hw_info/common.h Tue Nov 14 00:02:42 2023 +0100
12.3 @@ -185,10 +185,11 @@
12.4 void spi_send(void *channel, uint32_t bytes, const uint8_t data[]);
12.5
12.6 void spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],
12.7 - uint8_t unit_size, uint8_t char_size);
12.8 + uint8_t unit_size, uint8_t char_size, int big_endian);
12.9
12.10 -uint32_t spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
12.11 - uint32_t count, uint8_t unit_size, uint8_t char_size,
12.12 +uint32_t spi_transfer(void *channel, l4_addr_t vaddr,
12.13 + l4re_dma_space_dma_addr_t paddr, uint32_t count,
12.14 + uint8_t unit_size, uint8_t char_size,
12.15 l4_addr_t desc_vaddr, l4re_dma_space_dma_addr_t desc_paddr);
12.16
12.17
12.18 @@ -232,3 +233,13 @@
12.19 {
12.20 const uint32_t pull_ups, pull_downs;
12.21 };
12.22 +
12.23 +
12.24 +
12.25 +/* Memory definitions. */
12.26 +
12.27 +struct memory_region
12.28 +{
12.29 + unsigned int size;
12.30 + l4_addr_t addr;
12.31 +};
13.1 --- a/pkg/landfall-examples/hw_info/defs.h Mon Nov 13 01:20:09 2023 +0100
13.2 +++ b/pkg/landfall-examples/hw_info/defs.h Tue Nov 14 00:02:42 2023 +0100
13.3 @@ -27,7 +27,7 @@
13.4
13.5 /* Memory regions. */
13.6
13.7 -extern const char *memory_regions[];
13.8 +extern const char *io_memory_regions[];
13.9
13.10
13.11
14.1 --- a/pkg/landfall-examples/hw_info/hw_info.c Mon Nov 13 01:20:09 2023 +0100
14.2 +++ b/pkg/landfall-examples/hw_info/hw_info.c Tue Nov 14 00:02:42 2023 +0100
14.3 @@ -48,6 +48,14 @@
14.4
14.5 static l4_cap_idx_t icucap;
14.6
14.7 +/* Memory definitions. */
14.8 +
14.9 +static const unsigned int num_memory_regions = 8;
14.10 +
14.11 +static struct memory_region memory_regions[] = {
14.12 + {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
14.13 + };
14.14 +
14.15
14.16
14.17 /* Device and resource discovery. */
14.18 @@ -118,14 +126,14 @@
14.19 return token;
14.20 }
14.21
14.22 -static int read_increment(const char *message, int *increment)
14.23 +static int read_flag(const char *message, int *value, const char *flag, size_t n)
14.24 {
14.25 char *token = read_token(message);
14.26
14.27 if (token == NULL)
14.28 return 0;
14.29
14.30 - *increment = !strncmp(token, "i", 1);
14.31 + *value = !strncmp(token, flag, n);
14.32 return 1;
14.33 }
14.34
14.35 @@ -228,6 +236,23 @@
14.36 return &dma_regions[num];
14.37 }
14.38
14.39 +static struct memory_region *_get_memory_region(void)
14.40 +{
14.41 + int num = get_region_number(num_memory_regions);
14.42 +
14.43 + if (num < 0)
14.44 + return NULL;
14.45 +
14.46 + return &memory_regions[num];
14.47 +}
14.48 +
14.49 +static int get_memory_region(unsigned int size, l4_addr_t *addr)
14.50 +{
14.51 + *addr = (l4_addr_t) calloc(size, sizeof(char));
14.52 +
14.53 + return !(*addr);
14.54 +}
14.55 +
14.56
14.57
14.58 /* AIC/I2S operations. */
14.59 @@ -600,10 +625,10 @@
14.60 if (!read_number("Transfer size", &count))
14.61 return;
14.62
14.63 - if (!read_increment("Source increment", &source_increment))
14.64 + if (!read_flag("Source increment", &source_increment, "i", 1))
14.65 return;
14.66
14.67 - if (!read_increment("Destination increment", &destination_increment))
14.68 + if (!read_flag("Destination increment", &destination_increment, "i", 1))
14.69 return;
14.70
14.71 if (!read_number("Source width", &source_width))
14.72 @@ -995,6 +1020,99 @@
14.73
14.74
14.75
14.76 +/* Memory operations. */
14.77 +
14.78 +static void list_memory_regions(void)
14.79 +{
14.80 + unsigned int num;
14.81 + struct memory_region *region;
14.82 + unsigned int i;
14.83 +
14.84 + for (num = 0; num < num_memory_regions; num++)
14.85 + {
14.86 + printf("Region %d: ", num);
14.87 +
14.88 + region = &memory_regions[num];
14.89 +
14.90 + if (!region->addr)
14.91 + printf("(inactive)\n");
14.92 + else
14.93 + {
14.94 + printf("size = %d; virtual = 0x%lx; data =",
14.95 + region->size, region->addr);
14.96 +
14.97 + for (i = 0; (i < region->size) && (i < 16); i++)
14.98 + printf(" %02x", *((uint8_t *) region->addr + i));
14.99 +
14.100 + printf("\n");
14.101 + }
14.102 + }
14.103 +}
14.104 +
14.105 +static void new_memory_region(void)
14.106 +{
14.107 + struct memory_region *region = _get_memory_region();
14.108 +
14.109 + if (region == NULL)
14.110 + {
14.111 + list_memory_regions();
14.112 + return;
14.113 + }
14.114 +
14.115 + if (region->addr)
14.116 + {
14.117 + printf("Region already defined.\n");
14.118 + return;
14.119 + }
14.120 +
14.121 + if (!read_number("Size", ®ion->size))
14.122 + return;
14.123 +
14.124 + if (get_memory_region(region->size, ®ion->addr))
14.125 + printf("Could not allocate region.\n");
14.126 +}
14.127 +
14.128 +static void set_memory_region(void)
14.129 +{
14.130 + char *token;
14.131 + struct memory_region *region = _get_memory_region();
14.132 + FILE *fp;
14.133 +
14.134 + if (region == NULL)
14.135 + {
14.136 + list_memory_regions();
14.137 + return;
14.138 + }
14.139 +
14.140 + if (!region->addr)
14.141 + {
14.142 + printf("Region needs creating.\n");
14.143 + return;
14.144 + }
14.145 +
14.146 + memset((void *) region->addr, 0, region->size);
14.147 +
14.148 + if ((token = read_token("Filename")) == NULL)
14.149 + return;
14.150 +
14.151 + /* Populate the region from the file. */
14.152 +
14.153 + fp = fopen(token, "r");
14.154 +
14.155 + if (fp == NULL)
14.156 + {
14.157 + printf("File not readable.\n");
14.158 + return;
14.159 + }
14.160 +
14.161 + fread((char *) region->addr, sizeof(char), region->size, fp);
14.162 + fclose(fp);
14.163 +
14.164 + l4_cache_flush_data(region->addr, region->addr + region->size);
14.165 +}
14.166 +
14.167 +
14.168 +
14.169 /* SPI operations. */
14.170
14.171 static void new_spi_channel(void *spi, void *gpio[])
14.172 @@ -1121,22 +1239,32 @@
14.173 while ((byte < 256) && read_encoded_number(NULL, "%2x", &value))
14.174 buffer[byte++] = value;
14.175
14.176 - spi_send_units(channel, byte, (uint8_t *) buffer, unit_size, char_size);
14.177 + /* Explicitly indicate big endian data. */
14.178 +
14.179 + spi_send_units(channel, byte, (uint8_t *) buffer, unit_size, char_size, 1);
14.180 }
14.181
14.182 static void spi_transfer_data(void)
14.183 {
14.184 void *channel = get_channel(num_spi_channels, spi_channels, NULL);
14.185 - struct dma_region *region, *desc_region;
14.186 + struct dma_region *dma_region = NULL, *desc_region;
14.187 + struct memory_region *memory_region = NULL;
14.188 unsigned int char_size, unit_size;
14.189 uint32_t count, transferred;
14.190 + int using_dma;
14.191
14.192 if (channel == NULL)
14.193 return;
14.194
14.195 - region = _get_dma_region();
14.196 + if (!read_flag("Using DMA", &using_dma, "d", 1))
14.197 + return;
14.198
14.199 - if (region == NULL)
14.200 + if (using_dma)
14.201 + dma_region = _get_dma_region();
14.202 + else
14.203 + memory_region = _get_memory_region();
14.204 +
14.205 + if ((dma_region == NULL) && (memory_region == NULL))
14.206 return;
14.207
14.208 if (!read_number("Transfer size", &count))
14.209 @@ -1148,11 +1276,18 @@
14.210 if (!read_number("Character size", &char_size))
14.211 return;
14.212
14.213 - desc_region = _get_dma_region();
14.214 + if (using_dma)
14.215 + {
14.216 + desc_region = _get_dma_region();
14.217
14.218 - transferred = spi_transfer(channel, region->paddr, count, unit_size, char_size,
14.219 - desc_region != NULL ? desc_region->vaddr : 0,
14.220 - desc_region != NULL ? desc_region->paddr : 0);
14.221 + transferred = spi_transfer(channel, dma_region->vaddr, dma_region->paddr, count,
14.222 + unit_size, char_size,
14.223 + desc_region != NULL ? desc_region->vaddr : 0,
14.224 + desc_region != NULL ? desc_region->paddr : 0);
14.225 + }
14.226 + else
14.227 + transferred = spi_transfer(channel, memory_region->addr, 0, count,
14.228 + unit_size, char_size, 0, 0);
14.229
14.230 printf("Transferred: %d\n", transferred);
14.231 }
14.232 @@ -1174,7 +1309,7 @@
14.233 else if (!strcmp(token, "t") || !strcmp(token, "transfer"))
14.234 aic_transfer_data();
14.235 else
14.236 - printf("aic channel | list | set | transfer\n");
14.237 + printf("aic channel | list | transfer\n");
14.238 }
14.239 else
14.240 list_channels(num_aic_channels, aic_channels);
14.241 @@ -1270,6 +1405,23 @@
14.242 list_i2c_channels();
14.243 }
14.244
14.245 +static void handle_memory(void)
14.246 +{
14.247 + char *token;
14.248 +
14.249 + if ((token = read_token(NULL)) != NULL)
14.250 + {
14.251 + if (!strcmp(token, "r") || !strcmp(token, "region"))
14.252 + new_memory_region();
14.253 + else if (!strcmp(token, "s") || !strcmp(token, "set"))
14.254 + set_memory_region();
14.255 + else
14.256 + printf("memory region | set\n");
14.257 + }
14.258 + else
14.259 + list_memory_regions();
14.260 +}
14.261 +
14.262 static void handle_spi(void *spi, void *gpio[])
14.263 {
14.264 char *token;
14.265 @@ -1321,7 +1473,7 @@
14.266
14.267 printf("Access CPM...\n");
14.268
14.269 - if ((result = get_memory(memory_regions[CPM], &cpm_base, &cpm_base_end)) < 0)
14.270 + if ((result = get_memory(io_memory_regions[CPM], &cpm_base, &cpm_base_end)) < 0)
14.271 return 1;
14.272
14.273 printf("CPM at 0x%lx...0x%lx.\n", cpm_base, cpm_base_end);
14.274 @@ -1330,14 +1482,14 @@
14.275
14.276 printf("Access DMA...\n");
14.277
14.278 - if ((result = get_memory(memory_regions[DMA], &dma_base, &dma_base_end)) < 0)
14.279 + if ((result = get_memory(io_memory_regions[DMA], &dma_base, &dma_base_end)) < 0)
14.280 return 1;
14.281
14.282 printf("DMA at 0x%lx...0x%lx.\n", dma_base, dma_base_end);
14.283
14.284 dma = dma_init(dma_base, dma_base_end, cpm);
14.285
14.286 - if (get_irq(memory_regions[DMA], &dma_irq_start, &dma_irq_end) < 0)
14.287 + if (get_irq(io_memory_regions[DMA], &dma_irq_start, &dma_irq_end) < 0)
14.288 return 1;
14.289
14.290 printf("IRQ range at %d...%d.\n", dma_irq_start, dma_irq_end);
14.291 @@ -1349,7 +1501,7 @@
14.292
14.293 printf("Access GPIO...\n");
14.294
14.295 - if ((result = get_memory(memory_regions[GPIO], &gpio_base, &gpio_base_end)) < 0)
14.296 + if ((result = get_memory(io_memory_regions[GPIO], &gpio_base, &gpio_base_end)) < 0)
14.297 return 1;
14.298
14.299 printf("GPIO at 0x%lx...0x%lx.\n", gpio_base, gpio_base_end);
14.300 @@ -1360,21 +1512,21 @@
14.301
14.302 printf("Access I2C...\n");
14.303
14.304 - if ((result = get_memory(memory_regions[I2C], &i2c_base, &i2c_base_end)) < 0)
14.305 + if ((result = get_memory(io_memory_regions[I2C], &i2c_base, &i2c_base_end)) < 0)
14.306 return 1;
14.307
14.308 printf("I2C at 0x%lx...0x%lx.\n", i2c_base, i2c_base_end);
14.309
14.310 i2c = i2c_init(i2c_base, i2c_base_end, cpm, 100000);
14.311
14.312 - if (get_irq(memory_regions[I2C], &i2c_irq_start, &i2c_irq_end) < 0)
14.313 + if (get_irq(io_memory_regions[I2C], &i2c_irq_start, &i2c_irq_end) < 0)
14.314 return 1;
14.315
14.316 printf("IRQ range at %d...%d.\n", i2c_irq_start, i2c_irq_end);
14.317
14.318 printf("Access AIC...\n");
14.319
14.320 - if ((result = get_memory_complete(memory_regions[AIC], &aic_base, &aic_base_end,
14.321 + if ((result = get_memory_complete(io_memory_regions[AIC], &aic_base, &aic_base_end,
14.322 &aic_phys_base, &aic_phys_base_end)) < 0)
14.323 return 1;
14.324
14.325 @@ -1384,7 +1536,7 @@
14.326
14.327 printf("Access SSI...\n");
14.328
14.329 - if ((result = get_memory_complete(memory_regions[SSI], &ssi_base, &ssi_base_end,
14.330 + if ((result = get_memory_complete(io_memory_regions[SSI], &ssi_base, &ssi_base_end,
14.331 &ssi_phys_base, &ssi_phys_base_end)) < 0)
14.332 return 1;
14.333
14.334 @@ -1435,6 +1587,11 @@
14.335 else if (!strcmp(token, "i") || !strcmp(token, "i2c"))
14.336 handle_i2c(i2c);
14.337
14.338 + /* Generic memory commands. */
14.339 +
14.340 + else if (!strcmp(token, "m") || !strcmp(token, "mem") || !strcmp(token, "memory"))
14.341 + handle_memory();
14.342 +
14.343 /* SPI commands. */
14.344
14.345 else if (!strcmp(token, "s") || !strcmp(token, "spi"))
15.1 --- a/pkg/landfall-examples/hw_info/jz4780.c Mon Nov 13 01:20:09 2023 +0100
15.2 +++ b/pkg/landfall-examples/hw_info/jz4780.c Tue Nov 14 00:02:42 2023 +0100
15.3 @@ -375,28 +375,25 @@
15.4 }
15.5
15.6 void spi_send_units(void *channel, uint32_t bytes, const uint8_t data[],
15.7 - uint8_t unit_size, uint8_t char_size)
15.8 + uint8_t unit_size, uint8_t char_size, int big_endian)
15.9 {
15.10 - spi_hybrid_send_units(channel, bytes, data, unit_size, char_size);
15.11 + spi_hybrid_send_units(channel, bytes, data, unit_size, char_size, big_endian);
15.12 }
15.13
15.14 -uint32_t spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
15.15 - uint32_t count, uint8_t unit_size, uint8_t char_size,
15.16 +uint32_t spi_transfer(void *channel, l4_addr_t vaddr,
15.17 + l4re_dma_space_dma_addr_t paddr, uint32_t count,
15.18 + uint8_t unit_size, uint8_t char_size,
15.19 l4_addr_t desc_vaddr, l4re_dma_space_dma_addr_t desc_paddr)
15.20 {
15.21 - /* Transfer is not supported by the common interface. */
15.22 -
15.23 - void *ch = spi_hybrid_get_raw_channel(channel);
15.24 -
15.25 - return jz4780_spi_transfer_descriptor(ch, paddr, count, unit_size, char_size,
15.26 - desc_vaddr, desc_paddr);
15.27 + return spi_hybrid_transfer_descriptor(channel, vaddr, paddr, count, unit_size,
15.28 + char_size, desc_vaddr, desc_paddr);
15.29 }
15.30
15.31
15.32
15.33 /* Memory regions. */
15.34
15.35 -const char *memory_regions[] = {
15.36 +const char *io_memory_regions[] = {
15.37 [AIC] = "jz4780-aic",
15.38 [CPM] = "jz4780-cpm",
15.39 [DMA] = "jz4780-dma",
16.1 --- a/pkg/landfall-examples/hw_info/x1600.c Mon Nov 13 01:20:09 2023 +0100
16.2 +++ b/pkg/landfall-examples/hw_info/x1600.c Tue Nov 14 00:02:42 2023 +0100
16.3 @@ -367,28 +367,25 @@
16.4 }
16.5
16.6 void spi_send_units(void *channel, uint32_t bytes, const uint8_t data[], uint8_t unit_size,
16.7 - uint8_t char_size)
16.8 + uint8_t char_size, int big_endian)
16.9 {
16.10 - spi_hybrid_send_units(channel, bytes, data, unit_size, char_size);
16.11 + spi_hybrid_send_units(channel, bytes, data, unit_size, char_size, big_endian);
16.12 }
16.13
16.14 -uint32_t spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr,
16.15 - uint32_t count, uint8_t unit_size, uint8_t char_size,
16.16 +uint32_t spi_transfer(void *channel, l4_addr_t vaddr,
16.17 + l4re_dma_space_dma_addr_t paddr, uint32_t count,
16.18 + uint8_t unit_size, uint8_t char_size,
16.19 l4_addr_t desc_vaddr, l4re_dma_space_dma_addr_t desc_paddr)
16.20 {
16.21 - /* Transfer is not supported by the common interface. */
16.22 -
16.23 - void *ch = spi_hybrid_get_raw_channel(channel);
16.24 -
16.25 - return jz4780_spi_transfer_descriptor(ch, paddr, count, unit_size, char_size,
16.26 - desc_vaddr, desc_paddr);
16.27 + return spi_hybrid_transfer_descriptor(channel, vaddr, paddr, count, unit_size,
16.28 + char_size, desc_vaddr, desc_paddr);
16.29 }
16.30
16.31
16.32
16.33 /* Memory regions. */
16.34
16.35 -const char *memory_regions[] = {
16.36 +const char *io_memory_regions[] = {
16.37 [AIC] = "x1600-aic",
16.38 [CPM] = "x1600-cpm",
16.39 [DMA] = "x1600-dma",