Changeset 03ad2a5a in rtems


Ignore:
Timestamp:
Apr 20, 2016, 4:49:32 AM (4 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
master
Children:
8ce75671
Parents:
014292a1
git-author:
Chris Johns <chrisj@…> (04/20/16 04:49:32)
git-committer:
Chris Johns <chrisj@…> (05/11/16 01:45:01)
Message:

i386/pc386: Add IO and memory support to PCI UART devices.

Use the BAR to determine IO and memory mapped support for PCI UART
boards.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/pc386/console/uart_bus_pci.c

    r014292a1 r03ad2a5a  
    3737#include <stddef.h>
    3838#include <stdint.h>
     39#include <i386_io.h>
    3940#else
    4041#include <sys/cdefs.h>
     
    5556#include <dev/uart/uart.h>
    5657#include <dev/uart/uart_bus.h>
     58
    5759#endif
    5860
     
    226228
    227229#include <bsp.h>
    228 // #include <termios.h>
     230#include <bsp/bspimpl.h>
     231
    229232#include <stdio.h>
    230233#include <stdlib.h>
    231234
    232 // #include <rtems/termiostypes.h>
    233235#include <libchip/serial.h>
    234236#include <libchip/ns16550.h>
     
    243245 */
    244246typedef struct {
    245   bool      found;
    246   uint32_t  base;
    247   uint8_t   irq;
    248   uint8_t   bus;
    249   uint8_t   slot;
    250   int       ports;
    251   uint32_t  clock;
     247  bool        found;
     248  const char* desc;
     249  uint32_t    base;
     250  uint8_t     irq;
     251  uint8_t     bus;
     252  uint8_t     slot;
     253  int         ports;
     254  uint32_t    clock;
    252255} port_instance_conf_t;
    253256
    254257/*
    255  *  Register Access Routines
     258 *  Memory Mapped Register Access Routines
    256259 */
    257 static uint8_t pci_ns16550_get_register(uint32_t addr, uint8_t i)
     260
     261#define UART_PCI_IO (0)
     262
     263static uint8_t pci_ns16550_mem_get_register(uint32_t addr, uint8_t i)
    258264{
    259265  uint8_t          val = 0;
    260266  volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
    261 
    262267  val = *reg;
    263   /* printk( "RD(%p -> 0x%02x) ", reg, val ); */
     268  if (UART_PCI_IO)
     269    printk( "RD(%p -> 0x%02x) ", reg, val );
    264270  return val;
    265271}
    266272
    267 static void pci_ns16550_set_register(uint32_t addr, uint8_t i, uint8_t val)
     273static void pci_ns16550_mem_set_register(uint32_t addr, uint8_t i, uint8_t val)
    268274{
    269275  volatile uint32_t *reg = (volatile uint32_t *)(addr + (i*4));
    270 
    271   /* printk( "WR(%p <- 0x%02x) ", reg, val ); */
     276  if (UART_PCI_IO)
     277    printk( "WR(%p <- 0x%02x) ", reg, val );
    272278  *reg = val;
     279}
     280
     281/*
     282 *  IO Register Access Routines
     283 */
     284static uint8_t pci_ns16550_io_get_register(uint32_t addr, uint8_t i)
     285{
     286  uint8_t val = rtems_inb(addr + i);
     287  if (UART_PCI_IO)
     288    printk( "RD(%p -> 0x%02x) ", addr + i, val );
     289  return val;
     290}
     291
     292static void pci_ns16550_io_set_register(uint32_t addr, uint8_t i, uint8_t val)
     293{
     294  if (UART_PCI_IO)
     295    printk( "WR(%p <- 0x%02x) ", addr + i, val );
     296  rtems_outb(addr + i, val);
    273297}
    274298
     
    317341        uint8_t  irq;
    318342        uint32_t base;
    319 
    320         boards++;
    321         conf[instance].found = true;
    322         conf[instance].clock =  pci_ns8250_ids[i].rclk;
    323         conf[instance].ports = 1;
    324         total_ports += conf[instance].ports;
    325 
    326         pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
     343        bool io;
     344
    327345        pci_read_config_dword( bus, dev, fun, PCI_BASE_ADDRESS_0, &base );
    328346
    329         conf[instance].irq  = irq;
    330         conf[instance].base = base;
    331 
    332         printk(
    333           "Found %s #%d at 0x%08x IRQ %d with %d clock\n",
    334           pci_ns8250_ids[i].desc,
    335           instance,
    336           conf[instance].base,
    337           conf[instance].irq,
    338           conf[instance].clock
    339         );
     347        /*
     348         * Reject memory mapped 64-bit boards. We need 2 BAR registers and the
     349         * driver's base field is only 32-bits any way.
     350         */
     351        io = (base & 1) == 1;
     352        if (io || (!io && (((base >> 1) & 3) != 2))) {
     353          boards++;
     354          conf[instance].found = true;
     355          conf[instance].desc = pci_ns8250_ids[i].desc;
     356          conf[instance].clock =  pci_ns8250_ids[i].rclk;
     357          conf[instance].ports = 1;
     358          total_ports += conf[instance].ports;
     359
     360          pci_read_config_byte( bus, dev, fun, PCI_INTERRUPT_LINE, &irq );
     361
     362          conf[instance].irq  = irq;
     363          conf[instance].base = base;
     364        }
    340365      }
    341366    }
     
    353378      device_instance = 1;
    354379      for (b = 0; b < MAX_BOARDS; b++) {
     380        uint32_t base = 0;
     381        bool io;
     382        const char* locatable = "";
     383        const char* prefectable = locatable;
    355384        char name[32];
    356385        if ( conf[b].found == false )
     
    370399        }
    371400
     401        /*
     402         * PCI BAR (http://wiki.osdev.org/PCI#Base_Address_Registers):
     403         *
     404         *  Bit 0: 0 = memory, 1 = IO
     405         *
     406         * Memory:
     407         *  Bit 2-1  : 0 = any 32bit address,
     408         *             1 = < 1M
     409         *             2 = any 64bit address
     410         *  Bit 3    : 0 = no, 1 = yes
     411         *  Bit 31-4 : base address (16-byte aligned)
     412         *
     413         * IO:
     414         *  Bit 1    : reserved
     415         *  Bit 31-2 : base address (4-byte aligned)
     416         */
     417
     418        io = (conf[b].base & 1) == 1;
     419
     420        if (io) {
     421          base = conf[b].base & 0xfffffffc;
     422        } else {
     423          int loc = (conf[b].base >> 1) & 3;
     424          if (loc == 0) {
     425            base = conf[b].base & 0xfffffff0;
     426            locatable = ",A32";
     427          } else if (loc == 1) {
     428            base = conf[b].base & 0x0000fff0;
     429            locatable = ",A16";
     430          }
     431          prefectable = (conf[b].base & (1 << 3)) == 0 ? ",no-prefech" : ",prefetch";
     432        }
     433
    372434        port_p->deviceProbe   = NULL;
    373435        port_p->pDeviceFlow   = NULL;
     
    375437        port_p->ulHysteresis  = 8;
    376438        port_p->pDeviceParams = (void *) 9600;
    377         port_p->ulCtrlPort1   = conf[b].base;
     439        port_p->ulCtrlPort1   = base;
    378440        port_p->ulCtrlPort2   = 0;                   /* NA */
    379441        port_p->ulDataPort    = 0;                   /* NA */
    380         port_p->getRegister   = pci_ns16550_get_register;
    381         port_p->setRegister   = pci_ns16550_set_register;
     442        if (io) {
     443          port_p->getRegister = pci_ns16550_io_get_register;
     444          port_p->setRegister = pci_ns16550_io_set_register;
     445        } else {
     446          port_p->getRegister = pci_ns16550_mem_get_register;
     447          port_p->setRegister = pci_ns16550_mem_set_register;
     448        }
    382449        port_p->getData       = NULL;                /* NA */
    383450        port_p->setData       = NULL;                /* NA */
    384451        port_p->ulClock       = conf[b].clock;
    385452        port_p->ulIntVector   = conf[b].irq;
     453
     454
     455        printk(
     456          "%s:%d:%s,%s:0x%x%s%s,irq:%d,clk:%d\n", /*  */
     457          name, b, conf[b].desc,
     458          io ? "io" : "mem", base, locatable, prefectable,
     459          conf[b].irq, conf[b].clock
     460        );
     461
    386462
    387463        port_p++;
Note: See TracChangeset for help on using the changeset viewer.