summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/mips/jxmemory.c
blob: 4bc60d295e028fca7bf2ac0ca3f1367d281f5656 (plain) (blame)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#if defined(JAZZ)

/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    jxmemory.c

Abstract:

    This module implements the ARC firmware memory configuration operations
    for a MIPS R3000 or R4000 Jazz system.

Author:

    David N. Cutler (davec) 18-May-1991


Revision History:

--*/

#include "fwp.h"
#include "selfmap.h"
extern  end[];

//
// Define memory listhead, allocation entries, and free index.
//

ULONG FwMemoryFree;
LIST_ENTRY FwMemoryListHead;
FW_MEMORY_DESCRIPTOR FwMemoryTable[FW_MEMORY_TABLE_SIZE];

VOID
FwInitializeMemory (
    VOID
    )

/*++

Routine Description:

    This routine initializes the memory allocation list for the memory
    configuration routine.

Arguments:

    None.

Return Value:

    None.

--*/

{

    ULONG MemoryPages;
    //
    // Initialize the memory allocation listhead.
    //

    InitializeListHead(&FwMemoryListHead);

    //
    // Initialize the entry for the exception vectors and the system
    // parameter block.
    //

    FwMemoryTable[0].MemoryEntry.MemoryType = MemoryFirmwarePermanent;

    FwMemoryTable[0].MemoryEntry.BasePage = 0;
    FwMemoryTable[0].MemoryEntry.PageCount = 2;
    InsertTailList(&FwMemoryListHead, &FwMemoryTable[0].ListEntry);

    //
    // Initialize the entry for the firmware stack and code.
    //

    FwMemoryTable[1].MemoryEntry.MemoryType = MemoryFirmwareTemporary;

    FwMemoryTable[1].MemoryEntry.PageCount = FW_PAGES - 2;
    FwMemoryTable[1].MemoryEntry.BasePage = 2;
    InsertTailList(&FwMemoryListHead, &FwMemoryTable[1].ListEntry);

    //
    // Initialize the entry for free memory and zero the free memory area.
    //

    FwMemoryTable[2].MemoryEntry.MemoryType = MemoryFree;
    FwMemoryTable[2].MemoryEntry.BasePage = FW_PAGES;
    FwMemoryTable[2].MemoryEntry.PageCount = 0x7ed - FW_PAGES;
    InsertTailList(&FwMemoryListHead, &FwMemoryTable[2].ListEntry);

    //
    // Initialize the entry for the firmware pool.
    //

    FwMemoryTable[3].MemoryEntry.MemoryType = MemoryFirmwareTemporary;
    FwMemoryTable[3].MemoryEntry.BasePage = 0x7ed;
    FwMemoryTable[3].MemoryEntry.PageCount = 0x7fd - 0x7ed;
    InsertTailList(&FwMemoryListHead, &FwMemoryTable[3].ListEntry);

    //
    // Initialize the entry for the PCR page used by the kernel debugger.
    //

    FwMemoryTable[4].MemoryEntry.MemoryType = MemoryFirmwareTemporary;
    FwMemoryTable[4].MemoryEntry.BasePage = 0x7fd;
    FwMemoryTable[4].MemoryEntry.PageCount = 0x800 - 0x7fd;
    InsertTailList(&FwMemoryListHead, &FwMemoryTable[4].ListEntry);

    //
    // If the size of memory is greater than 8mb, then generate another
    // descriptor to describe the free memory above the PCR page.
    //

    if ((MemorySize > 8) && (((ULONG) end & ~KSEG1_BASE) < 0x0800000)) {
        MemoryPages = (MemorySize << (20 - PAGE_SHIFT));
        FwMemoryTable[5].MemoryEntry.MemoryType = MemoryFree;
        FwMemoryTable[5].MemoryEntry.BasePage = 0x800;
        FwMemoryTable[5].MemoryEntry.PageCount = MemoryPages - 0x800;
        InsertTailList(&FwMemoryListHead, &FwMemoryTable[5].ListEntry);
        //RtlZeroMemory((PVOID)(KSEG0_BASE + 0x800000),
        //               (MemoryPages - 0x800) << PAGE_SHIFT);
        FwMemoryFree = 6;

    } else if (((ULONG) end & ~KSEG1_BASE) > 0x0800000) {

        //
        // If this copy of the firmware is loaded above 8 MB, then
        // only part of memory should be zeroed and appropriate memory
        // descriptors should be created.
        //
        // Note: currently all the memory between 800000 and the end
        // of this code is made firmware permanent.
        //

        FwMemoryTable[5].MemoryEntry.MemoryType = MemoryFirmwarePermanent;
        FwMemoryTable[5].MemoryEntry.BasePage = 0x800;
        FwMemoryTable[5].MemoryEntry.PageCount =
            ROUND_TO_PAGES((ULONG) end & ~KSEG1_BASE) - 0x800;
        InsertTailList(&FwMemoryListHead, &FwMemoryTable[5].ListEntry);

        MemoryPages = (MemorySize << (20 - PAGE_SHIFT));
        FwMemoryTable[6].MemoryEntry.MemoryType = MemoryFree;
        FwMemoryTable[6].MemoryEntry.BasePage = ROUND_TO_PAGES((ULONG) end & ~KSEG1_BASE);
        FwMemoryTable[6].MemoryEntry.PageCount = MemoryPages -
            FwMemoryTable[6].MemoryEntry.BasePage;
        InsertTailList(&FwMemoryListHead, &FwMemoryTable[6].ListEntry);
        //RtlZeroMemory((PVOID)(KSEG0_BASE + (FwMemoryTable[6].MemoryEntry.BasePage << PAGE_SHIFT)),
        //              FwMemoryTable[6].MemoryEntry.PageCount << PAGE_SHIFT);
        FwMemoryFree = 7;

    } else {
        FwMemoryFree = 5;
    }

    //
    // Initialize the memory configuration routine address in the system
    // parameter block.
    //

    (PARC_MEMORY_ROUTINE)SYSTEM_BLOCK->FirmwareVector[MemoryRoutine] =
                                                            FwGetMemoryDescriptor;

    return;
}

