1.1 --- a/pkg/landfall-examples/letux400_dma/letux400_dma.cc Sun May 28 22:35:09 2023 +0200
1.2 +++ b/pkg/landfall-examples/letux400_dma/letux400_dma.cc Mon May 29 21:18:33 2023 +0200
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * Test DMA transfers.
1.6 *
1.7 - * Copyright (C) 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -25,14 +25,19 @@
1.13
1.14 #include <l4/re/c/util/cap_alloc.h>
1.15 #include <l4/re/c/dataspace.h>
1.16 +#include <l4/re/c/dma_space.h>
1.17 #include <l4/re/c/mem_alloc.h>
1.18 #include <l4/re/c/rm.h>
1.19 +#include <l4/re/protocols.h>
1.20
1.21 +#include <l4/sys/err.h>
1.22 #include <l4/sys/factory.h>
1.23 #include <l4/sys/icu.h>
1.24 #include <l4/sys/irq.h>
1.25 #include <l4/sys/rcv_endpoint.h>
1.26
1.27 +#include <l4/vbus/vbus.h>
1.28 +
1.29 #include <stdio.h>
1.30 #include <string.h>
1.31 #include <unistd.h>
1.32 @@ -53,14 +58,55 @@
1.33
1.34 int main(void)
1.35 {
1.36 + long err;
1.37 void *cpm;
1.38 - void *dma, *dma0;
1.39 + void *dmac, *dma0;
1.40 + l4_cap_idx_t dma, vbus;
1.41 +
1.42 + dma = l4re_util_cap_alloc();
1.43 + vbus = l4re_env_get_cap("vbus");
1.44 +
1.45 + if (l4_is_invalid_cap(dma))
1.46 + {
1.47 + printf("Could not allocate DMA capability.\n");
1.48 + return 1;
1.49 + }
1.50 +
1.51 + /* Create the DMA space. */
1.52 +
1.53 + err = l4_error(l4_factory_create(l4re_env()->mem_alloc, L4RE_PROTO_DMA_SPACE, dma));
1.54 +
1.55 + if (err)
1.56 + {
1.57 + printf("Could not create DMA space: %s\n", l4sys_errtostr(err));
1.58 + return 1;
1.59 + }
1.60 +
1.61 + l4vbus_device_handle_t device = L4VBUS_NULL;
1.62 + l4vbus_resource_t dma_resource;
1.63 +
1.64 + if (!find_resource(&device, &dma_resource, L4VBUS_RESOURCE_DMA_DOMAIN))
1.65 + {
1.66 + printf("Could not find DMA domain.\n");
1.67 + return 1;
1.68 + }
1.69 +
1.70 + err = l4vbus_assign_dma_domain(vbus, dma_resource.start,
1.71 + L4VBUS_DMAD_BIND | L4VBUS_DMAD_L4RE_DMA_SPACE,
1.72 + dma);
1.73 +
1.74 + if (err)
1.75 + {
1.76 + printf("Could not assign DMA space: %s\n", l4sys_errtostr(err));
1.77 + return 1;
1.78 + }
1.79
1.80 /* Allocate memory to test transfers. */
1.81
1.82 l4_cap_idx_t ds0_mem, ds1_mem;
1.83 l4_size_t ds0_size = L4_PAGESIZE, ds0_psize, ds1_size = L4_PAGESIZE, ds1_psize;
1.84 - l4_addr_t ds0_addr, ds0_paddr, ds1_addr, ds1_paddr;
1.85 + l4_addr_t ds0_addr, ds1_addr;
1.86 + l4re_dma_space_dma_addr_t ds0_paddr, ds1_paddr;
1.87
1.88 ds0_mem = l4re_util_cap_alloc();
1.89 ds1_mem = l4re_util_cap_alloc();
1.90 @@ -79,20 +125,24 @@
1.91 }
1.92
1.93 if (l4re_rm_attach((void **) &ds0_addr, ds0_size,
1.94 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
1.95 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
1.96 ds0_mem, 0, L4_PAGESHIFT) ||
1.97 l4re_rm_attach((void **) &ds1_addr, ds1_size,
1.98 - L4RE_RM_SEARCH_ADDR | L4RE_RM_EAGER_MAP,
1.99 + L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_EAGER_MAP | L4RE_RM_F_RW,
1.100 ds1_mem, 0, L4_PAGESHIFT))
1.101 {
1.102 printf("Could not map memory.\n");
1.103 return 1;
1.104 }
1.105
1.106 - if (l4re_ds_phys(ds0_mem, 0, &ds0_paddr, &ds0_psize) ||
1.107 - l4re_ds_phys(ds1_mem, 0, &ds1_paddr, &ds1_psize))
1.108 + err = l4re_dma_space_map(dma, ds0_mem | L4_CAP_FPAGE_RW, 0, &ds0_psize, 0,
1.109 + L4RE_DMA_SPACE_BIDIRECTIONAL, &ds0_paddr) ||
1.110 + l4re_dma_space_map(dma, ds1_mem | L4_CAP_FPAGE_RW, 0, &ds1_psize, 0,
1.111 + L4RE_DMA_SPACE_BIDIRECTIONAL, &ds1_paddr);
1.112 +
1.113 + if (err)
1.114 {
1.115 - printf("Could not get physical addresses for memory.\n");
1.116 + printf("Could not get physical addresses for memory: %s\n", l4sys_errtostr(err));
1.117 return 1;
1.118 }
1.119
1.120 @@ -136,8 +186,6 @@
1.121
1.122 /* Create interrupt objects. */
1.123
1.124 - long err;
1.125 -
1.126 err = l4_error(l4_factory_create_irq(l4re_global_env->factory, irq0cap));
1.127
1.128 if (err)
1.129 @@ -192,18 +240,18 @@
1.130 /* Obtain CPM and DMA references. */
1.131
1.132 cpm = jz4730_cpm_init(cpm_base);
1.133 - dma = jz4730_dma_init(dma_base, dma_base_end, cpm);
1.134 - dma0 = jz4730_dma_get_channel(dma, 0, irq0cap);
1.135 + dmac = jz4730_dma_init(dma_base, dma_base_end, cpm);
1.136 + dma0 = jz4730_dma_get_channel(dmac, 0, irq0cap);
1.137
1.138 /* Enable DMA. */
1.139
1.140 printf("Enable DMA...\n");
1.141
1.142 - jz4730_dma_enable(dma);
1.143 + jz4730_dma_enable(dmac);
1.144
1.145 /* Transfer data between the allocated memory regions. */
1.146
1.147 - printf("Transfer from %lx to %lx...\n", ds0_paddr, ds1_paddr);
1.148 + printf("Transfer from %llx to %llx...\n", ds0_paddr, ds1_paddr);
1.149
1.150 unsigned int ntransferred = jz4730_dma_transfer(dma0, (uint32_t) ds0_paddr,
1.151 (uint32_t) ds1_paddr,