#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; }