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#if !X86_COMMON
22#warning ISA DMA not supported on non-x86 architectures. TODO: FIXME
23#endif
24
30int cdi_dma_open(struct cdi_dma_handle* handle, uint8_t channel, uint8_t mode, size_t length, void* buffer)
31{
32#if 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
77int cdi_dma_read(struct cdi_dma_handle* handle)
78{
79#if 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
93int cdi_dma_write(struct cdi_dma_handle* handle)
94{
95#if 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
109int cdi_dma_close(struct cdi_dma_handle* handle)
110{
111#if 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}
Special memory entity in the kernel's virtual address space.
void * virtualAddress() const
physical_uintptr_t physicalAddress() const
static PhysicalMemoryManager & instance()