Initial version
Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@706 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
ENDIAN_FLAGS=-EB
|
||||||
|
CFLAGS=$(ENDIAN_FLAGS) -msoft-float -O2 -march=r3000 -I. -Wl,-M
|
||||||
|
|
||||||
|
AS=mipsel-elf-as
|
||||||
|
AR=mipsel-elf-ar
|
||||||
|
CC=mipsel-elf-gcc
|
||||||
|
LD=mipsel-elf-ld
|
||||||
|
OBJDUMP=mipsel-elf-objdump
|
||||||
|
OBJCOPY=mipsel-elf-objcopy
|
||||||
|
FLASHGEN=flashgen
|
||||||
|
|
||||||
|
SRCS=libsys.c xcpt.c syscalls.c irq.c dbg.c mips_dis.c mips_gfx.c mips_ps2.c
|
||||||
|
OBJS=libsys.o xcpt.o syscalls.o irq.o dbg.o mips_dis.o mips_gfx.o mips_ps2.o
|
||||||
|
|
||||||
|
all: libsys.a
|
||||||
|
|
||||||
|
%.o : %.c %.h
|
||||||
|
$(CC) $(CFLAGS) -G 0 -c $(SRCS)
|
||||||
|
|
||||||
|
libsys.a: $(OBJS)
|
||||||
|
$(AR) -r libsys.a $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) -G 0 -c startup.S
|
||||||
|
$(CC) $(CFLAGS) -G 0 -c kernel.S
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.a *.o *.map *.dis *.elf > /dev/null
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
#include "mips_ps2.h"
|
||||||
|
|
||||||
|
ps2_if_t ps2_if[2] =
|
||||||
|
{
|
||||||
|
{ps2_type_unknown, (UINT32*)SYS_PS2_0_STAT, (UINT32*)SYS_PS2_0_DATA},
|
||||||
|
{ps2_type_unknown, (UINT32*)SYS_PS2_1_STAT, (UINT32*)SYS_PS2_1_DATA}
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT32 PS2_get_num_if(void)
|
||||||
|
{
|
||||||
|
return (sizeof(ps2_if)/sizeof(ps2_if_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
ps2_if_t *PS2_get_if(UINT32 port)
|
||||||
|
{
|
||||||
|
if (port < PS2_get_num_if())
|
||||||
|
return &ps2_if[port];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS2_byte_write(UINT32 port, UINT8 byte)
|
||||||
|
{
|
||||||
|
ps2_if_t *pIF;
|
||||||
|
|
||||||
|
pIF = &ps2_if[port];
|
||||||
|
|
||||||
|
while(!(*pIF->pCTRL & SYS_PS2_BIT_TX_EMPTY));
|
||||||
|
|
||||||
|
*pIF->pDATA = (UINT32)byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 PS2_byte_read(UINT32 port, UINT32 timeout_ms)
|
||||||
|
{
|
||||||
|
ps2_if_t *pIF;
|
||||||
|
|
||||||
|
pIF = &ps2_if[port];
|
||||||
|
|
||||||
|
while(!(*pIF->pCTRL & SYS_PS2_BIT_RX_AVAIL))
|
||||||
|
{
|
||||||
|
timeout_ms--;
|
||||||
|
if (!timeout_ms)
|
||||||
|
return PS2_ERR_TIMEOUT;
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return (UINT32)*pIF->pDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 PS2_cmd(UINT32 port, UINT8 cmd, UINT32 ack_timeout_ms)
|
||||||
|
{
|
||||||
|
UINT32 result;
|
||||||
|
|
||||||
|
PS2_byte_write(port, cmd);
|
||||||
|
result = PS2_byte_read(port, ack_timeout_ms);
|
||||||
|
if (0xFA != result)
|
||||||
|
{
|
||||||
|
printf ("PS2_cmd(%d): no ACK received. Result = %08X\n", port, result);
|
||||||
|
return PS2_ERR_PS2_PREFIX | result;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS2_flush(UINT32 port)
|
||||||
|
{
|
||||||
|
while (!IS_ERROR(PS2_byte_read(port, 10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 PS2_init(UINT32 port)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ps2_if_t *pIF;
|
||||||
|
UINT8 id[2];
|
||||||
|
|
||||||
|
pIF = &ps2_if[port];
|
||||||
|
pIF->type = ps2_type_unknown;
|
||||||
|
|
||||||
|
UINT32 result;
|
||||||
|
|
||||||
|
// Disable RX-interrupt
|
||||||
|
*pIF->pCTRL &= ~SYS_PS2_BIT_RX_INTEN;
|
||||||
|
|
||||||
|
printf ("PS2_init(%d) - Initialize... ", port);
|
||||||
|
|
||||||
|
// Flush buffer
|
||||||
|
PS2_flush(port);
|
||||||
|
|
||||||
|
// send RESET
|
||||||
|
result = PS2_cmd(port, 0xFF, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("Reset error %08X\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read BAT
|
||||||
|
result = PS2_byte_read(port, 1000);
|
||||||
|
if (0xAA != result)
|
||||||
|
{
|
||||||
|
printf ("BAT error %08X\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Success\n");
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
// Read ID
|
||||||
|
result = PS2_byte_read(port, 10);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
// No ID => keyboard
|
||||||
|
printf ("PS2_init(%d) - Keyboard detected\n", port);
|
||||||
|
|
||||||
|
// send Get Device-ID
|
||||||
|
result = PS2_cmd(port, 0xF2, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("Get Device-ID error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
id[0] = PS2_byte_read(port, 1000);
|
||||||
|
id[1] = PS2_byte_read(port, 1000);
|
||||||
|
printf ("PS2_init(%d) - Device-ID: %02X%02X\n", port, id[0], id[1]);
|
||||||
|
|
||||||
|
// Get Scan code set (phase 1)
|
||||||
|
result = PS2_cmd(port, 0xF0, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. Get Scan code error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get Scan code set (phase 2)
|
||||||
|
result = PS2_cmd(port, 0x00, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. Get Scan code error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = PS2_byte_read(port, 1000);
|
||||||
|
printf ("PS2_init(%d) - Current scan code set = %d\n", port, result);
|
||||||
|
|
||||||
|
// if Scan code SET != 2
|
||||||
|
if (result != 2)
|
||||||
|
{
|
||||||
|
printf ("PS2_init(%d) - Set scan code set = 2\n", port);
|
||||||
|
// Set Scan code set (phase 1)
|
||||||
|
result = PS2_cmd(port, 0xF0, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. Set Scan code error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Set Scan code set (phase 2)
|
||||||
|
result = PS2_cmd(port, 0x02, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. Set Scan code error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test LEDs
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
{
|
||||||
|
result = PS2_cmd(port, 0xED, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = PS2_cmd(port, 0x02, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(100);
|
||||||
|
result = PS2_cmd(port, 0xED, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = PS2_cmd(port, 0x04, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(100);
|
||||||
|
result = PS2_cmd(port, 0xED, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = PS2_cmd(port, 0x01, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(100);
|
||||||
|
}
|
||||||
|
result = PS2_cmd(port, 0xED, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("1. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = PS2_cmd(port, 0x00, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("2. LED error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIF->type = ps2_type_keyb;
|
||||||
|
result = pIF->type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got a byte => maybe mouse
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
// We got zero => yes, it's a mouse
|
||||||
|
printf ("PS2_init(%d) - Mouse device detected\n", port);
|
||||||
|
|
||||||
|
// send Get Device-ID
|
||||||
|
result = PS2_cmd(port, 0xF2, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("Get Device-ID error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
id[0] = PS2_byte_read(port, 1000);
|
||||||
|
printf ("PS2_init(%d) - Device-ID: %02X\n", port, id[0]);
|
||||||
|
printf ("PS2_init(%d) - Enable stream mode...", port);
|
||||||
|
result = PS2_cmd(port, 0xF4, 1000);
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
{
|
||||||
|
printf ("error %08X\n", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf ("Success\n");
|
||||||
|
pIF->type = ps2_type_mouse;
|
||||||
|
result = pIF->type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush buffer
|
||||||
|
PS2_flush(port);
|
||||||
|
|
||||||
|
if (IS_ERROR(result))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// Enable RX-interrupt
|
||||||
|
*pIF->pCTRL |= SYS_PS2_BIT_RX_INTEN;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef PS2_H
|
||||||
|
#define PS2_H
|
||||||
|
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Types
|
||||||
|
// --------------------------------------------------
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ps2_type_unknown = 0,
|
||||||
|
ps2_type_keyb,
|
||||||
|
ps2_type_mouse
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _sps2_if_t
|
||||||
|
{
|
||||||
|
UINT32 type;
|
||||||
|
volatile UINT32 *pCTRL;
|
||||||
|
volatile UINT32 *pDATA;
|
||||||
|
} ps2_if_t;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// --------------------------------------------------
|
||||||
|
#define PS2_MODULE_PREFIX 0x1000000
|
||||||
|
#define PS2_SUCCESS LSYS_SUCCESS
|
||||||
|
#define PS2_ERROR (LSYS_ERR_BASE | PS2_MODULE_PREFIX)
|
||||||
|
#define PS2_ERR_TIMEOUT (PS2_ERROR | 0x0000001)
|
||||||
|
#define PS2_ERR_PS2_PREFIX (PS2_ERROR | 0x0010000)
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Functions
|
||||||
|
// --------------------------------------------------
|
||||||
|
UINT32 PS2_get_num_if(void);
|
||||||
|
ps2_if_t *PS2_get_if(UINT32 port);
|
||||||
|
UINT32 PS2_init(UINT32 port);
|
||||||
|
void PS2_byte_write(UINT32 port, UINT8 byte);
|
||||||
|
UINT32 PS2_byte_read(UINT32 port, UINT32 timeout_ms);
|
||||||
|
UINT32 PS2_cmd(UINT32 port, UINT8 cmd, UINT32 ack_timeout_ms);
|
||||||
|
void PS2_flush(UINT32 port);
|
||||||
|
|
||||||
|
#endif // PS2_H
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#include "libsys.h"
|
||||||
|
#include "xcpt.h"
|
||||||
|
|
||||||
|
/* 10 digits + 1 sign + 1 trailing nul */
|
||||||
|
static char itoa_buf[12];
|
||||||
|
|
||||||
|
char *itoa(int i)
|
||||||
|
{
|
||||||
|
char *pos = itoa_buf + sizeof(itoa_buf) - 1;
|
||||||
|
unsigned int u;
|
||||||
|
int negative = 0;
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
negative = 1;
|
||||||
|
u = ((unsigned int)(-(1+i))) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pos = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*--pos = '0' + (u % 10);
|
||||||
|
u /= 10;
|
||||||
|
} while (u);
|
||||||
|
|
||||||
|
if (negative)
|
||||||
|
{
|
||||||
|
*--pos = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int syscalls_handler(struct xcptcontext * xcp)
|
||||||
|
{
|
||||||
|
int syscall_code;
|
||||||
|
char *pStr;
|
||||||
|
|
||||||
|
syscall_code = xcp->regs[2];
|
||||||
|
|
||||||
|
switch(syscall_code)
|
||||||
|
{
|
||||||
|
case 1: // print integer
|
||||||
|
sputs(itoa(xcp->regs[4]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // print string
|
||||||
|
pStr = (char*)xcp->regs[4];
|
||||||
|
sputs(pStr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sputs("Unknown syscall (");print_word(syscall_code);sputs(") at ");print_word(xcp->epc);sputs("\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcp->epc += 4; // set return address to instruction after syscall
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscalls_init(void)
|
||||||
|
{
|
||||||
|
xcpt_register(Syscall, syscalls_handler);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user