URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1370 to Rev 1371
- ↔ Reverse comparison
Rev 1370 → Rev 1371
/trunk/or1ksim/sim-config.h
63,13 → 63,6
} gpios[MAX_GPIOS]; |
|
struct { |
int enabled; /* Is keyboard enabled? */ |
unsigned long baseaddr; /* Base address of frame buffer register */ |
int irq; /* Irq number of this device */ |
char rxfile[STR_SIZE]; /* Filename for RX */ |
} kbd; |
|
struct { |
int enabled; /* is MC enabled? */ |
unsigned long baseaddr; /* Naturally aligned base address */ |
unsigned POC; /* power on reset configuration register */ |
/trunk/or1ksim/sim.cfg
816,9 → 816,6
|
This section configures the PS/2 compatible keyboard |
|
enabled = 0/1 |
whether keyboard is enabled |
|
baseaddr = <hex_value> |
base address of the keyboard device |
|
827,7 → 824,6
*/ |
|
section kbd |
enabled = 1 |
irq = 5 |
baseaddr = 0x94000000 |
rxfile = "kbd.rx" |
/trunk/or1ksim/sim-cmd.c
62,7 → 62,6
#include "branch_predict.h" |
#include "ethernet.h" |
#include "gpio.h" |
#include "ps2kbd.h" |
|
struct sim_stat { |
void (*stat_func)(void *dat); |
424,7 → 423,6
if (config.mc.enabled) mc_status(); |
if (config.nethernets) eth_status(); |
if (config.ngpios) gpio_status(); |
kbd_info(); |
|
while(cur_stat) { |
cur_stat->stat_func(cur_stat->dat); |
/trunk/or1ksim/peripheral/ps2kbd.c
68,45 → 68,52
{0, 0x2D}, {0, 0x15}, {0, 0x2C}, {1, 0x1A}, {1, 0x2B}, {1, 0x1B}, {1, 0x29}, {0, 0x00} |
}; |
|
/* Temporary buffer to store incoming scan codes */ |
static unsigned char kbd_buf[KBD_MAX_BUF] = {0}; |
struct kbd_state { |
/* Temporary buffer to store incoming scan codes */ |
uint8_t buf[KBD_MAX_BUF]; |
|
/* Number of scan codes in buffer */ |
static unsigned long kbd_buf_count = 0; |
static unsigned long kbd_buf_head = 0; |
static unsigned long kbd_buf_tail = 0; |
/* Number of scan codes in buffer */ |
unsigned long buf_count; |
unsigned long buf_head; |
unsigned long buf_tail; |
|
/* Input stream */ |
static FILE *kbd_rxfs = NULL; |
/* Input stream */ |
FILE *rxfs; |
|
/* Controller Command (write into 0x64) */ |
static int kbd_ccmd; |
/* Controller Command (write into 0x64) */ |
int ccmd; |
|
/* Keyboard Command (write into 0x60) */ |
static unsigned char kbd_kcmd; |
/* Keyboard Command (write into 0x60) */ |
uint8_t kcmd; |
|
/* Controller Command Byte */ |
static unsigned char kbd_ccmdbyte; |
/* Controller Command Byte */ |
uint8_t ccmdbyte; |
|
/* Keyboard response pending */ |
static unsigned long kbd_kresp; |
/* Keyboard response pending */ |
unsigned long kresp; |
|
/* Keyboard slowdown factor */ |
static long kbd_slowdown; |
/* Keyboard slowdown factor */ |
long slowdown; |
|
static void kbd_put (unsigned char c) |
/* Cofiguration */ |
int irq; |
oraddr_t baseaddr; |
char *rxfile; |
}; |
|
static void kbd_put (struct kbd_state *kbd, unsigned char c) |
{ |
if (kbd_buf_count >= KBD_MAX_BUF) { |
if (kbd->buf_count >= KBD_MAX_BUF) { |
fprintf (stderr, "WARNING: Keyboard buffer overflow.\n"); |
} else { |
kbd_buf[kbd_buf_head] = c; |
kbd_buf_head = (kbd_buf_head + 1) % KBD_MAX_BUF; |
kbd_buf_count++; |
kbd->buf[kbd->buf_head] = c; |
kbd->buf_head = (kbd->buf_head + 1) % KBD_MAX_BUF; |
kbd->buf_count++; |
} |
} |
|
/* Decodes ascii code c into multiple scan codes, placed into buf, length is returned */ |
static void scan_decode (unsigned char c) |
static void scan_decode (struct kbd_state *kbd, unsigned char c) |
{ |
/* Do not handle special characters and extended ascii */ |
if (c >= 128 || !scan_table[c].code) |
113,47 → 120,48
return; |
|
/* Make shift? */ |
if (scan_table[c].shift) kbd_put (0x2a); |
if (scan_table[c].shift) kbd_put (kbd, 0x2a); |
/* Make char */ |
kbd_put (scan_table[c].code); |
kbd_put (kbd, scan_table[c].code); |
/* Break char */ |
kbd_put (scan_table[c].code | 0x80); |
kbd_put (kbd, scan_table[c].code | 0x80); |
/* Break shift? */ |
if (scan_table[c].shift) kbd_put (0xaa); |
if (scan_table[c].shift) kbd_put (kbd, 0xaa); |
} |
|
/* Write a register */ |
void kbd_write8 (oraddr_t addr, uint32_t value, void *dat) |
{ |
int a = (addr - config.kbd.baseaddr); |
struct kbd_state *kbd = dat; |
int a = (addr - kbd->baseaddr); |
switch (a) { |
case KBD_CTRL: |
kbd_ccmd = value & 0xff; |
if (kbd_ccmd == KBD_CCMD_RCB) |
kbd_kresp = 0x1; |
if (kbd_ccmd == KBD_CCMD_ST1) |
kbd_kresp = 0x1; |
if (kbd_ccmd == KBD_CCMD_ST2) |
kbd_kresp = 0x1; |
if (kbd_ccmd == KBD_CCMD_DKI) |
kbd_ccmdbyte |= KBD_CCMDBYTE_EN; |
if (kbd_ccmd == KBD_CCMD_EKI) |
kbd_ccmdbyte &= ~KBD_CCMDBYTE_EN; |
kbd->ccmd = value & 0xff; |
if (kbd->ccmd == KBD_CCMD_RCB) |
kbd->kresp = 0x1; |
if (kbd->ccmd == KBD_CCMD_ST1) |
kbd->kresp = 0x1; |
if (kbd->ccmd == KBD_CCMD_ST2) |
kbd->kresp = 0x1; |
if (kbd->ccmd == KBD_CCMD_DKI) |
kbd->ccmdbyte |= KBD_CCMDBYTE_EN; |
if (kbd->ccmd == KBD_CCMD_EKI) |
kbd->ccmdbyte &= ~KBD_CCMDBYTE_EN; |
if (config.sim.verbose) |
PRINTF("kbd_write8(%"PRIxADDR") %"PRIx32"\n", addr, value); |
break; |
case KBD_DATA: |
if (kbd_ccmd == KBD_CCMD_WCB) { |
kbd_ccmdbyte = value & 0xff; |
kbd_ccmd = 0x00; |
if (kbd->ccmd == KBD_CCMD_WCB) { |
kbd->ccmdbyte = value & 0xff; |
kbd->ccmd = 0x00; |
} else |
kbd_kcmd = value & 0xff; |
if (kbd_kcmd == KBD_KCMD_DK) |
kbd_ccmdbyte |= KBD_CCMDBYTE_EN; |
if (kbd_kcmd == KBD_KCMD_EK) |
kbd_ccmdbyte &= ~KBD_CCMDBYTE_EN; |
kbd_kresp = 0x1; |
kbd_ccmd = 0x00; |
kbd->kcmd = value & 0xff; |
if (kbd->kcmd == KBD_KCMD_DK) |
kbd->ccmdbyte |= KBD_CCMDBYTE_EN; |
if (kbd->kcmd == KBD_KCMD_EK) |
kbd->ccmdbyte &= ~KBD_CCMDBYTE_EN; |
kbd->kresp = 0x1; |
kbd->ccmd = 0x00; |
if (config.sim.verbose) |
PRINTF("kbd_write8(%"PRIxADDR") %"PRIx32"\n", addr, value); |
break; |
167,13 → 175,14
/* Read a register */ |
uint32_t kbd_read8 (oraddr_t addr, void *dat) |
{ |
int a = (addr - config.kbd.baseaddr); |
struct kbd_state *kbd = dat; |
int a = (addr - kbd->baseaddr); |
switch (a) { |
case KBD_CTRL: { |
unsigned long c = 0x0; |
if (kbd_kresp || kbd_buf_count) |
if (kbd->kresp || kbd->buf_count) |
c |= KBD_STATUS_OBF; |
c |= kbd_ccmdbyte & KBD_CCMDBYTE_SYS; |
c |= kbd->ccmdbyte & KBD_CCMDBYTE_SYS; |
c |= KBD_STATUS_INH; |
if (config.sim.verbose) |
PRINTF("kbd_read8(%"PRIxADDR") %lx\n", addr, c); |
180,49 → 189,49
return c; |
} |
case KBD_DATA: |
if (kbd_ccmd) { |
if (kbd->ccmd) { |
unsigned long rc; |
if (kbd_ccmd == KBD_CCMD_RCB) |
rc = kbd_ccmdbyte; |
if (kbd_ccmd == KBD_CCMD_ST1) |
if (kbd->ccmd == KBD_CCMD_RCB) |
rc = kbd->ccmdbyte; |
if (kbd->ccmd == KBD_CCMD_ST1) |
rc = 0x55; |
if (kbd_ccmd == KBD_CCMD_ST2) |
if (kbd->ccmd == KBD_CCMD_ST2) |
rc = 0x00; |
kbd_ccmd = 0x00; |
kbd_kresp = 0x0; |
kbd->ccmd = 0x00; |
kbd->kresp = 0x0; |
if (config.sim.verbose) |
PRINTF("kbd_read8(%"PRIxADDR") %lx\n", addr, rc); |
return rc; |
} |
else if (kbd_kresp) { |
else if (kbd->kresp) { |
unsigned long rc; |
if (kbd_kresp == 0x2) { |
kbd_kresp = 0x0; |
if (kbd->kresp == 0x2) { |
kbd->kresp = 0x0; |
rc = KBD_KRESP_RSTOK; |
} else if (kbd_kcmd == KBD_KCMD_RST) { |
kbd_kresp = 0x2; |
} else if (kbd->kcmd == KBD_KCMD_RST) { |
kbd->kresp = 0x2; |
rc = KBD_KRESP_ACK; |
} else if (kbd_kcmd == KBD_KCMD_ECHO) { |
kbd_kresp = 0x0; |
} else if (kbd->kcmd == KBD_KCMD_ECHO) { |
kbd->kresp = 0x0; |
rc = KBD_KRESP_ECHO; |
} else { |
kbd_kresp = 0x0; |
kbd->kresp = 0x0; |
rc = KBD_KRESP_ACK; |
} |
kbd_kcmd = 0x00; |
kbd->kcmd = 0x00; |
if (config.sim.verbose) |
PRINTF("kbd_read8(%"PRIxADDR") %lx\n", addr, rc); |
return rc; |
} else if (kbd_buf_count) { |
unsigned long c = kbd_buf[kbd_buf_tail]; |
kbd_buf_tail = (kbd_buf_tail + 1) % KBD_MAX_BUF; |
kbd_buf_count--; |
kbd_kresp = 0x0; |
} else if (kbd->buf_count) { |
unsigned long c = kbd->buf[kbd->buf_tail]; |
kbd->buf_tail = (kbd->buf_tail + 1) % KBD_MAX_BUF; |
kbd->buf_count--; |
kbd->kresp = 0x0; |
if (config.sim.verbose) |
PRINTF("kbd_read8(%"PRIxADDR") %lx\n", addr, c); |
return c; |
} |
kbd_kresp = 0x0; |
kbd->kresp = 0x0; |
if (config.sim.verbose) |
PRINTF("kbd_read8(%"PRIxADDR") fifo empty\n", addr); |
return 0; |
235,81 → 244,108
|
|
/* Simulation hook. Must be called every couple of clock cycles to simulate incomming data. */ |
void kbd_job(int param) |
void kbd_job(void *dat) |
{ |
struct kbd_state *kbd = dat; |
int c; |
int kbd_int = 0; |
|
/* Check if there is something waiting, and decode it into kdb_buf */ |
if((c = fgetc(kbd_rxfs)) != EOF) { |
scan_decode (c); |
if((c = fgetc(kbd->rxfs)) != EOF) { |
scan_decode (kbd, c); |
} |
kbd_int = kbd_kresp || kbd_buf_count; |
kbd_int = kbd_kresp || kbd_buf_count ? kbd_ccmdbyte & KBD_CCMDBYTE_INT : 0; |
kbd_int = kbd->kresp || kbd->buf_count ? kbd->ccmdbyte & KBD_CCMDBYTE_INT : 0; |
if (config.sim.verbose && kbd_int) |
PRINTF("Keyboard Interrupt.... kbd_kresp %lx kbd_buf_count %lx \n", |
kbd_kresp, kbd_buf_count); |
if (kbd_int) report_interrupt(config.kbd.irq); |
SCHED_ADD(kbd_job, 0, runtime.sim.cycles + kbd_slowdown); |
kbd->kresp, kbd->buf_count); |
if (kbd_int) report_interrupt(kbd->irq); |
SCHED_ADD(kbd_job, dat, runtime.sim.cycles + kbd->slowdown); |
} |
|
/* Reset all (simulated) ps2 controlers/keyboards */ |
void kbd_reset () |
void kbd_reset (void *dat) |
{ |
if (config.kbd.enabled) { |
kbd_buf_count = 0; |
kbd_buf_head = 0; |
kbd_buf_tail = 0; |
kbd_kresp = 0x0; |
kbd_ccmdbyte = 0x65; /* We reset into default normal operation. */ |
register_memoryarea(config.kbd.baseaddr, KBD_SPACE, 1, 0, kbd_read8, kbd_write8, NULL); |
struct kbd_state *kbd = dat; |
|
kbd->buf_count = 0; |
kbd->buf_head = 0; |
kbd->buf_tail = 0; |
kbd->kresp = 0x0; |
kbd->ccmdbyte = 0x65; /* We reset into default normal operation. */ |
|
if (!(kbd_rxfs = fopen(config.kbd.rxfile, "r")) |
&& !(kbd_rxfs = fopen(config.kbd.rxfile, "r+"))) { |
fprintf (stderr, "WARNING: Keyboard has problems with RX file stream.\n"); |
config.kbd.enabled = 0; |
} |
kbd_slowdown = (long) ((config.sim.system_kfreq * 1000.) / KBD_BAUD_RATE); |
if (kbd_slowdown <= 0) kbd_slowdown = 1; |
if (config.kbd.enabled) SCHED_ADD(kbd_job, 0, runtime.sim.cycles + kbd_slowdown); |
if (!(kbd->rxfs = fopen(kbd->rxfile, "r")) |
&& !(kbd->rxfs = fopen(kbd->rxfile, "r+"))) { |
fprintf (stderr, "WARNING: Keyboard has problems with RX file stream.\n"); |
return; |
} |
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); |
} |
|
|
void kbd_info() |
void kbd_info(void *dat) |
{ |
PRINTF("kbd_kcmd: %x\n", kbd_kcmd); |
PRINTF("kbd_ccmd: %x\n", kbd_ccmd); |
PRINTF("kbd_ccmdbyte: %x\n", kbd_ccmdbyte); |
PRINTF("kbd_kresp: %lx\n", kbd_kresp); |
PRINTF("kbd_buf_count: %lx\n", kbd_buf_count); |
struct kbd_state *kbd = dat; |
PRINTF("kbd_kcmd: %x\n", kbd->kcmd); |
PRINTF("kbd_ccmd: %x\n", kbd->ccmd); |
PRINTF("kbd_ccmdbyte: %x\n", kbd->ccmdbyte); |
PRINTF("kbd_kresp: %lx\n", kbd->kresp); |
PRINTF("kbd_buf_count: %lx\n", kbd->buf_count); |
} |
|
/*----------------------------------------------------[ KBD Configuration ]---*/ |
void kbd_enabled(union param_val val, void *dat) |
{ |
config.kbd.enabled = val.int_val; |
} |
|
void kbd_baseaddr(union param_val val, void *dat) |
{ |
config.kbd.baseaddr = val.addr_val; |
struct kbd_state *kbd = dat; |
kbd->baseaddr = val.addr_val; |
} |
|
void kbd_irq(union param_val val, void *dat) |
{ |
config.kbd.irq = val.int_val; |
struct kbd_state *kbd = dat; |
kbd->irq = val.int_val; |
} |
|
void kbd_rxfile(union param_val val, void *dat) |
{ |
strcpy(config.kbd.rxfile, val.str_val); |
struct kbd_state *kbd = dat; |
if(!(kbd->rxfile = strdup(val.str_val))) { |
fprintf(stderr, "Peripheral KBD: Run out of memory\n"); |
exit(-1); |
} |
} |
|
void *kbd_sec_start(void) |
{ |
struct kbd_state *new = malloc(sizeof(struct kbd_state)); |
|
if(!new) { |
fprintf(stderr, "Peripheral KBD: Run out of memory\n"); |
exit(-1); |
} |
|
new->buf_count = 0; |
new->buf_head = 0; |
new->buf_tail = 0; |
new->rxfs = NULL; |
|
return new; |
} |
|
void kbd_sec_end(void *dat) |
{ |
struct kbd_state *kbd = dat; |
|
register_memoryarea(kbd->baseaddr, KBD_SPACE, 1, 0, kbd_read8, kbd_write8, dat); |
reg_sim_reset(kbd_reset, dat); |
reg_sim_stat(kbd_info, dat); |
} |
|
void reg_kbd_sec(void) |
{ |
struct config_section *sec = reg_config_sec("kbd", NULL, NULL); |
struct config_section *sec = reg_config_sec("kbd", kbd_sec_start, kbd_sec_end); |
|
reg_config_param(sec, "enabled", paramt_int, kbd_enabled); |
reg_config_param(sec, "baseaddr", paramt_int, kbd_baseaddr); |
reg_config_param(sec, "irq", paramt_int, kbd_irq); |
reg_config_param(sec, "rxfile", paramt_str, kbd_rxfile); |
/trunk/or1ksim/peripheral/ps2kbd.h
69,6 → 69,4
/* Keyboard is checked every KBD_SLOWDOWN cycle */ |
#define KBD_BAUD_RATE 1200 |
|
void kbd_reset(); |
void kbd_info(); |
#endif /* !_PS2KBD_H_ */ |
/trunk/or1ksim/toplevel.c
47,7 → 47,6
#include "sim-config.h" |
#include "spr_defs.h" |
#include "sprs.h" |
#include "ps2kbd.h" |
#include "vapi.h" |
#include "gdbcomm.h" |
#include "debug_unit.h" |
72,7 → 71,7
#include "cuc.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.111 $"; |
const char rcsrev[] = "$Revision: 1.112 $"; |
|
inline void debug(int level, const char *format, ...) |
{ |
170,7 → 169,6
|
eth_reset(); |
gpio_reset(); |
kbd_reset (); |
tick_reset(); |
pm_reset(); |
pic_reset(); |