1.1 --- a/pkg/devices/lib/msc/include/msc-common.h Thu Feb 15 23:15:30 2024 +0100 1.2 +++ b/pkg/devices/lib/msc/include/msc-common.h Thu Feb 15 23:18:09 2024 +0100 1.3 @@ -144,7 +144,8 @@ 1.4 1.5 uint32_t get_status(); 1.6 1.7 - uint32_t read_block(uint8_t card, l4re_dma_space_dma_addr_t paddr); 1.8 + uint32_t read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr, 1.9 + uint32_t block_address, uint32_t block_count); 1.10 }; 1.11 1.12
2.1 --- a/pkg/devices/lib/msc/include/msc-jz4780.h Thu Feb 15 23:15:30 2024 +0100 2.2 +++ b/pkg/devices/lib/msc/include/msc-jz4780.h Thu Feb 15 23:18:09 2024 +0100 2.3 @@ -83,7 +83,8 @@ 2.4 2.5 void jz4780_msc_enable(void *msc_channel); 2.6 2.7 -uint32_t jz4780_msc_read_block(void *msc_channel, uint8_t card, 2.8 - l4re_dma_space_dma_addr_t paddr); 2.9 +uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, 2.10 + l4re_dma_space_dma_addr_t paddr, 2.11 + uint32_t block_address, uint32_t block_count); 2.12 2.13 EXTERN_C_END
3.1 --- a/pkg/devices/lib/msc/include/msc-x1600.h Thu Feb 15 23:15:30 2024 +0100 3.2 +++ b/pkg/devices/lib/msc/include/msc-x1600.h Thu Feb 15 23:18:09 2024 +0100 3.3 @@ -81,7 +81,8 @@ 3.4 3.5 void x1600_msc_enable(void *msc_channel); 3.6 3.7 -uint32_t x1600_msc_read_block(void *msc_channel, uint8_t card, 3.8 - l4re_dma_space_dma_addr_t paddr); 3.9 +uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, 3.10 + l4re_dma_space_dma_addr_t paddr, 3.11 + uint32_t block_address, uint32_t block_count); 3.12 3.13 EXTERN_C_END
4.1 --- a/pkg/devices/lib/msc/src/common.cc Thu Feb 15 23:15:30 2024 +0100 4.2 +++ b/pkg/devices/lib/msc/src/common.cc Thu Feb 15 23:18:09 2024 +0100 4.3 @@ -914,9 +914,11 @@ 4.4 4.5 // Determine whether a timeout occurred. 4.6 4.7 - bool have_response = !(_regs[Msc_interrupt_flag] & Int_response_timeout); 4.8 + bool have_response = !((_regs[Msc_interrupt_flag] & Int_response_timeout) || 4.9 + (_regs[Msc_status] & Status_response_crc_error) || 4.10 + (_regs[Msc_status] & Status_timeout_response)); 4.11 4.12 - // Acknowledge the interrupts and return the status. 4.13 + // Acknowledge the response interrupts and return the status. 4.14 4.15 ack_irq(flags); 4.16 return have_response; 4.17 @@ -1190,24 +1192,51 @@ 4.18 uint32_t 4.19 Msc_channel::recv_data(l4re_dma_space_dma_addr_t paddr, uint32_t count) 4.20 { 4.21 - return transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count); 4.22 + uint32_t flags = Int_data_transfer_done; 4.23 + 4.24 + unmask_irq(flags); 4.25 + 4.26 + uint32_t to_transfer = transfer(_msc_start + Msc_recv_data_fifo, paddr, true, count); 4.27 + 4.28 + wait_for_irq(flags); 4.29 + ack_irq(flags); 4.30 + 4.31 + if (!to_transfer || 4.32 + (_regs[Msc_status] & Status_read_crc_error) || 4.33 + (_regs[Msc_status] & Status_timeout_read)) 4.34 + return 0; 4.35 + 4.36 + return to_transfer; 4.37 } 4.38 4.39 uint32_t 4.40 Msc_channel::send_data(l4re_dma_space_dma_addr_t paddr, uint32_t count) 4.41 { 4.42 - return transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count); 4.43 + uint32_t flags = Int_data_transfer_done; 4.44 + 4.45 + unmask_irq(flags); 4.46 + 4.47 + uint32_t to_transfer = transfer(paddr, _msc_start + Msc_trans_data_fifo, false, count); 4.48 + 4.49 + wait_for_irq(flags); 4.50 + ack_irq(flags); 4.51 + 4.52 + if (!to_transfer || 4.53 + (_regs[Msc_status] & Status_write_crc_error_data) || 4.54 + (_regs[Msc_status] & Status_write_crc_error_no_status)) 4.55 + return 0; 4.56 + 4.57 + return to_transfer; 4.58 } 4.59 4.60 uint32_t 4.61 -Msc_channel::read_block(uint8_t card, l4re_dma_space_dma_addr_t paddr) 4.62 +Msc_channel::read_blocks(uint8_t card, l4re_dma_space_dma_addr_t paddr, 4.63 + uint32_t block_address, uint32_t block_count) 4.64 { 4.65 uint32_t block_size = 1 << _csd[card].read_blocklen; 4.66 uint16_t buffer[Response_size_R1]; 4.67 struct R1 *r = (struct R1 *) buffer; 4.68 4.69 - //printf("read_block: card %d -> %d\n", card, _rca[card]); 4.70 - 4.71 // Select the requested card. 4.72 4.73 if (_current_rca != _rca[card]) 4.74 @@ -1245,15 +1274,18 @@ 4.75 if (r->status & R1_status_error_mask) 4.76 return 0; 4.77 4.78 + // NOTE: Consider issuing a predefined block count command to any multiple 4.79 + // NOTE: block operation, at least for cards that support it. 4.80 + 4.81 // Apply block count and size properties to the issued command. 4.82 4.83 - _regs[Msc_block_count] = 1; 4.84 + _regs[Msc_block_count] = block_count; 4.85 _regs[Msc_block_length] = block_size; 4.86 4.87 - // NOTE: Support an actual address. 4.88 // NOTE: Where CCS = 0, byte addressing is used. Otherwise, block addressing is used. 4.89 4.90 - if (!send_command(Command_read_single_block, 0)) 4.91 + if (!send_command(block_count == 1 ? Command_read_single_block 4.92 + : Command_read_multiple_block, block_address)) 4.93 return 0; 4.94 4.95 read_response(buffer, Response_size_R1); 4.96 @@ -1261,7 +1293,14 @@ 4.97 if (r->status & R1_status_error_mask) 4.98 return 0; 4.99 4.100 - return recv_data(paddr, block_size); 4.101 + // NOTE: Use Msc_block_success_count instead. 4.102 + 4.103 + uint32_t transferred = recv_data(paddr, block_size * block_count); 4.104 + 4.105 + if (block_count > 1) 4.106 + send_command(Command_stop_transmission, 0); 4.107 + 4.108 + return transferred; 4.109 } 4.110 4.111 // Wait indefinitely for an interrupt request, returning true if one was delivered.
5.1 --- a/pkg/devices/lib/msc/src/jz4780.cc Thu Feb 15 23:15:30 2024 +0100 5.2 +++ b/pkg/devices/lib/msc/src/jz4780.cc Thu Feb 15 23:18:09 2024 +0100 5.3 @@ -50,7 +50,7 @@ 5.4 } 5.5 5.6 // Request the transfer of the indicated number of bytes between two physical 5.7 -// addresses in the indicated direction, returning the number of bytes 5.8 +// addresses in the indicated direction, returning the number of bytes to be 5.9 // transferred. 5.10 // NOTE: To be consolidated into a generic method that uses generic request types. 5.11 5.12 @@ -70,7 +70,7 @@ 5.13 4, 4, unit_size, 5.14 recv ? _request_type_in : _request_type_out); 5.15 5.16 - return to_transfer - _dma->wait() * unit_size; 5.17 + return to_transfer * unit_size; 5.18 } 5.19 5.20 5.21 @@ -126,8 +126,10 @@ 5.22 static_cast<Msc_channel *>(msc_channel)->enable(); 5.23 } 5.24 5.25 -uint32_t jz4780_msc_read_block(void *msc_channel, uint8_t card, 5.26 - l4re_dma_space_dma_addr_t paddr) 5.27 +uint32_t jz4780_msc_read_blocks(void *msc_channel, uint8_t card, 5.28 + l4re_dma_space_dma_addr_t paddr, 5.29 + uint32_t block_address, uint32_t block_count) 5.30 { 5.31 - return static_cast<Msc_channel *>(msc_channel)->read_block(card, paddr); 5.32 + return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, paddr, 5.33 + block_address, block_count); 5.34 }
6.1 --- a/pkg/devices/lib/msc/src/x1600.cc Thu Feb 15 23:15:30 2024 +0100 6.2 +++ b/pkg/devices/lib/msc/src/x1600.cc Thu Feb 15 23:18:09 2024 +0100 6.3 @@ -50,7 +50,7 @@ 6.4 } 6.5 6.6 // Request the transfer of the indicated number of bytes between two physical 6.7 -// addresses in the indicated direction, returning the number of bytes 6.8 +// addresses in the indicated direction, returning the number of bytes to be 6.9 // transferred. 6.10 // NOTE: To be consolidated into a generic method that uses generic request types. 6.11 6.12 @@ -70,7 +70,7 @@ 6.13 4, 4, unit_size, 6.14 recv ? _request_type_in : _request_type_out); 6.15 6.16 - return to_transfer - _dma->wait() * unit_size; 6.17 + return to_transfer * unit_size; 6.18 } 6.19 6.20 6.21 @@ -126,8 +126,10 @@ 6.22 static_cast<Msc_channel *>(msc_channel)->enable(); 6.23 } 6.24 6.25 -uint32_t x1600_msc_read_block(void *msc_channel, uint8_t card, 6.26 - l4re_dma_space_dma_addr_t paddr) 6.27 +uint32_t x1600_msc_read_blocks(void *msc_channel, uint8_t card, 6.28 + l4re_dma_space_dma_addr_t paddr, 6.29 + uint32_t block_address, uint32_t block_count) 6.30 { 6.31 - return static_cast<Msc_channel *>(msc_channel)->read_block(card, paddr); 6.32 + return static_cast<Msc_channel *>(msc_channel)->read_blocks(card, paddr, 6.33 + block_address, block_count); 6.34 }
7.1 --- a/pkg/landfall-examples/hw_info/common.h Thu Feb 15 23:15:30 2024 +0100 7.2 +++ b/pkg/landfall-examples/hw_info/common.h Thu Feb 15 23:18:09 2024 +0100 7.3 @@ -176,7 +176,9 @@ 7.4 7.5 void msc_enable(void *msc_channel); 7.6 7.7 -uint32_t msc_read_block(void *msc_channel, uint8_t card, l4re_dma_space_dma_addr_t paddr); 7.8 +uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 7.9 + l4re_dma_space_dma_addr_t paddr, 7.10 + uint32_t block_address, uint32_t block_count); 7.11 7.12 7.13
8.1 --- a/pkg/landfall-examples/hw_info/hw_info.c Thu Feb 15 23:15:30 2024 +0100 8.2 +++ b/pkg/landfall-examples/hw_info/hw_info.c Thu Feb 15 23:18:09 2024 +0100 8.3 @@ -497,11 +497,37 @@ 8.4 return init_irq(0, dma_irq, dma_irq_start, dma_irq_end); 8.5 } 8.6 8.7 +static void _show_dma_region(struct dma_region *region, uint32_t offset) 8.8 +{ 8.9 + unsigned int i; 8.10 + 8.11 + printf("size = %d; align = %d; virtual = 0x%lx; physical = 0x%llx\ndata (offset 0x%x) =", 8.12 + region->size, region->align, region->vaddr, region->paddr, offset); 8.13 + 8.14 + for (i = 0; (i < region->size) && (i < 16); i++) 8.15 + printf(" %02x", *((uint8_t *) region->vaddr + offset + i)); 8.16 + 8.17 + printf("\n"); 8.18 +} 8.19 + 8.20 +static void show_dma_region(void) 8.21 +{ 8.22 + struct dma_region *region = _get_dma_region(); 8.23 + uint32_t offset; 8.24 + 8.25 + if (region == NULL) 8.26 + return; 8.27 + 8.28 + if (!read_number("Offset", &offset)) 8.29 + return; 8.30 + 8.31 + _show_dma_region(region, offset); 8.32 +} 8.33 + 8.34 static void list_dma_regions(void) 8.35 { 8.36 unsigned int num; 8.37 struct dma_region *region; 8.38 - unsigned int i; 8.39 8.40 for (num = 0; num < num_dma_regions; num++) 8.41 { 8.42 @@ -512,15 +538,7 @@ 8.43 if (l4_is_invalid_cap(region->mem)) 8.44 printf("(inactive)\n"); 8.45 else 8.46 - { 8.47 - printf("size = %d; align = %d; virtual = 0x%lx; physical = 0x%llx\ndata =", 8.48 - region->size, region->align, region->vaddr, region->paddr); 8.49 - 8.50 - for (i = 0; (i < region->size) && (i < 16); i++) 8.51 - printf(" %02x", *((uint8_t *) region->vaddr + i)); 8.52 - 8.53 - printf("\n"); 8.54 - } 8.55 + _show_dma_region(region, 0); 8.56 } 8.57 } 8.58 8.59 @@ -1172,11 +1190,11 @@ 8.60 msc_enable(channel); 8.61 } 8.62 8.63 -static void read_block_from_msc(void) 8.64 +static void read_blocks_from_msc(void) 8.65 { 8.66 void *channel = get_channel(num_msc_channels, msc_channels, NULL); 8.67 struct dma_region *dma_region = NULL; 8.68 - uint32_t card, transferred; 8.69 + uint32_t card, transferred, block_address, block_count; 8.70 8.71 if (channel == NULL) 8.72 return; 8.73 @@ -1189,9 +1207,24 @@ 8.74 if (!read_number("Card", &card)) 8.75 return; 8.76 8.77 + if (!read_number("Block address", &block_address)) 8.78 + return; 8.79 + 8.80 + if (!read_number("Block count", &block_count)) 8.81 + return; 8.82 + 8.83 + /* NOTE: Assuming 512-byte blocks. */ 8.84 + 8.85 + if (block_count * 512 > dma_region->size) 8.86 + { 8.87 + printf("Too many blocks for region.\n"); 8.88 + return; 8.89 + } 8.90 + 8.91 l4_cache_inv_data(dma_region->vaddr, dma_region->vaddr + dma_region->size); 8.92 8.93 - transferred = msc_read_block(channel, (uint8_t) card, dma_region->paddr); 8.94 + transferred = msc_read_blocks(channel, (uint8_t) card, dma_region->paddr, 8.95 + block_address, block_count); 8.96 8.97 printf("Transferred: %d\n", transferred); 8.98 } 8.99 @@ -1642,6 +1675,8 @@ 8.100 new_dma_channel(dma); 8.101 else if (!strcmp(token, "r") || !strcmp(token, "region")) 8.102 new_dma_region(); 8.103 + else if (!strcmp(token, "R") || !strcmp(token, "show")) 8.104 + show_dma_region(); 8.105 else if (!strcmp(token, "s") || !strcmp(token, "set")) 8.106 set_dma_region(); 8.107 else if (!strcmp(token, "t") || !strcmp(token, "transfer")) 8.108 @@ -1725,7 +1760,7 @@ 8.109 else if (!strcmp(token, "e") || !strcmp(token, "enable")) 8.110 enable_msc_channel(); 8.111 else if (!strcmp(token, "r") || !strcmp(token, "read")) 8.112 - read_block_from_msc(); 8.113 + read_blocks_from_msc(); 8.114 else 8.115 printf("msc channel | enable | read\n"); 8.116 }
9.1 --- a/pkg/landfall-examples/hw_info/jz4780.c Thu Feb 15 23:15:30 2024 +0100 9.2 +++ b/pkg/landfall-examples/hw_info/jz4780.c Thu Feb 15 23:18:09 2024 +0100 9.3 @@ -359,9 +359,12 @@ 9.4 jz4780_msc_enable(msc_channel); 9.5 } 9.6 9.7 -uint32_t msc_read_block(void *msc_channel, uint8_t card, l4re_dma_space_dma_addr_t paddr) 9.8 +uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 9.9 + l4re_dma_space_dma_addr_t paddr, 9.10 + uint32_t block_address, uint32_t block_count) 9.11 { 9.12 - return jz4780_msc_read_block(msc_channel, card, paddr); 9.13 + return jz4780_msc_read_blocks(msc_channel, card, paddr, block_address, 9.14 + block_count); 9.15 } 9.16 9.17
10.1 --- a/pkg/landfall-examples/hw_info/x1600.c Thu Feb 15 23:15:30 2024 +0100 10.2 +++ b/pkg/landfall-examples/hw_info/x1600.c Thu Feb 15 23:18:09 2024 +0100 10.3 @@ -348,9 +348,12 @@ 10.4 return x1600_msc_enable(msc_channel); 10.5 } 10.6 10.7 -uint32_t msc_read_block(void *msc_channel, uint8_t card, l4re_dma_space_dma_addr_t paddr) 10.8 +uint32_t msc_read_blocks(void *msc_channel, uint8_t card, 10.9 + l4re_dma_space_dma_addr_t paddr, 10.10 + uint32_t block_address, uint32_t block_count) 10.11 { 10.12 - return x1600_msc_read_block(msc_channel, card, paddr); 10.13 + return x1600_msc_read_blocks(msc_channel, card, paddr, block_address, 10.14 + block_count); 10.15 } 10.16 10.17