# HG changeset patch # User Louis Opter # Date 1374795913 25200 # Node ID f3c7e9b0c5cfe82c6bff8887176e57b807ed51a4 # Parent 2a7126613c70ed150a2e0c6c850fc58cfe4ff8a9 WIP on the DMA API diff -r 2a7126613c70 -r f3c7e9b0c5cf rathaxes_samples_e1000_add_a_dma_abstraction.patch --- a/rathaxes_samples_e1000_add_a_dma_abstraction.patch Mon Jul 22 16:04:12 2013 -0700 +++ b/rathaxes_samples_e1000_add_a_dma_abstraction.patch Thu Jul 25 16:45:13 2013 -0700 @@ -1,5 +1,5 @@ # HG changeset patch -# Parent af7a1f8589d632497e2f2574570f5153cae59b91 +# Parent 61470dc5e775a696da551b5227663bf2659f8f4b e1000: start a DMA allocation/mapping abstraction It currently matches a lot the Linux DMA API but it should be usable by @@ -35,7 +35,7 @@ new file mode 100644 --- /dev/null +++ b/rathaxes/samples/e1000/dma.blt -@@ -0,0 +1,89 @@ +@@ -0,0 +1,103 @@ +with DMA, Builtin, LKM, Device +{ + template type DMA::AbstractDMAHandle() @@ -52,7 +52,21 @@ + + map + { -+ k_dma_handle: ((dma_addr_t)${self}); ++ k_dma_handle: (dma_addr_t)(${self}); ++ } ++ } ++ ++ template type DMA::DMAHandle() ++ { ++ decl data_types() ++ { ++ ${DMA::AbstractDMAHandle} data; ++ } ++ ++ map ++ { ++ /* XXX: we should use ${DMA::AbstractDMAHandle} here: */ ++ dma_handle: (dma_addr_t)(${self}); + } + } + @@ -65,7 +79,7 @@ + + map + { -+ k_dma_direction: ((enum dma_data_direction)${self}); ++ k_dma_direction: (enum dma_data_direction)(${self}); + } + } + @@ -81,7 +95,7 @@ + map + { + /* XXX: we should use ${DMA::AbstractDMADirection} here: */ -+ dma_direction: ((enum dma_data_direction)${self}); ++ dma_direction: (enum dma_data_direction)(${self}); + } + } + @@ -89,7 +103,7 @@ + { + chunk ::CALL() + { -+ ((${DMA::DMA::AbstractDMAHandle})dma_map_single(${dev.k_device}, ${buf}, ${size}, ${dir.dma_direction})); ++ ((${DMA::DMAHandle})dma_map_single(${dev.k_device}, ${buf}, ${size}, ${dir.dma_direction})); + } + } + @@ -129,7 +143,7 @@ new file mode 100644 --- /dev/null +++ b/rathaxes/samples/e1000/dma.rti -@@ -0,0 +1,48 @@ +@@ -0,0 +1,54 @@ +interface DMA : Builtin, LKM, Device +{ + provided type AbstractDMAHandle @@ -139,6 +153,12 @@ + attribute Builtin::symbol.scalar k_dma_handle; + } + ++ provided type DMAHandle ++ { ++ decl data_types(); ++ attribute AbstractDMAHandle.scalar dma_handle; ++ } ++ + provided type AbstractDMADirection + { + decl data_types(); diff -r 2a7126613c70 -r f3c7e9b0c5cf rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch --- a/rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch Mon Jul 22 16:04:12 2013 -0700 +++ b/rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch Thu Jul 25 16:45:13 2013 -0700 @@ -1,5 +1,5 @@ # HG changeset patch -# Parent 22cdd951a10d1b8b06daf6448da73e738f21d2e3 +# Parent 3cea76c8dbc4e341f3ff42e42532bdbd3f06fcac Replace Linux specific code in Socket by DMA calls diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt @@ -11,6 +11,15 @@ { template type Socket::AbstractSKBuff() { +@@ -14,7 +14,7 @@ + + map + { +- k_sk_buff: ((struct sk_buff *)${self}); ++ k_sk_buff: (struct sk_buff *)(${self}); + } + } + @@ -22,35 +22,34 @@ { decl data_types() @@ -35,13 +44,13 @@ static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref} self) { - WARN_ON(!self->skbuff); -+ WARN_ON(!${local.self.k_sk_buff}); ++ WARN_ON(!${local.self.sk_buff}); + -+ ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.self.k_sk_buff}->protocol) }; ++ ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.self.sk_buff.k_sk_buff}->protocol) }; + static const char * const ip_summed_values[] = { + "none", "unnecessary", "complete", "partial" + }; -+ struct skb_shared_info *shinfo = skb_shinfo(${local.self.k_sk_buff}); ++ struct skb_shared_info *shinfo = skb_shinfo(${local.self.sk_buff.k_sk_buff}); /* * We should use a Rathaxes log abstraction instead of pr_info here, @@ -58,14 +67,14 @@ pr_info( "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n" "\t len = %-5u data_len = %-5u head_len = %-5u\n" -@@ -58,30 +57,26 @@ +@@ -58,53 +57,46 @@ "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u", /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */ ethernet_proto.id, ${local.ethernet_proto.str}, - ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed], - ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}), -+ ${local.self.k_sk_buff}->ip_summed, ip_summed_values[${local.self.k_sk_buff}->ip_summed], -+ ${local.self.k_sk_buff}->len, ${local.self.k_sk_buff}->data_len, skb_headlen(${local.self.k_sk_buff}), ++ ${local.self.sk_buff.k_sk_buff}->ip_summed, ip_summed_values[${local.self.sk_buff.k_sk_buff}->ip_summed], ++ ${local.self.sk_buff.k_sk_buff}->len, ${local.self.sk_buff.k_sk_buff}->data_len, skb_headlen(${local.self.sk_buff.k_sk_buff}), shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type ); } @@ -77,8 +86,8 @@ + ${DMA::DMADirection.scalar} direction) { - ${Socket::AbstractSKBuff.ref} skb = self->skbuff; -+ WARN_ON(!${local.self.k_sk_buff}); -+ WARN_ON(${local.self.k_dma_handle}); ++ WARN_ON(!${local.self.sk_buff}); ++ WARN_ON(${local.self.dma_handle}); - WARN_ON(!${local.skb.k_sk_buff}); - WARN_ON(self->dma_handle); @@ -89,36 +98,62 @@ - skb_headlen(${local.skb.k_sk_buff}), - direction); - int err = dma_mapping_error(dev, self->dma_handle); -+ unsigned int len = skb_headlen(${local.skb.k_sk_buff}); ++ unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff}); + ${cast local.len as Builtin::number}; -+ ${local.self.k_dma_handle} = ${DMA::map(local.dev, local.skb.k_sk_buff, local.len, local.direction)}; -+ int err = ${DMA::mapping_error(local.dev, local.self.k_dma_handle)}; ++ ${local.self.dma_handle} = ${DMA::map(local.dev, local.self.sk_buff.k_sk_buff, local.len, local.direction)}; ++ int err = ${DMA::mapping_error(local.dev, local.self.dma_handle)}; if (err) { - self->dma_handle = 0; -+ ${local.self.k_dma_handle} = 0; ++ ${local.self.dma_handle} = 0; return err; } return 0; -@@ -89,7 +84,7 @@ + } static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref} self, - struct device *dev, +- struct device *dev, - enum dma_data_direction direction) ++ ${Device::AbstractDevice.ref} dev, + ${DMA::DMADirection} direction) { - ${Socket::AbstractSKBuff.ref} skb = self->skbuff; +- ${Socket::AbstractSKBuff.ref} skb = self->skbuff; ++ WARN_ON(!${local.self.sk_buff}); -@@ -100,7 +95,7 @@ - dma_unmap_single(dev, - self->dma_handle, - skb_headlen(${local.skb.k_sk_buff}), +- WARN_ON(!${local.skb.k_sk_buff}); +- +- if (self->dma_handle) ++ if (${local.self.dma_handle}) + { +- dma_unmap_single(dev, +- self->dma_handle, +- skb_headlen(${local.skb.k_sk_buff}), - direction); -+ ${local.direction.dma_direction}); - self->dma_handle = 0; +- self->dma_handle = 0; ++ unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff}); ++ ${cast local.len as Builtin::number}; ++ ${DMA::unmap(local.dev, local.self.dma_handle, local.len, local.direction)}; ++ ${local.self.dma_handle} = 0; } - dev_kfree_skb_any(${local.skb.k_sk_buff}); -@@ -126,30 +121,32 @@ +- dev_kfree_skb_any(${local.skb.k_sk_buff}); +- self->skbuff = 0; ++ dev_kfree_skb_any(${local.self.sk_buff.k_sk_buff}); ++ ${local.self.sk_buff} = NULL; + } + } + +@@ -115,8 +107,8 @@ + */ + method init(Socket::AbstractSKBuff kernel_skb) + { +- ${self}.skbuff = ${kernel_skb}; +- ${self}.dma_handle = 0; ++ ${self.sk_buff} = ${kernel_skb}; ++ ${self.dma_handle} = 0; + } + + method dump_infos() +@@ -126,30 +118,37 @@ method map_to(Device::AbstractDevice dev) { @@ -129,19 +164,19 @@ method map_from(Device::AbstractDevice dev) { - rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_FROM_DEVICE); -+ rtx_socket_skbuff_map(${self}, ${dev.k_device}, RTX_DMA_FROM_DEVICE); ++ rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_FROM_DEVICE); } method unmap_to_and_free(Device::AbstractDevice dev) { - rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_TO_DEVICE); -+ rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, RTX_DMA_TO_DEVICE); ++ rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_TO_DEVICE); } method unmap_from_and_free(Device::AbstractDevice dev) { - rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_FROM_DEVICE); -+ rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, RTX_DMA_FROM_DEVICE); ++ rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_FROM_DEVICE); } map @@ -154,8 +189,13 @@ + // field of the sk_buff. We should determine if all the sk_buff + // management can be abstracted from the user. But this is at least + // useful for internal use: -+ k_sk_buff: ((struct skbuff *)(${self}->skbuff)); -+ k_dma_handle: ((dma_addr_t)(${self}->dma_handle)); ++ sk_buff: (${self})->skbuff; ++ // XXX: We need to cast here so we can do things like ++ // var.dma_handle = 0; but the type shouldn't be hardcoded (at the ++ // same time ${DMA:AbstractDMAHandle} couldn't be used because that ++ // would yield to a struct type which you can't assign directly; ++ // but maybe doing the ->data in that case would be acceptable). ++ dma_handle: (dma_addr_t)((${self})->dma_handle); } } } @@ -173,7 +213,7 @@ method unmap_to_and_free(Device::AbstractDevice); method unmap_from_and_free(Device::AbstractDevice); + -+ attribute Socket::AbstractSKBuff.ref k_sk_buff; -+ attribute DMA::AbstractDMAHandle.scalar k_dma_handle; ++ attribute Socket::AbstractSKBuff.ref sk_buff; ++ attribute DMA::AbstractDMAHandle.scalar dma_handle; } }