OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1389 to Rev 1390
    Reverse comparison

Rev 1389 → Rev 1390

/trunk/or1ksim/tick/tick.c
70,7 → 70,7
if (!param) {
sprs[SPR_TTCR] = ttcr = 0;
cycles_start = runtime.sim.cycles - ttcr;
SCHED_ADD(tick_job, (void *)0, runtime.sim.cycles + (ttmr & SPR_TTMR_PERIOD) - ttcr);
SCHED_ADD(tick_job, (void *)0, (ttmr & SPR_TTMR_PERIOD) - ttcr);
}
case 2:
if (ttmr & SPR_TTMR_IE) {
81,7 → 81,7
else
/* If TEE is currently not set we have to pend tick exception
by rescheduling. */
SCHED_ADD(tick_job, (void *)1, runtime.sim.cycles + 1);
SCHED_ADD(tick_job, (void *)1, 1);
}
break;
}
97,7 → 97,7
SCHED_FIND_REMOVE(tick_job, (void *)0);
SCHED_FIND_REMOVE(tick_job, (void *)1);
if (mode == 1 || mode == 2) {
SCHED_ADD(tick_job, (void *)0, runtime.sim.cycles + (ttmr & SPR_TTMR_PERIOD) - ttcr);
SCHED_ADD(tick_job, (void *)0, (ttmr & SPR_TTMR_PERIOD) - ttcr);
cycles_start = runtime.sim.cycles - ttcr;
}
}
117,7 → 117,7
cycles_start = runtime.sim.cycles;
SCHED_FIND_REMOVE(tick_job, (void *)0);
SCHED_FIND_REMOVE(tick_job, (void *)1);
SCHED_ADD(tick_job, (void *)0, runtime.sim.cycles + (ttmr & SPR_TTMR_PERIOD) - ttcr);
SCHED_ADD(tick_job, (void *)0, (ttmr & SPR_TTMR_PERIOD) - ttcr);
break;
case 2: /* Stop the timer when match */
SCHED_FIND_REMOVE(tick_job, (void *)0);
/trunk/or1ksim/peripheral/gpio.c
222,7 → 222,7
/* Since we can't report an interrupt during a readmem/writemem
* schedule the scheduler to do it. Read the comment above
* report_interrupt in pic/pic.c */
SCHED_ADD( gpio_do_int, gpio, runtime.sim.cycles + 1 );
SCHED_ADD( gpio_do_int, gpio, 1 );
}
}
}
/trunk/or1ksim/peripheral/eth.c
232,7 → 232,7
}
 
/* Reschedule */
SCHED_ADD( eth_controller_tx_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( eth_controller_tx_clock, dat, 1 );
}
/* ========================================================================= */
 
434,7 → 434,7
}
/* Reschedule */
SCHED_ADD( eth_controller_rx_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( eth_controller_rx_clock, dat, 1 );
}
 
/* ========================================================================= */
699,13 → 699,13
 
if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN) &&
TEST_FLAG( value, ETH_MODER, RXEN) )
SCHED_ADD( eth_controller_rx_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( eth_controller_rx_clock, dat, 1 );
else if ( !TEST_FLAG( value, ETH_MODER, RXEN) )
SCHED_FIND_REMOVE( eth_controller_rx_clock, dat);
 
if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN) &&
TEST_FLAG( value, ETH_MODER, TXEN) )
SCHED_ADD( eth_controller_tx_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( eth_controller_tx_clock, dat, 1 );
else if ( !TEST_FLAG( value, ETH_MODER, TXEN) )
SCHED_FIND_REMOVE( eth_controller_tx_clock, dat);
 
/trunk/or1ksim/peripheral/ps2kbd.c
259,7 → 259,7
PRINTF("Keyboard Interrupt.... kbd_kresp %lx kbd_buf_count %lx \n",
kbd->kresp, kbd->buf_count);
if (kbd_int) report_interrupt(kbd->irq);
SCHED_ADD(kbd_job, dat, runtime.sim.cycles + kbd->slowdown);
SCHED_ADD(kbd_job, dat, kbd->slowdown);
}
 
