From a904272206ee9a4c66baffd2bbf323dac1c07812 Mon Sep 17 00:00:00 2001 From: nisimura Date: Mon, 7 Apr 2008 12:33:57 +0000 Subject: [PATCH] - add siisata.c which should cover SiI 3112, 3512 and 3114. - include IDE/SATA definitions in globals.h. --- sys/arch/sandpoint/stand/netboot/globals.h | 51 +++++++++++- sys/arch/sandpoint/stand/netboot/main.c | 16 +++- sys/arch/sandpoint/stand/netboot/pciide.c | 2 +- sys/arch/sandpoint/stand/netboot/siisata.c | 97 ++++++++++++++++++++++ 4 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 sys/arch/sandpoint/stand/netboot/siisata.c diff --git a/sys/arch/sandpoint/stand/netboot/globals.h b/sys/arch/sandpoint/stand/netboot/globals.h index 833670f6e2df..8ee35e3df036 100644 --- a/sys/arch/sandpoint/stand/netboot/globals.h +++ b/sys/arch/sandpoint/stand/netboot/globals.h @@ -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 diff --git a/sys/arch/sandpoint/stand/netboot/main.c b/sys/arch/sandpoint/stand/netboot/main.c index ef20fef06e41..e8860d44633e 100644 --- a/sys/arch/sandpoint/stand/netboot/main.c +++ b/sys/arch/sandpoint/stand/netboot/main.c @@ -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; diff --git a/sys/arch/sandpoint/stand/netboot/pciide.c b/sys/arch/sandpoint/stand/netboot/pciide.c index 43862bf72290..920efc991218 100644 --- a/sys/arch/sandpoint/stand/netboot/pciide.c +++ b/sys/arch/sandpoint/stand/netboot/pciide.c @@ -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 #include diff --git a/sys/arch/sandpoint/stand/netboot/siisata.c b/sys/arch/sandpoint/stand/netboot/siisata.c new file mode 100644 index 000000000000..04afcceffcbe --- /dev/null +++ b/sys/arch/sandpoint/stand/netboot/siisata.c @@ -0,0 +1,97 @@ +/* $NetBSD: siisata.c,v 1.1 2008/04/07 12:33:57 nisimura Exp $ */ + +#include +#include + +#include +#include + +#include +#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]; +}