Really create a tree for PCI devices (Laurent Vivier)

git-svn-id: svn://coreboot.org/openbios/openbios-devel@362 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Blue Swirl
2009-01-07 15:43:10 +00:00
parent 4a9d1a7613
commit 2742ea5723
9 changed files with 163 additions and 126 deletions

View File

@@ -142,7 +142,6 @@
<external-object source="target/arch/ppc/qemu/kernel.o"/>
<object source="qemu/main.c" flags="-Iarch/ppc"/>
<object source="qemu/methods.c" flags="-Iarch/ppc"/>
<object source="qemu/tree.c" flags="-Iarch/ppc"/>
<object source="qemu/vfd.c" flags="-Iarch/ppc"/>
<object source="qemu/console.c" flags="-Iarch/ppc"/>
</library>

View File

@@ -427,18 +427,6 @@ arch_of_init( void )
const struct cpudef *cpu;
char buf[64];
devtree_init();
/* ISA BASE */
push_str("/");
fword("find-device");
PUSH(isa_io_base);
fword("encode-int");
push_str("isa-io-base");
fword("property");
/* memory info */
push_str("/memory");

View File

@@ -44,51 +44,6 @@
; SYSTEM-initializer
\ -------------------------------------------------------------------------
\ device tree fixing
\ -------------------------------------------------------------------------
\ add decode-address methods
: (make-decodable) ( phandle -- )
dup " #address-cells" rot get-package-property 0= if
decode-int nip nip
over " decode-unit" rot find-method if 2drop else
( save phandle ncells )
over active-package!
case
1 of ['] parse-hex " decode-unit" is-xt-func endof
3 of
" bus-range" active-package get-package-property 0= if
decode-int nip nip
['] encode-unit-pci " encode-unit" is-xt-func
" decode-unit" is-func-begin
['] (lit) , ,
['] decode-unit-pci-bus ,
is-func-end
then
endof
endcase
then
then
drop
;
: init-qemu-tree ( -- )
active-package
iterate-tree-begin
begin ?dup while
dup (make-decodable)
iterate-tree
repeat
active-package!
;
\ use the tty interface if available
: activate-tty-interface
" /packages/terminal-emulator" find-dev if drop

View File

@@ -33,6 +33,43 @@ finish-device
" /openprom" find-device
" OBP 3.10.24 1999/01/01 01:01" encode-string " version" property
device-end
\ we only implement DD and DD,F
: encode-unit-pci ( phys.lo phy.mid phys.hi -- str len )
nip nip ff00 and 8 >> dup 3 >>
swap 7 and
( ddddd fff )
?dup if
pocket tohexstr
" ," pocket tmpstrcat
else
0 0 pocket tmpstrcpy
then
>r
rot pocket tohexstr r> tmpstrcat drop
;
dev /
\ simple pci bus node
new-device
" pci" device-name
3 encode-int " #address-cells" property
2 encode-int " #size-cells" property
0 encode-int 0 encode-int encode+ " bus-range" property
" pci" encode-string " device_type" property
external
: open ( cr ." opening PCI" cr ) true ;
: close ;
: decode-unit 0 decode-unit-pci-bus ;
: encode-unit encode-unit-pci ;
finish-device
device-end
dev /pci
\ simple isa bus node

View File

@@ -1312,7 +1312,7 @@ int ob_ide_init(const char *path, uint32_t io_port0, uint32_t ctl_port0,
uint32_t io_port1, uint32_t ctl_port1)
{
int i, j;
char nodebuff[32];
char nodebuff[128];
phandle_t dnode, aliases;
int hd_found, cd_found;

View File

@@ -40,6 +40,34 @@ DECLARE_UNNAMED_NODE( ob_pci_node, INSTALL_OPEN, 2*sizeof(int) );
const pci_arch_t *arch;
#define IS_NOT_RELOCATABLE 0x80000000
#define IS_PREFETCHABLE 0x40000000
#define IS_ALIASED 0x20000000
enum {
CONFIGURATION_SPACE = 0,
IO_SPACE = 1,
MEMORY_SPACE_32 = 2,
MEMORY_SPACE_64 = 3,
};
static inline void pci_encode_phys_addr(cell *phys, int flags, int space_code,
pci_addr dev, uint8_t reg, uint64_t addr)
{
/* phys.hi */
phys[0] = flags | (space_code << 24) | dev | reg;
/* phys.mid */
phys[1] = addr >> 32;
/* phys.lo */
phys[2] = addr;
}
static void
ob_pci_open(int *idx)
{
@@ -58,11 +86,82 @@ ob_pci_initialize(int *idx)
{
}
/* ( str len -- phys.lo phys.mid phys.hi ) */
static void
ob_pci_decode_unit(int *idx)
{
PUSH(0);
fword("decode-unit-pci-bus");
}
/* ( phys.lo phy.mid phys.hi -- str len ) */
static void
ob_pci_encode_unit(int *idx)
{
char buf[28];
cell hi = POP();
cell mid = POP();
cell lo = POP();
int n, p, t, ss, bus, dev, fn, reg;
n = hi & IS_NOT_RELOCATABLE;
p = hi & IS_PREFETCHABLE;
t = hi & IS_ALIASED;
ss = (hi >> 24) && 0x03;
bus = (hi >> 16) & 0xFF;
dev = (hi >> 11) & 0x1F;
fn = (hi >> 8) & 0x07;
reg = hi & 0xFF;
switch(ss) {
case CONFIGURATION_SPACE:
if (fn == 0) /* DD */
snprintf(buf, sizeof(buf), "%x", dev);
else /* DD,F */
snprintf(buf, sizeof(buf), "%x,%d", dev, fn);
break;
case IO_SPACE:
/* [n]i[t]DD,F,RR,NNNNNNNN */
snprintf(buf, sizeof(buf), "%si%s%x,%x,%x,%x",
n ? "n" : "", /* relocatable */
t ? "t" : "", /* aliased */
dev, fn, reg, t ? lo & 0x03FF : lo);
break;
case MEMORY_SPACE_32:
/* [n]m[t][p]DD,F,RR,NNNNNNNN */
snprintf(buf, sizeof(buf), "%sm%s%s%x,%x,%x,%x",
n ? "n" : "", /* relocatable */
t ? "t" : "", /* aliased */
p ? "p" : "", /* prefetchable */
dev, fn, reg, lo );
break;
case MEMORY_SPACE_64:
/* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN */
snprintf(buf, sizeof(buf), "%sx%s%x,%x,%x,%llx",
n ? "n" : "", /* relocatable */
p ? "p" : "", /* prefetchable */
dev, fn, reg, ((uint64_t)mid << 32) | (uint64_t)lo );
break;
}
push_str(buf);
}
NODE_METHODS(ob_pci_node) = {
{ NULL, ob_pci_initialize },
{ "open", ob_pci_open },
{ "close", ob_pci_close },
{ "decode-unit", ob_pci_decode_unit },
{ "encode-unit", ob_pci_encode_unit },
};
int ide_config_cb2 (const pci_config_t *config)
@@ -119,16 +218,19 @@ static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
int status,id;
uint16_t vendor_id, device_id;
uint8_t rev;
uint32_t class_code;
vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
device_id = pci_config_read16(addr, PCI_DEVICE_ID);
rev = pci_config_read8(addr, PCI_REVISION_ID);
class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
/* create properties as described in 2.5 */
set_int_property(dev, "vendor-id", vendor_id);
set_int_property(dev, "device-id", device_id);
set_int_property(dev, "revision-id", rev);
set_int_property(dev, "class-code", class_code << 8);
set_int_property(dev, "interrupts",
pci_config_read8(addr, PCI_INTERRUPT_LINE));
@@ -173,10 +275,6 @@ static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
if (pci_dev->compat)
set_property(dev, "compatible",
pci_dev->compat, pci_compat_len(pci_dev));
push_str(pci_dev->name);
fword("encode-string");
push_str("class");
fword("property");
if (pci_dev->config_cb)
pci_dev->config_cb(config);
}
@@ -310,17 +408,17 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, unsigned long *mem_base,
}
static void ob_scan_pci_bus(int bus, unsigned long *mem_base,
unsigned long *io_base, const char *path)
unsigned long *io_base, char **path)
{
int devnum, fn, is_multi, vid, did;
unsigned int htype;
pci_addr addr;
phandle_t dnode, dbus;
pci_config_t config;
const pci_dev_t *pci_dev;
uint32_t ccode;
uint8_t class, subclass, iface, rev;
activate_device("/");
for (devnum = 0; devnum < 32; devnum++) {
is_multi = 0;
for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
@@ -341,7 +439,8 @@ static void ob_scan_pci_bus(int bus, unsigned long *mem_base,
iface = pci_config_read8(addr, PCI_CLASS_PROG);
rev = pci_config_read8(addr, PCI_REVISION_ID);
pci_dev = pci_find_device(class, subclass, iface, vid, did);
pci_dev = pci_find_device(class, subclass, iface,
vid, did);
#ifdef CONFIG_DEBUG_PCI
printk("%x:%x.%x - %x:%x - ", bus, devnum, fn,
@@ -351,43 +450,41 @@ static void ob_scan_pci_bus(int bus, unsigned long *mem_base,
if (fn == 0)
is_multi = htype & 0x80;
activate_device(path);
dbus=get_cur_dev();
if (pci_dev == NULL || pci_dev->name == NULL)
snprintf(config.path, sizeof(config.path),
"%s/pci%x,%x", path, vid, did);
"%s/pci%x,%x", *path, vid, did);
else
snprintf(config.path, sizeof(config.path),
"%s/%s", path, pci_dev->name);
"%s/%s", *path, pci_dev->name);
#ifdef CONFIG_DEBUG_PCI
printk("%s - ", config.path);
#endif
config.dev = addr & 0x00FFFFFF;
REGISTER_NAMED_NODE(ob_pci_node, config.path);
dnode=find_dev(config.path);
activate_dev( dnode );
activate_device(config.path);
ob_pci_configure(addr, &config, mem_base, io_base);
{
int irq_pin, irq_line;
static const uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
irq_pin = pci_config_read8(addr, PCI_INTERRUPT_PIN);
if (irq_pin > 0) {
irq_pin = (devnum + irq_pin - 1) & 3;
irq_line = heathrow_pci_irqs[irq_pin];
}
}
ob_pci_add_properties(addr, pci_dev, &config);
ob_pci_add_reg(addr);
device_end();
if (ccode == 0x0600 || ccode == 0x0604) {
/* host or bridge */
free(*path);
*path = strdup(config.path);
}
}
}
device_end();
}
int ob_pci_init(void)
{
int bus;
unsigned long mem_base, io_base;
char *path;
#ifdef CONFIG_DEBUG_PCI
printk("Initializing PCI devices...\n");
@@ -399,8 +496,10 @@ int ob_pci_init(void)
mem_base = arch->mem_base;
io_base = arch->io_base;
path = strdup("");
for (bus = 0; bus<0x100; bus++) {
ob_scan_pci_bus(bus, &mem_base, &io_base, "/pci");
ob_scan_pci_bus(bus, &mem_base, &io_base, &path);
}
free(path);
return 0;
}

View File

@@ -1,24 +1,5 @@
[IFDEF] CONFIG_DRIVER_PCI
dev /
\ simple pci bus node
new-device
" pci" device-name
3 encode-int " #address-cells" property
2 encode-int " #size-cells" property
0 encode-int 0 encode-int encode+ " bus-range" property
" pci" encode-string " device_type" property
external
: open ( cr ." opening PCI" cr ) true ;
: close ;
: decode-unit 0 decode-unit-pci-bus ;
: encode-unit encode-unit-pci ;
finish-device
device-end
: pci-addr-encode ( addr.lo addr.mi addr.hi )
rot >r swap >r
encode-int
@@ -31,6 +12,4 @@ device-end
rot encode-int encode+
;
[THEN]

View File

@@ -2,6 +2,7 @@ typedef struct pci_config_t pci_config_t;
struct pci_config_t {
char path[256];
uint32_t dev; /* bus, dev, fn */
uint32_t regions[7];
uint32_t sizes[7];
};

View File

@@ -93,27 +93,6 @@ hex
\ only forth
\ -------------------------------------------------------------------------
\ PCI encode/decode unit
\ -------------------------------------------------------------------------
\ we only implement DD and DD,F
: encode-unit-pci ( phys.lo phy.mid phys.hi -- str len )
nip nip ff00 and 8 >> dup 3 >>
swap 7 and
( ddddd fff )
?dup if
pocket tohexstr
" ," pocket tmpstrcat
else
0 0 pocket tmpstrcpy
then
>r
rot pocket tohexstr r> tmpstrcat drop
;
: decode-unit-pci-bus ( str len bus -- phys.lo phys.mid phys.hi )
-rot ascii , left-split
( addr-R len-R addr-L len-L )