modified PCI configuration, RADEON card does not configure correctly

(MMIO space not accessible)
This commit is contained in:
Markus Fröschle
2015-02-22 19:46:16 +00:00
parent a63b1dfdbd
commit c036d08f6a
12 changed files with 2529 additions and 2467 deletions

View File

@@ -207,3 +207,12 @@ util/setjmp.S
include/x86emu_regs.h include/x86emu_regs.h
x86emu/x86emu_util.c x86emu/x86emu_util.c
include/setjmp.h include/setjmp.h
video/video.c
video/fbmem.c
video/fbmodedb.c
video/fbmon.c
video/fnt_st_8x16.c
video/offscreen.c
video/vdi_fill.c
video/videl.c
video/video.c

View File

@@ -47,6 +47,9 @@ CFLAGS=-mcpu=5474 \
CFLAGS_OPTIMIZED = -mcpu=5474 \ CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \ -Wall \
-O2 \ -O2 \
-ffixed-a3 \
-ffixed-a4 \
-ffixed-a5 \
-g \ -g \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffreestanding \ -ffreestanding \

View File

@@ -39,7 +39,7 @@
#error "unknown machine!" #error "unknown machine!"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
//#define DBG_DMA // #define DBG_DMA
#ifdef DBG_DMA #ifdef DBG_DMA
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else

View File

@@ -194,8 +194,8 @@ typedef struct /* structure of address conversion */
#define PCI_COMMAND(i) (((i) >> 16) & 0xffff) #define PCI_COMMAND(i) (((i) >> 16) & 0xffff)
/* register 0x08 macros */ /* register 0x08 macros */
#define PCI_CLASS_CODE(i) ((swpl((i)) & 0xffff0000) >> 16) #define PCI_CLASS_CODE(i) ((swpl((i)) & 0xff000000) >> 24)
#define PCI_SUBCLASS(i) ((swpl((i)) & 0xffffff00) >> 8) #define PCI_SUBCLASS(i) ((swpl((i)) & 0xffff0000) >> 16)
#define PCI_PROG_IF(i) ((swpl((i)) & 0x0000ff00) >> 8) #define PCI_PROG_IF(i) ((swpl((i)) & 0x0000ff00) >> 8)
#define PCI_REVISION_ID(i) ((swpl((i)) & 0x000000ff)) #define PCI_REVISION_ID(i) ((swpl((i)) & 0x000000ff))

View File

