Files
beaglefw/main.cc
Matthias Blankertz 76cc09a168 - WIP: OMAP35x SD/MMC controller driver
- WIP: Pagecache
- Added sleep() and usleep() functions
2013-07-19 19:51:40 +02:00

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;
}