158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <errno.h>
|
|
|
|
#include "drv_omap35x_gpt.hh"
|
|
#include "drv_omap35x_i2c.hh"
|
|
#include "drv_omap35x_sdmmc.hh"
|
|
#include "drv_tps65950.hh"
|
|
#include "omap35x.hh"
|
|
#include "omap35x_intc.hh"
|
|
#include "omap35x_prcm.hh"
|
|
#include "phys_mm.hh"
|
|
#include "mm.hh"
|
|
#include "scheduler.hh"
|
|
#include "cortexa8.hh"
|
|
#include "uart.hh"
|
|
#include "pagecache.hh"
|
|
#include "globals.hh"
|
|
|
|
namespace global {
|
|
OMAP35x_prcm* prcm = nullptr;
|
|
OMAP35x_intc* intc = nullptr;
|
|
OMAP35x_GPT* ticktimer = nullptr;
|
|
OMAP35x_GPT* ustimer = nullptr;
|
|
|
|
ICharacterDevice* console = nullptr;
|
|
Scheduler* scheduler = nullptr;
|
|
PageCache *pagecache = nullptr;
|
|
}
|
|
|
|
void sbrk_stats();
|
|
|
|
static volatile uint32_t tickctr = 0;
|
|
void tickfunc() noexcept {
|
|
++tickctr;
|
|
|
|
if(global::scheduler)
|
|
global::scheduler->timeslice();
|
|
|
|
global::prcm->clear_wake_per(3);
|
|
}
|
|
|
|
void setConsole(ICharacterDevice* newConsole);
|
|
|
|
int main(int argc, char* argv[]) {
|
|
cortexa8::init_mode(); // Enter system mode
|
|
// Initialize memory
|
|
cortexa8::enable_dcache();
|
|
cortexa8::enable_icache();
|
|
|
|
cortexa8::errata();
|
|
|
|
cortexa8::init_mmu();
|
|
|
|
// Enable early console
|
|
EarlyUART earlyUART{};
|
|
global::console = &earlyUART;
|
|
|
|
// Install handlers
|
|
cortexa8::init_handlers();
|
|
|
|
// Initialize physical memory managment
|
|
phys_mm::init();
|
|
|
|
// Initialize kernel dynamic memory management
|
|
mm::init();
|
|
// From here on, malloc/free and new/delete may be used
|
|
|
|
phys_mm::print_state();
|
|
|
|
// Configure PRCM
|
|
global::prcm = new OMAP35x_prcm{0x48004000, 0x48306000};
|
|
|
|
// Configure interrrupt & exception handling
|
|
global::intc = new OMAP35x_intc{0x48200000};
|
|
|
|
global::prcm->enable_peripherals();
|
|
|
|
// Enable interrupts
|
|
cortexa8_ena_int();
|
|
|
|
OMAP35x_Info chipInfo{0x48002000, 0x4830a000};
|
|
|
|
chipInfo.print_chip_id();
|
|
|
|
if(chipInfo.running_on_qemu())
|
|
printf("QEMU detected, avoiding bugs...\n");
|
|
|
|
global::ticktimer = new OMAP35x_GPT{0x49032000, 38};
|
|
|
|
global::ticktimer->ticktimer(&tickfunc);
|
|
|
|
global::ustimer = new OMAP35x_GPT{0x49034000, 39};
|
|
global::ustimer->ustimer();
|
|
|
|
// Configure TPS65950 (power control etc.)
|
|
OMAP35x_I2C i2c1{0x48070000};
|
|
TPS65950 tps65950{i2c1};
|
|
|
|
if(!chipInfo.running_on_qemu()) {
|
|
global::prcm->set_cpu_opp(3);
|
|
tps65950.set_cpu_opp(3);
|
|
}
|
|
|
|
{
|
|
cortexa8::ScopedSetIF disint{};
|
|
global::scheduler = new Scheduler{};
|
|
}
|
|
|
|
global::console = new UART{0x49020000, 74};
|
|
|
|
global::pagecache = new PageCache{};
|
|
|
|
OMAP35x_SDMMC *sdmmc1;
|
|
try {
|
|
sdmmc1 = new OMAP35x_SDMMC{0x4809c000, 83, 61, 60};
|
|
} catch(ex::error &ex) {
|
|
printf("SD initialization failed: %s (%d)\n", strerror(ex.getErrno()), ex.getErrno());
|
|
}
|
|
|
|
try {
|
|
auto test = global::pagecache->readAllocate(*sdmmc1, 0, 1);
|
|
for(int i = 0;i < 32;++i) {
|
|
for(int j = 0;j < 16;++j)
|
|
printf("%.2hhx ", test.data()[i*16+j]);
|
|
printf("\n");
|
|
}
|
|
} catch(ex::error &ex) {
|
|
printf("SD read failed: %s (%d)\n", strerror(ex.getErrno()), ex.getErrno());
|
|
}
|
|
|
|
while(1) {
|
|
char buf[256];
|
|
if(fgets(buf, 256, stdin))
|
|
printf("%s", buf);
|
|
else {
|
|
printf("Error %d\n", errno);
|
|
abort();
|
|
}
|
|
if(strcmp(buf, "exit\n") == 0)
|
|
break;
|
|
}
|
|
|
|
malloc_stats();
|
|
sbrk_stats();
|
|
phys_mm::print_state();
|
|
|
|
global::scheduler->exit();
|
|
|
|
// We shouldn't get here
|
|
__asm__ __volatile__ ("svc #42");
|
|
|
|
return 0;
|
|
}
|