1 /* 2 * Access to memory cards. 3 * 4 * Copyright (C) 2023, 2024 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/devices/msc.h> 23 #include <l4/sys/cache.h> 24 25 #include "msc_region_operations.h" 26 27 28 29 MscRegionOperations::MscRegionOperations(Msc_channel *msc_channel, uint8_t card, 30 struct dma_region region) 31 : _msc_channel(msc_channel), _card(card), _region(region) 32 { 33 } 34 35 long MscRegionOperations::read_partition_table(struct partition_table_entry **entry) 36 { 37 l4_cache_inv_data(_region.vaddr, _region.vaddr + _region.size); 38 39 uint32_t transferred = _msc_channel->read(_card, &_region, 0, _region.size); 40 41 if (!transferred) 42 return -L4_EIO; 43 44 *entry = get_partition_table((uint8_t *) _region.vaddr); 45 46 if (*entry == NULL) 47 return -L4_EIO; 48 49 return L4_EOK; 50 } 51 52 /* Public operations. */ 53 54 long MscRegionOperations::get_partition(uint8_t partition, 55 uint32_t *start_block, 56 uint32_t *num_blocks) 57 { 58 std::lock_guard<std::mutex> guard(_lock); 59 60 // Use the fileid to select the partition. 61 62 if (partition >= 4) 63 return -L4_ENOENT; 64 65 struct partition_table_entry *entry; 66 long err = read_partition_table(&entry); 67 68 if (err) 69 return err; 70 71 if (!entry[partition].num_sectors) 72 return -L4_ENOENT; 73 74 *start_block = entry[partition].lba_first_sector; 75 *num_blocks = entry[partition].num_sectors; 76 77 return L4_EOK; 78 } 79 80 void MscRegionOperations::read(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, 81 offset_t filepos, offset_t size) 82 { 83 std::lock_guard<std::mutex> guard(_lock); 84 85 struct dma_region region; 86 87 // NOTE: Truncating the file position and size. 88 89 region.vaddr = vaddr; 90 region.paddr = paddr; 91 region.size = size; 92 93 l4_cache_inv_data(vaddr, vaddr + size); 94 95 _msc_channel->read(_card, ®ion, (uint32_t) filepos, (uint32_t) size); 96 } 97 98 void MscRegionOperations::write(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, 99 offset_t filepos, offset_t size) 100 { 101 std::lock_guard<std::mutex> guard(_lock); 102 103 // NOTE: To be implemented. 104 105 (void) vaddr; (void) paddr; (void) filepos; (void) size; 106 }