Merge pci_BaS_gcc branch from trunk (new attempt)

This commit is contained in:
David Gálvez
2014-07-10 15:36:48 +00:00
parent b9bf2e32ba
commit 2a9e4fc1a6
54 changed files with 3645 additions and 998 deletions

View File

@@ -48,6 +48,7 @@
#include "bootp.h"
#include "interrupts.h"
#include "exceptions.h"
#include "net_timer.h"
//#define BAS_DEBUG
#if defined(BAS_DEBUG)
@@ -95,20 +96,20 @@ static inline bool pic_rxready(void)
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);
/* Transmit the byte */
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
/* Transmit the byte */
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
}
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);
/* Return the received byte */
return *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
/* Return the received byte */
return *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
}
void pic_init(void)
@@ -251,7 +252,7 @@ static ARP_INFO arp_info;
void network_init(void)
{
uint8_t mac[6] = {0x00, 0xcf, 0x54, 0x12, 0x34, 0x56};
uint8_t mac[6] = {0x00, 0xcf, 0x54, 0x85, 0xcf, 0x01}; /* this is the original MAC address dbug assigns */
uint8_t bc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* this is our broadcast MAC address */
IP_ADDR myip = {192, 168, 1, 100};
IP_ADDR gateway = {192, 168, 1, 1};
@@ -264,19 +265,19 @@ void network_init(void)
isr_init(); /* need to call that explicitely, otherwise isr table might be full */
if (!isr_register_handler(ISR_DBUG_ISR, vector, handler, NULL, (void *) &nif1))
if (!isr_register_handler(vector, handler, NULL, (void *) &nif1))
{
dbg("%s: unable to register handler for vector %d\r\n", __FUNCTION__, vector);
return;
}
/*
* Register the DMA interrupt handler
*/
handler = dma_interrupt_handler;
vector = 112;
/*
* Register the DMA interrupt handler
*/
handler = dma_interrupt_handler;
vector = 112;
if (!isr_register_handler(ISR_DBUG_ISR, vector, handler, NULL,NULL))
if (!isr_register_handler(vector, handler, NULL,NULL))
{
dbg("%s: Error: Unable to register handler for vector %s\r\n", __FUNCTION__, vector);
return;
@@ -290,10 +291,10 @@ void network_init(void)
memcpy(nif1.hwa, mac, 6);
memcpy(nif1.broadcast, bc, 6);
dbg("%s: ethernet address is %02X:%02X:%02X:%02X:%02X:%02X\r\n", __FUNCTION__,
dbg("%s: ethernet address is %02X:%02X:%02X:%02X:%02X:%02X\r\n", __FUNCTION__,
nif1.hwa[0], nif1.hwa[1], nif1.hwa[2],
nif1.hwa[3], nif1.hwa[4], nif1.hwa[5]);
timer_init(TIMER_NETWORK, TMR_INTC_LVL, TMR_INTC_PRI);
arp_init(&arp_info);
@@ -345,16 +346,16 @@ void BaS(void)
MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */
NOP(); /* force pipeline sync */
xprintf("finished\r\n");
#ifdef MACHINE_FIREBEE
xprintf("IDE reset: ");
/* IDE reset */
* (volatile uint8_t *) (0xffff8802 - 2) = 14;
* (volatile uint8_t *) (0xffff8802 - 0) = 0x80;
wait(1);
* (volatile uint8_t *) (0xffff8802 - 0) = 0;
xprintf("finished\r\n");
xprintf("enable video: ");
/*
@@ -383,22 +384,22 @@ void BaS(void)
#ifdef _NOT_USED_
screen_init();
/* experimental */
{
int i;
uint32_t *scradr = 0xd00000;
/* experimental */
{
int i;
uint32_t *scradr = 0xd00000;
for (i = 0; i < 100; i++)
{
uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0xffffffff;
}
for (i = 0; i < 100; i++)
{
uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
{
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0x0;
}
}
@@ -441,10 +442,11 @@ void BaS(void)
/* Jump into the OS */
typedef void void_func(void);
typedef struct {
struct rom_header
{
void *initial_sp;
void_func *initial_pc;
} ROM_HEADER;
};
xprintf("BaS initialization finished, enable interrupts\r\n");
enable_coldfire_interrupts();
@@ -453,6 +455,6 @@ void BaS(void)
network_init();
xprintf("call EmuTOS\r\n");
ROM_HEADER* os_header = (ROM_HEADER*)TOS;
struct rom_header *os_header = (struct rom_header *) TOS;
os_header->initial_pc();
}

View File

@@ -44,24 +44,24 @@ uint32_t cacr_get(void)
void flush_and_invalidate_caches(void)
{
__asm__ (
" clr.l d0\n\t"
" clr.l d1\n\t"
" move.l d0,a0\n\t"
"cfa_setloop:\n\t"
" cpushl bc,(a0) | flush\n\t"
" lea 0x10(a0),a0 | index+1\n\t"
" addq.l #1,d1 | index+1\n\t"
" cmpi.w #512,d1 | all sets?\n\t"
" bne.s cfa_setloop | no->\n\t"
" clr.l d1\n\t"
" addq.l #1,d0\n\t"
" move.l d0,a0\n\t"
" cmpi.w #4,d0 | all ways?\n\t"
" bne.s cfa_setloop | no->\n\t"
/* input */ :
/* output */ :
/* clobber */ : "d0", "d1", "a0"
__asm__ __volatile__(
" clr.l d0 \n\t"
" clr.l d1 \n\t"
" move.l d0,a0 \n\t"
"cfa_setloop: \n\t"
" cpushl bc,(a0) | flush\n\t"
" lea 0x10(a0),a0 | index+1\n\t"
" addq.l #1,d1 | index+1\n\t"
" cmpi.w #512,d1 | all sets?\n\t"
" bne.s cfa_setloop | no->\n\t"
" clr.l d1 \n\t"
" addq.l #1,d0 \n\t"
" move.l d0,a0 \n\t"
" cmpi.w #4,d0 | all ways?\n\t"
" bne.s cfa_setloop | no->\n\t"
/* input */ :
/* output */ :
/* clobber */ : "d0", "d1", "a0"
);
}
@@ -81,25 +81,35 @@ void flush_icache_range(void *address, size_t size)
if (start_set > end_set) {
/* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set));
__asm__ __volatile__(
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set) /* input parameters */
:
);
}
/* next loop will finish the cache ie pass the hole */
end_set = LAST_ICACHE_ADDR;
}
for (set = start_set; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq%.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set));
__asm__ __volatile__(
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set])"
: /* output parameters */
: [set] "a" (set)
:
);
}
}
@@ -121,25 +131,37 @@ void flush_dcache_range(void *address, size_t size)
if (start_set > end_set) {
/* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set));
for (set = 0; set <= end_set; set += (0x10 - 3))
{
__asm__ __volatile__(
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set)
: /* clobbered registers */
);
}
/* next loop will finish the cache ie pass the hole */
end_set = LAST_DCACHE_ADDR;
}
for (set = start_set; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq%.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set));
for (set = start_set; set <= end_set; set += (0x10 - 3))
{
__asm__ __volatile__(
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq%.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set)
: /* clobbered registers */
);
}
}

