- add siisata.c which should cover SiI 3112, 3512 and 3114.

- include IDE/SATA definitions in globals.h.
This commit is contained in:
nisimura 2008-04-07 12:33:57 +00:00
parent e3372d31c3
commit a904272206
4 changed files with 162 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: globals.h,v 1.3 2007/10/30 00:30:13 nisimura Exp $ */
/* $NetBSD: globals.h,v 1.4 2008/04/07 12:33:57 nisimura Exp $ */
/* clock feed */
#define TICKS_PER_SEC (100000000 / 4) /* 100MHz front bus */
@ -34,6 +34,7 @@ void pcicfgwrite(unsigned, int, unsigned);
#define PCI_VENDOR(id) ((id) & 0xffff)
#define PCI_PRODUCT(id) (((id) >> 16) & 0xffff)
#define PCI_VENDOR_INVALID 0xffff
#define PCI_DEVICE(v,p) ((v) | ((p) << 16))
#define PCI_CLASS_REG 0x08
#define PCI_CLASS_PPB 0x0604
#define PCI_CLASS_ETH 0x0200
@ -49,3 +50,51 @@ void _inv(uint32_t, uint32_t);
/* NIF */
int netif_init(unsigned);
#ifdef LABELSECTOR
/* IDE/SATA and disk */
struct atac_channel {
volatile uint8_t *c_cmdbase;
volatile uint8_t *c_ctlbase;
volatile uint8_t *c_cmdreg[8 + 2];
volatile uint16_t *c_data;
int compatchan;
#define WDC_READ_CMD(chp, reg) *(chp)->c_cmdreg[(reg)]
#define WDC_WRITE_CMD(chp, reg, val) *(chp)->c_cmdreg[(reg)] = (val)
#define WDC_READ_CTL(chp, reg) (chp)->c_ctlbase[(reg)]
#define WDC_WRITE_CTL(chp, reg, val) (chp)->c_ctlbase[(reg)] = (val)
#define WDC_READ_DATA(chp) *(chp)->c_data
};
struct atac_command {
uint8_t drive; /* drive id */
uint8_t r_command; /* Parameters to upload to registers */
uint8_t r_head;
uint16_t r_cyl;
uint8_t r_sector;
uint8_t r_count;
uint8_t r_precomp;
uint16_t bcount;
void *data;
uint64_t r_blkno;
};
struct atac_softc {
unsigned tag;
unsigned chvalid;
struct atac_channel channel[4];
};
struct wd_softc {
#define WDF_LBA 0x0001
#define WDF_LBA48 0x0002
int sc_flags;
int sc_unit, sc_part;
uint64_t sc_capacity;
struct atac_channel *sc_channel;
struct atac_command sc_command;
struct ataparams sc_params;
struct disklabel sc_label;
uint8_t sc_buf[DEV_BSIZE];
};
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.10 2007/12/12 04:17:49 nisimura Exp $ */
/* $NetBSD: main.c,v 1.11 2008/04/07 12:33:57 nisimura Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@ -90,7 +90,7 @@ main()
struct btinfo_clock bi_clk;
struct btinfo_bootpath bi_path;
struct btinfo_rootdevice bi_rdev;
unsigned lnif[1][2];
unsigned lnif[1][2], lata[1][2];
/* determine SDRAM size */
memsize = mpc107memsize();
@ -105,6 +105,18 @@ main()
printf("Encore PP1"); break;
}
printf(", %dMB SDRAM, ", memsize >> 20);
n = pcilookup(PCI_CLASS_IDE, lata, sizeof(lata)/sizeof(lata[0]));
if (n == 0)
printf("no IDE found, ");
else {
tag = lata[0][1];
pcidecomposetag(tag, &b, &d, &f);
printf("%04x.%04x IDE %02d:%02d:%02d\n",
PCI_VENDOR(lata[0][0]), PCI_PRODUCT(lata[0][0]),
b, d, f);
}
n = pcilookup(PCI_CLASS_ETH, lnif, sizeof(lnif)/sizeof(lnif[0]));
if (n == 0) {
tag = ~0;

View File

@ -1,4 +1,4 @@
/* $Id: pciide.c,v 1.1 2008/04/07 11:13:14 nisimura Exp $ */
/* $NetBSD: pciide.c,v 1.2 2008/04/07 12:33:57 nisimura Exp $ */
#include <sys/param.h>
#include <sys/disklabel.h>

View File

@ -0,0 +1,97 @@
/* $NetBSD: siisata.c,v 1.1 2008/04/07 12:33:57 nisimura Exp $ */
#include <sys/param.h>
#include <sys/disklabel.h>
#include <dev/ic/wdcreg.h>
#include <dev/ata/atareg.h>
#include <lib/libsa/stand.h>
#include "globals.h"
void *siisata_init(unsigned, unsigned);
#define PCIIDE_REG_CMD_BASE(chan) (0x10 + (8 * (chan)))
#define PCIIDE_REG_CTL_BASE(chan) (0x14 + (8 * (chan)))
static void map3112chan(unsigned, int, struct atac_channel *);
static void map3114chan(unsigned, int, struct atac_channel *);
void *
siisata_init(unsigned tag, unsigned data)
{
unsigned val, chvalid;
struct atac_softc *l;
struct atac_channel *cp;
val = pcicfgread(tag, PCI_ID_REG);
switch (val) {
case PCI_DEVICE(0x1095, 0x3112): /* SiI 3112 SATALink */
case PCI_DEVICE(0x1095, 0x3512): /* 3512 SATALink */
chvalid = 0x3;
break;
case PCI_DEVICE(0x1095, 0x3114): /* SiI 3114 SATALink */
chvalid = 0xf;
default:
return NULL;
}
l = alloc(sizeof(struct atac_softc));
memset(l, 0, sizeof(struct atac_softc));
if ((PCI_PRODUCT(val) & 0xf) == 0x2) {
map3112chan(tag, 0, &l->channel[0]);
map3112chan(tag, 1, &l->channel[1]);
}
else {
map3114chan(tag, 0, &l->channel[0]);
map3114chan(tag, 1, &l->channel[1]);
map3114chan(tag, 2, &l->channel[2]);
map3114chan(tag, 3, &l->channel[3]);
}
cp = &l->channel[1];
l->chvalid = chvalid & data;
l->tag = tag;
return l;
}
static void
map3112chan(unsigned tag, int ch, struct atac_channel *cp)
{
int i;
cp->c_cmdbase = (void *)pcicfgread(tag, PCIIDE_REG_CMD_BASE(ch));
cp->c_ctlbase = (void *)pcicfgread(tag, PCIIDE_REG_CTL_BASE(ch));
cp->c_data = (u_int16_t *)(cp->c_cmdbase + wd_data);
for (i = 0; i < 8; i++)
cp->c_cmdreg[i] = cp->c_cmdbase + i;
cp->c_cmdreg[wd_status] = cp->c_cmdreg[wd_command];
cp->c_cmdreg[wd_features] = cp->c_cmdreg[wd_precomp];
}
static const struct {
int IDE_TF0, IDE_TF8;
} regmap[4] = {
{ 0x080, 0x091 },
{ 0x0c0, 0x0d1 },
{ 0x280, 0x291 },
{ 0x2c0, 0x2d1 },
};
static void
map3114chan(unsigned tag, int ch, struct atac_channel *cp)
{
int i;
uint8_t *ba5;
ba5 = (uint8_t *)pcicfgread(tag, 0x24); /* PCI_BAR5 */
cp->c_cmdbase = ba5 + regmap[ch].IDE_TF0;
cp->c_ctlbase = ba5 + regmap[ch].IDE_TF8;
cp->c_data = (u_int16_t *)(cp->c_cmdbase + wd_data);
for (i = 0; i < 8; i++)
cp->c_cmdreg[i] = cp->c_cmdbase + i;
cp->c_cmdreg[wd_status] = cp->c_cmdreg[wd_command];
cp->c_cmdreg[wd_features] = cp->c_cmdreg[wd_precomp];
}