1
0
Files
irix-657m-src/stand/arcs/lib/libsk/cmd/endian_cmd.c
2022-09-29 17:59:04 +03:00

211 lines
3.6 KiB
C

#if R4000 && !EVEREST && !IP30 && !IP32
#ident "$Revision: 1.8 $"
#include <sys/cpu.h>
#include <sys/param.h>
#include <sys/sbd.h>
#include <sys/types.h>
#include <libsc.h>
#include <libsk.h>
#define EEROM_REG_SIZE sizeof(u_short)
#define ENDIAN_BIG 0x0400
#define ENDIAN_LITTLE 0x8000
#define ENDIAN_MASK 0x8400
#define RESET_SCK *eerom &= ~EEROM_SCK
#define SET_SCK *eerom |= EEROM_SCK
static u_short read_eerom(int);
static int write_eerom(int, u_short);
static void eerom_cs_on(void);
static void eerom_cs_off(void);
static void eerom_cmd(u_int, u_int);
static int eerom_hold(void);
static volatile u_int *eerom = (u_int *)PHYS_TO_K1(EEROM);
/* allows user to switch the machine between little and big endians */
int
endian_cmd(int argc, char **argv)
{
int error = 0;
u_short new_endian;
u_short reg0;
if (argc == 2) {
if (argv[1][0] != '-')
error = 1;
else {
switch (argv[1][1]) {
case 'b':
new_endian = ENDIAN_BIG;
break;
case 'l':
new_endian = ENDIAN_LITTLE;
break;
default:
error = 1;
break;
}
}
} else
error = 1;
if (error) {
printf("usage: %s -(b|l)\n", argv[0]);
return 1;
}
reg0 = read_eerom(0);
reg0 &= ~ENDIAN_MASK;
reg0 |= new_endian;
return write_eerom(0, reg0);
}
/* read a 16 bits register from the R4000 EEROM */
static u_short
read_eerom(int regnum)
{
u_short data_read = 0;
int i = EEROM_REG_SIZE;
eerom_cs_on();
eerom_cmd(SER_READ, regnum);
/* clock the data out of the EEROM */
while (i--) {
RESET_SCK;
SET_SCK;
data_read <<= 1;
data_read |= (*eerom & EEROM_SI) ? 1 : 0;
}
eerom_cs_off();
return data_read;
}
/* write a 16 bits register in the R4000 EEROM */
static int
write_eerom(int regnum, u_short value)
{
int error;
int i = EEROM_REG_SIZE;
eerom_cs_on();
eerom_cmd(SER_WEN, 0);
eerom_cs_off();
eerom_cs_on();
eerom_cmd(SER_WRITE, regnum);
/* clock the data into the EEROM */
while (i--) {
if (value & 0x8000)
*eerom |= EEROM_SO;
else
*eerom &= ~EEROM_SO;
RESET_SCK;
SET_SCK;
value <<= 1;
}
*eerom &= ~EEROM_SO; /* see timing diagram, DI should */
/* be low after writing */
eerom_cs_off();
error = eerom_hold();
eerom_cs_on();
eerom_cmd(SER_WDS, 0);
eerom_cs_off();
return error;
}
/* enable access to the EEROM by setting the chip select */
static void
eerom_cs_on(void)
{
*eerom = 0x0; /* see timing diagram, DI should */
/* be low when asserting CS */
RESET_SCK;
*eerom |= EEROM_CS;
SET_SCK;
}
/* disable access to the EEROM by clearing the chip select */
static void
eerom_cs_off(void)
{
RESET_SCK;
*eerom &= ~EEROM_CS;
SET_SCK;
}
#define COMMAND_SIZE 11
/* clock in the EEROM command and the register number */
static void
eerom_cmd(u_int cmd, u_int regnum)
{
int i = COMMAND_SIZE;
cmd |= regnum << (16 - COMMAND_SIZE);
while (i--) {
if (cmd & 0x8000)
*eerom |= EEROM_SO;
else
*eerom &= ~EEROM_SO;
RESET_SCK;
SET_SCK;
cmd <<= 1;
}
*eerom &= ~EEROM_SO; /* see timing diagram, DI should */
/* be low after writing command */
}
/*
* after the write command, we must wait for the command to complete.
* write cycle time is 10 ms max (~5 ms nom); we timeout after ~20 ms
* NVDELAY_TIME * NVDELAY_LIMIT = 20 ms
*/
#define NVDELAY_TIME 100 /* 100 us delay times */
#define NVDELAY_LIMIT 200 /* 200 delay limit */
static int
eerom_hold(void)
{
int error;
int timeout = NVDELAY_LIMIT;
eerom_cs_on();
while (!(*eerom & EEROM_SI) && timeout--)
DELAY(NVDELAY_TIME);
if (!(*eerom & EEROM_SI))
error = -1;
else
error = 0;
eerom_cs_off();
return error;
}
#else
extern int _prom; /* silence compiler */
#endif /* R4000 && !EVEREST && !IP30 && !IP32 */