View File

@@ -18,10 +18,14 @@
#include "usb.h"
#include "exceptions.h" /* set_ipl() */
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif
//#define DBG_DM

View File

@@ -33,64 +33,69 @@
#define FPGA_DATA0 (1 << 3)
#define FPGA_CONF_DONE (1 << 5)
extern uint8_t _FPGA_FLASH_DATA[];
#define FPGA_FLASH_DATA &_FPGA_FLASH_DATA[0]
extern uint8_t _FPGA_FLASH_DATA_SIZE[];
#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_FLASH_DATA_SIZE[0])
extern uint8_t _FPGA_CONFIG[];
#define FPGA_FLASH_DATA &_FPGA_CONFIG[0]
extern uint8_t _FPGA_CONFIG_SIZE[];
#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_CONFIG_SIZE[0])
/*
* flag located in processor SRAM1 that indicates that the FPGA configuration has
* been loaded through JTAG. init_fpga() will honour this and not overwrite config.
*/
extern int32_t _FPGA_JTAG_LOADED;
#ifdef _NOT_USED_
void test_longword(void)
void config_gpio_for_fpga_config(void)
{
uint32_t *fpga_data = (uint32_t *) FPGA_FLASH_DATA;
const uint32_t *fpga_flash_data_end = (uint32_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE;
do
{
uint32_t value = *fpga_data++;
xprintf("LONGWORDS: addr=%p, value=%08x\r", fpga_data, value);
} while (fpga_data < fpga_flash_data_end);
xprintf("finished. \r\n");
#if defined(MACHINE_FIREBEE)
/*
* Configure GPIO FEC1L port directions (needed to load FPGA configuration)
*/
MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */
0 | /* bit 6 = input */
0 | /* bit 5 = input */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 | /* bit 4 = LED => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 | /* bit 3 = PRG_DQ0 => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 | /* bit 2 = FPGA_CONFIG => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1 | /* bit 1 = PRG_CLK (FPGA) => output */
0; /* bit 0 => input */
#endif /* MACHINE_FIREBEE */
}
void test_word(void)
void config_gpio_for_jtag_config(void)
{
uint16_t *fpga_data = (uint16_t *) FPGA_FLASH_DATA;
const uint16_t *fpga_flash_data_end = (uint16_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE;
do
{
uint16_t value = *fpga_data++;
xprintf("WORDS: addr=%p, value=%04x\r", fpga_data, value);
} while (fpga_data < fpga_flash_data_end);
xprintf("finished. \r\n");
/*
* configure FEC1L port directions to enable external JTAG configuration download to FPGA
*/
MCF_GPIO_PDDR_FEC1L = 0 |
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4; /* bit 4 = LED => output */
/* all other bits = input */
/*
* unfortunately, the GPIO module cannot trigger interrupts. That means FPGA_CONFIG needs to be polled to detect
* external FPGA (re)configuration and reset the system in that case. Could be done from the OS as well...
*/
}
void test_byte(void)
{
uint8_t *fpga_data = (uint8_t *) FPGA_FLASH_DATA;
const uint8_t *fpga_flash_data_end = (uint8_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE;
do
{
uint8_t value = *fpga_data++;
xprintf("LONGWORDS: addr=%p, value=%08x\r", fpga_data, value);
} while (fpga_data < fpga_flash_data_end);
xprintf("finished. \r\n");
}
#endif /* _NOT_USED_ */
/*
* load FPGA
*/
void init_fpga(void)
bool init_fpga(void)
{
uint8_t *fpga_data;
volatile int32_t time, start, end;
int i;
xprintf("FPGA load config... ");
start = MCF_SLT0_SCNT;
xprintf("FPGA load config (_FPGA_JTAG_LOADED = %x)...", _FPGA_JTAG_LOADED);
if (_FPGA_JTAG_LOADED == 1)
{
xprintf("detected _FPGA_JTAG_LOADED flag. Not overwriting FPGA config.\r\n");
/* reset the flag so that next boot will load config again from flash */
_FPGA_JTAG_LOADED = 0;
return true;
}
start = MCF_SLT0_SCNT;
config_gpio_for_fpga_config();
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */
/* pulling FPGA_CONFIG to low resets the FPGA */
@@ -109,7 +114,7 @@ void init_fpga(void)
* configuration cycle consists of 3 stages<65>reset, configuration, and initialization.
* While nCONFIG is low, the device is in reset. When the device comes out of reset,
* nCONFIG must be at a logic high level in order for the device to release the open-drain
* nSTATUS pin. After nSTATUS is released, it is pulled high by a pull-up resistor and the FPGA
* nSTATUS pin. After nSTATUS is released, it is pulled high by a pull-up resistor and the FPGA
* is ready to receive configuration data. Before and during configuration, all user I/O pins
* are tri-stated. Stratix series, Arria series, and Cyclone series have weak pull-up resistors
* on the I/O pins which are on, before and during configuration.
@@ -159,11 +164,12 @@ void init_fpga(void)
#endif /* _NOT_USED_ */
end = MCF_SLT0_SCNT;
time = (start - end) / (SYSCLK / 1000) / 1000;
xprintf("finished (took %f seconds).\r\n", time / 1000.0);
config_gpio_for_jtag_config();
return true;
}
else
{
xprintf("FAILED!\r\n");
}
xprintf("FAILED!\r\n");
config_gpio_for_jtag_config();
return false;
}

View File

@@ -30,13 +30,16 @@
#include "exceptions.h"
#include "interrupts.h"
#include "bas_printf.h"
#include "startcf.h"
#include "cache.h"
#include "util.h"
extern void (*rt_vbr[])(void);
#define VBR rt_vbr
#define IRQ_DEBUG
#if defined(IRQ_DEBUG)
#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
#define dbg(format, arg...) do { ; } while (0)
#endif
@@ -57,7 +60,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
if (source < 1 || source > 63)
{
dbg("%s: interrupt source %d not defined\r\n", __FUNCTION__, source);
dbg("interrupt source %d not defined\r\n", source);
return -1;
}
@@ -68,7 +71,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
{
if (ICR[i] == lp)
{
dbg("%s: level %d and priority %d already used for interrupt source %d!\r\n", __FUNCTION__,
dbg("level %d and priority %d already used for interrupt source %d!\r\n",
level, priority, i);
return -1;
}
@@ -88,31 +91,29 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
return 0;
}
#ifndef UIF_MAX_ISR_ENTRY
#define UIF_MAX_ISR_ENTRY (20)
#ifndef MAX_ISR_ENTRY
#define MAX_ISR_ENTRY (20)
#endif
typedef struct
{
int vector;
int type;
int (*handler)(void *, void *);
void *hdev;
void *harg;
} ISRENTRY;
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
ISRENTRY isrtab[MAX_ISR_ENTRY];
void isr_init(void)
{
int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
isrtab[index].vector = 0;
isrtab[index].type = 0;
isrtab[index].handler = 0;
isrtab[index].hdev = 0;
isrtab[index].harg = 0;
@@ -120,41 +121,36 @@ void isr_init(void)
}
int isr_register_handler(int type, int vector,
int (*handler)(void *, void *), void *hdev, void *harg)
int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg)
{
/*
* This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it.
*
* The two parameters are intended for the first arg to be a
* pointer to the device itself, and the second a pointer to a data
* The two parameters are intended for the first arg to be a
* pointer to the device itself, and the second a pointer to a data
* structure used by the device driver for that particular device.
*/
int index;
if ((vector == 0) ||
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
(handler == NULL))
if ((vector == 0) || (handler == NULL))
{
dbg("%s: illegal type, vector or handler!\r\n", __FUNCTION__);
dbg("illegal vector or handler!\r\n");
return false;
}
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if ((isrtab[index].vector == vector) &&
(isrtab[index].type == type))
if (isrtab[index].vector == vector)
{
/* only one entry of each type per vector */
dbg("%s: already set handler with this type and vector (%d, %d)\r\n", __FUNCTION__, type, vector);
/* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false;
}
if (isrtab[index].vector == 0)
{
isrtab[index].vector = vector;
isrtab[index].type = type;
isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
@@ -162,26 +158,24 @@ int isr_register_handler(int type, int vector,
return true;
}
}
dbg("%s: no available slots to register handler for vector %d\n\r", __FUNCTION__, vector);
dbg("no available slots to register handler for vector %d\n\r", vector);
return false; /* no available slots */
}
void isr_remove_handler(int type, int (*handler)(void *, void *))
void isr_remove_handler(int (*handler)(void *, void *))
{
/*
* This routine removes from the ISR table all
* entries that matches 'type' and 'handler'.
* entries that matches 'handler'.
*/
int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if ((isrtab[index].handler == handler) &&
(isrtab[index].type == type))
if (isrtab[index].handler == handler)
{
isrtab[index].vector = 0;
isrtab[index].type = 0;
isrtab[index].handler = 0;
isrtab[index].hdev = 0;
isrtab[index].harg = 0;
@@ -189,7 +183,7 @@ void isr_remove_handler(int type, int (*handler)(void *, void *))
return;
}
}
dbg("%s: no such handler registered (type=%d, handler=%p\r\n", __FUNCTION__, type, handler);
dbg("no such handler registered (handler=%p\r\n", handler);
}
@@ -203,22 +197,216 @@ bool isr_execute_handler(int vector)
bool retval = false;
/*
* First locate a BaS Interrupt Service Routine handler.
* locate a BaS Interrupt Service Routine handler.
*/
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if ((isrtab[index].vector == vector) &&
(isrtab[index].type == ISR_DBUG_ISR))
if (isrtab[index].vector == vector)
{
retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{
return retval;
}
}
}
dbg("%s: no BaS isr handler for vector %d found\r\n", __FUNCTION__, vector);
dbg("no BaS isr handler for vector %d found\r\n", vector);
return retval;
}
/*
* PIC interrupt handler for Firebee
*/
void pic_interrupt_handler(void)
{
uint8_t rcv_byte;
rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data
{
uint8_t *rtc_reg= (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963;
int index = 0;
xprintf("PIC interrupt requesting RTC data\r\n");
MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC
do
{
*rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64);
}
}
extern int32_t video_sbt;
extern int32_t video_tlb;
void video_addr_timeout(void)
{
uint32_t addr = 0x0L;
uint32_t *src;
uint32_t *dst;
uint32_t asid;
dbg("video address timeout\r\n");
flush_and_invalidate_caches();
do
{
uint32_t tlb;
uint32_t page_attr;
/*
* search tlb entry id for addr (if not available, the MMU
* will provide a new one based on its LRU algorithm)
*/
MCF_MMU_MMUAR = addr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
tlb = (MCF_MMU_MMUOR >> 16) & 0xffff;
/*
* retrieve tlb entry with the found TLB entry id
*/
MCF_MMU_MMUAR = tlb;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
asid = (MCF_MMU_MMUTR >> 2) & 0x1fff; /* fetch ASID of page */;
if (asid != sca_page_ID) /* check if screen area */
{
addr += 0x100000;
continue; /* next page */
}
/* modify found TLB entry */
if (addr == 0x0)
{
page_attr =
MCF_MMU_MMUDR_LK |
MCF_MMU_MMUDR_SZ(0) |
MCF_MMU_MMUDR_CM(0) |
MCF_MMU_MMUDR_R |
MCF_MMU_MMUDR_W |
MCF_MMU_MMUDR_X;
}
else
{
page_attr =
MCF_MMU_MMUTR_SG |
MCF_MMU_MMUTR_V;
}
MCF_MMU_MMUTR = addr;
MCF_MMU_MMUDR = page_attr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_ACC |
MCF_MMU_MMUOR_UAA;
NOP();
dst = (uint32_t *) 0x60000000 + addr;
src = (uint32_t *) addr;
while (dst < (uint32_t *) 0x60000000 + addr + 0x10000)
{
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}
addr += 0x100000;
} while (addr < 0xd00000);
video_tlb = 0x2000;
video_sbt = 0;
}
/*
* blink the Firebee's LED to show we are still alive
*/
void blink_led(void)
{
static uint16_t blinker = 0;
if ((blinker++ & 0x80) > 0)
{
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
}
else
{
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
}
}
/*
* Atari MFP interrupt registers.
*
* TODO: should go into a header file
*/
#define FALCON_MFP_IERA *((volatile uint8_t *) 0xfffffa07)
#define FALCON_MFP_IERB *((volatile uint8_t *) 0xfffffa09)
#define FALCON_MFP_IPRA *((volatile uint8_t *) 0xfffffa0b)
#define FALCON_MFP_IPRB *((volatile uint8_t *) 0xfffffa0d)
#define FALCON_MFP_IMRA *((volatile uint8_t *) 0xfffffa13)
#define FALCON_MFP_IMRB *((volatile uint8_t *) 0xfffffa15)
bool irq6_acsi_dma_interrupt(void)
{
dbg("ACSI DMA interrupt\r\n");
/*
* TODO: implement handler
*/
return false;
}
bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
{
bool handled = false;
MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */
if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT)
{
video_addr_timeout();
handled = true;
}
/*
* check if ACSI DMA interrupt
*/
if (FALCON_MFP_IERA & (1 << 7))
{
/* ACSI interrupt is enabled */
if (FALCON_MFP_IPRA & (1 << 7))
{
irq6_acsi_dma_interrupt();
handled = true;
}
}
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{
blink_led();
}
return handled;
}

