207 lines
3.3 KiB
C
207 lines
3.3 KiB
C
#include "memio.h"
|
|
#include "articiaS.h"
|
|
|
|
#ifndef FALSE
|
|
#define FALSE 0
|
|
#endif
|
|
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#endif
|
|
|
|
|
|
void sm_write_mode(void)
|
|
{
|
|
out_byte(0xA539, 0x00);
|
|
out_byte(0xA53A, 0x03);
|
|
}
|
|
|
|
void sm_read_mode(void)
|
|
{
|
|
out_byte(0xA53A, 0x02);
|
|
out_byte(0xA539, 0x02);
|
|
}
|
|
|
|
void sm_write_byte(uint8 writeme)
|
|
{
|
|
int i;
|
|
int level;
|
|
|
|
out_byte(0xA539, 0x00);
|
|
|
|
level = 0;
|
|
|
|
for (i=0; i<8; i++)
|
|
{
|
|
if ((writeme & 0x80) == (level<<7))
|
|
{
|
|
/* Bit did not change, rewrite strobe */
|
|
out_byte(0xA539, level | 0x02);
|
|
out_byte(0xA539, level);
|
|
}
|
|
else
|
|
{
|
|
/* Bit changed, set bit, then strobe */
|
|
level = (writeme & 0x80) >> 7;
|
|
out_byte(0xA539, level);
|
|
out_byte(0xA539, level | 0x02);
|
|
out_byte(0xA539, level);
|
|
}
|
|
writeme <<= 1;
|
|
}
|
|
out_byte(0xA539, 0x00);
|
|
}
|
|
|
|
uint8 sm_read_byte(void)
|
|
{
|
|
uint8 retme, r;
|
|
int i;
|
|
|
|
retme = 0;
|
|
for (i=0; i<8; i++)
|
|
{
|
|
retme <<= 1;
|
|
out_byte(0xA539, 0x00);
|
|
out_byte(0xA539, 0x02);
|
|
r = in_byte(0xA538) & 0x01;
|
|
retme |= r;
|
|
}
|
|
|
|
return retme;
|
|
}
|
|
|
|
int sm_get_ack(void)
|
|
{
|
|
uint8 r;
|
|
r = in_byte(0xA538);
|
|
if ((r&0x01) == 0) return TRUE;
|
|
else return FALSE;
|
|
}
|
|
|
|
void sm_write_ack(void)
|
|
{
|
|
out_byte(0xA539, 0x00);
|
|
out_byte(0xA539, 0x02);
|
|
out_byte(0xA539, 0x00);
|
|
}
|
|
|
|
void sm_write_nack(void)
|
|
{
|
|
out_byte(0xA539, 0x01);
|
|
out_byte(0xA539, 0x03);
|
|
out_byte(0xA539, 0x01);
|
|
}
|
|
|
|
void sm_send_start(void)
|
|
{
|
|
out_byte(0xA539, 0x03);
|
|
out_byte(0xA539, 0x02);
|
|
}
|
|
|
|
void sm_send_stop(void)
|
|
{
|
|
out_byte(0xA539, 0x02);
|
|
out_byte(0xA539, 0x03);
|
|
}
|
|
|
|
int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
|
|
{
|
|
/* S Addr Wr */
|
|
sm_write_mode();
|
|
sm_send_start();
|
|
sm_write_byte((addr<<1));
|
|
|
|
/* [A] */
|
|
sm_read_mode();
|
|
if (sm_get_ack() == FALSE) return FALSE;
|
|
|
|
/* Comm */
|
|
sm_write_mode();
|
|
sm_write_byte(reg);
|
|
|
|
/* [A] */
|
|
sm_read_mode();
|
|
if (sm_get_ack() == FALSE) return FALSE;
|
|
|
|
/* S Addr Rd */
|
|
sm_write_mode();
|
|
sm_send_start();
|
|
sm_write_byte((addr<<1)|1);
|
|
|
|
/* [A] */
|
|
sm_read_mode();
|
|
if (sm_get_ack() == FALSE) return FALSE;
|
|
|
|
/* [Data] */
|
|
*storage = sm_read_byte();
|
|
|
|
/* NA */
|
|
sm_write_mode();
|
|
sm_write_nack();
|
|
sm_send_stop();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void sm_init(void)
|
|
{
|
|
/* Switch to PMC mode */
|
|
pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
|
|
|
|
/* Set GPIO Base */
|
|
pci_write_cfg_long(0, 0, 0x40, 0xa500);
|
|
|
|
/* Enable GPIO */
|
|
pci_write_cfg_byte(0, 0, 0x44, 0x11);
|
|
|
|
/* Set both GPIO 0 and 1 as output */
|
|
out_byte(0xA53A, 0x03);
|
|
}
|
|
|
|
|
|
void sm_term(void)
|
|
{
|
|
/* Switch to normal mode */
|
|
pci_write_cfg_byte(0, 0, REG_GROUP, 0);
|
|
}
|
|
|
|
|
|
int sm_get_data(uint8 *DataArray, int dimm_socket)
|
|
{
|
|
int j;
|
|
|
|
#if 0
|
|
/* Switch to PMC mode */
|
|
pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
|
|
|
|
/* Set GPIO Base */
|
|
pci_write_cfg_long(0, 0, 0x40, 0xa500);
|
|
|
|
/* Enable GPIO */
|
|
pci_write_cfg_byte(0, 0, 0x44, 0x11);
|
|
|
|
/* Set both GPIO 0 and 1 as output */
|
|
out_byte(0xA53A, 0x03);
|
|
#endif
|
|
|
|
sm_init();
|
|
/* Start reading the rom */
|
|
|
|
j = 0;
|
|
|
|
do
|
|
{
|
|
if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
|
|
{
|
|
sm_term();
|
|
return FALSE;
|
|
}
|
|
|
|
DataArray++;
|
|
j++;
|
|
} while (j < 128);
|
|
|
|
sm_term();
|
|
return TRUE;
|
|
}
|