/* Reset all (simulated) ps2 controlers/keyboards */
280,7 → 280,7
}
kbd->slowdown = (long) ((config.sim.system_kfreq * 1000.) / KBD_BAUD_RATE);
if (kbd->slowdown <= 0) kbd->slowdown = 1;
SCHED_ADD(kbd_job, dat, runtime.sim.cycles + kbd->slowdown);
SCHED_ADD(kbd_job, dat, kbd->slowdown);
}
 
 
/trunk/or1ksim/peripheral/fb.c
284,13 → 284,13
else fb_dump_image8 (fb, temp);
fb->pic++;
}
SCHED_ADD(fb_job, dat, runtime.sim.cycles + fb->refresh_rate - fb->refresh_rate / REFRESH_DIVIDER);
SCHED_ADD(fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
fb->in_refresh = 0;
fb->refresh = 0;
} else {
fb->refresh_count++;
fb->refresh = 1;
SCHED_ADD(fb_job, dat, runtime.sim.cycles + fb->refresh_rate / REFRESH_DIVIDER);
SCHED_ADD(fb_job, dat, fb->refresh_rate / REFRESH_DIVIDER);
}
}
 
307,7 → 307,7
for (i = 0; i < 256; i++)
fb->pal[i] = (i << 16) | (i << 8) | (i << 0);
 
SCHED_ADD(fb_job, dat, runtime.sim.cycles + fb->refresh_rate);
SCHED_ADD(fb_job, dat, fb->refresh_rate);
fb->refresh = 0;
}
 
/trunk/or1ksim/peripheral/dma.c
239,7 → 239,7
/* Check if we should *start* a transfer */
if ( !TEST_FLAG( channel->regs.csr, DMA_CH_CSR, CH_EN ) &&
TEST_FLAG( value, DMA_CH_CSR, CH_EN ))
SCHED_ADD( dma_channel_clock, channel, runtime.sim.cycles + 1 );
SCHED_ADD( dma_channel_clock, channel, 1 );
else if ( !TEST_FLAG( value, DMA_CH_CSR, CH_EN ) )
/* The CH_EN flag is clear, check if we have a transfer in progress and
* clear it */
281,7 → 281,7
/* In HW Handshake mode, only work when dma_req_i asserted */
if ( TEST_FLAG(channel->regs.csr, DMA_CH_CSR, MODE) && !channel->dma_req_i ) {
/* Reschedule */
SCHED_ADD( dma_channel_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( dma_channel_clock, dat, 1 );
return;
}
 
335,7 → 335,7
}
 
/* Reschedule to transfer the next chunk */
SCHED_ADD( dma_channel_clock, dat, runtime.sim.cycles + 1 );
SCHED_ADD( dma_channel_clock, dat, 1 );
}
 
 
387,7 → 387,7
dma_load_descriptor( channel );
dma_init_transfer( channel );
/* Reschedule */
SCHED_ADD( dma_channel_clock, channel, runtime.sim.cycles + 1 );
SCHED_ADD( dma_channel_clock, channel, 1 );
return;
}
 
/trunk/or1ksim/peripheral/vga.c
210,7 → 210,7
sprintf (temp, "%s%04i.bmp", vga->filename, vga->pics++);
vga_dump_image (temp, vga);
SCHED_ADD(vga_job, dat, runtime.sim.cycles + vga->refresh_rate);
SCHED_ADD(vga_job, dat, vga->refresh_rate);
}
 
/* Reset all VGAs */
234,7 → 234,7
vga->pindex = 0;
vga->vbindex = 0;
 
SCHED_ADD(vga_job, dat, runtime.sim.cycles + vga->refresh_rate);
SCHED_ADD(vga_job, dat, vga->refresh_rate);
}
 
/*----------------------------------------------------[ VGA Configuration ]---*/
/trunk/or1ksim/peripheral/16450.c
335,7 → 335,7
int retval;
 