PMEMORY_DESCRIPTOR
FwGetMemoryDescriptor (
    IN PMEMORY_DESCRIPTOR MemoryDescriptor OPTIONAL
    )

/*++

Routine Description:

    This routine returns a pointer to the next memory descriptor. If
    the specified memory descriptor is NULL, then a pointer to the
    first memory descriptor is returned. If there are no more memory
    descriptors, then NULL is returned.

Arguments:

    MemoryDescriptor - Supplies a optional pointer to a memory descriptor.

Return Value:

    If there are any more entries in the memory descriptor list, the
    address of the next descriptor is returned. Otherwise, NULL is
    returned.

--*/

{

    PFW_MEMORY_DESCRIPTOR TableEntry;
    PLIST_ENTRY NextEntry;

    //
    // If a memory descriptor address is specified, then return the
    // address of the next descriptor or NULL as appropriate. Otherwise,
    // return the address of the first memory descriptor.
    //

    if (ARGUMENT_PRESENT(MemoryDescriptor)) {
        TableEntry = CONTAINING_RECORD(MemoryDescriptor,
                                       FW_MEMORY_DESCRIPTOR,
                                       MemoryEntry);

        NextEntry = TableEntry->ListEntry.Flink;
        if (NextEntry != &FwMemoryListHead) {
            return &(CONTAINING_RECORD(NextEntry,
                                       FW_MEMORY_DESCRIPTOR,
                                       ListEntry)->MemoryEntry);

        } else {
            return NULL;
        }

    } else {
        return &FwMemoryTable[0].MemoryEntry;
    }
}

VOID
FwGenerateDescriptor (
    IN PFW_MEMORY_DESCRIPTOR MemoryDescriptor,
    IN MEMORY_TYPE MemoryType,
    IN ULONG BasePage,
    IN ULONG PageCount
    )

