temporary disabled PCI interrupts

This commit is contained in:
Markus Fröschle
2015-10-03 08:31:58 +00:00
parent dc5ca12f86
commit 282b249ad8
13 changed files with 835 additions and 746 deletions

View File

@@ -1 +1,2 @@
// ADD PREDEFINED MACROS HERE! // ADD PREDEFINED MACROS HERE!
#define MACHINE_FIREBEE

View File

@@ -37,25 +37,19 @@ endif
INCLUDE=-Iinclude INCLUDE=-Iinclude
CFLAGS=-mcpu=5474 \ CFLAGS=-mcpu=5474 \
-g \ -Wall \
-Wall \ -fomit-frame-pointer \
-fomit-frame-pointer \ -ffreestanding \
-ffreestanding \ -fleading-underscore \
-fleading-underscore \ -Wa,--register-prefix-optional
-mno-strict-align \
-Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \ CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \ -Wall \
-O2 \ -O2 \
-ffixed-a3 \
-ffixed-a4 \
-ffixed-a5 \
-g \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffreestanding \ -ffreestanding \
-fleading-underscore \ -fleading-underscore \
-Wa,--register-prefix-optional -Wa,--register-prefix-optional
LDFLAGS=-g LDFLAGS=
TRGTDIRS= ./firebee ./m5484lite ./m54455 TRGTDIRS= ./firebee ./m5484lite ./m54455
OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS)) OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS))
@@ -94,7 +88,7 @@ CSRCS= \
s19reader.c \ s19reader.c \
flash.c \ flash.c \
dma.c \ dma.c \
i2c.c \ i2c.c \
xhdi_sd.c \ xhdi_sd.c \
xhdi_interface.c \ xhdi_interface.c \
pci.c \ pci.c \
@@ -212,17 +206,6 @@ define CC_TEMPLATE
#MACHINE=MACHINE_M5484LITE #MACHINE=MACHINE_M5484LITE
#endif #endif
# always optimize x86 emulator objects
#$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/%.o:%.c $(1)/objs/%.o:%.c
$(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@ $(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@

View File

@@ -646,8 +646,8 @@ void *dma_memcpy(void *dst, void *src, size_t n)
#ifdef DBG_DMA #ifdef DBG_DMA
end = MCF_SLT0_SCNT; end = MCF_SLT0_SCNT;
time = (start - end) / (SYSCLK / 1000) / 1000; time = (start - end) / (SYSCLK / 1000) / 1000;
#endif /* DBG_DMA */
dbg("took %d ms (%f Mbytes/second)\r\n", time, n / (float) time / 1000.0); dbg("took %d ms (%f Mbytes/second)\r\n", time, n / (float) time / 1000.0);
#endif /* DBG_DMA */
return dst; return dst;
} }

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
@@ -132,7 +132,7 @@ static inline __attribute__((aligned(16))) void chip_errata_135(void)
" tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t"
" tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t"
" tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t"
::: "memory"); ::: "d0", "memory");
} }
static inline void chip_errata_055(int32_t handle) static inline void chip_errata_055(int32_t handle)
@@ -242,7 +242,7 @@ static char *device_class(int classcode)
return pci_classes[i].description; return pci_classes[i].description;
} }
} }
return "not found"; return "unknown device class";
} }
/* /*
@@ -298,11 +298,6 @@ static int pci_check_status(void)
ret = 1; ret = 1;
} }
if (!ret)
{
dbg("no error\r\n");
}
return ret; return ret;
} }
@@ -331,7 +326,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;
} }
@@ -544,7 +539,7 @@ int32_t pci_find_device(uint16_t device_id, uint16_t vendor_id, int index)
if (value != 0xffffffff) /* device found */ if (value != 0xffffffff) /* device found */
{ {
if (vendor_id == 0xffff || if (vendor_id == 0xffff ||
(PCI_VENDOR_ID(value) == vendor_id && PCI_DEVICE_ID(value) == device_id)) ((PCI_VENDOR_ID(value) == vendor_id) && (PCI_DEVICE_ID(value) == device_id)))
{ {
if (n == index) if (n == index)
{ {
@@ -648,7 +643,7 @@ int32_t pci_hook_interrupt(int32_t handle, void *handler, void *parameter)
{ {
int i; int i;
pci_interrupt_handler h = handler; // pci_interrupt_handler h = handler;
/* /*
* find empty slot * find empty slot
@@ -1072,6 +1067,7 @@ void pci_scan(void)
uint32_t value; uint32_t value;
value = pci_read_config_longword(handle, PCIIDR); value = pci_read_config_longword(handle, PCIIDR);
xprintf(" %02x | %02x | %02x |%04x|%04x|%04x| %s (0x%02x)\r\n", xprintf(" %02x | %02x | %02x |%04x|%04x|%04x| %s (0x%02x)\r\n",
PCI_BUS_FROM_HANDLE(handle), PCI_BUS_FROM_HANDLE(handle),
PCI_DEVICE_FROM_HANDLE(handle), PCI_DEVICE_FROM_HANDLE(handle),
@@ -1083,6 +1079,7 @@ void pci_scan(void)
/* save handle to index value so that we'll be able to later find our resources */ /* save handle to index value so that we'll be able to later find our resources */
handles[index] = handle; handles[index] = handle;
if (PCI_VENDOR_ID(value) != 0x1057 && PCI_DEVICE_ID(value) != 0x5806) /* do not configure bridge */ if (PCI_VENDOR_ID(value) != 0x1057 && PCI_DEVICE_ID(value) != 0x5806) /* do not configure bridge */
{ {
/* configure memory and I/O for card */ /* configure memory and I/O for card */
@@ -1116,6 +1113,7 @@ void init_eport(void)
MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_FALLING) | MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_FALLING) |
MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_FALLING) | MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_FALLING) |
MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_FALLING); MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_FALLING);
MCF_EPORT_EPDDR = 0; /* clear data direction register. All pins as input */ MCF_EPORT_EPDDR = 0; /* clear data direction register. All pins as input */
MCF_EPORT_EPFR = -1; /* clear all EPORT interrupt flags */ MCF_EPORT_EPFR = -1; /* clear all EPORT interrupt flags */
MCF_EPORT_EPIER = 0xfe; /* enable all EPORT interrupts (for now) */ MCF_EPORT_EPIER = 0xfe; /* enable all EPORT interrupts (for now) */
@@ -1172,7 +1170,7 @@ void init_pci(void)
init_eport(); init_eport();
init_xlbus_arbiter(); init_xlbus_arbiter();
MCF_PCI_PCIGSCR = 1; /* reset PCI */ MCF_PCI_PCIGSCR = -1;
/* /*
* setup the PCI arbiter * setup the PCI arbiter
@@ -1198,11 +1196,11 @@ void init_pci(void)
MCF_PAD_PAR_PCIBR = 0x3ff; MCF_PAD_PAR_PCIBR = 0x3ff;
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_PCI_PCISCR = MCF_PCI_PCISCR_M | /* memory access control enabled */ MCF_PCI_PCISCR = MCF_PCI_PCISCR_M | /* memory access control enabled */
MCF_PCI_PCISCR_B | /* bus master enabled */ MCF_PCI_PCISCR_B | /* bus master enabled */
MCF_PCI_PCISCR_M | /* mem access enable */ MCF_PCI_PCISCR_M | /* mem access enable */
MCF_PCI_PCISCR_MA | /* clear master abort error */ MCF_PCI_PCISCR_MA | /* clear master abort error */
MCF_PCI_PCISCR_MW; /* memory write and invalidate enabled */ MCF_PCI_PCISCR_MW; /* memory write and invalidate enabled */
/* Setup burst parameters */ /* Setup burst parameters */

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,75 @@ 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 +273,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 +285,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, 5, 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

@@ -27,7 +27,7 @@
#error "unknown machine!" #error "unknown machine!"
#endif #endif
//#define DBG_DM #define DBG_DM
#ifdef DBG_DM #ifdef DBG_DM
#define dbg(fmt, args...) xprintf(fmt, ##args) #define dbg(fmt, args...) xprintf(fmt, ##args)
#else #else

View File

@@ -6,11 +6,11 @@
.equ MCF_MMU_MMUCR, __MMUBAR + 0 .equ MCF_MMU_MMUCR, __MMUBAR + 0
.global _rom_header .globl _rom_header
.global _rom_entry .globl _rom_entry
.extern _initialize_hardware .extern _initialize_hardware
.extern _rt_mbar .extern _rt_mbar
/* ROM header */ /* ROM header */
_rom_header: _rom_header:
@@ -26,7 +26,7 @@ _rom_header:
/* ROM entry point */ /* ROM entry point */
_rom_entry: _rom_entry:
/* disable interrupts */ /* disable interrupts */
move.w #0x2700,SR move.w #0x2700,sr
/* Initialize MBAR */ /* Initialize MBAR */
move.l #__MBAR,d0 move.l #__MBAR,d0

View File

@@ -46,8 +46,6 @@
#else #else
#error "unknown machine" #error "unknown machine"
#endif /* MACHINE_M5484LITE */ #endif /* MACHINE_M5484LITE */
#
#include "dma.h" #include "dma.h"
#include "mod_devicetable.h" #include "mod_devicetable.h"
#include "pci_ids.h" #include "pci_ids.h"
@@ -70,7 +68,7 @@ extern volatile long _VRAM; /* start address of video ram from linker script */
* BYT3 = 7.576ns/tick = 132.00MHz offset 3 * BYT3 = 7.576ns/tick = 132.00MHz offset 3
* count down!!! 132MHz!!! * count down!!! 132MHz!!!
*/ */
void init_slt(void) static void init_slt(void)
{ {
xprintf("slice timer initialization: "); xprintf("slice timer initialization: ");
MCF_SLT0_STCNT = 0xffffffff; MCF_SLT0_STCNT = 0xffffffff;
@@ -81,7 +79,7 @@ void init_slt(void)
/* /*
* init GPIO general purpose I/O module * init GPIO general purpose I/O module
*/ */
void init_gpio(void) static void init_gpio(void)
{ {
/* /*
* pad register P.S.:FBCTL and FBCS set correctly at reset * pad register P.S.:FBCTL and FBCS set correctly at reset
@@ -214,7 +212,7 @@ void init_gpio(void)
/* /*
* init serial * init serial
*/ */
void init_serial(void) static void init_serial(void)
{ {
/* PSC0: SER1 */ /* PSC0: SER1 */
MCF_PSC0_PSCSICR = 0; /* PSC control register: select UART mode */ MCF_PSC0_PSCSICR = 0; /* PSC control register: select UART mode */
@@ -276,7 +274,7 @@ void init_serial(void)
/********************************************************************/ /********************************************************************/
/* Initialize DDR DIMMs on the EVB board */ /* Initialize DDR DIMMs on the EVB board */
/********************************************************************/ /********************************************************************/
bool init_ddram(void) static bool init_ddram(void)
{ {
xprintf("SDRAM controller initialization: "); xprintf("SDRAM controller initialization: ");
@@ -401,43 +399,46 @@ bool init_ddram(void)
/* /*
* initialize FlexBus chip select registers * initialize FlexBus chip select registers
*/ */
void init_fbcs() static void init_fbcs()
{ {
xprintf("FlexBus chip select registers initialization: "); xprintf("FlexBus chip select registers initialization: ");
/* Flash */ /* Flash */
MCF_FBCS0_CSAR = MCF_FBCS_CSAR_BA(BOOTFLASH_BASE_ADDRESS); /* flash base address */ MCF_FBCS0_CSAR = MCF_FBCS_CSAR_BA(BOOTFLASH_BASE_ADDRESS); /* flash base address */
MCF_FBCS0_CSCR = MCF_FBCS_CSCR_PS_16 | /* 16 bit word access */ MCF_FBCS0_CSCR = MCF_FBCS_CSCR_PS_16 | /* 16 bit word access */
MCF_FBCS_CSCR_WS(6)| /* 6 Waitstates */ MCF_FBCS_CSCR_WS(8)| /* 6 wait states */
MCF_FBCS_CSCR_AA | MCF_FBCS_CSCR_AA | /* auto /TA acknowledge */
MCF_FBCS_CSCR_ASET(1) | MCF_FBCS_CSCR_ASET(1) | /* assert chip select on second rising edge after address assertion */
MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */ MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */
MCF_FBCS0_CSMR = BOOTFLASH_BAM | MCF_FBCS0_CSMR = BOOTFLASH_BAM |
MCF_FBCS_CSMR_V; /* enable */ MCF_FBCS_CSMR_V; /* enable */
#if defined(MACHINE_FIREBEE) /* FBC setup for FireBee */ #if defined(MACHINE_FIREBEE) /* FBC setup for FireBee */
MCF_FBCS1_CSAR = MCF_FBCS_CSAR_BA(0xFFF00000); /* ATARI I/O ADRESS */ MCF_FBCS1_CSAR = MCF_FBCS_CSAR_BA(0xFFF00000); /* ATARI I/O address range */
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */ MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */ | MCF_FBCS_CSCR_WS(32) /* 8 wait states */
| MCF_FBCS_CSCR_AA; /* AA */ | MCF_FBCS_CSCR_AA; /* auto /TA acknowledge */
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V; MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
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(4) /* DEFAULT 4WS */ | MCF_FBCS_CSCR_WS(32) /* 4 wait states */
| MCF_FBCS_CSCR_AA; /* AA */ | MCF_FBCS_CSCR_AA; /* auto /TA acknowledge */
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);
MCF_FBCS3_CSAR = MCF_FBCS_CSAR_BA(0xF8000000); /* Firebee new I/O address range */ MCF_FBCS3_CSAR = MCF_FBCS_CSAR_BA(0xF8000000); /* Firebee new I/O address range */
MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */ MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 /* 16 bit port */
| MCF_FBCS_CSCR_AA; // AA | MCF_FBCS_CSCR_WS(32) /* 0 wait states */
| MCF_FBCS_CSCR_AA; /* auto /TA acknowledge */
MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M /* F800'0000-FBFF'FFFF */ MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M /* F800'0000-FBFF'FFFF */
| MCF_FBCS_CSMR_V); | MCF_FBCS_CSMR_V);
MCF_FBCS4_CSAR = MCF_FBCS_CSAR_BA(0x40000000); /* video ram area, FB_CS3 not used, decoded on FPGA */ MCF_FBCS4_CSAR = MCF_FBCS_CSAR_BA(0x40000000); /* video ram area, FB_CS3 not used, decoded on FPGA */
MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 /* 32BIT PORT */ MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 /* 32 bit port */
| MCF_FBCS_CSCR_WS(32) /* 0 wait states */
| MCF_FBCS_CSCR_AA /* /TA auto acknowledge */
| MCF_FBCS_CSCR_BSTR /* burst read enable */ | MCF_FBCS_CSCR_BSTR /* burst read enable */
| MCF_FBCS_CSCR_BSTW; /* burst write enable */ | MCF_FBCS_CSCR_BSTW; /* burst write enable */
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G /* 4000'0000-7FFF'FFFF */ MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G /* 4000'0000-7FFF'FFFF */
@@ -470,7 +471,8 @@ void init_fbcs()
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
void wait_pll(void) #ifdef MACHINE_FIREBEE
static void wait_pll(void)
{ {
int32_t trgt = MCF_SLT0_SCNT - 100000; int32_t trgt = MCF_SLT0_SCNT - 100000;
do do
@@ -481,12 +483,12 @@ void wait_pll(void)
static volatile uint8_t *pll_base = (volatile uint8_t *) 0xf0000600; static volatile uint8_t *pll_base = (volatile uint8_t *) 0xf0000600;
void init_pll(void) static void init_pll(void)
{ {
xprintf("FPGA PLL initialization: "); xprintf("FPGA PLL initialization: ");
wait_pll(); wait_pll();
* (volatile uint16_t *) (pll_base + 0x48) = 27; /* loopfilter r */ * (volatile uint16_t *) (pll_base + 0x48) = 27; /* loopfilter r */
wait_pll(); wait_pll();
* (volatile uint16_t *) (pll_base + 0x08) = 1; /* charge pump 1 */ * (volatile uint16_t *) (pll_base + 0x08) = 1; /* charge pump 1 */
@@ -528,13 +530,10 @@ void init_pll(void)
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
/* /*
* INIT VIDEO DDR RAM * INIT VIDEO DDR RAM
*/ */
static void init_video_ddr(void) {
void init_video_ddr(void) {
xprintf("init video RAM: "); xprintf("init video RAM: ");
* (volatile uint16_t *) 0xf0000400 = 0xb; /* set cke = 1, cs=1, config = 1 */ * (volatile uint16_t *) 0xf0000400 = 0xb; /* set cke = 1, cs=1, config = 1 */
@@ -563,10 +562,11 @@ void init_video_ddr(void) {
NOP(); NOP();
* (uint32_t *) 0xf0000400 = 0x01070002; /* fifo on, refresh on, ddrcs und cke on, video dac on */ * (uint32_t *) 0xf0000400 = 0x01070002; /* fifo on, refresh on, ddrcs und cke on, video dac on */
// * (uint32_t *) 0xf0000400 = 0x0107820b; /* fifo on, refresh on, ddrcs und cke on, video dac on */
xprintf("finished\r\n"); xprintf("finished\r\n");
} }
#endif /* MACHINE_FIREBEE */
/* /*
* probe for NEC compatible USB host controller and install if found * probe for NEC compatible USB host controller and install if found
@@ -635,6 +635,8 @@ void init_usb(void)
xprintf("finished (found %d USB controller(s))\r\n", usb_found); xprintf("finished (found %d USB controller(s))\r\n", usb_found);
} }
#ifdef MACHINE_FIREBEE
static bool i2c_transfer_finished(void) static bool i2c_transfer_finished(void)
{ {
if (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF) if (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF)
@@ -657,7 +659,7 @@ static bool i2c_bus_free(void)
/* /*
* TFP410 (DVI) on * TFP410 (DVI) on
*/ */
void dvi_on(void) static void dvi_on(void)
{ {
uint8_t receivedByte; uint8_t receivedByte;
uint8_t dummyByte; /* only used for a dummy read */ uint8_t dummyByte; /* only used for a dummy read */
@@ -806,7 +808,7 @@ try_again:
/* /*
* AC97 * AC97
*/ */
void init_ac97(void) static void init_ac97(void)
{ {
// PSC2: AC97 ---------- // PSC2: AC97 ----------
int i; int i;
@@ -900,6 +902,7 @@ livo:
MCF_PSC2_PSCTB_AC97 = 0x00000000; //last data MCF_PSC2_PSCTB_AC97 = 0x00000000; //last data
xprintf(" finished\r\n"); xprintf(" finished\r\n");
} }
#endif /* MACHINE_FIREBEE */
/* Symbols from the linker script */ /* Symbols from the linker script */
@@ -927,14 +930,14 @@ extern uint8_t _BAS_RESIDENT_TEXT[];
extern uint8_t _BAS_RESIDENT_TEXT_SIZE[]; extern uint8_t _BAS_RESIDENT_TEXT_SIZE[];
#define BAS_RESIDENT_TEXT_SIZE ((uint32_t) _BAS_RESIDENT_TEXT_SIZE) #define BAS_RESIDENT_TEXT_SIZE ((uint32_t) _BAS_RESIDENT_TEXT_SIZE)
void clear_bss_segment(void) static void clear_bss_segment(void)
{ {
extern uint8_t _BAS_BSS_START[]; extern uint8_t _BAS_BSS_START[];
uint8_t * BAS_BSS_START = &_BAS_BSS_START[0]; uint8_t * BAS_BSS_START = &_BAS_BSS_START[0];
extern uint8_t _BAS_BSS_END[]; extern uint8_t _BAS_BSS_END[];
uint8_t *BAS_BSS_END = &_BAS_BSS_END[0]; uint8_t *BAS_BSS_END = &_BAS_BSS_END[0];
bzero(BAS_BSS_START, BAS_BSS_END - BAS_BSS_START - 1); bzero(BAS_BSS_START, BAS_BSS_END - BAS_BSS_START + 1);
} }
void initialize_hardware(void) void initialize_hardware(void)
@@ -1120,13 +1123,9 @@ void initialize_hardware(void)
init_pll(); init_pll();
init_video_ddr(); init_video_ddr();
dvi_on(); dvi_on();
#endif /* MACHINE_FIREBEE */
driver_mem_init();
#if MACHINE_FIREBEE
init_ac97(); init_ac97();
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
driver_mem_init();
/* jump into the BaS */ /* jump into the BaS */
extern void BaS(void); extern void BaS(void);

View File

@@ -61,396 +61,400 @@ 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 */
flush_left = 1;
f++;
}
if (*f == '0' || *f == '.')
{
/* padding with 0 rather than blank */
pad = '0';
f++;
}
if (*f == '*')
{
/* field width */
f_width = va_arg(ap, int);
f++;
}
else if (isdigit((unsigned char)*f))
{
f_width = atoi(f);
while (isdigit((unsigned char)*f))
f++; /* skip the digits */
}
if (*f == '.')
{ /* precision */
f++;
if (*f == '*')
{
prec = va_arg(ap, int);
f++;
}
else if (isdigit((unsigned char)*f))
{
prec = atoi(f);
while (isdigit((unsigned char)*f))
f++; /* skip the digits */
}
}
if (*f == '#')
{ /* alternate form */
hash = 1;
f++;
}
if (*f == 'l')
{ /* long format */
do_long++;
f++;
if (*f == 'l')
{
do_long++;
f++;
}
}
fmt = (unsigned char) *f;
if (fmt != 'S' && fmt != 'Q' && isupper(fmt))
{
do_long = 1;
fmt = tolower(fmt);
}
bp = buf;
switch (fmt)
{ /* do the format */
case 'd':
switch (do_long)
{
case 0:
l = (long) (va_arg(ap, int));
break;
case 1:
default:
l = va_arg(ap, long);
break;
}
if (l < 0)
{
sign = 1;
l = -l;
}
do
{
*bp++ = (char) (l % 10) + '0';
} while ((l /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (int) (bp - buf);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'f':
/* this is actually more than stupid, but does work for now */
flt = (float) (va_arg(ap, double)); /* beware: va_arg() extends float to double! */
if (flt < 0)
{ {
sign = 1; /* minus: flush left */
flt = -flt; flush_left = 1;
f++;
} }
if (*f == '0' || *f == '.')
{ {
int quotient, remainder; /* padding with 0 rather than blank */
pad = '0';
quotient = (int) flt; f++;
remainder = (flt - quotient) * 10E5;
for (i = 0; i < 6; i++)
{
*bp++ = (char) (remainder % 10) + '0';
remainder /= 10;
}
*bp++ = '.';
do
{
*bp++ = (char) (quotient % 10) + '0';
} while ((quotient /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (int) (bp - buf);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
} }
break; if (*f == '*')
{
/* field width */
case 'p': f_width = va_arg(ap, int);
do_long = 1; f++;
hash = 1; }
fmt = 'x'; else if (isdigit((unsigned char) *f))
/* no break */ {
case 'o': f_width = atoi(f);
case 'x': while (isdigit((unsigned char) *f))
case 'u': f++; /* skip the digits */
switch (do_long) }
{
case 0:
u = (unsigned long) (va_arg(ap, unsigned int));
break;
case 1:
default:
u = va_arg(ap, unsigned long);
break;
}
if (fmt == 'u')
{ /* unsigned decimal */
do
{
*bp++ = (char) (u % 10) + '0';
} while ((u /= 10) > 0);
}
else if (fmt == 'o')
{ /* octal */
do
{
*bp++ = (char) (u % 8) + '0';
} while ((u /= 8) > 0);
if (hash)
*bp++ = '0';
}
else if (fmt == 'x')
{ /* hex */
do
{
i = (int) (u % 16);
if (i < 10)
*bp++ = i + '0';
else
*bp++ = i - 10 + 'a';
} while ((u /= 16) > 0);
if (hash)
{
*bp++ = 'x';
*bp++ = '0';
}
}
i = f_width - (int) (bp - buf);
if (!flush_left)
while (i-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (i-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'c': if (*f == '.')
i = va_arg(ap, int); { /* precision */
(*addchar)((int) (i | attributes)); f++;
break; if (*f == '*')
{
prec = va_arg(ap, int);
f++;
}
else if (isdigit((unsigned char)*f))
{
prec = atoi(f);
while (isdigit((unsigned char)*f))
f++; /* skip the digits */
}
}
case 'S': if (*f == '#')
case 'Q': { /* alternate form */
case 's': hash = 1;
case 'q': f++;
bp = va_arg(ap, char *); }
if (!bp)
bp = snil;
f_width = f_width - strlen((char *) bp);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (i = 0; *bp && i < prec; i++)
{
if (fmt == 'q' && (*bp & QUOTE))
(*addchar)((int) ('\\' | attributes));
(*addchar)(
(int) (((unsigned char) *bp & TRIM) | attributes));
bp++;
}
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'a': if (*f == 'l')
attributes = va_arg(ap, int); { /* long format */
break; do_long++;
f++;
if (*f == 'l')
{
do_long++;
f++;
}
}
case '%': fmt = (unsigned char) *f;
(*addchar)((int) ('%' | attributes)); if (fmt != 'S' && fmt != 'Q' && isupper(fmt))
break; {
do_long = 1;
fmt = tolower(fmt);
}
bp = buf;
switch (fmt)
{ /* do the format */
case 'd':
switch (do_long)
{
case 0:
l = (long) (va_arg(ap, int));
break;
case 1:
default:
l = va_arg(ap, long);
break;
}
default: if (l < 0)
break; {
} sign = 1;
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0; l = -l;
sign = 0; }
pad = ' '; do
} {
} *bp++ = (char) (l % 10) + '0';
} while ((l /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (int) (bp - buf);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'f':
/* this is actually more than stupid, but does work for now */
flt = (float) (va_arg(ap, double)); /* beware: va_arg() extends float to double! */
if (flt < 0)
{
sign = 1;
flt = -flt;
}
{
int quotient, remainder;
quotient = (int) flt;
remainder = (flt - quotient) * 10E5;
for (i = 0; i < 6; i++)
{
*bp++ = (char) (remainder % 10) + '0';
remainder /= 10;
}
*bp++ = '.';
do
{
*bp++ = (char) (quotient % 10) + '0';
} while ((quotient /= 10) > 0);
if (sign)
*bp++ = '-';
f_width = f_width - (int) (bp - buf);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
}
break;
case 'p':
do_long = 1;
hash = 1;
fmt = 'x';
/* no break */
case 'o':
case 'x':
case 'u':
switch (do_long)
{
case 0:
u = (unsigned long) (va_arg(ap, unsigned int));
break;
case 1:
default:
u = va_arg(ap, unsigned long);
break;
}
if (fmt == 'u')
{ /* unsigned decimal */
do
{
*bp++ = (char) (u % 10) + '0';
} while ((u /= 10) > 0);
}
else if (fmt == 'o')
{ /* octal */
do
{
*bp++ = (char) (u % 8) + '0';
} while ((u /= 8) > 0);
if (hash)
*bp++ = '0';
}
else if (fmt == 'x')
{ /* hex */
do
{
i = (int) (u % 16);
if (i < 10)
*bp++ = i + '0';
else
*bp++ = i - 10 + 'a';
} while ((u /= 16) > 0);
if (hash)
{
*bp++ = 'x';
*bp++ = '0';
}
}
i = f_width - (int) (bp - buf);
if (!flush_left)
while (i-- > 0)
(*addchar)((int) (pad | attributes));
for (bp--; bp >= buf; bp--)
(*addchar)((int) (((unsigned char) *bp) | attributes));
if (flush_left)
while (i-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'c':
i = va_arg(ap, int);
(*addchar)((int) (i | attributes));
break;
case 'S':
case 'Q':
case 's':
case 'q':
bp = va_arg(ap, char *);
if (!bp)
bp = snil;
f_width = f_width - strlen((char *) bp);
if (!flush_left)
while (f_width-- > 0)
(*addchar)((int) (pad | attributes));
for (i = 0; *bp && i < prec; i++)
{
if (fmt == 'q' && (*bp & QUOTE))
(*addchar)((int) ('\\' | attributes));
(*addchar)(
(int) (((unsigned char) *bp & TRIM) | attributes));
bp++;
}
if (flush_left)
while (f_width-- > 0)
(*addchar)((int) (' ' | attributes));
break;
case 'a':
attributes = va_arg(ap, int);
break;
case '%':
(*addchar)((int) ('%' | attributes));
break;
default:
break;
}
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
sign = 0;
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);
xstring = str; va_start(va, fmt);
xestring = str + size - 1;
doprnt(xaddchar, fmt, va); xstring = str;
va_end(va); xestring = str + size - 1;
*xstring++ = '\0'; doprnt(xaddchar, fmt, va);
va_end(va);
*xstring++ = '\0';
} }
void xprintf(const char *fmt, ...) void xprintf(const char *fmt, ...)
{ {
va_list va; va_list va;
va_start(va, fmt);
doprnt(xputchar, fmt, va); va_start(va, fmt);
va_end(va); doprnt(xputchar, fmt, 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)
{ {
int i; int i;
int line = 0; int line = 0;
uint8_t *bp = buffer; uint8_t *bp = buffer;
while (bp < buffer + size) { while (bp < buffer + size) {
uint8_t *lbp = bp; uint8_t *lbp = bp;
xprintf("%08x ", line); xprintf("%08x ", line);
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (bp + i > buffer + size) { if (bp + i > buffer + size) {
break; break;
} }
xprintf("%02x ", (uint8_t) *lbp++); xprintf("%02x ", (uint8_t) *lbp++);
} }
lbp = bp; lbp = bp;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
int8_t c = *lbp++; int8_t c = *lbp++;
if (bp + i > buffer + size) { if (bp + i > buffer + size) {
break; break;
} }
if (c > ' ' && c < '~') { if (c > ' ' && c < '~') {
xprintf("%c", c); xprintf("%c", c);
} else { } else {
xprintf("."); xprintf(".");
} }
} }
xprintf("\r\n"); xprintf("\r\n");
bp += 16; bp += 16;
line += 16; line += 16;
} }
} }

View File

@@ -20,19 +20,19 @@
* *
* Copyright 2010 - 2012 F. Aschwanden * Copyright 2010 - 2012 F. Aschwanden
* Copyright 2011 - 2012 V. Riviere * Copyright 2011 - 2012 V. Riviere
* Copyright 2012 M. Froeschle * Copyright 2012 - 2025 M. Froeschle
*/ */
.global printf_helper .globl printf_helper
printf_helper:
.extern __MBAR
.wait_txready:
move.w __MBAR+0x8604,d2 // PSCSCR0 status register
btst #10,d2 // space left in TX fifo?
beq.s .wait_txready // no, loop
lea __MBAR+0x860C,a0 // PSCSTB0 transmitter buffer register
move.b d0,(a0) // send byte
rts
// vim: set syntax=asm68k : printf_helper:
.extern __MBAR
.wait_txready:
move.w __MBAR+0x8604,d2 // PSCSCR0 status register
btst #10,d2 // space left in TX fifo?
beq.s .wait_txready // no, loop
lea __MBAR+0x860C,a0 // PSCSTB0 transmitter buffer register
move.b d0,(a0) // send byte
rts

View File

@@ -24,6 +24,100 @@ extern volatile uint32_t _VRAM[];
volatile int32_t time, start, end; volatile int32_t time, start, end;
int i; int i;
static void wait_pll(void)
{
int32_t trgt = MCF_SLT0_SCNT - 100000;
do
{
;
} while ((* (volatile int16_t *) 0xf0000800 < 0) && MCF_SLT0_SCNT > trgt);
}
static volatile uint8_t *pll_base = (volatile uint8_t *) 0xf0000600;
static void init_pll(void)
{
xprintf("FPGA PLL initialization: ");
wait_pll();
* (volatile uint16_t *) (pll_base + 0x48) = 27; /* loopfilter r */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x08) = 1; /* charge pump 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x00) = 12; /* N counter high = 12 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x40) = 12; /* N counter low = 12 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x114) = 1; /* ck1 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x118) = 1; /* ck2 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x11c) = 1; /* ck3 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x10) = 1; /* ck0 high = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x50) = 1; /* ck0 low = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x144) = 1; /* M odd division */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x44) = 1; /* M low = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x04) = 145; /* M high = 145 = 146 MHz */
wait_pll();
* (volatile uint8_t *) 0xf0000800 = 0; /* set */
xprintf("finished\r\n");
}
/*
* INIT VIDEO DDR RAM
*/
static void init_video_ddr(void) {
xprintf("init video RAM: ");
* (volatile uint16_t *) 0xf0000400 = 0xb; /* set cke = 1, cs=1, config = 1 */
NOP();
_VRAM[0] = 0x00050400; /* IPALL */
NOP();
_VRAM[0] = 0x00072000; /* load EMR pll on */
NOP();
_VRAM[0] = 0x00070122; /* load MR: reset pll, cl=2, burst=4lw */
NOP();
_VRAM[0] = 0x00050400; /* IPALL */
NOP();
_VRAM[0] = 0x00060000; /* auto refresh */
NOP();
_VRAM[0] = 0x00060000; /* auto refresh */
NOP();
/* FIXME: what's this? */
_VRAM[0] = 0000070022; /* load MR dll on */
NOP();
* (uint32_t *) 0xf0000400 = 0x01070002; /* fifo on, refresh on, ddrcs und cke on, video dac on */
xprintf("finished\r\n");
}
void do_tests(void) void do_tests(void)
{ {
uint32_t version; uint32_t version;
@@ -121,6 +215,13 @@ void wait_for_jtag(void)
: /* no output */ : /* no output */
: /* no input */ : /* no input */
: "d0", "memory"); : "d0", "memory");
xprintf("init FPGA PLLs\r\n");
init_pll();
xprintf("init video DDR RAM\r\n");
init_video_ddr();
/* begin of tests */ /* begin of tests */
do_tests(); do_tests();

View File

@@ -26,131 +26,131 @@
void *memcpy(void *dst, const void *src, size_t n) void *memcpy(void *dst, const void *src, size_t n)
{ {
uint8_t *to = dst; uint8_t *to = dst;
while (to < (uint8_t *) dst + n) while (to < (uint8_t *) dst + n)
*to++ = * (uint8_t *) src++; *to++ = * (uint8_t *) src++;
return dst; return dst;
} }
void bzero(void *s, size_t n) void bzero(void *s, size_t n)
{ {
size_t i; size_t i;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
((unsigned char *) s)[i] = '\0'; ((unsigned char *) s)[i] = '\0';
} }
void *memset(void *s, int c, size_t n) void *memset(void *s, int c, size_t n)
{ {
uint8_t *dst = s; uint8_t *dst = s;
do do
{ {
*dst++ = c; *dst++ = c;
} while ((dst - (uint8_t *) s) < n); } while ((dst - (uint8_t *) s) < n);
return s; return s;
} }
int memcmp(const void *s1, const void *s2, size_t max) int memcmp(const void *s1, const void *s2, size_t max)
{ {
int i; int i;
int cmp; int cmp = 0;
for (i = 0; i < max; i++) for (i = 0; i < max; i++)
{ {
cmp = (* (const char *) s1 - * (const char *) s2); cmp = (* (const char *) s1 - * (const char *) s2);
if (cmp != 0) return cmp; if (cmp != 0) return cmp;
} }
return cmp; return cmp;
} }
int strcmp(const char *s1, const char *s2) int strcmp(const char *s1, const char *s2)
{ {
int i; int i;
int cmp; int cmp;
for (i = 0; *s1++ && *s2++; i++) for (i = 0; *s1++ && *s2++; i++)
{ {
cmp = (*s1 - *s2); cmp = (*s1 - *s2);
if (cmp != 0) return cmp; if (cmp != 0) return cmp;
} }
return cmp; return cmp;
} }
int strncmp(const char *s1, const char *s2, size_t max) int strncmp(const char *s1, const char *s2, size_t max)
{ {
int i; int i;
int cmp; int cmp;
for (i = 0; i < max && *s1++ && *s2++; i++); for (i = 0; i < max && *s1++ && *s2++; i++);
{ {
cmp = (*s1 - *s2); cmp = (*s1 - *s2);
if (cmp != 0) return cmp; if (cmp != 0) return cmp;
} }
return cmp; return cmp;
} }
char *strcpy(char *dst, const char *src) char *strcpy(char *dst, const char *src)
{ {
char *ptr = dst; char *ptr = dst;
while ((*dst++ = *src++) != '\0'); while ((*dst++ = *src++) != '\0');
return ptr; return ptr;
} }
char *strncpy(char *dst, const char *src, size_t max) char *strncpy(char *dst, const char *src, size_t max)
{ {
char *ptr = dst; char *ptr = dst;
while ((*dst++ = *src++) != '\0' && max-- >= 0); while ((*dst++ = *src++) != '\0' && max-- >= 0);
return ptr; return ptr;
} }
int atoi(const char *c) int atoi(const char *c)
{ {
int value = 0; int value = 0;
while (isdigit(*c)) while (isdigit(*c))
{ {
value *= 10; value *= 10;
value += (int) (*c - '0'); value += (int) (*c - '0');
c++; c++;
} }
return value; return value;
} }
size_t strlen(const char *s) size_t strlen(const char *s)
{ {
const char *start = s; const char *start = s;
while (*s++); while (*s++);
return s - start - 1; return s - start - 1;
} }
char *strcat(char *dst, const char *src) char *strcat(char *dst, const char *src)
{ {
char *ret = dst; char *ret = dst;
dst = &dst[strlen(dst)]; dst = &dst[strlen(dst)];
while ((*dst++ = *src++) != '\0'); while ((*dst++ = *src++) != '\0');
return ret; return ret;
} }
char *strncat(char *dst, const char *src, size_t max) char *strncat(char *dst, const char *src, size_t max)
{ {
size_t i; size_t i;
char *ret = dst; char *ret = dst;
dst = &dst[strlen(dst)]; dst = &dst[strlen(dst)];
for (i = 0; i < max && *src; i++) for (i = 0; i < max && *src; i++)
{ {
*dst++ = *src++; *dst++ = *src++;
} }
*dst++ = '\0'; *dst++ = '\0';
return ret; return ret;
} }

View File

@@ -243,13 +243,15 @@ void videl_screen_init(void)
/* 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 */