VirtualBox

Ignore:
Timestamp:
Jul 12, 2012 3:21:46 PM (12 years ago)
Author:
vboxsync
Message:

BIOS: Updating PCI BIOS service.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/pcibios.c

    r42030 r42127  
    6363#define BP      r.gr.u.r16.bp
    6464#define SP      r.gr.u.r16.sp
    65 #define FLAGS   r.ra.flags.u.r16.flags
    6665#define EAX     r.gr.u.r32.eax
    6766#define EBX     r.gr.u.r32.ebx
     
    9089#define PCI_CFG_ADDR    0xCF8
    9190#define PCI_CFG_DATA    0xCFC
     91
     92#ifdef __386__
     93
     94#define PCIxx(x)    pci32_##x
     95
     96/* The stack layout is different in 32-bit mode. */
     97typedef struct {
     98    pushad_regs_t   gr;
     99    uint32_t        flags;
     100} pci_regs_t;
     101
     102#define FLAGS   r.flags
     103
     104/* In 32-bit mode, don't do any output; not technically impossible but needs
     105 * a lot of extra code.
     106 */
     107#undef  BX_INFO
     108#define BX_INFO(...)
     109#undef  BX_DEBUG_PCI
     110#define BX_DEBUG_PCI(...)
     111
     112#else
     113
     114#define PCIxx(x)    pci16_##x
     115
     116typedef struct {
     117    pushad_regs_t   gr;
     118    uint16_t        es;
     119    uint16_t        ds;
     120    iret_addr_t     ra;
     121} pci_regs_t;
     122
     123#define FLAGS   r.ra.flags.u.r16.flags
     124
     125#endif
     126
     127#ifdef __386__
     128
     129/* 32-bit code can just use the compiler intrinsics. */
     130extern unsigned inpd(unsigned port);
     131extern unsigned outpd(unsigned port, unsigned value);
     132#pragma intrinsic(inpd,outpd)
     133
     134#else
    92135
    93136//@todo: merge with AHCI code
     
    113156    parm [dx] [cx ax] modify nomemory;
    114157
     158#endif
     159
    115160/* Write the CONFIG_ADDRESS register to prepare for data access. Requires
    116161 * the register offset to be DWORD aligned (low two bits clear). Warning:
     
    131176 * This is largely a wrapper to avoid excessive inlining.
    132177 */
    133 void pci16_select_reg(uint16_t bus_dev_fn, uint16_t ofs)
     178void PCIxx(select_reg)(uint16_t bus_dev_fn, uint16_t ofs)
    134179{
    135180    pci16_w_addr(bus_dev_fn, ofs & ~3, PCI_CFG_ADDR);
    136181}
    137182
     183/* Selected configuration space offsets. */
    138184#define PCI_VEN_ID          0x00
    139185#define PCI_DEV_ID          0x02
     
    141187#define PCI_CLASS_CODE      0x09
    142188#define PCI_HEADER_TYPE     0x0E
    143 
     189#define PCI_BRIDGE_SUBORD   0x1A
     190
     191/* To avoid problems with 16-bit code, we reserve the last possible
     192 * bus/dev/fn combination (65,535). Upon reaching this location, the
     193 * probing will end.
     194 */
     195#define INDEX_NOT_FOUND     0xFFFF
    144196
    145197/* Find a specified PCI device, either by vendor+device ID or class.
     
    151203 * non-present devices.
    152204 */
    153 uint16_t pci16_find_device(uint32_t search_item, uint16_t index, int search_class)
     205uint16_t PCIxx(find_device)(uint32_t search_item, uint16_t index, int search_class)
    154206{
    155207    uint32_t    data;
     
    157209    uint8_t     max_bus;
    158210    uint8_t     hdr_type;
     211    uint8_t     subordinate;
    159212    int         step;
    160213    int         found;
     
    179232         */
    180233        if ((bus_dev_fn & 7) == 0) {
    181             pci16_select_reg(bus_dev_fn, PCI_HEADER_TYPE);
     234            PCIxx(select_reg)(bus_dev_fn, PCI_HEADER_TYPE);
    182235            hdr_type = inp(PCI_CFG_DATA + (PCI_HEADER_TYPE & 3));
    183236            if (hdr_type == 0xFF) {
     
    196249         * there will be only the primary bus (i.e. bus 0) and we can avoid
    197250         * looking at the remaining 255 theoretically present buses. This check
    198          * only needs to be done on the primary bus (bridges must report all
    199          * bridges behind them).
     251         * only needs to be done on the primary bus, since bridges must report
     252         * all bridges potentially behind them.
    200253         */
    201254        if ((hdr_type & 7) == 1 && (bus_dev_fn >> 8) == 0) {
     255            /* Read the subordinate (last) bridge number. */
     256            PCIxx(select_reg)(bus_dev_fn, PCI_BRIDGE_SUBORD);
     257            subordinate = inp(PCI_CFG_DATA + (PCI_BRIDGE_SUBORD & 3));
     258            if (subordinate > max_bus)
     259                max_bus = subordinate;
    202260        }
    203261
    204262        /* Select the appropriate register. */
    205         pci16_select_reg(bus_dev_fn, search_class ? PCI_REV_ID : PCI_VEN_ID);
     263        PCIxx(select_reg)(bus_dev_fn, search_class ? PCI_REV_ID : PCI_VEN_ID);
    206264        data  = inpd(PCI_CFG_DATA);
    207265        found = 0;
     
    226284    } while ((bus_dev_fn >> 8) <= max_bus);
    227285
    228     if (index == ~0)
     286    if (index == INDEX_NOT_FOUND)
    229287        BX_DEBUG_PCI("PCI: Device found (%02X:%%02X:%01X)\n", bus_dev_fn >> 8,
    230288                     bus_dev_fn >> 3 & 31, bus_dev_fn & 7);
    231289
    232     return index == ~0 ? bus_dev_fn : ~0;
     290    return index == INDEX_NOT_FOUND ? bus_dev_fn : INDEX_NOT_FOUND;
    233291}
    234292
    235 void BIOSCALL pci16_function(volatile pci_regs_t r)
     293void BIOSCALL PCIxx(function)(volatile pci_regs_t r)
    236294{
    237295    uint16_t    device;
     
    254312         * be easily detected.
    255313         */
    256         if (DX == ~0) {
     314        if (DX == 0xFFFF) {
    257315            SET_AH(BAD_VENDOR_ID);
    258316            SET_CF();
    259317        } else {
    260             device = pci16_find_device(DX | (uint32_t)CX << 16, SI, 0);
    261             if (device == ~0) {
     318            device = PCIxx(find_device)(DX | (uint32_t)CX << 16, SI, 0);
     319            if (device == INDEX_NOT_FOUND) {
    262320                SET_AH(DEVICE_NOT_FOUND);
    263321                SET_CF();
     
    268326        break;
    269327    case FIND_PCI_CLASS_CODE:
    270         device = pci16_find_device(ECX, SI, 1);
    271         if (device == ~0) {
     328        device = PCIxx(find_device)(ECX, SI, 1);
     329        if (device == INDEX_NOT_FOUND) {
    272330            SET_AH(DEVICE_NOT_FOUND);
    273331            SET_CF();
     
    286344            SET_CF();
    287345        } else {
    288             pci16_select_reg(BX, DI);
     346            PCIxx(select_reg)(BX, DI);
    289347            switch (GET_AL()) {
    290348            case READ_CONFIG_BYTE:
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette