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