/* Schedule for later */
SCHED_ADD (uart_clock16, dat, runtime.sim.cycles + UART_CLOCK_DIVIDER);
SCHED_ADD (uart_clock16, dat, UART_CLOCK_DIVIDER);
/* If VAPI is not selected, UART communicates with two file streams;
if VAPI is selected, we use VAPI streams. */
635,7 → 635,7
uart->vapi_buf_tail_ptr = 0;
memset(uart->vapi_buf, 0, sizeof(uart->vapi_buf));
 
SCHED_ADD (uart_clock16, dat, runtime.sim.cycles + UART_CLOCK_DIVIDER);
SCHED_ADD (uart_clock16, dat, UART_CLOCK_DIVIDER);
}
 
/* Print register values on stdout. */
/trunk/or1ksim/toplevel.c
68,7 → 68,7
#include "cuc.h"
 
/* CVS revision number. */
const char rcsrev[] = "$Revision: 1.117 $";
const char rcsrev[] = "$Revision: 1.118 $";
 
inline void debug(int level, const char *format, ...)
{
157,7 → 157,8
{
struct sim_reset_hook *cur_reset = sim_reset_hooks;
 
SCHED_INIT();
/* We absolutely MUST reset the scheduler first */
sched_reset();
 
while(cur_reset) {
cur_reset->reset_hook(cur_reset->dat);
179,6 → 180,8
init_breakpoints();
initstats();
build_automata();
 
sched_init();
if (config.sim.profile) {
runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
327,16 → 330,17
/* Executes jobs in time queue */
static inline void do_scheduler ()
{
void (*func)(void *);
void *param;
struct sched_entry *tmp;
 
/* Execute all jobs till now */
do {
func = SCHED_PEEK().func;
param = SCHED_PEEK().param;
SCHED_REMOVE();
func (param);
} while (runtime.sim.cycles >= SCHED_PEEK().time);
tmp = scheduler.job_queue;
scheduler.job_queue = tmp->next;
tmp->next = scheduler.free_job_queue;
scheduler.free_job_queue = tmp;
 
tmp->func (tmp->param);
} while (scheduler.job_queue->time <= 0);
}
 
/* Main function */
399,6 → 403,7
 
/* MM: 'run -1' means endless execution. */
while(runtime.sim.cont_run) {
long long time_start = runtime.sim.cycles;
if (config.debug.enabled) {
du_clock(); // reset watchpoints
if (runtime.cpu.stalled) {
430,7 → 435,8
if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
 
runtime.sim.cycles += runtime.sim.mem_cycles;
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler ();
scheduler.job_queue->time -= runtime.sim.cycles - time_start;
if (scheduler.job_queue->time <= 0) do_scheduler ();
if (!runtime.sim.hush) dumpreg();
}
runtime.sim.hush = 0;
/trunk/or1ksim/support/sched.c
45,6 → 45,49
emptying */
void sched_guard (void *dat)
{
SCHED_INIT ();
if(scheduler.job_queue)
SCHED_ADD(sched_guard, dat, SCHED_TIME_MAX);
else {
scheduler.job_queue = scheduler.free_job_queue;
scheduler.free_job_queue = scheduler.free_job_queue->next;
scheduler.job_queue->next = NULL;
scheduler.job_queue->func = sched_guard;
scheduler.job_queue->time = SCHED_TIME_MAX;
#if DYNAMIC_EXECUTION
set_sched_cycle(SCHED_TIME_MAX);
#endif
}
}
 
void sched_reset(void)
{
struct sched_entry *cur, *next;
 
for(cur = scheduler.job_queue; cur; cur = next) {
next = cur->next;
cur->next = scheduler.free_job_queue;
scheduler.free_job_queue = cur;
}
scheduler.job_queue = NULL;
sched_guard(NULL);
}
 
void sched_init(void)
{
int i;
struct sched_entry *new;
 
scheduler.free_job_queue = NULL;
 
for(i = 0; i < SCHED_HEAP_SIZE; i++) {
if(!(new = malloc(sizeof(struct sched_entry)))) {
fprintf(stderr, "Out-of-memory while allocateing scheduler queue\n");
exit(1);
}
new->next = scheduler.free_job_queue;
scheduler.free_job_queue = new;
}
scheduler.job_queue = NULL;
sched_guard(NULL);
}
#warning Scheduler should continue from previous cycles not current ones
/trunk/or1ksim/support/dbchs.h
19,3 → 19,4
 
 
/* Declatrations of all debug channels */
DECLARE_DEBUG_CHANNEL(sched)
/trunk/or1ksim/support/sched.h
1,5 → 1,6
/* sched.h -- Abstract entities header file handling job scheduler
Copyright (C) 2001 Marko Mlinar, markom@opencores.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
20,45 → 21,46
#ifndef _SCHED_H_
#define _SCHED_H_
 
#include "debug.h"
 
/* Scheduler debug level */
#define SCHED_DEBUG 0
 
#define SCHED_HEAP_SIZE 128
#define SCHED_TIME_MAX 0x7fffffffffffffffLL
#define SCHED_TIME_MAX INT32_MAX
 
DECLARE_DEBUG_CHANNEL(sched);
 
/* Structure for holding one job entry */
struct sched_entry {
long long time; /* Clock cycles before job starts */
void *param; /* Parameter to pass to the function */
int32_t time; /* Clock cycles before job starts */
void *param; /* Parameter to pass to the function */
void (*func)(void *); /* Function to call when time reaches 0 */
struct sched_entry *next;
};
 
/* Heap of jobs */
struct scheduler_struct {
int size;
struct sched_entry heap[SCHED_HEAP_SIZE];
struct sched_entry *free_job_queue;
struct sched_entry *job_queue;
};
 
void sched_init(void);
void sched_reset(void);
 
extern struct scheduler_struct scheduler;
 
/* Dummy function, representing a guard, which protects heap from
emptying */
extern void sched_guard (void *);
#if SCHED_DEBUG > 1
#define SCHED_PRINT_JOBS() sched_print_jobs()
static inline void sched_print_jobs(void)
{
struct sched_entry *cur;
int i;
 
/* Init scheduler -- clear the heap */
#define SCHED_INIT() {\
scheduler.heap[1].func = sched_guard;\
scheduler.heap[1].time = SCHED_TIME_MAX;\
scheduler.size = 2;\
for (cur = scheduler.job_queue, i = 0; cur; cur = cur->next, i++)
TRACE_(sched)("\t%i: %p $%p @ %"PRIi32"\n", i, cur->func, cur->param,
cur->time);
}
 
#if SCHED_DEBUG > 1
#define SCHED_PRINT_JOBS() {\
int i;\
for (i = 1; i < scheduler.size; i++) \
PRINTF ("\t%i: %x $%i @ %i\n", i, scheduler.heap[i].func, scheduler.heap[i].param, scheduler.heap[i].time);\
}
#else
#define SCHED_PRINT_JOBS()
#endif
65,82 → 67,94
 
/* Adds new job to the queue */
static inline void sched_add(void (*job_func)(void *), void *job_param,
long long job_time, const char *func)
int32_t job_time, const char *func)
{
int i;
struct sched_entry *cur, *prev, *new_job;
int32_t alltime;
 
if (SCHED_DEBUG > 0)
PRINTF ("%s@%lli:SCHED_ADD(func %p, param %p, time %lli)\n", func,
runtime.sim.cycles, job_func, job_param, job_time);
if (SCHED_DEBUG > 1)
TRACE_(sched)("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func,
runtime.sim.cycles, job_time);
SCHED_PRINT_JOBS();
 
if (SCHED_DEBUG > 1) PRINTF ("--------\n");\
if (SCHED_DEBUG > 1) TRACE_(sched) ("--------\n");
 
i = scheduler.size++;
while (i > 1 && scheduler.heap[i / 2].time > job_time) {
scheduler.heap[i] = scheduler.heap[i / 2];
i /= 2;
cur = scheduler.job_queue;
prev = NULL;
alltime = cur->time;
while(cur && (alltime < job_time)) {
prev = cur;
cur = cur->next;
if(cur)
alltime += cur->time;
}
 
scheduler.heap[i].func = job_func;
scheduler.heap[i].param = job_param;
scheduler.heap[i].time = job_time;
new_job = scheduler.free_job_queue;
scheduler.free_job_queue = new_job->next;
new_job->next = cur;
 
new_job->func = job_func;
new_job->param = job_param;
 
if(prev) {
new_job->time = job_time - (alltime - (cur ? cur->time : 0));
prev->next = new_job;
TRACE_(sched)("Scheduled job not going to head of queue, relative time: %"
PRIi32"\n", new_job->time);
} else {
scheduler.job_queue = new_job;
new_job->time = job_time;
#if DYNAMIC_EXECUTION
/* If we are replaceing the first job in the queue, then update the
* recompiler's internal cycle counter */
set_sched_cycle(job_time);
#endif
TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
runtime.sim.cycles);
}
 
if(cur)
cur->time -= new_job->time;
 
SCHED_PRINT_JOBS();
}
 
#define SCHED_ADD(job_func, job_param, job_time) sched_add(job_func, job_param, job_time, __FUNCTION__)
 
/* Removes an item from the heap */
#define SCHED_REMOVE_ITEM(index) {\
struct sched_entry *tmp;\
int ___i = (index), ___j;\
if (SCHED_DEBUG > 0) PRINTF ("%s@%i:SCHED_REMOVE%i(time %li)\n", __FUNCTION__, runtime.sim.cycles, (index), scheduler.heap[___i].time); \
SCHED_PRINT_JOBS();\
if (SCHED_DEBUG > 1) PRINTF ("--------\n");\
tmp = &scheduler.heap[--scheduler.size];\
while (___i <= scheduler.size / 2) {\
___j = 2 * ___i;\
if (___j < scheduler.size && scheduler.heap[___j].time > scheduler.heap[___j + 1].time) ___j++;\
if (scheduler.heap[___j].time >= tmp->time) break;\
scheduler.heap[___i] = scheduler.heap[___j];\
___i = ___j;\
}\
scheduler.heap[___i] = *tmp;\
SCHED_PRINT_JOBS();\
}
/* Returns a job with specified function and param, NULL if not found */
static inline void sched_find_remove(void (*job_func)(void *), void *dat,
const char *func)
{
struct sched_entry *cur;
struct sched_entry *prev = NULL;
 
/* Removes first item from the heap */
#define SCHED_REMOVE() SCHED_REMOVE_ITEM(1)
TRACE_(sched)("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
 
/* Returns item with lowest time in the heap */
#define SCHED_PEEK() scheduler.heap[1]
for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
if ((cur->func == job_func) && (cur->param == dat)) {
if(cur->next)
cur->next->time += cur->time;
 
/* Returns a job with specified function and param, NULL if not found */
#define SCHED_FIND(f, p) ({\
int i;\
struct sched_entry *t = NULL;\
for (i = 1; i < scheduler.size; i++)\
if (scheduler.heap[i].func == (f) && scheduler.heap[i].param == (p)) {\
t = &scheduler.heap[i]; break;\
}\
tmp;\
})
if(prev) {
prev->next = cur->next;
} else {
scheduler.job_queue = cur->next;
#if DYNAMIC_EXECUTION
if(cur->next)
set_sched_cycle(cur->next->time);
#endif
if(cur->next)
TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n",
cur->next->time, runtime.sim.cycles);
}
cur->next = scheduler.free_job_queue;
scheduler.free_job_queue = cur;
break;
}
}
}
 
/* Returns a index of the job with specified function and param, 0 if not found */
#define SCHED_FIND_INDEX(f, p) ({\
int i, found = 0;\
for (i = 1; i < scheduler.size; i++)\
if (scheduler.heap[i].func == (f) && scheduler.heap[i].param == (p)) {\
found = i; break;\
}\
found;\
})
 
/* Deletes job with specified function and param */
#define SCHED_FIND_REMOVE(f, p) {\
int index;\
index = SCHED_FIND_INDEX(f, p);\
if (index) SCHED_REMOVE_ITEM(index);\
}
#define SCHED_FIND_REMOVE(f, p) sched_find_remove(f, p, __FUNCTION__)
 
#endif /* _SCHED_H_ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.