OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [ioport.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/* $Id: ioport.c,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
2
 * ioport.c:  Simple io mapping allocator.
3
 *
4
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5
 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
6
 *
7
 * The routines in this file should be changed for a memory allocator
8
 * that would be setup just like NetBSD does : you create regions that
9
 * are administered by a general purpose allocator, and then you call
10
 * that allocator with your handle and the block size instead of this
11
 * weak stuff.
12
 *
13
 * XXX No joke, this needs to be rewritten badly. XXX
14
 */
15
 
16
#include <linux/sched.h>
17
#include <linux/kernel.h>
18
#include <linux/errno.h>
19
#include <linux/types.h>
20
#include <linux/ioport.h>
21
#include <linux/mm.h>
22
 
23
#include <asm/io.h>
24
#include <asm/vaddrs.h>
25
#include <asm/oplib.h>
26
#include <asm/page.h>
27
#include <asm/pgtable.h>
28
 
29
/* This points to the next to use virtual memory for io mappings */
30
static long next_free_region = IOBASE_VADDR;
31
static long dvma_next_free   = DVMA_VADDR;
32
 
33
/*
34
 * sparc_alloc_io:
35
 * Map and allocates an obio device.
36
 * Implements a simple linear allocator, you can force the function
37
 * to use your own mapping, but in practice this should not be used.
38
 *
39
 * Input:
40
 *  address: the obio address to map
41
 *  virtual: if non zero, specifies a fixed virtual address where
42
 *           the mapping should take place.
43
 *  len:     the length of the mapping
44
 *  bus_type: The bus on which this io area sits.
45
 *
46
 * Returns:
47
 *  The virtual address where the mapping actually took place.
48
 */
49
 
50
void *sparc_alloc_io (void *address, void *virtual, int len, char *name,
51
                      int bus_type, int rdonly)
52
{
53
        unsigned long vaddr, base_address;
54
        unsigned long addr = (unsigned long) address;
55
        unsigned long offset = (addr & (~PAGE_MASK));
56
 
57
        if (virtual)
58
                vaddr = (unsigned long) virtual;
59
        else
60
                vaddr = next_free_region;
61
 
62
        len += offset;
63
        if(((unsigned long) virtual + len) > (IOBASE_VADDR + IOBASE_LEN)) {
64
                prom_printf("alloc_io: Mapping outside IOBASE area\n");
65
                prom_halt();
66
        }
67
        if(check_region ((vaddr | offset), len)) {
68
                prom_printf("alloc_io: 0x%lx is already in use\n", vaddr);
69
                prom_halt();
70
        }
71
 
72
        /* Tell Linux resource manager about the mapping */
73
        request_region ((vaddr | offset), len, name);
74
 
75
        base_address = vaddr;
76
        /* Do the actual mapping */
77
        for (; len > 0; len -= PAGE_SIZE) {
78
                mapioaddr(addr, vaddr, bus_type, rdonly);
79
                vaddr += PAGE_SIZE;
80
                addr += PAGE_SIZE;
81
                if (!virtual)
82
                        next_free_region += PAGE_SIZE;
83
        }
84
        return (void *) (base_address | offset);
85
}
86
 
87
/* Does DVMA allocations with PAGE_SIZE granularity.  How this basically
88
 * works is that the ESP chip can do DVMA transfers at ANY address with
89
 * certain size and boundary restrictions.  But other devices that are
90
 * attached to it and would like to do DVMA have to set things up in
91
 * a special way, if the DVMA sees a device attached to it transfer data
92
 * at addresses above DVMA_VADDR it will grab them, this way it does not
93
 * now have to know the peculiarities of where to read the Lance data
94
 * from. (for example)
95
 */
96
void *sparc_dvma_malloc (int len, char *name)
97
{
98
        unsigned long vaddr, base_address;
99
 
100
        vaddr = dvma_next_free;
101
        if(check_region (vaddr, len)) {
102
                prom_printf("alloc_dma: 0x%lx is already in use\n", vaddr);
103
                prom_halt();
104
        }
105
        if(vaddr + len > (DVMA_VADDR + DVMA_LEN)) {
106
                prom_printf("alloc_dvma: out of dvma memory\n");
107
                prom_halt();
108
        }
109
 
110
        /* Basically these can be mapped just like any old
111
         * IO pages, cacheable bit off, etc.  The physical
112
         * pages are pre-mapped in paging_init()
113
         */
114
        base_address = vaddr;
115
        /* Assign the memory area. */
116
        dvma_next_free = PAGE_ALIGN(dvma_next_free+len);
117
 
118
        request_region(base_address, len, name);
119
 
120
        return (void *) base_address;
121
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.