/*++

Routine Description:

    This routine allocates a new memory descriptor to describe the
    specified region of memory which is assumed to lie totally within
    the specified region which is free.

Arguments:

    MemoryDescriptor - Supplies a pointer to a free memory descriptor
        from which the specified memory is to be allocated.

    MemoryType - Supplies the type that is assigned to the allocated
        memory.

    BasePage - Supplies the base page number.

    PageCount - Supplies the number of pages.

Return Value:

    None.

--*/

{

    PLIST_ENTRY NextEntry;
    ULONG Offset;

    //
    // If the specified region totally consumes the free region, then no
    // additional descriptors need to be allocated. If the specified region
    // is at the start or end of the free region, then only one descriptor
    // needs to be allocated. Otherwise, two additional descriptors need to
    // be allocated.
    //

    Offset = BasePage - MemoryDescriptor->MemoryEntry.BasePage;
    if ((Offset == 0) && (PageCount == MemoryDescriptor->MemoryEntry.PageCount)) {

        //
        // The specified region totally consumes the free region.
        //

        MemoryDescriptor->MemoryEntry.MemoryType = MemoryType;

    } else {

        //
        // A memory descriptor must be generated to describe the allocated
        // memory.
        //

        FwMemoryTable[FwMemoryFree].MemoryEntry.MemoryType = MemoryType;
        FwMemoryTable[FwMemoryFree].MemoryEntry.BasePage = BasePage;
        FwMemoryTable[FwMemoryFree].MemoryEntry.PageCount = PageCount;
        InsertTailList(&FwMemoryListHead,
                       &FwMemoryTable[FwMemoryFree].ListEntry);

        FwMemoryFree += 1;

        //
        // Determine whether an additional memory descriptor must be generated.
        //

        if (BasePage == MemoryDescriptor->MemoryEntry.BasePage) {

            //
            // The specified region lies at the start of the free region.
            //

            MemoryDescriptor->MemoryEntry.BasePage += PageCount;
            MemoryDescriptor->MemoryEntry.PageCount -= PageCount;

        } else if ((Offset + PageCount) == MemoryDescriptor->MemoryEntry.PageCount) {

            //
            // The specified region lies at the end of the free region.
            //

            MemoryDescriptor->MemoryEntry.PageCount -= PageCount;

        } else {

            //
            // The specified region lies in the middle of the free region.
            // Another memory descriptor must be generated.
            //

            FwMemoryTable[FwMemoryFree].MemoryEntry.MemoryType = MemoryFree;
            FwMemoryTable[FwMemoryFree].MemoryEntry.BasePage = BasePage + PageCount;
            FwMemoryTable[FwMemoryFree].MemoryEntry.PageCount =
                                    MemoryDescriptor->MemoryEntry.PageCount -
                                    (PageCount + Offset);
            InsertTailList(&FwMemoryListHead,
                           &FwMemoryTable[FwMemoryFree].ListEntry);

            FwMemoryFree += 1;
            MemoryDescriptor->MemoryEntry.PageCount = Offset;
        }
    }

    return;
}

VOID
FwResetMemory(
    VOID
)

/*++

Routine Description:

    This routine calls FwInitializeMemory to reset the memory descriptors
    and then loops through and clears all of the appropriate memory.

Arguments:

    None.

Return Value:

    None.

--*/

{
    PMEMORY_DESCRIPTOR MemoryDescriptor;

    FwInitializeMemory();

    //
    // Reset all memory not used by the firmware.
    // TEMPTEMP Just reset under 8M Bytes for now.
    //

    MemoryDescriptor = FwGetMemoryDescriptor(NULL);
    while (MemoryDescriptor != NULL) {

        if ((MemoryDescriptor->MemoryType != MemoryFirmwarePermanent) &&
            (MemoryDescriptor->MemoryType != MemoryFirmwareTemporary) &&
            (MemoryDescriptor->BasePage < 0x800)) {
            RtlZeroMemory((PVOID)(KSEG0_BASE + (MemoryDescriptor->BasePage << PAGE_SHIFT)),
                          MemoryDescriptor->PageCount << PAGE_SHIFT);
        }

        MemoryDescriptor = FwGetMemoryDescriptor(MemoryDescriptor);
    }

    //
    // Sweep the data cache
    //

    HalSweepDcache();

}
#endif