mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
ide: allow to have multiple instances
git-svn-id: svn://coreboot.org/openbios/openbios-devel@411 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -249,7 +249,6 @@ struct first_info {
|
|||||||
unsigned blknos[64];
|
unsigned blknos[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
quik_startup( void )
|
quik_startup( void )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
/* DECLARE data structures for the nodes. */
|
/* DECLARE data structures for the nodes. */
|
||||||
DECLARE_UNNAMED_NODE( ob_ide, INSTALL_OPEN, 2*sizeof(int) );
|
DECLARE_UNNAMED_NODE( ob_ide, INSTALL_OPEN, sizeof(struct ide_drive*) );
|
||||||
DECLARE_UNNAMED_NODE( ob_ide_ctrl, INSTALL_OPEN, sizeof(int));
|
DECLARE_UNNAMED_NODE( ob_ide_ctrl, INSTALL_OPEN, sizeof(int));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -58,10 +58,26 @@ DECLARE_UNNAMED_NODE( ob_ide_ctrl, INSTALL_OPEN, sizeof(int));
|
|||||||
|
|
||||||
static int current_channel = FIRST_UNIT;
|
static int current_channel = FIRST_UNIT;
|
||||||
|
|
||||||
static struct ide_channel ob_ide_channels[IDE_MAX_CHANNELS];
|
static struct ide_channel *channels = NULL;
|
||||||
|
|
||||||
static int io_ports[IDE_MAX_CHANNELS];
|
static inline void ide_add_channel(struct ide_channel *chan)
|
||||||
static int ctl_ports[IDE_MAX_CHANNELS];
|
{
|
||||||
|
chan->next = channels;
|
||||||
|
channels = chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ide_channel *ide_seek_channel(const char *name)
|
||||||
|
{
|
||||||
|
struct ide_channel *current;
|
||||||
|
|
||||||
|
current = channels;
|
||||||
|
while (current) {
|
||||||
|
if (!strcmp(current->name, name))
|
||||||
|
return current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* don't be pedantic
|
* don't be pedantic
|
||||||
@@ -1150,7 +1166,7 @@ ob_ide_probe(struct ide_channel *chan)
|
|||||||
static void
|
static void
|
||||||
ob_ide_max_transfer(int *idx)
|
ob_ide_max_transfer(int *idx)
|
||||||
{
|
{
|
||||||
struct ide_drive *drive=&ob_ide_channels[idx[1]].drives[idx[0]];
|
struct ide_drive *drive = *(struct ide_drive **)idx;
|
||||||
#ifdef CONFIG_DEBUG_IDE
|
#ifdef CONFIG_DEBUG_IDE
|
||||||
printk("max_transfer %x\n", drive->max_sectors * drive->bs);
|
printk("max_transfer %x\n", drive->max_sectors * drive->bs);
|
||||||
#endif
|
#endif
|
||||||
@@ -1164,7 +1180,7 @@ ob_ide_read_blocks(int *idx)
|
|||||||
cell n = POP(), cnt=n;
|
cell n = POP(), cnt=n;
|
||||||
ucell blk = POP();
|
ucell blk = POP();
|
||||||
unsigned char *dest = (unsigned char *)POP();
|
unsigned char *dest = (unsigned char *)POP();
|
||||||
struct ide_drive *drive=&ob_ide_channels[idx[1]].drives[idx[0]];
|
struct ide_drive *drive = *(struct ide_drive **)idx;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_IDE
|
#ifdef CONFIG_DEBUG_IDE
|
||||||
printk("ob_ide_read_blocks %lx block=%ld n=%ld\n", (unsigned long)dest,
|
printk("ob_ide_read_blocks %lx block=%ld n=%ld\n", (unsigned long)dest,
|
||||||
@@ -1192,7 +1208,7 @@ ob_ide_read_blocks(int *idx)
|
|||||||
static void
|
static void
|
||||||
ob_ide_block_size(int *idx)
|
ob_ide_block_size(int *idx)
|
||||||
{
|
{
|
||||||
struct ide_drive *drive=&ob_ide_channels[idx[1]].drives[idx[0]];
|
struct ide_drive *drive = *(struct ide_drive **)idx;
|
||||||
#ifdef CONFIG_DEBUG_IDE
|
#ifdef CONFIG_DEBUG_IDE
|
||||||
printk("ob_ide_block_size: block size %x\n", drive->bs);
|
printk("ob_ide_block_size: block size %x\n", drive->bs);
|
||||||
#endif
|
#endif
|
||||||
@@ -1225,21 +1241,25 @@ ob_ide_open(int *idx)
|
|||||||
int ret=1, len;
|
int ret=1, len;
|
||||||
phandle_t ph;
|
phandle_t ph;
|
||||||
struct ide_drive *drive;
|
struct ide_drive *drive;
|
||||||
|
struct ide_channel *chan;
|
||||||
char *idename;
|
char *idename;
|
||||||
|
int unit;
|
||||||
|
|
||||||
fword("my-unit");
|
fword("my-unit");
|
||||||
idx[0]=POP();
|
unit = POP();
|
||||||
|
|
||||||
fword("my-parent");
|
fword("my-parent");
|
||||||
fword("ihandle>phandle");
|
fword("ihandle>phandle");
|
||||||
ph=(phandle_t)POP();
|
ph=(phandle_t)POP();
|
||||||
idename=get_property(ph, "name", &len);
|
idename=get_property(ph, "name", &len);
|
||||||
idx[1]=(idename[strlen(idename) - 1] - '0' - FIRST_UNIT) % 2;
|
|
||||||
|
chan = ide_seek_channel(idename);
|
||||||
|
drive = &chan->drives[unit];
|
||||||
|
*(struct ide_drive **)idx = drive;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_IDE
|
#ifdef CONFIG_DEBUG_IDE
|
||||||
printk("opening channel %d unit %d\n", idx[1], idx[0]);
|
printk("opening channel %d unit %d\n", idx[1], idx[0]);
|
||||||
#endif
|
#endif
|
||||||
drive=&ob_ide_channels[idx[1]].drives[idx[0]];
|
|
||||||
dump_drive(drive);
|
dump_drive(drive);
|
||||||
|
|
||||||
if (drive->type != ide_type_ata)
|
if (drive->type != ide_type_ata)
|
||||||
@@ -1274,16 +1294,17 @@ NODE_METHODS(ob_ide) = {
|
|||||||
static void
|
static void
|
||||||
ob_ide_ctrl_initialize(int *idx)
|
ob_ide_ctrl_initialize(int *idx)
|
||||||
{
|
{
|
||||||
int len, devnum, props[6];
|
int len, props[6];
|
||||||
phandle_t ph=get_cur_dev();
|
phandle_t ph=get_cur_dev();
|
||||||
char *idename;
|
char *idename;
|
||||||
|
struct ide_channel *chan;
|
||||||
|
|
||||||
/* set device type */
|
/* set device type */
|
||||||
push_str(DEV_TYPE);
|
push_str(DEV_TYPE);
|
||||||
fword("device-type");
|
fword("device-type");
|
||||||
|
|
||||||
idename=get_property(ph, "name", &len);
|
idename=get_property(ph, "name", &len);
|
||||||
devnum=idename[strlen(idename) - 1] - '0' - FIRST_UNIT;
|
chan = ide_seek_channel(idename);
|
||||||
|
|
||||||
/* Create interrupt properties. */
|
/* Create interrupt properties. */
|
||||||
props[0]=14; props[1]=0;
|
props[0]=14; props[1]=0;
|
||||||
@@ -1292,9 +1313,9 @@ ob_ide_ctrl_initialize(int *idx)
|
|||||||
set_int_property(ph, "#address-cells", 1);
|
set_int_property(ph, "#address-cells", 1);
|
||||||
set_int_property(ph, "#size-cells", 0);
|
set_int_property(ph, "#size-cells", 0);
|
||||||
|
|
||||||
props[0] = __cpu_to_be32(io_ports[devnum]);
|
props[0] = __cpu_to_be32(chan->io_regs[0]);
|
||||||
props[1] = __cpu_to_be32(1); props[2] = __cpu_to_be32(8);
|
props[1] = __cpu_to_be32(1); props[2] = __cpu_to_be32(8);
|
||||||
props[3] = __cpu_to_be32(ctl_ports[devnum]);
|
props[3] = __cpu_to_be32(chan->io_regs[8]);
|
||||||
props[4] = __cpu_to_be32(1); props[5] = __cpu_to_be32(2);
|
props[4] = __cpu_to_be32(1); props[5] = __cpu_to_be32(2);
|
||||||
set_property(ph, "reg", (char *)&props, 6*sizeof(int));
|
set_property(ph, "reg", (char *)&props, 6*sizeof(int));
|
||||||
}
|
}
|
||||||
@@ -1354,6 +1375,9 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
|
|||||||
int i, j;
|
int i, j;
|
||||||
char nodebuff[128];
|
char nodebuff[128];
|
||||||
phandle_t dnode;
|
phandle_t dnode;
|
||||||
|
struct ide_channel *chan;
|
||||||
|
int io_ports[IDE_MAX_CHANNELS];
|
||||||
|
int ctl_ports[IDE_MAX_CHANNELS];
|
||||||
|
|
||||||
io_ports[0] = io_port0;
|
io_ports[0] = io_port0;
|
||||||
ctl_ports[0] = ctl_port0 + 2;
|
ctl_ports[0] = ctl_port0 + 2;
|
||||||
@@ -1361,7 +1385,11 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
|
|||||||
ctl_ports[1] = ctl_port1 + 2;
|
ctl_ports[1] = ctl_port1 + 2;
|
||||||
|
|
||||||
for (i = 0; i < IDE_NUM_CHANNELS; i++, current_channel++) {
|
for (i = 0; i < IDE_NUM_CHANNELS; i++, current_channel++) {
|
||||||
struct ide_channel *chan = &ob_ide_channels[i];
|
|
||||||
|
chan = malloc(sizeof(struct ide_channel));
|
||||||
|
|
||||||
|
snprintf(chan->name, sizeof(chan->name),
|
||||||
|
DEV_NAME, current_channel);
|
||||||
|
|
||||||
chan->mmio = 0;
|
chan->mmio = 0;
|
||||||
|
|
||||||
@@ -1393,6 +1421,8 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
|
|||||||
chan->drives[j].nr = i * 2 + j;
|
chan->drives[j].nr = i * 2 + j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ide_add_channel(chan);
|
||||||
|
|
||||||
ob_ide_probe(chan);
|
ob_ide_probe(chan);
|
||||||
|
|
||||||
if (!chan->present)
|
if (!chan->present)
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ struct ide_drive {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ide_channel {
|
struct ide_channel {
|
||||||
|
|
||||||
|
char name[32];
|
||||||
|
struct ide_channel *next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* either mmio or io_regs is set to indicate mmio or not
|
* either mmio or io_regs is set to indicate mmio or not
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user