void _optimsoc_set_itlb(uint32_t vaddr, optimsoc_pte_t pte) { // Extract the index uint32_t index = OR1K_ADDR_L2_INDEX_GET(vaddr) & 0x3f; // Extract PPN from pte uint32_t ppn = OR1K_PTE_PPN_GET(pte); // Assemble translation register // Set PPN uint32_t tr = OR1K_SPR_IMMU_ITLBW_TR_PPN_SET(0, ppn); // Set access rights if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_EXEC_BIT)) { tr = OR1K_SPR_IMMU_ITLBW_TR_SXE_SET(tr, 1); // Allow user access if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_USER_BIT)) { tr = OR1K_SPR_IMMU_ITLBW_TR_UXE_SET(tr, 1); } } // Write translate register or1k_mtspr (OR1K_SPR_IMMU_ITLBW_TR_ADDR(0, index), tr); // Set page match register // - valid // - level 2 (8kB) // - VPN from vaddr uint32_t mr = OR1K_SPR_IMMU_ITLBW_MR_V_SET(0, 1); mr = OR1K_SPR_IMMU_ITLBW_MR_VPN_SET(mr, OR1K_ADDR_PN_GET(vaddr)); // Write match register or1k_mtspr (OR1K_SPR_IMMU_ITLBW_MR_ADDR(0, index), mr); }
/* --------------------------------------------------------------------------*/ int or1k_timer_init(unsigned int hz) { uint32_t upr = or1k_mfspr(OR1K_SPR_SYS_UPR_ADDR); if (OR1K_SPR_SYS_UPR_TTP_GET(upr) == 0) { return -1; } /* Set this, for easy access when reloading */ uint32_t period = (_or1k_board_clk_freq/hz) & OR1K_SPR_TICK_TTMR_TP_MASK; OR1K_REENT.or1k_timer_period = period; or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, period); /* Reset timer tick counter */ OR1K_REENT.or1k_timer_ticks = 0; /* Install handler */ or1k_exception_handler_add(0x5, _or1k_timer_interrupt_handler); OR1K_REENT.or1k_timer_mode = OR1K_SPR_TICK_TTMR_MODE_RESTART; /* Reset counter register */ or1k_mtspr(OR1K_SPR_TICK_TTCR_ADDR, 0); return 0; }
void timer_isr() { _cust_print("<timer interrupt>"); or1k_mtspr(17, or1k_mfspr(17) | 2 ); or1k_mtspr((10<<11)+1, 0); or1k_mtspr((10<<11), 0xa0<<24 | 40000); return; }
void arch_set_dtlb(void *vaddr, void *paddr) { // Extract the index (shift by 13 and mask) uint32_t index = OR1K_SPR_DMMU_DTLBW_MR_VPN_GET((uint32_t) vaddr) & 0x3f; // Extract VPN (properly shift and mask) uint32_t vpn = OR1K_SPR_DMMU_DTLBW_MR_VPN_GET((uint32_t) vaddr); // Set page match register // - valid // - level 2 (8kB) // - VPN from vaddr uint32_t mr = OR1K_SPR_DMMU_DTLBW_MR_V_SET(0, 1); mr = OR1K_SPR_DMMU_DTLBW_MR_VPN_SET(mr, vpn); or1k_mtspr (OR1K_SPR_DMMU_DTLBW_MR_ADDR(0, index), mr); // Extract PPN (properly shift and mask) uint32_t ppn = OR1K_SPR_DMMU_DTLBW_TR_PPN_GET((uint32_t) paddr); // Set page translation register // - allow all accesses uint32_t tr = OR1K_SPR_DMMU_DTLBW_TR_URE_SET(0, 1); tr = OR1K_SPR_DMMU_DTLBW_TR_UWE_SET(tr, 1); tr = OR1K_SPR_DMMU_DTLBW_TR_SRE_SET(tr, 1); tr = OR1K_SPR_DMMU_DTLBW_TR_SWE_SET(tr, 1); tr = OR1K_SPR_DMMU_DTLBW_TR_PPN_SET(tr, ppn); or1k_mtspr (OR1K_SPR_DMMU_DTLBW_TR_ADDR(0, index), tr); }
void or1k_timer_reset(void) { uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); ttmr = OR1K_SPR_TICK_TTMR_IP_SET(ttmr, 0); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); or1k_mtspr(OR1K_SPR_TICK_TTCR_ADDR, 0); }
void arch_set_dtlb(void *vaddr,void *paddr) { unsigned int flags = DTLB_PR_NOLIMIT; unsigned int mr = ((unsigned int)vaddr & SPR_DTLBMR_VPN) | SPR_ITLBMR_V; unsigned int tr = ((unsigned int)paddr & SPR_DTLBTR_PPN) | (flags & DTLB_PR_MASK) | SPR_DTLBTR_A | SPR_DTLBTR_D; unsigned int set = ((((unsigned int)vaddr) >> PAGE_BITS) & 63); or1k_mtspr (SPR_DTLBMR_BASE(0)+set, mr); or1k_mtspr (SPR_DTLBTR_BASE(0)+set, tr); }
/* --------------------------------------------------------------------------*/ void or1k_timer_enable(void) { uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); ttmr = OR1K_SPR_TICK_TTMR_IE_SET(ttmr, 1); ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_REENT.or1k_timer_mode); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); sr = OR1K_SPR_SYS_SR_TEE_SET(sr, 1); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr); }
void interrupt_handler(void) { unsigned mask = or1k_mfspr((9<<11)|0); or1k_mtspr((9<<11),0); unsigned irq = or1k_mfspr(9<<11|2) & mask; or1k_mtspr((9<<11) |2,0); for (int i = 0;i<32;i++){ if (irq & (1<<i)){ if (global_irqhandler[i]){ (*global_irqhandler[i])(); } } } or1k_mtspr((9<<5),mask); }
void or1k_interrupts_restore(uint32_t sr_iee) { uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); sr = OR1K_SPR_SYS_SR_IEE_SET(sr, sr_iee); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr); }
void or1k_interrupts_enable(void) { uint32_t sr = or1k_mfspr(SPR_SR); sr |= SPR_SR_IEE; or1k_mtspr(SPR_SR, sr); }
void or1k_interrupts_enable(void) { uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); sr = OR1K_SPR_SYS_SR_IEE_SET(sr, 1); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr); }
void or1k_timer_pause(void) { uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_SPR_TICK_TTMR_MODE_DISABLE); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); }
void or1k_timer_restore(uint32_t sr_tee) { uint32_t sr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); sr = OR1K_SPR_SYS_SR_TEE_SET(sr, sr_tee); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr); }
/* --------------------------------------------------------------------------*/ uint32_t or1k_timer_disable(void) { uint32_t oldsr = or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); uint32_t sr = OR1K_SPR_SYS_SR_TEE_SET(oldsr, 0); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, sr); return OR1K_SPR_SYS_SR_TEE_GET(oldsr); }
uint32_t or1k_interrupts_disable(void) { uint32_t oldsr, newsr; oldsr= or1k_mfspr(SPR_SR); newsr = oldsr & ~SPR_SR_IEE; or1k_mtspr(SPR_SR, newsr); return oldsr & SPR_SR_IEE; }
uint32_t or1k_interrupts_disable(void) { uint32_t oldsr, newsr; oldsr= or1k_mfspr(OR1K_SPR_SYS_SR_ADDR); newsr = OR1K_SPR_SYS_SR_IEE_SET(oldsr, 0); or1k_mtspr(OR1K_SPR_SYS_SR_ADDR, newsr); return OR1K_SPR_SYS_SR_IEE_GET(oldsr); }
void or1k_timer_set_period(uint32_t hz) { uint32_t period = (_or1k_board_clk_freq/hz) & OR1K_SPR_TICK_TTMR_TP_MASK; uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); ttmr = OR1K_SPR_TICK_TTMR_TP_SET(ttmr, period); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); OR1K_REENT.or1k_timer_period = period; }
/* --------------------------------------------------------------------------*/ void _or1k_timer_interrupt_handler(void) { OR1K_REENT.or1k_timer_ticks++; uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); ttmr = OR1K_SPR_TICK_TTMR_IE_SET(ttmr, 1); ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, OR1K_SPR_TICK_TTMR_MODE_RESTART); ttmr = OR1K_SPR_TICK_TTMR_IP_SET(ttmr, 0); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); }
void or1k_timer_set_mode(uint32_t mode) { // Store mode in variable OR1K_REENT.or1k_timer_mode = mode; uint32_t ttmr = or1k_mfspr(OR1K_SPR_TICK_TTMR_ADDR); // If the timer is currently running, we also change the mode if (OR1K_SPR_TICK_TTMR_MODE_GET(ttmr) != 0) { ttmr = OR1K_SPR_TICK_TTMR_MODE_SET(ttmr, mode); or1k_mtspr(OR1K_SPR_TICK_TTMR_ADDR, ttmr); } }
void or1k_timer_interrupt_handler_new(void) { /* Re-initialise timer */ or1k_mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (or1k_timer_period & SPR_TTMR_PERIOD)); /* Increment global ticks value */ or1k_timer_ticks++; /* Call a user handler function */ or1k_timer_user_handler(); }
void or1k_interrupts_restore(uint32_t sr_iee) { or1k_mtspr(SPR_SR, or1k_mfspr(SPR_SR) | (sr_iee & SPR_SR_IEE)); }
int main(int arcg,char * argv[]){ int i = or1k_mfspr(17); char * newline = "\n"; //_cust_print_int((int)newline); *(volatile char*)0x80000000 = 'm'; *(volatile char*)0x80000000 = 'a'; *(volatile char*)0x80000000 = 'i'; *(volatile char*)0x80000000 = 'n'; *(volatile char*)0x80000000 = ' '; *(volatile char*)0x80000000 = 'c'; *(volatile char*)0x80000000 = 'a'; *(volatile char*)0x80000000 = 'l'; *(volatile char*)0x80000000 = 'l'; *(volatile char*)0x80000000 = 'e'; *(volatile char*)0x80000000 = 'd'; *(volatile char*)0x80000000 = '\n'; for (int i = 0;i<32;i++) global_irqhandler[i] = 0; global_irqhandler[2] = irq2; or1k_exception_handler_add (0x8, &interrupt_handler); or1k_interrupt_enable(2); /*__asm__( ".byte 0x7C,0x00,0x00,0x00" );*/ // Timer interrupt int or1k_timer_period = 40000; or1k_exception_handler_add(0x5, &timer_isr); // Install handler for Timer interrupt or1k_mtspr(10<<11, 0x00<<24 | or1k_timer_period); // Set Timer Mode Register or1k_mtspr(17, or1k_mfspr(17) | 2 ); // Set Special Purpose Register: Enable Timer interrupt or1k_mtspr((10<<11) + 1, 0); // reset counter register (qemu bug: automatic counter reset does not work) for (int i = 1;i<10000; i = i * 2){ _cust_print_int(i); _cust_print(newline); } //or1k_exception_handler_add (0x8, &or1k_interrupt_handler); //or1k_interrupt_handler_add(11, &irq2); //or1k_interrupt_enable(10); /* float x = 0; for (int j = 0;j<(1<<16);j++){ for (int i = 0;i<(100);i++){ x += 0.1; } *((int*)0x0000A000) = (int) x; } *((int*)0x10000000) = 0; */ float p = 2 * F(1); _cust_print("pi 1: "); _cust_print_float(p); _cust_print("\n"); _cust_print("pi 2: "); _cust_print_float(pi()); _cust_print("\n"); //if (pi > 0.0) //_cust_print("\n\n3-pi > 0\n\n\n"); //float c = 0; //for (int i = 0;i < 10000000;i++){ // c+=0.1; //} //return (int)c; return 0; }