@@ -33,7 +33,7 @@
#include "interrupts.h" #include "interrupts.h"
#include "wait.h" #include "wait.h"
//#define DEBUG_PCI #define DEBUG_PCI
#ifdef DEBUG_PCI #ifdef DEBUG_PCI
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -333,7 +333,7 @@ uint32_t pci_read_config_longword(int32_t handle, int offset)
/* finish PCI configuration access special cycle (allow regular PCI accesses) */ /* finish PCI configuration access special cycle (allow regular PCI accesses) */
MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E;
pci_check_status(); //pci_check_status();
return value; return value;
} }
@@ -593,6 +593,11 @@ int32_t pci_find_classcode(uint32_t classcode, int index)
{ {
value = pci_read_config_longword(handle, PCICCR); value = pci_read_config_longword(handle, PCICCR);
dbg("classcode to search for=%x\r\n", classcode);
dbg("PCI_CLASSCODE found=%x\r\n", PCI_CLASS_CODE(value));
dbg("PCI_SUBCLASS found=%x\r\n", PCI_SUBCLASS(value));
dbg("PCI_PROG_IF found=%x\r\n", PCI_PROG_IF(value));
if ((classcode & (1 << 26) ? ((PCI_CLASS_CODE(value) == (classcode & 0xff))) : true) && if ((classcode & (1 << 26) ? ((PCI_CLASS_CODE(value) == (classcode & 0xff))) : true) &&
(classcode & (1 << 25) ? ((PCI_SUBCLASS(value) == ((classcode & 0xff00) >> 8))) : true) && (classcode & (1 << 25) ? ((PCI_SUBCLASS(value) == ((classcode & 0xff00) >> 8))) : true) &&
(classcode & (1 << 24) ? ((PCI_PROG_IF(value) == ((classcode & 0xff0000) >> 16))) : true)) (classcode & (1 << 24) ? ((PCI_PROG_IF(value) == ((classcode & 0xff0000) >> 16))) : true))
@@ -930,7 +935,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
/* fill resource descriptor */ /* fill resource descriptor */
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);
rd->flags = 0 | FLG_32BIT | FLG_16BIT | FLG_8BIT | 2; /* little endian, lane swapped */ rd->flags = 0 | FLG_32BIT | FLG_16BIT | FLG_8BIT | ORD_INTEL_LS; /* little endian, lane swapped */
rd->start = address; rd->start = address;
rd->length = size; rd->length = size;
rd->offset = 0; rd->offset = 0;
@@ -1222,15 +1227,21 @@ void init_pci(void)
/* Configure Initiator Windows */ /* Configure Initiator Windows */
/* initiator window 0 base / translation adress register */ /*
MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET | (((PCI_MEMORY_SIZE - 1) >> 8) & 0xffff0000)) * initiator window 0 base / translation adress register
| ((PCI_MEMORY_OFFSET >> 16) & 0xff00); * used for PCI memory access
*/
MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE - 1) >> 8))
+ (PCI_MEMORY_OFFSET >> 16);
NOP(); NOP();
dbg("PCIIW0BTAR=0x%08x\r\n", MCF_PCI_PCIIW0BTAR); dbg("PCIIW0BTAR=0x%08x\r\n", MCF_PCI_PCIIW0BTAR);
/* initiator window 1 base / translation adress register */ /*
MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET | ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000; * initiator window 1 base / translation adress register
* used for PCI I/O access
*/
MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET + ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000;
NOP(); NOP();
/* initiator window 2 base / translation address register */ /* initiator window 2 base / translation address register */
MCF_PCI_PCIIW2BTAR = 0L; /* not used */ MCF_PCI_PCIIW2BTAR = 0L; /* not used */
@@ -1241,6 +1252,7 @@ void init_pci(void)
MCF_PCI_PCIIWCR_WINCTRL0_E | MCF_PCI_PCIIWCR_WINCTRL0_E |
MCF_PCI_PCIIWCR_WINCTRL1_E; MCF_PCI_PCIIWCR_WINCTRL1_E;
NOP(); NOP();
/* /*
* Initialize target control register. * Initialize target control register.
* Used when an external bus master accesses the Coldfire PCI as target * Used when an external bus master accesses the Coldfire PCI as target

File diff suppressed because it is too large Load Diff

View File

@@ -79,12 +79,12 @@ extern uint8_t _EMUTOS_SIZE[];
*/ */
static inline bool pic_txready(void) static inline bool pic_txready(void)
{ {
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY)
{ {
return true; return true;
} }
return false; return false;
} }
/* /*
@@ -92,98 +92,98 @@ static inline bool pic_txready(void)
*/ */
static inline bool pic_rxready(void) static inline bool pic_rxready(void)
{ {
if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY)
{ {
return true; return true;
} }
return false; return false;
} }
void write_pic_byte(uint8_t value) void write_pic_byte(uint8_t value)
{ {
/* /*
* Wait until the transmitter is ready or 1000us are passed * Wait until the transmitter is ready or 1000us are passed
*/ */
waitfor(1000, pic_txready); waitfor(1000, pic_txready);
/* /*
* Transmit the byte * Transmit the byte
*/ */
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
} }
uint8_t read_pic_byte(void) uint8_t read_pic_byte(void)
{ {
/* /*
* Wait until a byte has been received or 1000us are passed * Wait until a byte has been received or 1000us are passed
*/ */
waitfor(1000, pic_rxready); waitfor(1000, pic_rxready);
/* /*
* Return the received byte * Return the received byte
*/ */
return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
} }
void pic_init(void) void pic_init(void)
{ {
char answer[4] = "OLD"; char answer[4] = "OLD";
xprintf("initialize the PIC: "); xprintf("initialize the PIC: ");
/* /*
* Send the PIC initialization string * Send the PIC initialization string
*/ */
write_pic_byte('A'); write_pic_byte('A');
write_pic_byte('C'); write_pic_byte('C');
write_pic_byte('P'); write_pic_byte('P');
write_pic_byte('F'); write_pic_byte('F');
/* /*
* Read the 3-char answer string. Should be "OK!". * Read the 3-char answer string. Should be "OK!".
*/ */
answer[0] = read_pic_byte(); answer[0] = read_pic_byte();
answer[1] = read_pic_byte(); answer[1] = read_pic_byte();
answer[2] = read_pic_byte(); answer[2] = read_pic_byte();
answer[3] = '\0'; answer[3] = '\0';
if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!')
{ {
dbg("PIC initialization failed. Already initialized?\r\n"); dbg("PIC initialization failed. Already initialized?\r\n");
} }
else else
{ {
xprintf("%s\r\n", answer); xprintf("%s\r\n", answer);
} }
} }
void nvram_init(void) void nvram_init(void)
{ {
int i; int i;
xprintf("Restore the NVRAM data: "); xprintf("Restore the NVRAM data: ");
/* Request for NVRAM backup data */ /* Request for NVRAM backup data */
write_pic_byte(0x01); write_pic_byte(0x01);
/* Check answer type */ /* Check answer type */
if (read_pic_byte() != 0x81) if (read_pic_byte() != 0x81)
{ {
// FIXME: PIC protocol error // FIXME: PIC protocol error
xprintf("FAILED\r\n"); xprintf("FAILED\r\n");
return; return;
} }
/* Restore the NVRAM backup to the FPGA */ /* Restore the NVRAM backup to the FPGA */
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
{ {
uint8_t data = read_pic_byte(); uint8_t data = read_pic_byte();
*(volatile uint8_t*)0xffff8961 = i; *(volatile uint8_t*)0xffff8961 = i;
*(volatile uint8_t*)0xffff8963 = data; *(volatile uint8_t*)0xffff8963 = data;
} }
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
#define KBD_ACIA_CONTROL * ((uint8_t *) 0xfffffc00) #define KBD_ACIA_CONTROL * ((uint8_t *) 0xfffffc00)
@@ -193,74 +193,74 @@ void nvram_init(void)
void acia_init() void acia_init()
{ {
xprintf("init ACIA: "); xprintf("init ACIA: ");
/* init ACIA */ /* init ACIA */
KBD_ACIA_CONTROL = 3; /* master reset */ KBD_ACIA_CONTROL = 3; /* master reset */
NOP(); NOP();
MIDI_ACIA_CONTROL = 3; /* master reset */ MIDI_ACIA_CONTROL = 3; /* master reset */
NOP(); NOP();
KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */
NOP(); NOP();
MFP_INTR_IN_SERVICE_A = 0xff; MFP_INTR_IN_SERVICE_A = 0xff;
NOP(); NOP();
MFP_INTR_IN_SERVICE_B = 0xff; MFP_INTR_IN_SERVICE_B = 0xff;
NOP(); NOP();
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
void enable_coldfire_interrupts() void enable_coldfire_interrupts()
{ {
xprintf("enable interrupts: "); xprintf("enable interrupts: ");
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
FBEE_INTR_CONTROL = 0L; /* disable all interrupts */ FBEE_INTR_CONTROL = 0L; /* disable all interrupts */
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
/* /*
* TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write
* access to 0xff8201 (vbasehi), i.e. everytime the video base address is written * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written
*/ */
MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */
MCF_GPT_GMS_IEN | MCF_GPT_GMS_IEN |
MCF_GPT_GMS_TMS(1); /* route GPT0 interrupt on interrupt controller */ MCF_GPT_GMS_TMS(1); /* route GPT0 interrupt on interrupt controller */
MCF_INTC_ICR62 = MCF_INTC_ICR_IL(7) | MCF_INTC_ICR62 = MCF_INTC_ICR_IL(7) |
MCF_INTC_ICR_IP(6); /* interrupt level 7, interrupt priority 7 */ MCF_INTC_ICR_IP(6); /* interrupt level 7, interrupt priority 7 */
MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */
MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */
MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */
//MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ //MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */
MCF_INTC_IMRH = 0; MCF_INTC_IMRH = 0;
FBEE_INTR_ENABLE = FBEE_INTR_INT_IRQ7 | /* enable pseudo bus error */ FBEE_INTR_ENABLE = FBEE_INTR_INT_IRQ7 | /* enable pseudo bus error */
FBEE_INTR_INT_MFP_IRQ6 | /* enable MFP interrupts */ FBEE_INTR_INT_MFP_IRQ6 | /* enable MFP interrupts */
FBEE_INTR_INT_FPGA_IRQ5 | /* enable Firebee (PIC, PCI, ETH PHY, DVI, DSP) interrupts */ FBEE_INTR_INT_FPGA_IRQ5 | /* enable Firebee (PIC, PCI, ETH PHY, DVI, DSP) interrupts */
FBEE_INTR_INT_VSYNC_IRQ4 | /* enable vsync interrupts */ FBEE_INTR_INT_VSYNC_IRQ4 | /* enable vsync interrupts */
FBEE_INTR_PCI_INTA | /* enable PCI interrupts */ FBEE_INTR_PCI_INTA | /* enable PCI interrupts */
FBEE_INTR_PCI_INTB | FBEE_INTR_PCI_INTB |
FBEE_INTR_PCI_INTC | FBEE_INTR_PCI_INTC |
FBEE_INTR_PCI_INTD; FBEE_INTR_PCI_INTD;
#endif #endif
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
void disable_coldfire_interrupts() void disable_coldfire_interrupts()
{ {
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
FBEE_INTR_ENABLE = 0; /* disable all interrupts */ FBEE_INTR_ENABLE = 0; /* disable all interrupts */
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_EPORT_EPIER = 0x0; MCF_EPORT_EPIER = 0x0;
MCF_INTC_IMRL = 0xfffffffe; MCF_INTC_IMRL = 0xfffffffe;
MCF_INTC_IMRH = 0xffffffff; MCF_INTC_IMRH = 0xffffffff;
} }
@@ -272,11 +272,11 @@ NIF nif2;
bool spurious_interrupt_handler(void *arg1, void *arg2) bool spurious_interrupt_handler(void *arg1, void *arg2)
{ {
dbg("IMRH=%lx, IMRL=%lx\r\n", MCF_INTC_IMRH, MCF_INTC_IMRL); dbg("IMRH=%lx, IMRL=%lx\r\n", MCF_INTC_IMRH, MCF_INTC_IMRL);
dbg("IPRH=%lx, IPRL=%lx\r\n", MCF_INTC_IPRH, MCF_INTC_IPRL); dbg("IPRH=%lx, IPRL=%lx\r\n", MCF_INTC_IPRH, MCF_INTC_IPRL);
dbg("IRLR=%x\r\n", MCF_INTC_IRLR); dbg("IRLR=%x\r\n", MCF_INTC_IRLR);
return true; return true;
} }
/* /*
@@ -284,195 +284,195 @@ bool spurious_interrupt_handler(void *arg1, void *arg2)
*/ */
void init_isr(void) void init_isr(void)
{ {
isr_init(); /* need to call that explicitely, otherwise isr table might be full */ isr_init(); /* need to call that explicitely, otherwise isr table might be full */
/* /*
* register spurious interrupt handler * register spurious interrupt handler
*/ */
if (!isr_register_handler(24, 6, 6, spurious_interrupt_handler, NULL, NULL)) if (!isr_register_handler(24, 6, 6, spurious_interrupt_handler, NULL, NULL))
{ {
dbg("unable to register spurious interrupt handler\r\n"); dbg("unable to register spurious interrupt handler\r\n");
} }
/* /*
* register the FEC interrupt handler * register the FEC interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1)) if (!isr_register_handler(64 + INT_SOURCE_FEC0, 5, 1, fec0_interrupt_handler, NULL, (void *) &nif1))
{ {
dbg("unable to register isr for FEC0\r\n"); dbg("unable to register isr for FEC0\r\n");
} }
/* /*
* Register the DMA interrupt handler * Register the DMA interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_DMA, 5, 3, dma_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_DMA, 5, 3, dma_interrupt_handler, NULL, NULL))
{ {
dbg("unable to register isr for DMA\r\n"); dbg("unable to register isr for DMA\r\n");
} }
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
/* /*
* register GPT0 timer interrupt vector * register GPT0 timer interrupt vector
*/ */
if (!isr_register_handler(64 + INT_SOURCE_GPT0, 5, 2, gpt0_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_GPT0, 5, 2, gpt0_interrupt_handler, NULL, NULL))
{ {
dbg("unable to register isr for GPT0 timer\r\n"); dbg("unable to register isr for GPT0 timer\r\n");
} }
/* /*
* register the PIC interrupt handler * register the PIC interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_PSC3, 5, 5, pic_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_PSC3, 5, 5, pic_interrupt_handler, NULL, NULL))
{ {
dbg("Error: unable to register ISR for PSC3\r\n"); dbg("Error: unable to register ISR for PSC3\r\n");
} }
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
/* /*
* register the XLB PCI interrupt handler * register the XLB PCI interrupt handler
*/ */
if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, 7, 0, xlbpci_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, 7, 0, xlbpci_interrupt_handler, NULL, NULL))
{ {
dbg("Error: unable to register isr for XLB PCI interrupts\r\n"); dbg("Error: unable to register isr for XLB PCI interrupts\r\n");
} }
MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */
MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */ MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */
MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */ MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */
MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */ MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */
MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */ MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */
MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */ MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */
MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */ MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */
if (!isr_register_handler(64 + INT_SOURCE_PCIARB, 7, 1, pciarb_interrupt_handler, NULL, NULL)) if (!isr_register_handler(64 + INT_SOURCE_PCIARB, 7, 1, pciarb_interrupt_handler, NULL, NULL))
{ {
dbg("Error: unable to register isr for PCIARB interrupts\r\n"); dbg("Error: unable to register isr for PCIARB interrupts\r\n");
return; return;
} }
MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */ MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */
MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */ MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */
} }
void BaS(void) void BaS(void)
{ {
uint8_t *src; uint8_t *src;
uint8_t *dst = (uint8_t *) TOS; uint8_t *dst = (uint8_t *) TOS;
#if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */ #if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */
pic_init(); pic_init();
nvram_init(); nvram_init();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
xprintf("initialize MMU: "); xprintf("initialize MMU: ");
mmu_init(); mmu_init();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("copy EmuTOS: "); xprintf("copy EmuTOS: ");
dma_init(); dma_init();
/* copy EMUTOS */ /* copy EMUTOS */
src = (uint8_t *) EMUTOS; src = (uint8_t *) EMUTOS;
dma_memcpy(dst, src, EMUTOS_SIZE); dma_memcpy(dst, src, EMUTOS_SIZE);
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("initialize exception vector table: "); xprintf("initialize exception vector table: ");
vec_init(); vec_init();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("flush caches: "); xprintf("flush caches: ");
flush_and_invalidate_caches(); flush_and_invalidate_caches();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("enable MMU: "); xprintf("enable MMU: ");
MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */
NOP(); /* force pipeline sync */ NOP(); /* force pipeline sync */
xprintf("finished\r\n"); xprintf("finished\r\n");
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
xprintf("IDE reset: "); xprintf("IDE reset: ");
/* IDE reset */ /* IDE reset */
* (volatile uint8_t *) (0xffff8802 - 2) = 14; * (volatile uint8_t *) (0xffff8802 - 2) = 14;
* (volatile uint8_t *) (0xffff8802 - 0) = 0x80; * (volatile uint8_t *) (0xffff8802 - 0) = 0x80;
wait(1); wait(1);
* (volatile uint8_t *) (0xffff8802 - 0) = 0; * (volatile uint8_t *) (0xffff8802 - 0) = 0;
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("enable video: "); xprintf("enable video: ");
/* /*
* video setup (25MHz) * video setup (25MHz)
*/ */
* (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */
* (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */
* (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */
* (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */
/* fifo on, refresh on, ddrcs and cke on, video dac on */ /* fifo on, refresh on, ddrcs and cke on, video dac on */
* (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002;
xprintf("finished\r\n"); xprintf("finished\r\n");
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
sd_card_init(); sd_card_init();
/* /*
* memory setup * memory setup
*/ */
memset((void *) 0x400, 0, 0x400); memset((void *) 0x400, 0, 0x400);
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
/* set Falcon bus control register */ /* set Falcon bus control register */
/* sets bit 3 and 6. Both are undefined on an original Falcon? */ /* sets bit 3 and 6. Both are undefined on an original Falcon? */
* (volatile uint8_t *) 0xffff8007 = 0x48; * (volatile uint8_t *) 0xffff8007 = 0x48;
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
/* ST RAM */ /* ST RAM */
* (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */
* (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */
* (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
* (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */ /* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
#if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */ #if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */
acia_init(); acia_init();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
srec_execute("BASFLASH.S19"); srec_execute("BASFLASH.S19");
/* Jump into the OS */ /* Jump into the OS */
typedef void void_func(void); typedef void void_func(void);
struct rom_header struct rom_header
{ {
void *initial_sp; void *initial_sp;
void_func *initial_pc; void_func *initial_pc;
}; };
xprintf("BaS initialization finished, enable interrupts\r\n"); xprintf("BaS initialization finished, enable interrupts\r\n");
init_isr(); init_isr();
enable_coldfire_interrupts(); enable_coldfire_interrupts();
MCF_INTC_IMRH = 0; MCF_INTC_IMRH = 0;
MCF_INTC_IMRL = 0; MCF_INTC_IMRL = 0;
dma_irq_enable(); dma_irq_enable();
fec_irq_enable(0, 5, 1); fec_irq_enable(0, 5, 1);
init_pci(); init_pci();
// video_init(); video_init();
/* initialize USB devices */ /* initialize USB devices */
//init_usb(); //init_usb();
set_ipl(7); /* disable interrupts */ set_ipl(7); /* disable interrupts */
xprintf("call EmuTOS\r\n"); xprintf("call EmuTOS\r\n");
struct rom_header *os_header = (struct rom_header *) TOS; struct rom_header *os_header = (struct rom_header *) TOS;
os_header->initial_pc(); os_header->initial_pc();
} }

View File

@@ -37,7 +37,7 @@
#include "dma.h" #include "dma.h"
#include "pci.h" #include "pci.h"
//#define IRQ_DEBUG // #define IRQ_DEBUG
#if defined(IRQ_DEBUG) #if defined(IRQ_DEBUG)
#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else

View File

@@ -1,6 +1,7 @@
#include "mmu.h" #include "mmu.h"
#include "acia.h" #include "acia.h"
#include "exceptions.h" #include "exceptions.h"
#include "pci.h"
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
@@ -626,7 +627,7 @@ void mmu_init(void)
ACR_BA(0x80000000)); /* (equals area from 3 to 4 GB */ ACR_BA(0x80000000)); /* (equals area from 3 to 4 GB */
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */ ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */
ACR_BA(0x80000000)); ACR_BA(PCI_MEMORY_OFFSET));
#elif defined(MACHINE_M54455) #elif defined(MACHINE_M54455)
ACR_ADMSK(0x7f) | ACR_ADMSK(0x7f) |
ACR_BA(0x80000000)); /* FIXME: not determined yet */ ACR_BA(0x80000000)); /* FIXME: not determined yet */
@@ -634,8 +635,6 @@ void mmu_init(void)
#error unknown machine! #error unknown machine!
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
// set_acr1(0x601fc000);
/* data access attributes for BaS in flash */ /* data access attributes for BaS in flash */
set_acr1(ACR_W(0) | set_acr1(ACR_W(0) |

View File

@@ -425,7 +425,7 @@ void init_fbcs()
MCF_FBCS2_CSAR = MCF_FBCS_CSAR_BA(0xF0000000); /* Firebee new I/O address range */ MCF_FBCS2_CSAR = MCF_FBCS_CSAR_BA(0xF0000000); /* Firebee new I/O address range */
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 /* 32BIT PORT */ MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 /* 32BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 4WS */ | MCF_FBCS_CSCR_WS(4) /* DEFAULT 4WS */
| MCF_FBCS_CSCR_AA; /* AA */ | MCF_FBCS_CSCR_AA; /* AA */
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M /* F000'0000-F7FF'FFFF */ MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M /* F000'0000-F7FF'FFFF */
| MCF_FBCS_CSMR_V); | MCF_FBCS_CSMR_V);

View File

@@ -61,148 +61,148 @@ static char snil[] = "(nil)";
void xputchar(int c) void xputchar(int c)
{ {
__asm__ __volatile__ __asm__ __volatile__
( (
".extern printf_helper\n\t" ".extern printf_helper\n\t"
"move.b %0,d0\n\t" "move.b %0,d0\n\t"
"bsr printf_helper\n\t" "bsr printf_helper\n\t"
/* output */: /* output */:
/* input */: "r" (c) /* input */: "r" (c)
/* clobber */: "d0","d2","a0","memory" /* clobber */: "d0","d2","a0","memory"
); );
} }
static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap) static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap)
{ {
char buf[128]; char buf[128];
char *bp; char *bp;
const char *f; const char *f;
float flt; float flt;
long l; long l;
unsigned long u; unsigned long u;
int i; int i;
int fmt; int fmt;
unsigned char pad = ' '; unsigned char pad = ' ';
int flush_left = 0; int flush_left = 0;
int f_width = 0; int f_width = 0;
int prec = INF; int prec = INF;
int hash = 0; int hash = 0;
int do_long = 0; int do_long = 0;
int sign = 0; int sign = 0;
int attributes = 0; int attributes = 0;
f = sfmt; f = sfmt;
for (; *f; f++) for (; *f; f++)
{ {
if (*f != '%') if (*f != '%')
{ {
/* then just out the char */ /* then just out the char */
(*addchar)((int) (((unsigned char) *f) | attributes)); (*addchar)((int) (((unsigned char) *f) | attributes));
} }
else else
{ {
f++; /* skip the % */ f++; /* skip the % */
if (*f == '-') if (*f == '-')
{ /* minus: flush left */ { /* minus: flush left */
flush_left = 1; flush_left = 1;
f++; f++;
} }
if (*f == '0' || *f == '.') if (*f == '0' || *f == '.')
{ {
/* padding with 0 rather than blank */ /* padding with 0 rather than blank */
pad = '0'; pad = '0';
f++; f++;
} }
if (*f == '*') if (*f == '*')
{ {
/* field width */ /* field width */
f_width = va_arg(ap, int); f_width = va_arg(ap, int);
f++; f++;
} }
else if (isdigit((unsigned char)*f)) else if (isdigit((unsigned char)*f))
{ {
f_width = atoi(f); f_width = atoi(f);
while (isdigit((unsigned char)*f)) while (isdigit((unsigned char)*f))
f++; /* skip the digits */ f++; /* skip the digits */
} }
if (*f == '.') if (*f == '.')
{ /* precision */ { /* precision */
f++; f++;
if (*f == '*') if (*f == '*')
{ {
prec = va_arg(ap, int); prec = va_arg(ap, int);
f++; f++;
} }
else if (isdigit((unsigned char)*f)) else if (isdigit((unsigned char)*f))
{ {
prec = atoi(f); prec = atoi(f);
while (isdigit((unsigned char)*f)) while (isdigit((unsigned char)*f))
f++; /* skip the digits */ f++; /* skip the digits */
} }
} }
if (*f == '#') if (*f == '#')
{ /* alternate form */ { /* alternate form */
hash = 1; hash = 1;
f++; f++;
} }
if (*f == 'l') if (*f == 'l')
{ /* long format */ { /* long format */
do_long++; do_long++;
f++; f++;
if (*f == 'l') if (*f == 'l')
{ {
do_long++; do_long++;
f++; f++;
} }
} }
fmt = (unsigned char) *f; fmt = (unsigned char) *f;
if (fmt != 'S' && fmt != 'Q' && isupper(fmt)) if (fmt != 'S' && fmt != 'Q' && isupper(fmt))
{ {
do_long = 1; do_long = 1;
fmt = tolower(fmt); fmt = tolower(fmt);
} }
bp = buf; bp = buf;
switch (fmt) switch (fmt)
{ /* do the format */ { /* do the format */
case 'd': case 'd':
switch (do_long) switch (do_long)
{ {
case 0: case 0:
l = (long) (va_arg(ap, int)); l = (long) (va_arg(ap, int));
break; break;
case 1: case 1:
default: default:
l = va_arg(ap, long); l = va_arg(ap, long);
break; break;
} }
if (l < 0) if (l < 0)
{ {
sign = 1; sign = 1;
l = -l; l = -l;
} }
do do
{ {
*bp++ = (char) (l % 10) + '0'; *bp++ = (char) (l % 10) + '0';
} while ((l /= 10) > 0); } while ((l /= 10) > 0);
if (sign) if (sign)
*bp++ = '-'; *bp++ = '-';
f_width = f_width - (int) (bp - buf); f_width = f_width - (int) (bp - buf);
if (!flush_left) if (!flush_left)
while (f_width-- > 0) while (f_width-- > 0)
(*addchar)((int) (pad | attributes)); (*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--) for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes)); (*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left) if (flush_left)
while (f_width-- > 0) while (f_width-- > 0)
(*addchar)((int) (' ' | attributes)); (*addchar)((int) (' ' | attributes));
break; break;
case 'f': case 'f':
/* this is actually more than stupid, but does work for now */ /* this is actually more than stupid, but does work for now */
@@ -242,179 +242,179 @@ static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap)
} }
break; break;
case 'p': case 'p':
do_long = 1; do_long = 1;
hash = 1; hash = 1;
fmt = 'x'; fmt = 'x';
/* no break */ /* no break */
case 'o': case 'o':
case 'x': case 'x':
case 'u': case 'u':
switch (do_long) switch (do_long)
{ {
case 0: case 0:
u = (unsigned long) (va_arg(ap, unsigned int)); u = (unsigned long) (va_arg(ap, unsigned int));
break; break;
case 1: case 1:
default: default:
u = va_arg(ap, unsigned long); u = va_arg(ap, unsigned long);
break; break;
} }
if (fmt == 'u') if (fmt == 'u')
{ /* unsigned decimal */ { /* unsigned decimal */
do do
{ {
*bp++ = (char) (u % 10) + '0'; *bp++ = (char) (u % 10) + '0';
} while ((u /= 10) > 0); } while ((u /= 10) > 0);
} }
else if (fmt == 'o') else if (fmt == 'o')
{ /* octal */ { /* octal */
do do
{ {
*bp++ = (char) (u % 8) + '0'; *bp++ = (char) (u % 8) + '0';
} while ((u /= 8) > 0); } while ((u /= 8) > 0);
if (hash) if (hash)
*bp++ = '0'; *bp++ = '0';
} }
else if (fmt == 'x') else if (fmt == 'x')
{ /* hex */ { /* hex */
do do
{ {
i = (int) (u % 16); i = (int) (u % 16);
if (i < 10) if (i < 10)
*bp++ = i + '0'; *bp++ = i + '0';
else else
*bp++ = i - 10 + 'a'; *bp++ = i - 10 + 'a';
} while ((u /= 16) > 0); } while ((u /= 16) > 0);
if (hash) if (hash)
{ {
*bp++ = 'x'; *bp++ = 'x';
*bp++ = '0'; *bp++ = '0';
} }
} }
i = f_width - (int) (bp - buf); i = f_width - (int) (bp - buf);
if (!flush_left) if (!flush_left)
while (i-- > 0) while (i-- > 0)
(*addchar)((int) (pad | attributes)); (*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--) for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes)); (*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left) if (flush_left)
while (i-- > 0) while (i-- > 0)
(*addchar)((int) (' ' | attributes)); (*addchar)((int) (' ' | attributes));
break; break;
case 'c': case 'c':
i = va_arg(ap, int); i = va_arg(ap, int);
(*addchar)((int) (i | attributes)); (*addchar)((int) (i | attributes));
break; break;
case 'S': case 'S':
case 'Q': case 'Q':
case 's': case 's':
case 'q': case 'q':
bp = va_arg(ap, char *); bp = va_arg(ap, char *);
if (!bp) if (!bp)
bp = snil; bp = snil;
f_width = f_width - strlen((char *) bp); f_width = f_width - strlen((char *) bp);
if (!flush_left) if (!flush_left)
while (f_width-- > 0) while (f_width-- > 0)
(*addchar)((int) (pad | attributes)); (*addchar)((int) (pad | attributes));
for (i = 0; *bp && i < prec; i++) for (i = 0; *bp && i < prec; i++)
{ {
if (fmt == 'q' && (*bp & QUOTE)) if (fmt == 'q' && (*bp & QUOTE))
(*addchar)((int) ('\\' | attributes)); (*addchar)((int) ('\\' | attributes));
(*addchar)( (*addchar)(
(int) (((unsigned char) *bp & TRIM) | attributes)); (int) (((unsigned char) *bp & TRIM) | attributes));
bp++; bp++;
} }
if (flush_left) if (flush_left)
while (f_width-- > 0) while (f_width-- > 0)
(*addchar)((int) (' ' | attributes)); (*addchar)((int) (' ' | attributes));
break; break;
case 'a': case 'a':
attributes = va_arg(ap, int); attributes = va_arg(ap, int);
break; break;
case '%': case '%':
(*addchar)((int) ('%' | attributes)); (*addchar)((int) ('%' | attributes));
break; break;
default: default:
break; break;
} }
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
sign = 0; sign = 0;
pad = ' '; pad = ' ';
} }
} }
} }
static char *xstring, *xestring; static char *xstring, *xestring;
void xaddchar(int c) void xaddchar(int c)
{ {
if (xestring == xstring) if (xestring == xstring)
*xstring = '\0'; *xstring = '\0';
else else
*xstring++ = (char) c; *xstring++ = (char) c;
} }
int sprintf(char *str, const char *format, ...) int sprintf(char *str, const char *format, ...)
{ {
va_list va; va_list va;
va_start(va, format); va_start(va, format);
xstring = str; xstring = str;
doprnt(xaddchar, format, va); doprnt(xaddchar, format, va);
va_end(va); va_end(va);
*xstring++ = '\0'; *xstring++ = '\0';
return 0; return 0;
} }
void xsnprintf(char *str, size_t size, const char *fmt, ...) void xsnprintf(char *str, size_t size, const char *fmt, ...)
{ {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
xstring = str; xstring = str;
xestring = str + size - 1; xestring = str + size - 1;
doprnt(xaddchar, fmt, va); doprnt(xaddchar, fmt, va);
va_end(va); va_end(va);
*xstring++ = '\0'; *xstring++ = '\0';
} }
void xprintf(const char *fmt, ...) void xprintf(const char *fmt, ...)
{ {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
doprnt(xputchar, fmt, va); doprnt(xputchar, fmt, va);
va_end(va); va_end(va);
} }
void xvprintf(const char *fmt, va_list va) void xvprintf(const char *fmt, va_list va)
{ {
doprnt(xputchar, fmt, va); doprnt(xputchar, fmt, va);
} }
void xvsnprintf(char *str, size_t size, const char *fmt, va_list va) void xvsnprintf(char *str, size_t size, const char *fmt, va_list va)
{ {
xstring = str; xstring = str;
xestring = str + size - 1; xestring = str + size - 1;
doprnt(xaddchar, fmt, va); doprnt(xaddchar, fmt, va);
*xstring++ = '\0'; *xstring++ = '\0';
} }
void display_progress() void display_progress()
{ {
static int _progress_index; static int _progress_index;
char progress_char[] = "|/-\\"; char progress_char[] = "|/-\\";
xputchar(progress_char[_progress_index++ % strlen(progress_char)]); xputchar(progress_char[_progress_index++ % strlen(progress_char)]);
xputchar('\r'); xputchar('\r');
} }
void hexdump(uint8_t buffer[], int size) void hexdump(uint8_t buffer[], int size)
@@ -426,7 +426,7 @@ void hexdump(uint8_t buffer[], int size)
while (bp < buffer + size) { while (bp < buffer + size) {
uint8_t *lbp = bp; uint8_t *lbp = bp;
xprintf("%08x ", line); xprintf("%08x ", bp);
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (bp + i > buffer + size) { if (bp + i > buffer + size) {

View File

@@ -7,12 +7,13 @@
#include "fb.h" #include "fb.h"
#include "radeonfb.h" #include "radeonfb.h"
//#define DBG_VIDEO #define DBG_VIDEO
#ifdef DBG_VIDEO #ifdef DBG_VIDEO
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG (%s()): " format, __FUNCTION__, ##arg);} while(0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do {;} while (0)
#endif /* DBG_VIDEO */ #endif /* DBG_VIDEO */
#define err(format, arg...) do { xprintf("ERROR (%s()): " format, __FUNCTION__, ##arg); } while(0)
#ifdef _USE_VIDEL_ #ifdef _USE_VIDEL_
#define MON_ALL -1 /* code used in VMODE_ENTRY for match on mode only */ #define MON_ALL -1 /* code used in VMODE_ENTRY for match on mode only */
@@ -206,9 +207,9 @@ int16_t current_video_mode;
static void setphys(int32_t addr,int checkaddr) static void setphys(int32_t addr,int checkaddr)
{ {
*(volatile uint8_t *) VIDEOBASE_ADDR_HI = ((uint32_t) addr) >> 16; *(volatile uint8_t *) VIDEOBASE_ADDR_HI = ((uint32_t) addr) >> 16;
*(volatile uint8_t *) VIDEOBASE_ADDR_MID = ((uint32_t) addr) >> 8; *(volatile uint8_t *) VIDEOBASE_ADDR_MID = ((uint32_t) addr) >> 8;
*(volatile uint8_t *) VIDEOBASE_ADDR_LOW = ((uint32_t) addr); *(volatile uint8_t *) VIDEOBASE_ADDR_LOW = ((uint32_t) addr);
} }
/* /*
@@ -219,57 +220,57 @@ static void setphys(int32_t addr,int checkaddr)
void videl_screen_init(void) void videl_screen_init(void)
{ {
uint32_t screen_start; uint32_t screen_start;
uint16_t boot_resolution = FALCON_DEFAULT_BOOT; uint16_t boot_resolution = FALCON_DEFAULT_BOOT;
int16_t monitor_type, sync_mode; int16_t monitor_type, sync_mode;
int16_t rez = 0; /* avoid 'may be uninitialized' warning */ int16_t rez = 0; /* avoid 'may be uninitialized' warning */
/* Initialize the interrupt handlers. /* Initialize the interrupt handlers.
* It is important to do this first because the initialization code below * It is important to do this first because the initialization code below
* may call vsync(), which temporarily enables the interrupts. */ * may call vsync(), which temporarily enables the interrupts. */
/* TODO: VEC_HBL = int_hbl; */ /* TODO: VEC_HBL = int_hbl; */
/* TODO: VEC_VBL = int_vbl; */ /* TODO: VEC_VBL = int_vbl; */
/* /*
* first, see what we're connected to, and set the * first, see what we're connected to, and set the
* resolution / video mode appropriately * resolution / video mode appropriately
*/ */
monitor_type = MON_COLOR; monitor_type = MON_COLOR;
xprintf("monitor_type = %d\r\n", monitor_type); xprintf("monitor_type = %d\r\n", monitor_type);
/* reset VIDEL on boot-up */ /* reset VIDEL on boot-up */
/* first set the physbase to a safe memory */ /* first set the physbase to a safe memory */
setphys(0xd00000, 0); setphys(0xd00000, 0);
if (!lookup_videl_mode(boot_resolution, monitor_type)) { /* mode isn't in table */ if (!lookup_videl_mode(boot_resolution, monitor_type)) { /* mode isn't in table */
xprintf("Invalid video mode 0x%04x changed to 0x%04x\r\n", xprintf("Invalid video mode 0x%04x changed to 0x%04x\r\n",
boot_resolution, FALCON_DEFAULT_BOOT); boot_resolution, FALCON_DEFAULT_BOOT);
boot_resolution = FALCON_DEFAULT_BOOT; /* so pick one that is */ boot_resolution = FALCON_DEFAULT_BOOT; /* so pick one that is */
} }
if (!VALID_VDI_BPP(boot_resolution)) { /* mustn't confuse VDI */ if (!VALID_VDI_BPP(boot_resolution)) { /* mustn't confuse VDI */
xprintf("VDI doesn't support video mode 0x%04x, changed to 0x%04x\r\n", xprintf("VDI doesn't support video mode 0x%04x, changed to 0x%04x\r\n",
boot_resolution, FALCON_DEFAULT_BOOT); boot_resolution, FALCON_DEFAULT_BOOT);
boot_resolution = FALCON_DEFAULT_BOOT; /* so use default */ boot_resolution = FALCON_DEFAULT_BOOT; /* so use default */
} }
vsetmode(boot_resolution); vsetmode(boot_resolution);
rez = FALCON_REZ; /* fake value indicates Falcon/Videl */ rez = FALCON_REZ; /* fake value indicates Falcon/Videl */
sync_mode = (boot_resolution & VIDEL_PAL) ? 0x02 : 0x00; sync_mode = (boot_resolution & VIDEL_PAL) ? 0x02 : 0x00;
*(volatile uint8_t *) SYNCMODE = sync_mode; *(volatile uint8_t *) SYNCMODE = sync_mode;
/* /*
* next, set up the palette(s) * next, set up the palette(s)
*/ */
initialise_palette_registers(rez, boot_resolution); initialise_palette_registers(rez, boot_resolution);
/* FIXME: sshiftmod = rez; */ /* FIXME: sshiftmod = rez; */
/* videoram is placed just below the phystop */ /* videoram is placed just below the phystop */
screen_start = 0xd00000; screen_start = 0xd00000;
/* correct physical address */ /* correct physical address */
setphys(screen_start, 1); setphys(screen_start, 1);
} }
#endif /* _USE_VIDEL_ */ #endif /* _USE_VIDEL_ */
@@ -280,20 +281,20 @@ struct fb_info *info_fb = &fb;
const char monitor_layout[1024] = "CRT,CRT"; const char monitor_layout[1024] = "CRT,CRT";
int16_t ignore_edid; int16_t ignore_edid;
struct mode_option resolution = struct mode_option resolution =
{ {
.used = 0, .used = 0,
.width = 640, .width = 640,
.height = 480, .height = 480,
.bpp = 8, .bpp = 8,
.freq = 60, .freq = 60,
.flags = 0 .flags = 0
}; };
int16_t force_measure_pll; int16_t force_measure_pll;
void install_vbl_timer(void *func, int remove) void install_vbl_timer(void *func, int remove)
{ {
dbg("%s: not implemented\r\n", __FUNCTION__); dbg("not implemented\r\n");
} }
/* /*
@@ -301,58 +302,63 @@ void install_vbl_timer(void *func, int remove)
*/ */
void video_init(void) void video_init(void)
{ {
/* /*
* detect PCI video card * detect PCI video card
*/ */
int index = 0;
int32_t handle;
struct pci_device_id *board;
int32_t id;
bool radeon_found = false;
dbg("%s\r\n", __FUNCTION__);
do
{
/*
* scan PCI bus for graphics cards
*/
handle = pci_find_classcode(PCI_BASE_CLASS_DISPLAY | PCI_FIND_BASE_CLASS, index);
if (handle > 0) /* found a display device */
{
dbg("%s: handle = 0x%x\r\n", __FUNCTION__, handle);
id = swpl(pci_read_config_longword(handle, PCIIDR)); /* get vendor + device id */ int index = 0;
dbg("%s: PCIIDR=0x%x\r\n", __FUNCTION__, id); int32_t handle;
struct pci_device_id *board;
int32_t id;
bool radeon_found = false;
board = &radeonfb_pci_table[0]; dbg("\r\n");
do /* FIXME: we currently just return here because the PCI configuration of ATI cards does not (yet) work */
{ return;
/* check it against elements of table */
dbg("%s: check %x %x against %08x\r\n", __FUNCTION__, board->device, board->vendor, id);
if ((board->device == (id >> 16)) && (board->vendor == (id & 0xffff)))
{
radeon_found = true;
dbg("%s: matched\r\n", __FUNCTION__); do
if (radeonfb_pci_register(handle, board) >= 0) {
{ /*
xprintf("RADEON video card found and registered\r\n"); * scan PCI bus for graphics cards
} */
else handle = pci_find_classcode(PCI_BASE_CLASS_DISPLAY | PCI_FIND_BASE_CLASS, index);
{ dbg("handle=%d\r\n", handle);
dbg("%s: failed to register RADEON PCI video card\r\n", __FUNCTION__); if (handle > 0) /* found a display device */
} {
return; dbg("handle = 0x%x\r\n", handle);
}
board++; id = swpl(pci_read_config_longword(handle, PCIIDR)); /* get vendor + device id */
} while (board->vendor); dbg("PCIIDR=0x%x\r\n", id);
}
index++; board = &radeonfb_pci_table[0];
} while (handle > 0);
xprintf("%s: RADEON video card %sfound and %sregistered\r\n", __FUNCTION__, do
(radeon_found ? "" : "not "), (radeon_found ? "" : "not ")); {
/* check it against elements of table */
dbg("check %x %x against %08x\r\n", board->device, board->vendor, id);
if ((board->device == (id >> 16)) && (board->vendor == (id & 0xffff)))
{
radeon_found = true;
dbg("matched\r\n");
if (radeonfb_pci_register(handle, board) >= 0)
{
xprintf("RADEON video card found and registered\r\n");
}
else
{
dbg("failed to register RADEON PCI video card\r\n");
}
return;
}
board++;
} while (board->vendor);
}
index++;
} while (handle > 0);
xprintf("%s: RADEON video card %sfound and %sregistered\r\n", __FUNCTION__,
(radeon_found ? "" : "not "), (radeon_found ? "" : "not "));
} }