View File

@@ -56,6 +56,8 @@
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_FIREBEE */
@@ -80,7 +82,7 @@ inline uint32_t set_asid(uint32_t value)
"movec %[value],ASID\n\t"
: /* no output */
: [value] "r" (value)
:
:
);
rt_asid = value;
@@ -88,7 +90,7 @@ inline uint32_t set_asid(uint32_t value)
return ret;
}
/*
* set ACRx register
* saves new value to rt_acrx and returns former value
@@ -97,7 +99,7 @@ inline uint32_t set_acr0(uint32_t value)
{
extern uint32_t rt_acr0;
uint32_t ret = rt_acr0;
__asm__ __volatile__(
"movec %[value],ACR0\n\t"
: /* not output */
@@ -117,7 +119,7 @@ inline uint32_t set_acr1(uint32_t value)
{
extern uint32_t rt_acr1;
uint32_t ret = rt_acr1;
__asm__ __volatile__(
"movec %[value],ACR1\n\t"
: /* not output */
@@ -138,7 +140,7 @@ inline uint32_t set_acr2(uint32_t value)
{
extern uint32_t rt_acr2;
uint32_t ret = rt_acr2;
__asm__ __volatile__(
"movec %[value],ACR2\n\t"
: /* not output */
@@ -158,7 +160,7 @@ inline uint32_t set_acr3(uint32_t value)
{
extern uint32_t rt_acr3;
uint32_t ret = rt_acr3;
__asm__ __volatile__(
"movec %[value],ACR3\n\t"
: /* not output */
@@ -193,7 +195,7 @@ void mmu_init(void)
uint32_t MMUBAR = (uint32_t) &_MMUBAR[0];
extern uint8_t _TOS[];
uint32_t TOS = (uint32_t) &_TOS[0];
set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */
/* set data access attributes in ACR0 and ACR1 */
@@ -203,29 +205,38 @@ void mmu_init(void)
ACR_AMM(0) | /* control region > 16 MB */
ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */
ACR_E(1) | /* enable ACR */
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
ACR_ADMSK(0x3f) | /* cover 1GB area from 0xc0000000 to 0xffffffff */
ACR_BA(0xc0000000)); /* (equals area from 3 to 4 GB */
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */
ACR_BA(0x80000000));
#elif defined(MACHINE_M54455)
ACR_ADMSK(0x7f) |
ACR_BA(0x80000000)); /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */
// set_acr1(0x601fc000);
set_acr1(ACR_W(0) |
ACR_SP(0) |
ACR_CM(0) |
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
ACR_CM(ACR_CM_CACHEABLE_WT) | /* video RAM on the Firebee */
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */
#elif defined(MACHINE_M54455)
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */
ACR_AMM(0) |
ACR_S(ACR_S_ALL) |
ACR_E(1) |
ACR_ADMSK(0x1f) |
ACR_BA(0x60000000));
/* set instruction access attributes in ACR2 and ACR3 */
//set_acr2(0xe007c400);
@@ -273,7 +284,7 @@ void mmu_init(void)
* mapped to physical address 0x60d0'0000 (FPGA video memory)
* video RAM: read write execute normal write true
*/
MCF_MMU_MMUTR = 0x00d00000 | /* virtual address */
#if defined(MACHINE_FIREBEE)
MCF_MMU_MMUTR_ID(SCA_PAGE_ID) |
@@ -285,6 +296,10 @@ void mmu_init(void)
MCF_MMU_MMUDR = 0x60d00000 | /* physical address */
#elif defined(MACHINE_M5484LITE)
MCF_MMU_MMUDR = 0x00d00000 | /* physical address */
#elif defined(MACHINE_M54455)
MCF_MMU_MMUDR = 0x60d00000 | /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x0) | /* cachable writethrough */
@@ -370,7 +385,7 @@ void mmu_init(void)
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
/*
* Map (locked) the very last MB of physical SDRAM (this is where the driver buffers reside) to the same
* virtual address. Used uncached for drivers.

View File

@@ -1,3 +1,4 @@
/*
* This object file must be the first to be linked,
* so it will be placed at the very beginning of the ROM.
@@ -49,7 +50,8 @@ _rom_entry:
lea __SUP_SP,a7
move.l #0,(sp)
/* Initialize the processor caches.
/*
* Initialize the processor caches.
* The instruction cache is fully enabled.
* The data cache is enabled, but cache-inhibited by default.
* Later, the MMU will fully activate the data cache for specific areas.

View File

@@ -2,7 +2,7 @@
* File: sysinit.c
* Purpose: Power-on Reset configuration of the Firebee board.
*
* Notes:
* Notes:
*
* This file is part of BaS_gcc.
*
@@ -37,14 +37,17 @@
#include "wait.h"
#include "util.h"
#include "version.h"
#ifdef MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#endif /* MACHINE_FIREBEE */
#ifdef MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_M5484LITE */
#
#include "dma.h"
#include "mod_devicetable.h"
#include "pci_ids.h"
@@ -52,12 +55,14 @@
#include "usb.h"
#include "video.h"
#define UNUSED(x) (void)(x) /* Unused variable */
#define UNUSED(x) (void)(x) /* Unused variable */
bool fpga_configured = false; /* for FPGA JTAG configuration */
extern volatile long _VRAM; /* start address of video ram from linker script */
/*
* init SLICE TIMER 0
* init SLICE TIMER 0
* all = 32.538 sec = 30.736mHz
* BYT0 = 127.1ms/tick = 7.876Hz offset 0
* BYT1 = 496.5us/tick = 2.014kHz offset 1
@@ -86,16 +91,16 @@ void init_gpio(void)
* configure all four 547x GPIO module DMA pins:
*
* /DACK1 - DMA acknowledge 1
* /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0
*
* /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0
*
* for DMA operation
*/
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0b11) |
MCF_PAD_PAR_DMA_PAR_DACK1(0b11) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0b11) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0b11);
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0x3) |
MCF_PAD_PAR_DMA_PAR_DACK1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0x3);
/*
* configure FEC0 pin assignment on GPIO module as FEC0
@@ -204,20 +209,6 @@ void init_gpio(void)
MCF_PAD_PAR_TIMER_PAR_TOUT3 |
MCF_PAD_PAR_TIMER_PAR_TIN2(MCF_PAD_PAR_TIMER_PAR_TIN2_IRQ2) |
MCF_PAD_PAR_TIMER_PAR_TOUT2;
#if defined(MACHINE_FIREBEE)
/*
* Configure GPIO FEC1L port directions (needed to load FPGA configuration)
*/
MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */
0 | /* bit 6 = input */
0 | /* bit 5 = input */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 | /* bit 4 = LED => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 | /* bit 3 = PRG_DQ0 => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 | /* bit 2 = FPGA_CONFIG => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1 | /* bit 1 = PRG_CLK (FPGA) => output */
0; /* bit 0 => input */
#endif /* MACHINE_FIREBEE */
}
/*
@@ -427,27 +418,27 @@ void init_fbcs()
#if MACHINE_FIREBEE /* FBC setup for FireBee */
MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF
| MCF_FBCS_CSMR_V);
MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 // 16BIT PORT
| MCF_FBCS_CSCR_AA; // AA
| MCF_FBCS_CSCR_AA; // AA
MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M // F800'0000-FBFF'FFFF
| MCF_FBCS_CSMR_V);
MCF_FBCS4_CSAR = 0x40000000; // VIDEO RAM BEREICH, #FB_CS3 WIRD NICHT BENÜTZT, DECODE DIREKT AUF DEM FPGA
MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF
| MCF_FBCS_CSMR_V;
#elif MACHINE_M5484LITE
@@ -462,7 +453,7 @@ void init_fbcs()
| MCF_FBCS_CSCR_WS(32)
| MCF_FBCS_CSCR_ASET(1)
| MCF_FBCS_CSCR_AA;
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
| MCF_FBCS_CSMR_V;
#endif /* MACHINE_FIREBEE */
@@ -580,7 +571,7 @@ void init_video_ddr(void) {
/*
* probe for NEC compatible USB host controller and install if found
*/
void init_usb(void)
void init_usb(void)
{
extern struct pci_device_id ohci_usb_pci_table[];
extern struct pci_device_id ehci_usb_pci_table[];
@@ -666,18 +657,20 @@ static bool i2c_bus_free(void)
/*
* TFP410 (DVI) on
*/
void dvi_on(void) {
void dvi_on(void)
{
uint8_t receivedByte;
uint8_t dummyByte; /* only used for a dummy read */
int num_tries = 0;
xprintf("DVI digital video output initialization: ");
MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */
do {
do
{
/* disable all i2c interrupt routing targets */
MCF_I2C_I2ICR = 0x0; //~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE);
MCF_I2C_I2ICR = 0x0; // ~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE);
/* disable i2c, disable i2c interrupts, slave, receive, i2c = acknowledge, no repeat start */
MCF_I2C_I2CR = 0x0;
@@ -814,16 +807,16 @@ void init_ac97(void) {
int va;
int vb;
int vc;
xprintf("AC97 sound chip initialization: ");
MCF_PAD_PAR_PSC2 = MCF_PAD_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_TXD2
| MCF_PAD_PAR_PSC2_PAR_RXD2;
MCF_PSC2_PSCMR1 = 0x0;
MCF_PSC2_PSCMR2 = 0x0;
MCF_PSC2_PSCIMR = 0x0300;
MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCRFCR = 0x0f000000;
MCF_PSC2_PSCTFCR = 0x0f000000;
MCF_PSC2_PSCRFAR = 0x00F0;
@@ -844,7 +837,7 @@ void init_ac97(void) {
{
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// read register
MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x82000000; //SLOT1:master volume
@@ -854,7 +847,7 @@ void init_ac97(void) {
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0
}
wait(50);
va = MCF_PSC2_PSCTB_AC97;
if ((va & 0x80000fff) == 0x80000800) {
vb = MCF_PSC2_PSCTB_AC97;
@@ -958,10 +951,10 @@ void initialize_hardware(void)
* (volatile uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
* (volatile uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */
/* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
/* Jump into FireTOS */
typedef void void_func(void);
@@ -974,7 +967,7 @@ void initialize_hardware(void)
init_serial();
xprintf("\n\n");
xprintf("%s BASIS system (BaS) v %d.%d (%s, %s)\r\n\r\n",
xprintf("%s BASIS system (BaS) v %d.%d (%s, %s)\r\n\r\n",
#if MACHINE_FIREBEE
"Firebee"
#elif MACHINE_M5484LITE
@@ -1052,7 +1045,7 @@ void initialize_hardware(void)
/*
* Determine the processor revision
*/
xprintf(" (revision %d)\r\n",((MCF_SIU_JTAGID & MCF_SIU_JTAGID_REV) >> 28));
xprintf(" (revision %d)\r\n", ((MCF_SIU_JTAGID & MCF_SIU_JTAGID_REV) >> 28));
init_slt();
init_fbcs();
@@ -1090,6 +1083,7 @@ void initialize_hardware(void)
/* the following only makes sense _after_ DDRAM has been initialized */
clear_bss_segment();
xprintf(".bss segment cleared\r\n");
if (BAS_LMA != BAS_IN_RAM)
{
@@ -1103,39 +1097,17 @@ void initialize_hardware(void)
#if MACHINE_FIREBEE
if (coldboot) /* does not work with BDM */
;
init_fpga();
fpga_configured = init_fpga();
init_pll();
init_video_ddr();
dvi_on();
#ifdef _NOT_USED_
/* experimental */
{
int i;
uint32_t *scradr = (uint32_t *) 0xd00000;
for (i = 0; i < 100; i++)
{
uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0x0;
}
}
}
#endif /* _NOT_USED_ */
#endif /* MACHINE_FIREBEE */
driver_mem_init();
init_pci();
video_init();
/* do not try to init USB for now on the Firebee, it hangs the machine */
#ifndef MACHINE_FIREBEE
//init_usb();