summaryrefslogtreecommitdiffstats
path: root/src/include/kernel/devicesegment.H
blob: e3e2d97239f12e03b5c694ddb57d52611e7533d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//  IBM_PROLOG_BEGIN_TAG
//  This is an automatically generated prolog.
//
//  $Source: src/include/kernel/devicesegment.H $
//
//  IBM CONFIDENTIAL
//
//  COPYRIGHT International Business Machines Corp. 2011
//
//  p1
//
//  Object Code Only (OCO) source materials
//  Licensed Internal Code Source Materials
//  IBM HostBoot Licensed Internal Code
//
//  The source code for this program is not published or other-
//  wise divested of its trade secrets, irrespective of what has
//  been deposited with the U.S. Copyright Office.
//
//  Origin: 30
//
//  IBM_PROLOG_END
#ifndef __KERNEL_DEVICESEGMENT_H
#define __KERNEL_DEVICESEGMENT_H

#include <kernel/segment.H>
#include <sys/mmio.h>

/**
 * @class DeviceSegment
 * @brief Manages the device virtual memory segment
 */
class DeviceSegment : public Segment
{
    public:
        /**
         * @brief Constructor (Device segment at 2TB)
         */
        DeviceSegment() : Segment(0x020000000000ull) {};

        /**
         * @brief Destructor
         */
        ~DeviceSegment() {};

        /**
         * @brief Add the device segment
         */
        static void init();
        
        /**
         * @brief Handle a page fault for a device address access
         * @param i_task[in] - Task pointer to the task requiring the page
         * @param i_addr[in] - 64-bit address needed to be paged
         * @return bool - true: Page added to page table
         *               false: Not a valid address to be paged
         */
        bool handlePageFault(task_t* i_task, uint64_t i_addr);

        /**
         * @brief DEPRECATED
         */
        static void* mmioMap(void* ra, size_t pages);

        /**
         * @brief DEPRECATED
         */
        static int mmioUnmap(void* ea, size_t pages);

        /**
         * @brief Map a device into the device segment(2TB)
         * @param ra[in] - Void pointer to real address to be mapped in
         * @param i_devDataSize[in] - Size of device segment block
         * @return void* - Pointer to beginning virtual address, NULL otherwise
         */
        static void* devMap(void* ra, SEG_DATA_SIZES i_devDataSize);

        /**
         * @brief Unmap a device from the device segment(2TB)
         * @param ea[in] - Void pointer to effective address
         * @return int - 0 for successful unmap, non-zero otherwise
         */
        static int devUnmap(void* ea);

    private:
        /**
         * Attributes to represent a mapped device within a segment block
         */
        struct devSegData
        {
            uint64_t addr; /* Real address assigned to device */
            SEG_DATA_SIZES size; /* A particular device's segment block size */
            devSegData(): addr(0),size(THIRTYTWO_GB){};
        };

        /**
         * Number of devices that can be mapped with a given segment block size
         */
        enum
        {
            MMIO_MAP_DEVICES = 32
        }; //TODO - Only necessary if a device uses a SCOM region other than 32GB

        devSegData iv_mmioMap[MMIO_MAP_DEVICES];

        /**
         * @brief Add the device segment
         */
        void _init();

        /**
         * @brief DEPRECATED
         */
        void* _mmioMap(void* ra, size_t pages);

        /**
         * @brief DEPRECATED
         */
        int _mmioUnmap(void* ea, size_t pages);

        /**
         * @brief Map a device into the device segment(2TB)
         * @param ra[in] - Void pointer to real address to be mapped in
         * @param i_devDataSize[in] - Size of device segment block
         * @return void* - Pointer to beginning virtual address, NULL otherwise
         */
        void* _devMap(void* ra, SEG_DATA_SIZES i_devDataSize);

        /**
         * @brief Unmap a device from the device segment(2TB)
         * @param ea[in] - Void pointer to effective address
         * @return int - 0 for successful unmap, non-zero otherwise
         */
        int _devUnmap(void* ea);
};

#endif
OpenPOWER on IntegriCloud