The Pedigree Project  0.1
dma.cc
1 /*
2  * Copyright (c) 2007 Antoine Kaufmann
3  *
4  * This program is free software. It comes without any warranty, to
5  * the extent permitted by applicable law. You can redistribute it
6  * and/or modify it under the terms of the Do What The Fuck You Want
7  * To Public License, Version 2, as published by Sam Hocevar. See
8  * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9  */
10 
11 #include "cdi-osdep.h"
12 #include "cdi/dma.h"
13 #include "modules/drivers/common/dma/IsaDma.h"
14 #include "pedigree/kernel/Log.h"
15 #include "pedigree/kernel/processor/MemoryRegion.h"
16 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"
17 #include "pedigree/kernel/processor/VirtualAddressSpace.h"
18 #include "pedigree/kernel/processor/types.h"
19 #include "pedigree/kernel/utilities/utility.h"
20 
21 #ifndef X86_COMMON
22 #warning ISA DMA not supported on non-x86 architectures. TODO: FIXME
23 #endif
24 
30 int cdi_dma_open(struct cdi_dma_handle* handle, uint8_t channel, uint8_t mode, size_t length, void* buffer)
31 {
32 #ifdef X86_COMMON
33  // All good
34  handle->channel = channel;
35  handle->mode = mode;
36  handle->length = length;
37  handle->buffer = handle->meta.realbuffer = buffer;
38 
39  MemoryRegion* region = new MemoryRegion("isa-dma");
40  size_t page_size = PhysicalMemoryManager::instance().getPageSize();
41 
42  // Allocate memory under 16 MB for the transfer
43  if (!PhysicalMemoryManager::instance().allocateRegion(*region,
44  (length + page_size - 1) / page_size,
47  -1))
48  {
49  WARNING("cdi: Couldn't allocate physical memory for DMA!");
50  delete region;
51  return -1;
52  }
53 
54  // Add the region to the handle
55  handle->meta.region = reinterpret_cast<void*>(region);
56  handle->buffer = region->virtualAddress();
57  ByteSet(handle->buffer, 0, handle->length);
58 
59  // Do the deed
60  if(IsaDma::instance().initTransfer(handle->channel, handle->mode, handle->length, region->physicalAddress()))
61  return 0;
62  else
63  {
64  delete region;
65  return -1;
66  }
67 #else
68  return -1;
69 #endif
70 }
71 
77 int cdi_dma_read(struct cdi_dma_handle* handle)
78 {
79 #ifdef X86_COMMON
80  // Copy the memory across
81  MemoryCopy(handle->meta.realbuffer, handle->buffer, handle->length);
82  return 0;
83 #else
84  return -1;
85 #endif
86 }
87 
93 int cdi_dma_write(struct cdi_dma_handle* handle)
94 {
95 #ifdef X86_COMMON
96  // Copy the memory across
97  MemoryCopy(handle->buffer, handle->meta.realbuffer, handle->length);
98  return 0;
99 #else
100  return -1;
101 #endif
102 }
103 
109 int cdi_dma_close(struct cdi_dma_handle* handle)
110 {
111 #ifdef X86_COMMON
112  // Grab the region from the handle and free it
113  MemoryRegion* region = reinterpret_cast<MemoryRegion*>(handle->meta.region);
114  delete region;
115 
116  return 0;
117 #else
118  return -1;
119 #endif
120 }
static PhysicalMemoryManager & instance()
#define WARNING(text)
Definition: Log.h:78
Special memory entity in the kernel&#39;s virtual address space.
Definition: MemoryRegion.h:35
physical_uintptr_t physicalAddress() const
Definition: MemoryRegion.cc:44
void * virtualAddress() const
Definition: MemoryRegion.cc:39