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
#include "freeldr.h"
#include "machine.h"
#include "ppcmmu/mmu.h"
#include "prep.h"

int prep_serial = 0x800003f8;
extern int mem_range_end;

void sync() { __asm__("eieio\n\tsync"); }

/* Simple serial */

void PpcPrepPutChar( int ch ) {
    if( ch == 0x0a ) {
    SetPhysByte(prep_serial, 0x0d);
    sync();
    }
    SetPhysByte(prep_serial, ch);
    sync();
}

BOOLEAN PpcPrepDiskReadLogicalSectors
( ULONG DriveNumber, ULONGLONG SectorNumber,
  ULONG SectorCount, PVOID Buffer ) {
    int secct;

    for(secct = 0; secct < SectorCount; secct++)
    {
    ide_seek(&ide1_desc, SectorNumber + secct, 0);
    ide_read(&ide1_desc, ((PCHAR)Buffer) + secct * 512, 512);
    }
    /* Never give up! */
    return TRUE;
}

BOOLEAN PpcPrepConsKbHit()
{
    return 1;
    //return GetPhysByte(prep_serial+5) & 1;
}

int PpcPrepConsGetCh()
{
    while(!PpcPrepConsKbHit());<--- Condition '!PpcPrepConsKbHit()' is always false
    return GetPhysByte(prep_serial);
}

void PpcPrepVideoClearScreen(UCHAR Attr)
{
    printf("\033c");
}

VIDEODISPLAYMODE PpcPrepVideoSetDisplayMode( char *DisplayMode, BOOLEAN Init )
{
    return VideoTextMode;
}

void PpcPrepVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth )
{
    *Width = 80;
    *Height = 25;
    *Depth = 16;
}

VOID PpcInitializeMmu(int max);

ULONG PpcPrepGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
               ULONG MaxMemoryMapSize )
{
    // Probe memory
    paddr_t physAddr;
    register int oldStore = 0, newStore = 0, change = 0, oldmsr;

    __asm__("mfmsr %0\n" : "=r" (oldmsr));
    change = oldmsr & 0x6fff;
    __asm__("mtmsr %0\n" : : "r" (change));

    // Find the last ram address in physical space ... this bypasses mapping
    // but could run into non-ram objects right above ram.  Usually systems
    // aren't designed like that though.
    for (physAddr = 0x40000, change = newStore;
         (physAddr < 0x80000000) && (change == newStore);
         physAddr += 1 << 12)
    {
        oldStore = GetPhys(physAddr);
        newStore = (physAddr & 0x1000) ? 0x55aa55aa : 0xaa55aa55;
        SetPhys(physAddr, newStore);
        change = GetPhys(physAddr);
        SetPhys(physAddr, oldStore);
    }
    // Back off by one page
    physAddr -= 0x1000;
    BiosMemoryMap[0].BaseAddress = 0x30000; // End of ppcmmu
    BiosMemoryMap[0].Type = BiosMemoryUsable;
    BiosMemoryMap[0].Length = physAddr - BiosMemoryMap[0].BaseAddress;

    __asm__("mtmsr %0\n" : : "r" (oldmsr));

    mem_range_end = physAddr;

    printf("Actual RAM: %d Mb\n", physAddr >> 20);
    return 1;
}

/* Most PReP hardware is in standard locations, based on the corresponding
 * hardware on PCs. */
PCONFIGURATION_COMPONENT_DATA PpcPrepHwDetect() {
  PCONFIGURATION_COMPONENT_DATA SystemKey;

  /* Create the 'System' key */
  FldrCreateSystemKey(&SystemKey);

  printf("DetectHardware() Done\n");
  return SystemKey;
}

VOID
PpcPrepHwIdle(VOID)
{
    /* UNIMPLEMENTED */
}

void PpcPrepInit()
{
    MachVtbl.ConsPutChar = PpcPrepPutChar;

    printf("Serial on\n");

    ide_setup( &ide1_desc );

    MachVtbl.DiskReadLogicalSectors = PpcPrepDiskReadLogicalSectors;

    MachVtbl.ConsKbHit   = PpcPrepConsKbHit;
    MachVtbl.ConsGetCh   = PpcPrepConsGetCh;

    MachVtbl.VideoClearScreen = PpcPrepVideoClearScreen;
    MachVtbl.VideoSetDisplayMode = PpcPrepVideoSetDisplayMode;
    MachVtbl.VideoGetDisplaySize = PpcPrepVideoGetDisplaySize;

    MachVtbl.GetMemoryMap = PpcPrepGetMemoryMap;
    MachVtbl.HwDetect = PpcPrepHwDetect;
    MachVtbl.HwIdle = PcPrepHwIdle;

    printf( "FreeLDR version [%s]\n", FrLdrVersionString );

    BootMain( "" );
}