Compare commits

..

8 Commits

Author SHA1 Message Date
David Gálvez
8e6e28f5c0 Add format specifier to fix debug messages format 2014-07-13 15:18:23 +00:00
David Gálvez
fa6e0f0177 Make PCI memory space uncachable 2014-07-10 16:46:21 +00:00
David Gálvez
2b8162a1e1 Merge pci_BaS_gcc branch from trunk (new attempt) 2014-07-10 15:36:48 +00:00
David Gálvez
b0617246e2 Reverse merge from trunk in pci_BaS_gcc branch 2014-07-10 13:20:14 +00:00
David Gálvez
818cb2bcd7 Merge from trunk 2014-07-10 11:09:09 +00:00
David Gálvez
73f75895bc Add driver interface for PCI 2014-05-21 08:40:50 +00:00
David Gálvez
f0d0af7add Create new branch for PCI development 2014-05-21 07:38:47 +00:00
Markus Fröschle
a23abf0b5d corresponds to the equivalent file release. Contains networking code for EmuTOS, PCI bus scan and card configuration. X86emu included but deactivated. 2014-01-06 19:50:52 +00:00
21 changed files with 3840 additions and 1065 deletions

1689
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -124,6 +124,7 @@ CSRCS= \
radeon_accel.c \ radeon_accel.c \
radeon_cursor.c \ radeon_cursor.c \
radeon_monitor.c \ radeon_monitor.c \
fnt_st_8x16.c \
\ \
x86decode.c \ x86decode.c \
x86sys.c \ x86sys.c \
@@ -143,7 +144,8 @@ ASRCS= \
startcf.S \ startcf.S \
printf_helper.S \ printf_helper.S \
exceptions.S \ exceptions.S \
xhdi_vec.S xhdi_vec.S \
pci_wrappers.S
SRCS=$(ASRCS) $(CSRCS) SRCS=$(ASRCS) $(CSRCS)
COBJS=$(patsubst %.c,%.o,$(CSRCS)) COBJS=$(patsubst %.c,%.o,$(CSRCS))

View File

@@ -48,6 +48,7 @@ SECTIONS
OBJDIR/BaS.o(.text) OBJDIR/BaS.o(.text)
OBJDIR/pci.o(.text) OBJDIR/pci.o(.text)
OBJDIR/pci_wrappers.o(.text)
OBJDIR/usb.o(.text) OBJDIR/usb.o(.text)
OBJDIR/driver_mem.o(.text) OBJDIR/driver_mem.o(.text)
OBJDIR/usb_mouse.o(.text) OBJDIR/usb_mouse.o(.text)
@@ -203,8 +204,8 @@ SECTIONS
__EMUTOS_SIZE = 0x00100000; __EMUTOS_SIZE = 0x00100000;
/* where FPGA data lives in flash */ /* where FPGA data lives in flash */
__FPGA_FLASH_DATA = 0xe0700000; __FPGA_CONFIG = 0xe0700000;
__FPGA_FLASH_DATA_SIZE = 0x100000; __FPGA_CONFIG_SIZE = 0x100000;
/* VIDEO RAM BASIS */ /* VIDEO RAM BASIS */
__VRAM = 0x60000000; __VRAM = 0x60000000;
@@ -228,8 +229,13 @@ SECTIONS
/* 4KB on-chip Core SRAM1 */ /* 4KB on-chip Core SRAM1 */
__RAMBAR1 = 0xFF101000; __RAMBAR1 = 0xFF101000;
__RAMBAR1_SIZE = 0x00001000; __RAMBAR1_SIZE = 0x00001000;
__SUP_SP = __RAMBAR0 + __RAMBAR0_SIZE - 4; __SUP_SP = __RAMBAR1 + __RAMBAR1_SIZE - 4;
/*
* this flag (if 1) indicates that FPGA configuration has been loaded through JTAG
* and shouldn't be overwritten on boot
*/
__FPGA_JTAG_LOADED = __RAMBAR1;
/* system variables */ /* system variables */
/* RAMBAR0 0 to 0x7FF -> exception vectors */ /* RAMBAR0 0 to 0x7FF -> exception vectors */

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: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else #else

View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/bdmctrl #!/usr/local/bin/bdmctrl -D2
# #
# firebee board initialization for bdmctrl # firebee board initialization for bdmctrl
# #
@@ -21,32 +21,32 @@ write 0xFF000508 0x00001180 4
write 0xFF000504 0x007F0001 4 write 0xFF000504 0x007F0001 4
# SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes # SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes
write 0xFF000004 0x000002AA 4 # SDRAMDS configuration #write 0xFF000004 0x000002AA 4 # SDRAMDS configuration
write 0xFF000020 0x0000001A 4 # SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF) #write 0xFF000020 0x0000001A 4 # SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF)
write 0xFF000024 0x0800001A 4 # SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF) #write 0xFF000024 0x0800001A 4 # SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF)
write 0xFF000028 0x1000001A 4 # SDRAM CS2 configuration (128Mbytes 1000_0000 - 17FF_FFFF) #write 0xFF000028 0x1000001A 4 # SDRAM CS2 configuration (128Mbytes 1000_0000 - 17FF_FFFF)
write 0xFF00002C 0x1800001A 4 # SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF) #write 0xFF00002C 0x1800001A 4 # SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF)
write 0xFF000108 0x73622830 4 # SDCFG1 #write 0xFF000108 0x73622830 4 # SDCFG1
write 0xFF00010C 0x46770000 4 # SDCFG2 #write 0xFF00010C 0x46770000 4 # SDCFG2
write 0xFF000104 0xE10D0002 4 # SDCR + IPALL #write 0xFF000104 0xE10D0002 4 # SDCR + IPALL
write 0xFF000100 0x40010000 4 # SDMR (write to LEMR) #write 0xFF000100 0x40010000 4 # SDMR (write to LEMR)
write 0xFF000100 0x048D0000 4 # SDMR (write to LMR) #write 0xFF000100 0x048D0000 4 # SDMR (write to LMR)
sleep 100 #sleep 100
write 0xFF000104 0xE10D0002 4 # SDCR + IPALL #write 0xFF000104 0xE10D0002 4 # SDCR + IPALL
write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh) #write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh)
write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh) #write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh)
write 0xFF000100 0x008D0000 4 # SDMR (write to LMR) #write 0xFF000100 0x008D0000 4 # SDMR (write to LMR)
write 0xFF000104 0x710D0F00 4 # SDCR (lock SDMR and enable refresh) #write 0xFF000104 0x710D0F00 4 # SDCR (lock SDMR and enable refresh)
sleep 10 #sleep 10
# use system sdram as flashlib scratch area. # use system sdram as flashlib scratch area.
# TODO: plugin flashing seems to work o.k. now for smaller binaries, while it doesn't for larger ones (EmuTOS) yet. # TODO: plugin flashing seems to work o.k. now for smaller binaries, while it doesn't for larger ones (EmuTOS) yet.
# This seems to be related to large flash buffers and PC-relative adressing of the plugin # This seems to be related to large flash buffers and PC-relative adressing of the plugin
flash-plugin 0x1000 0xf000 flash29.plugin #flash-plugin 0x1000 0xf000 flash29-5475.plugin
# notify flashlib that we have flash at address 0xE0000000, length 0x7FFFFF, plugin is flash29 # notify flashlib that we have flash at address 0xE0000000, length 0x7FFFFF, plugin is flash29
flash 0xE0000000 flash 0xe0000000
# Erase flash from 0xE0000000 to 0xE00FFFFF (reserved space for BaS) # Erase flash from 0xE0000000 to 0xE00FFFFF (reserved space for BaS)
# #
@@ -55,17 +55,44 @@ flash 0xE0000000
# #
# contrary to documentation, it seems we need to erase-wait after each sector # contrary to documentation, it seems we need to erase-wait after each sector
erase 0xE0000000 0 erase 0xe0000000 0
erase 0xE0000000 1 erase-wait 0xe0000000
erase 0xE0000000 2 erase 0xe0000000 0x1000
erase 0xE0000000 3 erase-wait 0xe0000000
erase 0xE0000000 4 erase 0xe0000000 0x2000
erase 0xE0000000 5 erase-wait 0xe0000000
erase 0xE0000000 7 erase 0xe0000000 0x3000
erase 0xE0000000 8 erase-wait 0xe0000000
erase 0xE0000000 9 erase 0xe0000000 0x4000
erase 0xE0000000 10 erase-wait 0xe0000000
erase-wait 0xE0000000 erase 0xe0000000 0x5000
erase-wait 0xe0000000
erase 0xe0000000 0x6000
erase-wait 0xe0000000
erase 0xe0000000 0x7000
erase-wait 0xe0000000
erase 0xe0000000 0x8000
erase-wait 0xe0000000
erase 0xe0000000 0x10000
erase-wait 0xe0000000
erase 0xe0000000 0x18000
erase-wait 0xe0000000
erase 0xe0000000 0x20000
erase-wait 0xe0000000
erase 0xe0000000 0x28000
erase-wait 0xe0000000
erase 0xe0000000 0x30000
erase-wait 0xe0000000
erase 0xe0000000 0x38000
erase-wait 0xe0000000
erase 0xe0000000 0x40000
erase-wait 0xe0000000
erase 0xe0000000 0x48000
erase-wait 0xe0000000
erase 0xe0000000 0x50000
erase-wait 0xe0000000
erase 0xe0000000 0x58000
erase-wait 0xe0000000
load -v ../firebee/bas.elf load -v ../firebee/bas.elf
wait wait

View File

@@ -30,6 +30,7 @@
#include "dma.h" #include "dma.h"
#include "driver_vec.h" #include "driver_vec.h"
#include "driver_mem.h" #include "driver_mem.h"
#include "pci.h"
/* /*
* driver interface struct for the SD card BaS driver * driver interface struct for the SD card BaS driver
@@ -69,6 +70,58 @@ static struct dma_driver_interface dma_interface =
extern const struct fb_info *info_fb; extern const struct fb_info *info_fb;
/*
* driver interface struct for the PCI_BIOS BaS driver
*/
static struct pci_bios_interface pci_interface =
{
.subjar = 0,
.version = 0x00010000,
.find_pci_device = wrapper_find_pci_device,
.find_pci_classcode = wrapper_find_pci_classcode,
.read_config_byte = wrapper_read_config_byte,
.read_config_word = wrapper_read_config_word,
.read_config_longword = wrapper_read_config_longword,
.fast_read_config_byte = wrapper_fast_read_config_byte,
.fast_read_config_word = wrapper_fast_read_config_word,
.fast_read_config_longword = wrapper_fast_read_config_longword,
.write_config_byte = wrapper_write_config_byte,
.write_config_word = wrapper_write_config_word,
.write_config_longword = wrapper_write_config_longword,
.hook_interrupt = wrapper_hook_interrupt,
.unhook_interrupt = wrapper_unhook_interrupt,
.special_cycle = wrapper_special_cycle,
.get_routing = wrapper_get_routing,
.set_interrupt = wrapper_set_interrupt,
.get_resource = wrapper_get_resource,
.get_card_used = wrapper_get_card_used,
.set_card_used = wrapper_set_card_used,
.read_mem_byte = wrapper_read_mem_byte,
.read_mem_word = wrapper_read_mem_word,
.read_mem_longword = wrapper_read_mem_longword,
.fast_read_mem_byte = wrapper_fast_read_mem_byte,
.fast_read_mem_word = wrapper_fast_read_mem_word,
.fast_read_mem_longword = wrapper_fast_read_mem_longword,
.write_mem_byte = wrapper_write_mem_byte,
.write_mem_word = wrapper_write_mem_word,
.write_mem_longword = wrapper_write_mem_longword,
.read_io_byte = wrapper_read_io_byte,
.read_io_word = wrapper_read_io_word,
.read_io_longword = wrapper_read_io_longword,
.fast_read_io_byte = wrapper_fast_read_io_byte,
.fast_read_io_word = wrapper_fast_read_io_word,
.fast_read_io_longword = wrapper_fast_read_io_longword,
.write_io_byte = wrapper_write_io_byte,
.write_io_word = wrapper_write_io_word,
.write_io_longword = wrapper_write_io_longword,
.get_machine_id = wrapper_get_machine_id,
.get_pagesize = wrapper_get_pagesize,
.virt_to_bus = wrapper_virt_to_bus,
.bus_to_virt = wrapper_bus_to_virt,
.virt_to_phys = wrapper_virt_to_phys,
.phys_to_virt = wrapper_phys_to_virt,
};
/* /*
* driver interface struct for the BaS framebuffer video driver * driver interface struct for the BaS framebuffer video driver
*/ */
@@ -105,7 +158,14 @@ static struct generic_interface interfaces[] =
.revision = 1, .revision = 1,
.interface.fb = &framebuffer_interface, .interface.fb = &framebuffer_interface,
}, },
{
.type = PCI_DRIVER,
.name = "PCI",
.description = "BaS PCI_BIOS driver",
.version = 0,
.revision = 1,
.interface.pci = &pci_interface,
},
/* insert new drivers here */ /* insert new drivers here */
{ {

View File

@@ -27,15 +27,17 @@
#include "xhdi_sd.h" #include "xhdi_sd.h"
#include "MCD_dma.h" #include "MCD_dma.h"
#include "pci.h"
enum driver_type enum driver_type
{ {
END_OF_DRIVERS, /* marks end of driver list */ // BLOCKDEV_DRIVER,
BLOCKDEV_DRIVER, // CHARDEV_DRIVER,
CHARDEV_DRIVER,
VIDEO_DRIVER,
XHDI_DRIVER, XHDI_DRIVER,
MCD_DRIVER, MCD_DRIVER,
VIDEO_DRIVER,
PCI_DRIVER,
END_OF_DRIVERS, /* marks end of driver list */
}; };
struct generic_driver_interface struct generic_driver_interface
@@ -204,12 +206,66 @@ struct framebuffer_driver_interface
struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */ struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */
}; };
struct pci_bios_interface {
uint32_t subjar;
uint32_t version;
/* Although we declare this functions as standard gcc functions (cdecl),
* they expect paramenters inside registers (fastcall) unsupported by gcc m68k.
* Caller will take care of parameters passing convention.
*/
int32_t (*find_pci_device) (uint32_t id, uint16_t index);
int32_t (*find_pci_classcode) (uint32_t class, uint16_t index);
int32_t (*read_config_byte) (int32_t handle, uint16_t reg, uint8_t *address);
int32_t (*read_config_word) (int32_t handle, uint16_t reg, uint16_t *address);
int32_t (*read_config_longword) (int32_t handle, uint16_t reg, uint32_t *address);
uint8_t (*fast_read_config_byte) (int32_t handle, uint16_t reg);
uint16_t (*fast_read_config_word) (int32_t handle, uint16_t reg);
uint32_t (*fast_read_config_longword) (int32_t handle, uint16_t reg);
int32_t (*write_config_byte) (int32_t handle, uint16_t reg, uint16_t val);
int32_t (*write_config_word) (int32_t handle, uint16_t reg, uint16_t val);
int32_t (*write_config_longword) (int32_t handle, uint16_t reg, uint32_t val);
int32_t (*hook_interrupt) (int32_t handle, uint32_t *routine, uint32_t *parameter);
int32_t (*unhook_interrupt) (int32_t handle);
int32_t (*special_cycle) (uint16_t bus, uint32_t data);
int32_t (*get_routing) (int32_t handle);
int32_t (*set_interrupt) (int32_t handle);
int32_t (*get_resource) (int32_t handle);
int32_t (*get_card_used) (int32_t handle, uint32_t *address);
int32_t (*set_card_used) (int32_t handle, uint32_t *callback);
int32_t (*read_mem_byte) (int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_mem_word) (int32_t handle, uint32_t offset, uint16_t *address);
int32_t (*read_mem_longword) (int32_t handle, uint32_t offset, uint32_t *address);
uint8_t (*fast_read_mem_byte) (int32_t handle, uint32_t offset);
uint16_t (*fast_read_mem_word) (int32_t handle, uint32_t offset);
uint32_t (*fast_read_mem_longword) (int32_t handle, uint32_t offset);
int32_t (*write_mem_byte) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_mem_word) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_mem_longword) (int32_t handle, uint32_t offset, uint32_t val);
int32_t (*read_io_byte) (int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_io_word) (int32_t handle, uint32_t offset, uint16_t *address);
int32_t (*read_io_longword) (int32_t handle, uint32_t offset, uint32_t *address);
uint8_t (*fast_read_io_byte) (int32_t handle, uint32_t offset);
uint16_t (*fast_read_io_word) (int32_t handle, uint32_t offset);
uint32_t (*fast_read_io_longword) (int32_t handle, uint32_t offset);
int32_t (*write_io_byte) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_io_word) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_io_longword) (int32_t handle, uint32_t offset, uint32_t val);
int32_t (*get_machine_id) (void);
int32_t (*get_pagesize) (void);
int32_t (*virt_to_bus) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*bus_to_virt) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*virt_to_phys) (uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*phys_to_virt) (uint32_t address, PCI_CONV_ADR *pointer);
// int32_t reserved[2];
};
union interface union interface
{ {
struct generic_driver_interface *gdi; struct generic_driver_interface *gdi;
struct xhdi_driver_interface *xhdi; struct xhdi_driver_interface *xhdi;
struct dma_driver_interface *dma; struct dma_driver_interface *dma;
struct framebuffer_driver_interface *fb; struct framebuffer_driver_interface *fb;
struct pci_bios_interface *pci;
}; };
struct generic_interface struct generic_interface

98
include/font.h Normal file
View File

@@ -0,0 +1,98 @@
/*
* font.h - font specific definitions
*
* Copyright (c) 2001 Lineo, Inc.
* Copyright (c) 2004 by Authors:
*
* Authors:
* MAD Martin Doering
*
* This file is distributed under the GPL, version 2 or at your
* option any later version. See doc/license.txt for details.
*/
#ifndef FONT_H
#define FONT_H
#include <stdint.h>
/* font header flags */
#define F_DEFAULT 1 /* this is the default font (face and size) */
#define F_HORZ_OFF 2 /* there are left and right offset tables */
#define F_STDFORM 4 /* is the font in standard format */
#define F_MONOSPACE 8 /* is the font monospaced */
/* font style bits */
#define F_THICKEN 1
#define F_LIGHT 2
#define F_SKEW 4
#define F_UNDER 8
#define F_OUTLINE 16
#define F_SHADOW 32
/* font specific linea variables */
extern const uint16_t *v_fnt_ad; /* address of current monospace font */
extern const uint16_t *v_off_ad; /* address of font offset table */
extern uint16_t v_fnt_nd; /* ascii code of last cell in font */
extern uint16_t v_fnt_st; /* ascii code of first cell in font */
extern uint16_t v_fnt_wr; /* font cell wrap */
/* character cell specific linea variables */
extern uint16_t v_cel_ht; /* cell height (width is 8) */
extern uint16_t v_cel_mx; /* needed by MiNT: columns on the screen minus 1 */
extern uint16_t v_cel_my; /* needed by MiNT: rows on the screen minus 1 */
extern uint16_t v_cel_wr; /* needed by MiNT: length (in int8_ts) of a line of characters */
/*
* font_ring is a struct of four pointers, each of which points to
* a list of font headers linked together to form a string.
*/
extern struct font_head *font_ring[4]; /* Ring of available fonts */
extern int16_t font_count; /* all three fonts and NULL */
/* the font header descibes a font */
struct font_head {
int16_t font_id;
int16_t point;
int8_t name[32];
uint16_t first_ade;
uint16_t last_ade;
uint16_t top;
uint16_t ascent;
uint16_t half;
uint16_t descent;
uint16_t bottom;
uint16_t max_char_width;
uint16_t max_cell_width;
uint16_t left_offset; /* amount character slants left when skewed */
uint16_t right_offset; /* amount character slants right */
uint16_t thicken; /* number of pixels to smear */
uint16_t ul_size; /* size of the underline */
uint16_t lighten; /* mask to and with to lighten */
uint16_t skew; /* mask for skewing */
uint16_t flags;
const uint8_t *hor_table; /* horizontal offsets */
const uint16_t *off_table; /* character offsets */
const uint16_t *dat_table; /* character definitions */
uint16_t form_width;
uint16_t form_height;
struct font_head *next_font;/* pointer to next font */
uint16_t font_seg;
};
/* prototypes */
void font_init(void); /* initialize BIOS font ring */
void font_set_default(void); /* choose the default font */
#endif /* FONT_H */

View File

@@ -243,10 +243,94 @@ extern int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t va
extern int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value); extern int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value);
extern int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value); extern int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value);
extern struct pci_rd *pci_get_resource(int32_t handle);
extern int32_t pci_hook_interrupt(int32_t handle, void *interrupt_handler, void *parameter); extern int32_t pci_hook_interrupt(int32_t handle, void *interrupt_handler, void *parameter);
extern int32_t pci_unhook_interrupt(int32_t handle); extern int32_t pci_unhook_interrupt(int32_t handle);
extern struct pci_rd *pci_get_resource(int32_t handle);
/*
* Not implemented PCI_BIOS functions
*/
extern uint8_t pci_fast_read_config_byte(int32_t handle, uint16_t reg);
extern uint16_t pci_fast_read_config_word(int32_t handle, uint16_t reg);
extern uint32_t pci_fast_read_config_longword(int32_t handle, uint16_t reg);
extern int32_t pci_special_cycle(uint16_t bus, uint32_t data);
extern int32_t pci_get_routing(int32_t handle);
extern int32_t pci_set_interrupt(int32_t handle);
extern int32_t pci_get_card_used(int32_t handle, uint32_t *address);
extern int32_t pci_set_card_used(int32_t handle, uint32_t *callback);
extern int32_t pci_read_mem_byte(int32_t handle, uint32_t offset, uint8_t *address);
extern int32_t pci_read_mem_word(int32_t handle, uint32_t offset, uint16_t *address);
extern int32_t pci_read_mem_longword(int32_t handle, uint32_t offset, uint32_t *address);
extern uint8_t pci_fast_read_mem_byte(int32_t handle, uint32_t offset);
extern uint16_t pci_fast_read_mem_word(int32_t handle, uint32_t offset);
extern uint32_t pci_fast_read_mem_longword(int32_t handle, uint32_t offset);
extern int32_t pci_write_mem_byte(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t pci_write_mem_word(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t pci_write_mem_longword(int32_t handle, uint32_t offset, uint32_t val);
extern int32_t pci_read_io_byte(int32_t handle, uint32_t offset, uint8_t *address);
extern int32_t pci_read_io_word(int32_t handle, uint32_t offset, uint16_t *address);
extern int32_t pci_read_io_longword(int32_t handle, uint32_t offset, uint32_t *address);
extern uint8_t pci_fast_read_io_byte(int32_t handle, uint32_t offset);
extern uint16_t pci_fast_read_io_word(int32_t handle, uint32_t offset);
extern uint32_t pci_fast_read_io_longword(int32_t handle, uint32_t offset);
extern int32_t pci_write_io_byte(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t pci_write_io_word(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t pci_write_io_longword(int32_t handle, uint32_t offset, uint32_t val);
extern int32_t pci_get_machine_id(void);
extern int32_t pci_get_pagesize(void);
extern int32_t pci_virt_to_bus(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t pci_bus_to_virt(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t pci_virt_to_phys(uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t pci_phys_to_virt(uint32_t address, PCI_CONV_ADR *pointer);
/*
* prototypes for PCI wrapper routines
*/
extern int32_t wrapper_find_pci_device(uint32_t id, uint16_t index);
extern int32_t wrapper_find_pci_classcode(uint32_t class, uint16_t index);
extern int32_t wrapper_read_config_byte(int32_t handle, uint16_t reg, uint8_t *address);
extern int32_t wrapper_read_config_word(int32_t handle, uint16_t reg, uint16_t *address);
extern int32_t wrapper_read_config_longword(int32_t handle, uint16_t reg, uint32_t *address);
extern uint8_t wrapper_fast_read_config_byte(int32_t handle, uint16_t reg);
extern uint16_t wrapper_fast_read_config_word(int32_t handle, uint16_t reg);
extern uint32_t wrapper_fast_read_config_longword(int32_t handle, uint16_t reg);
extern int32_t wrapper_write_config_byte(int32_t handle, uint16_t reg, uint16_t val);
extern int32_t wrapper_write_config_word(int32_t handle, uint16_t reg, uint16_t val);
extern int32_t wrapper_write_config_longword(int32_t handle, uint16_t reg, uint32_t val);
extern int32_t wrapper_hook_interrupt(int32_t handle, uint32_t *routine, uint32_t *parameter);
extern int32_t wrapper_unhook_interrupt(int32_t handle);
extern int32_t wrapper_special_cycle(uint16_t bus, uint32_t data);
extern int32_t wrapper_get_routing(int32_t handle);
extern int32_t wrapper_set_interrupt(int32_t handle);
extern int32_t wrapper_get_resource(int32_t handle);
extern int32_t wrapper_get_card_used(int32_t handle, uint32_t *address);
extern int32_t wrapper_set_card_used(int32_t handle, uint32_t *callback);
extern int32_t wrapper_read_mem_byte(int32_t handle, uint32_t offset, uint8_t *address);
extern int32_t wrapper_read_mem_word(int32_t handle, uint32_t offset, uint16_t *address);
extern int32_t wrapper_read_mem_longword(int32_t handle, uint32_t offset, uint32_t *address);
extern uint8_t wrapper_fast_read_mem_byte(int32_t handle, uint32_t offset);
extern uint16_t wrapper_fast_read_mem_word(int32_t handle, uint32_t offset);
extern uint32_t wrapper_fast_read_mem_longword(int32_t handle, uint32_t offset);
extern int32_t wrapper_write_mem_byte(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t wrapper_write_mem_word(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t wrapper_write_mem_longword(int32_t handle, uint32_t offset, uint32_t val);
extern int32_t wrapper_read_io_byte(int32_t handle, uint32_t offset, uint8_t *address);
extern int32_t wrapper_read_io_word(int32_t handle, uint32_t offset, uint16_t *address);
extern int32_t wrapper_read_io_longword(int32_t handle, uint32_t offset, uint32_t *address);
extern uint8_t wrapper_fast_read_io_byte(int32_t handle, uint32_t offset);
extern uint16_t wrapper_fast_read_io_word(int32_t handle, uint32_t offset);
extern uint32_t wrapper_fast_read_io_longword(int32_t handle, uint32_t offset);
extern int32_t wrapper_write_io_byte(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t wrapper_write_io_word(int32_t handle, uint32_t offset, uint16_t val);
extern int32_t wrapper_write_io_longword(int32_t handle, uint32_t offset, uint32_t val);
extern int32_t wrapper_get_machine_id(void);
extern int32_t wrapper_get_pagesize(void);
extern int32_t wrapper_virt_to_bus(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t wrapper_bus_to_virt(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t wrapper_virt_to_phys(uint32_t address, PCI_CONV_ADR *pointer);
extern int32_t wrapper_phys_to_virt(uint32_t address, PCI_CONV_ADR *pointer);
#define PCI_MK_CONF_ADDR(bus, device, function) (MCF_PCI_PCICAR_E | \ #define PCI_MK_CONF_ADDR(bus, device, function) (MCF_PCI_PCICAR_E | \
((bus) << 16) | \ ((bus) << 16) | \
((device << 8) | \ ((device << 8) | \

View File

@@ -29,7 +29,7 @@
*/ */
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 84 #define MINOR_VERSION 85
#endif /* VERSION_H_ */ #endif /* VERSION_H_ */

View File

@@ -32,7 +32,7 @@
#error Unknown machine! #error Unknown machine!
#endif #endif
#define DBG_FEC // #define DBG_FEC
#ifdef DBG_FEC #ifdef DBG_FEC
#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
@@ -538,12 +538,19 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
{ {
uint32_t initiator; uint32_t initiator;
int channel; int channel;
#ifdef DBG_FEC
int res; int res;
#endif
/* /*
* Make the initiator assignment * Make the initiator assignment
*/ */
res = dma_set_initiator(DMA_FEC_RX(ch)); #if defined(DBG_FEC)
res =
#else
(void)
#endif
dma_set_initiator(DMA_FEC_RX(ch));
dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res); dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res);
/* /*
@@ -844,15 +851,21 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
{ {
uint32_t initiator; uint32_t initiator;
int channel; int channel;
int result;
void fec0_tx_frame(void); void fec0_tx_frame(void);
void fec1_tx_frame(void); void fec1_tx_frame(void);
#ifdef DBG_FEC
int res; int res;
#endif
/* /*
* Make the initiator assignment * Make the initiator assignment
*/ */
res = dma_set_initiator(DMA_FEC_TX(ch)); #ifdef DBG_FEC
res =
#else
(void)
#endif
dma_set_initiator(DMA_FEC_TX(ch));
dbg("dma_set_initiator(%d) = %d\r\n", ch, res); dbg("dma_set_initiator(%d) = %d\r\n", ch, res);
/* /*
@@ -1284,7 +1297,7 @@ static void fec_irq_handler(uint8_t ch)
*/ */
int fec0_interrupt_handler(void* arg1, void* arg2) int fec0_interrupt_handler(void* arg1, void* arg2)
{ {
(void) arg1; (void) arg1; /* not used */
(void) arg2; (void) arg2;
fec_irq_handler(0); fec_irq_handler(0);
@@ -1294,7 +1307,7 @@ int fec0_interrupt_handler(void* arg1, void* arg2)
int fec1_interrupt_handler(void* arg1, void* arg2) int fec1_interrupt_handler(void* arg1, void* arg2)
{ {
(void) arg1; (void) arg1; /* not used */
(void) arg2; (void) arg2;
fec_irq_handler(1); fec_irq_handler(1);

177
pci/pci.c
View File

@@ -33,9 +33,9 @@
#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: " 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 /* DEBUG_PCI */ #endif /* DEBUG_PCI */
@@ -162,7 +162,7 @@ static int32_t pci_get_interrupt_cause(int32_t *handles)
return handle; return handle;
} }
} }
dbg("%s: no interrupt cause found\r\n", __FUNCTION__); dbg("%s: no interrupt cause found\r\n");
return -1; return -1;
} }
@@ -189,7 +189,7 @@ void irq5_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n", __FUNCTION__); dbg("%s: interrupt not handled!\r\n");
} }
} }
} }
@@ -211,7 +211,7 @@ void irq7_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n", __FUNCTION__); dbg("%s: interrupt not handled!\r\n");
} }
} }
} }
@@ -587,7 +587,168 @@ int32_t pci_unhook_interrupt(int32_t handle)
return PCI_SUCCESSFUL; return PCI_SUCCESSFUL;
} }
/*
* Not implemented PCI_BIOS functions
*/
uint8_t pci_fast_read_config_byte(int32_t handle, uint16_t reg)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint16_t pci_fast_read_config_word(int32_t handle, uint16_t reg)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint32_t pci_fast_read_config_longword(int32_t handle, uint16_t reg)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_special_cycle(uint16_t bus, uint32_t data)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_get_routing(int32_t handle)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_set_interrupt(int32_t handle)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_get_card_used(int32_t handle, uint32_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_set_card_used(int32_t handle, uint32_t *callback)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_mem_byte(int32_t handle, uint32_t offset, uint8_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_mem_word(int32_t handle, uint32_t offset, uint16_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_mem_longword(int32_t handle, uint32_t offset, uint32_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint8_t pci_fast_read_mem_byte(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint16_t pci_fast_read_mem_word(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint32_t pci_fast_read_mem_longword(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_mem_byte(int32_t handle, uint32_t offset, uint16_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_mem_word(int32_t handle, uint32_t offset, uint16_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_mem_longword(int32_t handle, uint32_t offset, uint32_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_io_byte(int32_t handle, uint32_t offset, uint8_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_io_word(int32_t handle, uint32_t offset, uint16_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_read_io_longword(int32_t handle, uint32_t offset, uint32_t *address)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint8_t pci_fast_read_io_byte(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint16_t pci_fast_read_io_word(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
uint32_t pci_fast_read_io_longword(int32_t handle, uint32_t offset)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_io_byte(int32_t handle, uint32_t offset, uint16_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_io_word(int32_t handle, uint32_t offset, uint16_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_write_io_longword(int32_t handle, uint32_t offset, uint32_t val)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_get_machine_id(void)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_get_pagesize(void)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_virt_to_bus(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_bus_to_virt(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_virt_to_phys(uint32_t address, PCI_CONV_ADR *pointer)
{
return PCI_FUNC_NOT_SUPPORTED;
}
int32_t pci_phys_to_virt(uint32_t address, PCI_CONV_ADR *pointer)
{
return PCI_FUNC_NOT_SUPPORTED;
}
/* /*
* pci_device_config() * pci_device_config()
@@ -649,7 +810,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
*/ */
struct pci_rd *rd = &descriptors[barnum]; struct pci_rd *rd = &descriptors[barnum];
dbg("%s: address = %08x\r\n", __FUNCTION__, address); dbg("%s: address = %08x\r\n", address);
if (IS_PCI_MEM_BAR(address)) if (IS_PCI_MEM_BAR(address))
{ {
/* adjust base address to card's alignment requirements */ /* adjust base address to card's alignment requirements */
@@ -738,10 +899,10 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
/* write it to PCIERBAR and enable ROM */ /* write it to PCIERBAR and enable ROM */
pci_write_config_longword(handle, PCIERBAR, swpl(address | 1)); pci_write_config_longword(handle, PCIERBAR, swpl(address | 1));
dbg("%s: set PCIERBAR on device 0x%02x to 0x%08x\r\n", __FUNCTION__, handle, address | 1); dbg("%s: set PCIERBAR on device 0x%02x to 0x%08x\r\n", handle, address | 1);
/* read value back just to be sure */ /* read value back just to be sure */
dbg("%s: PCIERBAR = %p\r\n", __FUNCTION__, swpl(pci_read_config_longword(handle, PCIERBAR))); dbg("%s: PCIERBAR = %p\r\n", swpl(pci_read_config_longword(handle, PCIERBAR)));
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);

469
pci/pci_wrappers.S Normal file
View File

@@ -0,0 +1,469 @@
/*
* pci.S
*
* Purpose: PCI configuration for the Coldfire builtin PCI bridge.
*
* Notes:
*
* This file is part of BaS_gcc.
*
* BaS_gcc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BaS_gcc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
*
* Created on: 08.05.2014
* Author: David Galvez
*/
.global _wrapper_find_pci_device
.global _wrapper_find_pci_classcode
.global _wrapper_read_config_longword
.global _wrapper_read_config_word
.global _wrapper_read_config_byte
.global _wrapper_fast_read_config_byte
.global _wrapper_fast_read_config_word
.global _wrapper_fast_read_config_longword
.global _wrapper_write_config_longword
.global _wrapper_write_config_word
.global _wrapper_write_config_byte
.global _wrapper_get_resource
.global _wrapper_hook_interrupt
.global _wrapper_unhook_interrupt
.global _wrapper_special_cycle
.global _wrapper_get_routing
.global _wrapper_set_interrupt
.global _wrapper_get_resource
.global _wrapper_get_card_used
.global _wrapper_set_card_used
.global _wrapper_read_mem_byte
.global _wrapper_read_mem_word
.global _wrapper_read_mem_longword
.global _wrapper_fast_read_mem_byte
.global _wrapper_fast_read_mem_word
.global _wrapper_fast_read_mem_longword
.global _wrapper_write_mem_byte
.global _wrapper_write_mem_word
.global _wrapper_write_mem_longword
.global _wrapper_read_io_byte
.global _wrapper_read_io_word
.global _wrapper_read_io_longword
.global _wrapper_fast_read_io_byte
.global _wrapper_fast_read_io_word
.global _wrapper_fast_read_io_longword
.global _wrapper_write_io_byte
.global _wrapper_write_io_word
.global _wrapper_write_io_longword
.global _wrapper_get_machine_id
.global _wrapper_get_pagesize
.global _wrapper_virt_to_bus
.global _wrapper_bus_to_virt
.global _wrapper_virt_to_phys
.global _wrapper_phys_to_virt
_wrapper_find_pci_device:
move.l D1,-(SP) // index
move.l D0,-(SP) // Vendor ID
move.l #16,D1
lsr.l D1,D0
move.l D0,-(SP) // Device ID
jsr _pci_find_device
add.l #12,SP
rts
_wrapper_find_pci_classcode:
move.l D1,-(SP) // index
move.l D0,-(SP) // ID
jsr _pci_find_classcode
addq.l #8,SP
rts
_wrapper_read_config_byte:
move.l A0,-(SP) // pointer to space for read data
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_read_config_byte
move.l 8(SP),A0 // PCI_BIOS expects value in memory
move.l D0,(A0)
add.l #12,SP
move.l #0,D0
rts
_wrapper_read_config_word:
move.l A0,-(SP) // pointer to space for read data
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_read_config_word
move.l 8(SP),A0 // little to big endian
move.l D0,(A0)
mvz.b 1(A0),D0
lsl.l #8,D0
move.b (A0),D0
move.l D0,(A0) // PCI_BIOS expects value in memory, not in D0
add.l #12,SP
move.l #0,D0
rts
_wrapper_read_config_longword:
move.l A0,-(SP) // pointer to space for read data
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_read_config_longword
move.l 8(SP),A0 // little to big endian
move.l D0,(A0)
mvz.b 3(A0),D0
lsl.l #8,D0
move.b 2(A0),D0
lsl.l #8,D0
move.b 1(A0),D0
lsl.l #8,D0
move.b (A0),D0
move.l D0,(A0) // PCI_BIOS expects value in memory, not in D0
add.l #12,SP
move.l #0,D0
rts
/* Not implemented */
_wrapper_fast_read_config_byte:
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_fast_read_config_byte
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_config_word:
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_fast_read_config_word
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_config_longword:
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_fast_read_config_longword
addq.l #8,SP
rts
_wrapper_write_config_byte:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_write_config_byte
add.l #12,SP
rts
_wrapper_write_config_word:
move.l D0,-(SP) // make data little endian
moveq #0,D1
move.w D2,D1
lsr.l #8,D1
asl.l #8,D2
or.l D1,D2
move.l (SP)+,D0
move.l D2,-(SP) // data to write
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_write_config_word
add.l #12,SP
rts
_wrapper_write_config_longword:
move.l D0,-(SP)
move.l D2,D0 // make data little endian
lsr.l #8,D0
asl.l #8,D2
and.l #0x00FF00FF,D0
and.l #0xFF00FF00,D2
or.l D0,D2
swap D2
move.l (SP)+,D0
move.l D2,-(SP) // data to write
move.l D1,-(SP) // PCI register
move.l D0,-(SP) // handle
jsr _pci_write_config_longword
add.l #12,SP
rts
_wrapper_hook_interrupt:
move.l A1,-(SP) // parameter for interrupt handler
move.l A0,-(SP) // pointer to interrupt handler
move.l D0,-(SP) // handle
jsr _pci_hook_interrupt
add.l #12,SP
rts
_wrapper_unhook_interrupt:
move.l D0,-(SP) // handle
jsr _pci_unhook_interrupt
addq.l #4,SP
rts
/* Not implemented */
_wrapper_special_cycle:
move.l D1,-(SP) // special cycle data
move.l D0,-(SP) // bus number
jsr _pci_special_cycle
addq.l #8,SP
rts
/* Not implemented */
_wrapper_get_routing:
move.l D0,-(SP) // handle
jsr _pci_get_routing
addq.l #4,SP
rts
/* Not implemented */
_wrapper_set_interrupt:
move.l D1,-(SP) // mode
move.l D0,-(SP) // handle
jsr _pci_set_interrupt
addq.l #8,SP
rts
_wrapper_get_resource:
move.l D0,-(SP) // handle
jsr _pci_get_resource
addq.l #4,SP
rts
/* Not implemented */
_wrapper_get_card_used:
move.l D1,-(SP) // address
move.l D0,-(SP) // handle
jsr _pci_get_card_used
addq.l #8,SP
rts
/* Not implemented */
_wrapper_set_card_used:
move.l A0,-(SP) // callback
move.l D0,-(SP) // handle
jsr _pci_set_card_used
addq.l #8,SP
rts
/* Not implemented */
_wrapper_read_mem_byte:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_byte
add.l #12,SP
rts
/* Not implemented */
_wrapper_read_mem_word:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_word
add.l #12,SP
rts
/* Not implemented */
_wrapper_read_mem_longword:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_longword
add.l #12,SP
rts
/* Not implemented */
_wrapper_fast_read_mem_byte:
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_byte
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_mem_word:
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_word
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_mem_longword:
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_read_mem_longword
addq.l #8,SP
rts
/* Not implemented */
_wrapper_write_mem_byte:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_write_mem_byte
add.l #12,SP
rts
/* Not implemented */
_wrapper_write_mem_word:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_write_mem_word
add.l #12,SP
rts
/* Not implemented */
_wrapper_write_mem_longword:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI memory address space)
move.l D0,-(SP) // handle
jsr _pci_write_mem_longword
add.l #12,SP
rts
/* Not implemented */
_wrapper_read_io_byte:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_byte
add.l #12,SP
rts
/* Not implemented */
_wrapper_read_io_word:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_word
add.l #12,SP
rts
/* Not implemented */
_wrapper_read_io_longword:
move.l A0,-(SP) // pointer to data in memory
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_longword
add.l #12,SP
rts
/* Not implemented */
_wrapper_fast_read_io_byte:
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_byte
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_io_word:
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_word
addq.l #8,SP
rts
/* Not implemented */
_wrapper_fast_read_io_longword:
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_read_io_longword
addq.l #8,SP
rts
/* Not implemented */
_wrapper_write_io_byte:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_write_io_byte
add.l #12,SP
rts
/* Not implemented */
_wrapper_write_io_word:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_write_io_word
add.l #12,SP
rts
/* Not implemented */
_wrapper_write_io_longword:
move.l D2,-(SP) // data to write
move.l D1,-(SP) // address to access (in PCI I/O address space)
move.l D0,-(SP) // handle
jsr _pci_write_io_longword
add.l #12,SP
rts
/* Not implemented */
_wrapper_get_machine_id:
jsr _pci_get_machine_id
rts
/* Not implemented */
_wrapper_get_pagesize:
jsr _pci_get_pagesize
rts
/* Not implemented */
_wrapper_virt_to_bus:
move.l A0,-(SP) // ptr
move.l D1,-(SP) // address in virtual CPU space
move.l D0,-(SP) // handle
jsr _pci_virt_to_bus
add.l #12,SP
rts
/* Not implemented */
_wrapper_bus_to_virt:
move.l A0,-(SP) // ptr
move.l D1,-(SP) // PCI bus address
move.l D0,-(SP) // handle
jsr _pci_bus_to_virt
add.l #12,SP
rts
/* Not implemented */
_wrapper_virt_to_phys:
move.l A0,-(SP) // ptr
move.l D0,-(SP) // address in virtual CPU space
jsr _pci_virt_to_phys
addq.l #8,SP
rts
/* Not implemented */
_wrapper_phys_to_virt:
move.l A0,-(SP) // ptr
move.l D0,-(SP) // physical CPU address
jsr _pci_phys_to_virt
addq.l #8,SP
rts

View File

@@ -44,11 +44,13 @@
* *
*/ */
#include "bas_types.h"
#include "bas_printf.h"
#include "radeonfb.h" #include "radeonfb.h"
#define DBG_RADEON #define DBG_RADEON
#ifdef DBG_RADEON #ifdef DBG_RADEON
#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_RADEON */ #endif /* DBG_RADEON */
@@ -91,7 +93,9 @@ void radeon_set_cursor_colors(struct fb_info *info, int bg, int fg)
if (fg == rinfo->cursor_fg && bg == rinfo->cursor_bg) if (fg == rinfo->cursor_fg && bg == rinfo->cursor_bg)
return; return;
CURSOR_SWAPPING_START(); CURSOR_SWAPPING_START();
/* Note: We assume that the pixels are either fully opaque or fully
/*
* Note: We assume that the pixels are either fully opaque or fully
* transparent, so we won't premultiply them, and we can just * transparent, so we won't premultiply them, and we can just
* check for non-zero pixel values; those are either fg or bg * check for non-zero pixel values; those are either fg or bg
*/ */
@@ -118,10 +122,12 @@ void radeon_set_cursor_position(struct fb_info *info, int x, int y)
xorigin = 1 - x; xorigin = 1 - x;
if (y < 0) if (y < 0)
yorigin = 1 - y; yorigin = 1 - y;
// DPRINTVALHEX("radeonfb: RADEONSetCursorPosition: cursor_start ",rinfo->cursor_start); // DPRINTVALHEX("radeonfb: RADEONSetCursorPosition: cursor_start ",rinfo->cursor_start);
// DPRINTVAL(" x ",x); // DPRINTVAL(" x ",x);
// DPRINTVAL(" y ",y); // DPRINTVAL(" y ",y);
// DPRINT("\r\n"); // DPRINT("\r\n");
OUTREG(CUR_HORZ_VERT_OFF, (CUR_LOCK | (xorigin << 16) | yorigin)); OUTREG(CUR_HORZ_VERT_OFF, (CUR_LOCK | (xorigin << 16) | yorigin));
OUTREG(CUR_HORZ_VERT_POSN, (CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); OUTREG(CUR_HORZ_VERT_POSN, (CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
OUTREG(CUR_OFFSET, rinfo->cursor_start + yorigin * 256); OUTREG(CUR_OFFSET, rinfo->cursor_start + yorigin * 256);
@@ -132,7 +138,8 @@ void radeon_set_cursor_position(struct fb_info *info, int x, int y)
rinfo->cursor_y = (unsigned long) y; rinfo->cursor_y = (unsigned long) y;
} }
/* Copy cursor image from `image' to video memory. RADEONSetCursorPosition /*
* Copy cursor image from `image' to video memory. RADEONSetCursorPosition
* will be called after this, so we can ignore xorigin and yorigin. * will be called after this, so we can ignore xorigin and yorigin.
*/ */
void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsigned short *data, int zoom) void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsigned short *data, int zoom)
@@ -143,11 +150,14 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
unsigned short chunk, mchunk; unsigned short chunk, mchunk;
unsigned long i, j, k; unsigned long i, j, k;
CURSOR_SWAPPING_DECL CURSOR_SWAPPING_DECL
// DPRINTVALHEX("radeonfb: RADEONLoadCursorImage: cursor_start ",rinfo->cursor_start); // DPRINTVALHEX("radeonfb: RADEONLoadCursorImage: cursor_start ",rinfo->cursor_start);
// DPRINT("\r\n"); // DPRINT("\r\n");
save = INREG(CRTC_GEN_CNTL) & ~(unsigned long) (3 << 20); save = INREG(CRTC_GEN_CNTL) & ~(unsigned long) (3 << 20);
save |= (unsigned long) (2 << 20); save |= (unsigned long) (2 << 20);
OUTREG(CRTC_GEN_CNTL, save & (unsigned long)~CRTC_CUR_EN); OUTREG(CRTC_GEN_CNTL, save & (unsigned long)~CRTC_CUR_EN);
/* /*
* Convert the bitmap to ARGB32. * Convert the bitmap to ARGB32.
*/ */
@@ -282,6 +292,7 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
void radeon_hide_cursor(struct fb_info *info) void radeon_hide_cursor(struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
// DPRINT("radeonfb: RADEONHideCursor\r\n"); // DPRINT("radeonfb: RADEONHideCursor\r\n");
OUTREGP(CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN); OUTREGP(CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
rinfo->cursor_show = 0; rinfo->cursor_show = 0;
@@ -291,6 +302,7 @@ void radeon_hide_cursor(struct fb_info *info)
void radeon_show_cursor(struct fb_info *info) void radeon_show_cursor(struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
// DPRINT("radeonfb: RADEONShowCursor\r\n"); // DPRINT("radeonfb: RADEONShowCursor\r\n");
OUTREGP(CRTC_GEN_CNTL, CRTC_CUR_EN, ~CRTC_CUR_EN); OUTREGP(CRTC_GEN_CNTL, CRTC_CUR_EN, ~CRTC_CUR_EN);
rinfo->cursor_show = 1; rinfo->cursor_show = 1;
@@ -303,7 +315,7 @@ long radeon_cursor_init(struct fb_info *info)
int size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; int size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT;
unsigned long fbarea = offscreen_alloc(rinfo->info, size_bytes + 256); unsigned long fbarea = offscreen_alloc(rinfo->info, size_bytes + 256);
dbg("radeonfb: %s: fbarea: %p\r\n", __FUNCTION__, fbarea); dbg("radeonfb: %s: fbarea: %p\r\n", fbarea);
if (!fbarea) if (!fbarea)
rinfo->cursor_start = 0; rinfo->cursor_start = 0;

View File

@@ -442,10 +442,11 @@ void BaS(void)
/* Jump into the OS */ /* Jump into the OS */
typedef void void_func(void); typedef void void_func(void);
typedef struct { struct rom_header
{
void *initial_sp; void *initial_sp;
void_func *initial_pc; void_func *initial_pc;
} ROM_HEADER; };
xprintf("BaS initialization finished, enable interrupts\r\n"); xprintf("BaS initialization finished, enable interrupts\r\n");
enable_coldfire_interrupts(); enable_coldfire_interrupts();
@@ -454,6 +455,6 @@ void BaS(void)
network_init(); network_init();
xprintf("call EmuTOS\r\n"); 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(); os_header->initial_pc();
} }

View File

@@ -20,8 +20,6 @@
* Author: Markus Fröschle * Author: Markus Fröschle
*/ */
#define DBG_EXC
#include "startcf.h" #include "startcf.h"
#if MACHINE_FIREBEE #if MACHINE_FIREBEE
#include "firebee.h" #include "firebee.h"
@@ -63,6 +61,7 @@
#define MCF_EPORT_EPFR __MBAR+0xF0C #define MCF_EPORT_EPFR __MBAR+0xF0C
#define MCF_GPIO_PODR_FEC1L __MBAR+0xA07 #define MCF_GPIO_PODR_FEC1L __MBAR+0xA07
#define MCF_PSC0_PSCTB_8BIT __MBAR+0x860C #define MCF_PSC0_PSCTB_8BIT __MBAR+0x860C
#define MCF_PSC3_PSCRB_8BIT __MBAR+0x890C #define MCF_PSC3_PSCRB_8BIT __MBAR+0x890C
@@ -125,9 +124,8 @@
// Atari register equates (provided by FPGA) // Atari register equates (provided by FPGA)
.equ vbasehi, 0xffff8201 .equ vbasehi, 0xffff8201
//mmu ---------------------------------------------------
/* MMU register read/write macros */ /* Register read/write macros */
#define MCF_MMU_MMUCR __MMUBAR #define MCF_MMU_MMUCR __MMUBAR
#define MCF_MMU_MMUOR __MMUBAR+0x04 #define MCF_MMU_MMUOR __MMUBAR+0x04
#define MCF_MMU_MMUSR __MMUBAR+0x08 #define MCF_MMU_MMUSR __MMUBAR+0x08
@@ -187,11 +185,27 @@
.equ MCD_TT_FLAGS_RL, 0x1 .equ MCD_TT_FLAGS_RL, 0x1
.equ MCD_TT_FLAGS_SP, 0x4 .equ MCD_TT_FLAGS_SP, 0x4
.equ DMA_ALWAYS, 0 .equ DMA_ALWAYS, 0
//---------------------------------------------------
/*********************************************************************
*
* General Purpose Timers (GPT)
*
*********************************************************************/
/* Register read/write macros */ /* Register read/write macros */
#define MCF_GPT0_GMS __MBAR+0x800 #define MCF_GPT0_GMS __MBAR+0x800
/*********************************************************************
*
* Slice Timers (SLT)
*
*********************************************************************/
#define MCF_SLT0_SCNT __MBAR+0x908 #define MCF_SLT0_SCNT __MBAR+0x908
/**********************************************************/
// macros
/**********************************************************/
.altmacro .altmacro
.macro irq vector,int_mask,clr_int .macro irq vector,int_mask,clr_int
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
@@ -239,7 +253,6 @@ _vec_init:
movec d0,VBR movec d0,VBR
move.l d0,a0 move.l d0,a0
move.l a0,a2 move.l a0,a2
init_vec: init_vec:
move.l #256,d0 move.l #256,d0
lea std_exc_vec(pc),a1 // standard vector lea std_exc_vec(pc),a1 // standard vector
@@ -253,7 +266,7 @@ init_vec_loop:
lea reset_vector(pc),a1 // set reset vector lea reset_vector(pc),a1 // set reset vector
move.l a1,0x04(a0) move.l a1,0x04(a0)
lea access_exception(pc),a1 // set illegal access exception handler lea access(pc),a1 // set illegal access exception handler
move.l a1,0x08(a0) move.l a1,0x08(a0)
.extern _get_bas_drivers .extern _get_bas_drivers
@@ -308,8 +321,6 @@ init_vec_loop:
move.l (sp)+,a2 // Restore registers move.l (sp)+,a2 // Restore registers
rts rts
/* /*
* exception vector routines * exception vector routines
*/ */
@@ -372,40 +383,52 @@ reset_vector:
beq std_exc_vec // yes-> beq std_exc_vec // yes->
jmp _rom_entry // no, cold start machine jmp _rom_entry // no, cold start machine
// access:
// Triggered when code tries to access a memory area that is not known to the MMU yet. move.w #0x2700,sr // disable interrupt
// This is either a "classic" bus error or the MMU hit a "legal" page not yet mapped. move.l d0,-(sp) // ++ vr
//
access_exception:
move.w #0x2700,sr // avoid us being interrupted by the video handler
// (this would probably overwrite the MMUAR register)
// save gcc scratch registers, others will be handled by called function move.w 4(sp),d0 // get format_status word from stack
lea -4*4(sp),sp andi.l #0x0c03,d0 // mask out fault status bits
movem.l d0-d1/a0-a1,(sp) cmpi.l #0x0401,d0 // TLB miss on opword of instruction fetch?
beq access_mmu // yes
cmpi.l #0x0402,d0 // TLB miss on extension word of instruction fetch?
beq access_mmu // yes
cmpi.l #0x0802,d0 // TLB miss on data write?
beq access_mmu // yes
cmpi.l #0x0c02,d0 // TLB miss on data read, or read-modify-write?
beq access_mmu // yes
bra bus_error // everything else is a classic bus error
lea 4*4(sp),a0 // original stack pointer access_mmu:
move.l MCF_MMU_MMUSR,d0 // did the last fault hit in TLB?
btst #1,d0 // yes, it did. So we already mapped that page
bne bus_error // and this must be a real bus error
move.l (a0),-(sp) // format status word move.l MCF_MMU_MMUAR,d0
move.l 4(a0),-(sp) // program counter at access error cmp.l #__FASTRAM_END,d0 // above max User RAM area?
bge bus_error // -> bus error
jsr _access_exception // note the underscore lea -5*4(sp),sp // save gcc scratch registers
lea 2*4(sp),sp // adjust stack movem.l d0-d1/a0-a2,(sp)
tst.l d0 // handled? move.l d0,-(sp) // fault address
jsr _mmutr_miss // else we have an MMU TLB miss
addq.l #4,sp
movem.l (sp),d0-d1/a0-a1 // restore scratch registers movem.l (sp),d0-d1/a0-a2 // restore gcc scratch registers
lea 4*4(sp),sp lea 5*4(sp),sp
beq bus_error // no move.l (sp)+,d0 // restore register
rte rte
bus_error: bus_error:
move.l (sp)+,d0 // restore register
bra std_exc_vec bra std_exc_vec
zero_divide: zero_divide:
move.w #0x2700,sr // disable interrupt
move.l a0,-(a7) move.l a0,-(a7)
move.l d0,-(a7) move.l d0,-(a7)
move.l 12(a7),a0 // pc move.l 12(a7),a0 // pc
@@ -435,6 +458,31 @@ zd_end:
move.l (a7)+,a0 move.l (a7)+,a0
rte rte
#ifdef _NOT_USED_
linea:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
linef:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
format:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
//floating point
flpoow:
move.w #0x2700,sr // disable interrupt
halt
nop
nop
#endif /* _NOT_USED */
irq1: irq1:
irq 0x64,1,0x02 irq 0x64,1,0x02
@@ -449,7 +497,7 @@ irq3:
irq4: // vbl irq4: // vbl
irq 0x70,4,0x10 irq 0x70,4,0x10
#if MACHINE_M5484LITE // handlers for M5484LITE #if MACHINE_M5484LITE_notyet // handlers for M5484LITE
irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
@@ -490,43 +538,11 @@ irq7text:
.dc.b 13,10,0 .dc.b 13,10,0
#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ #elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */
irq5: irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE
irq 0x74,5,0x20 irq 0x74,5,0x20
.extern _irq6_interrupt_handler // highlevel C handler
irq6: // MFP interrupt from FPGA irq6: // MFP interrupt from FPGA
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupt
lea -4 * 4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp)
move.l 4 * 4(sp),-(sp) // push original exception stack frame
move.l 5 * 4(sp),-(sp)
jsr _irq6_interrupt_handler // call highlevel C handler
lea.l 2 * 4(sp),sp
tst.l d0 // completely handled?
movem.l (sp),d0-d1/a0-a1 // restore registers saved above
lea 4 * 4(sp),sp // adjust stack
beq irq6_os // call OS handler
rte
irq6_os: // call native OS irq6 handler
move.l a5,-(sp) // save registers: TODO: this could be done more effective
move.l d0,-(sp)
move.l 0xf0020000,a5 // fetch vector
add.l _rt_vbr,a5 // add vector base
move.l (a5),d0 // fetch handler
move.l 4(sp),a5 // restore a5
move.l d0,4(sp) // prepare indirect return
move.l (sp)+,d0 // restore d0
move.w #0x2600,sr // set interrupt mask
rts
#ifdef _NOT_USED_ /* functionality moved to _irq6_interrupt_handler() (C) */
subq.l #8,a7 subq.l #8,a7
movem.l d0/a5,(a7) // save registers movem.l d0/a5,(a7) // save registers
@@ -587,6 +603,46 @@ irq6_sca_pn1c:
move.l d3,a1 move.l d3,a1
move.l #0x10000,d4 // one whole page (1 MB) move.l #0x10000,d4 // one whole page (1 MB)
#define _DO_CPU_COPY
#ifndef _DO_CPU_COPY
// experiment: do video page copy using Coldfire DMA
lea -15 * 4(sp),sp
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
clr.l -(sp) // no special functions
move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp)
mov3q #7,-(sp) // highest DMA priority
move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA
move.l #1,-(sp) // copy 4 bytes at a time
move.l #0x100000,-(sp) // copy 1 Megabyte
move.l #4,-(sp) // destination increment
move.l a1,-(sp) // destination adress
move.l #4,-(sp) // source increment
move.l a0,-(sp) // source adress
move.l #1,-(sp) // channel 1
jsr _MCD_startDma
movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers
lea 15 * 4(sp),sp // adjust stack
wait_dma_finished:
clr.l -(sp)
jsr _MCD_dmaStatus
addq.l #4,sp
tst.l d0
cmp.l #6,d0
bne wait_dma_finished
#else
irq6_vcd0_loop:
move.l (a0)+,(a1)+ // page copy
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
subq.l #1,d4
bne irq6_vcd0_loop
#endif /* _DO_CPU_COPY */
irq6_sca_pn: irq6_sca_pn:
add.l #0x00100000,d3 // next add.l #0x00100000,d3 // next
cmp.l #0x00d00000,d3 // ende? cmp.l #0x00d00000,d3 // ende?
@@ -626,7 +682,12 @@ irq6_1:
lea MCF_GPIO_PODR_FEC1L,a5 lea MCF_GPIO_PODR_FEC1L,a5
bset.b #4,(a5) // led off bset.b #4,(a5) // led off
irq6_2: irq6_2:
move.l 0xf0020000,a5 // vector holen // test auf protect mode ---------------------
move.b DIP_SWITCHa,d0
btst #7,d0
bne irq6_3 // ja->
// -------------------------------------------
move.l 0xF0020000,a5 // vector holen
add.l _rt_vbr,a5 // basis add.l _rt_vbr,a5 // basis
move.l (a5),d0 // vector holen move.l (a5),d0 // vector holen
move.l 4(a7),a5 // a5 zurück move.l 4(a7),a5 // a5 zurück
@@ -634,6 +695,33 @@ irq6_2:
move.l (a7)+,d0 // d0 zurück move.l (a7)+,d0 // d0 zurück
move #0x2600,sr move #0x2600,sr
rts rts
irq6_3:
move.l usp,a5 // usp holen
tst.b _rt_mod // supervisor?
bne sev_sup6 // ja ->
mov3q.l #-1,_rt_mod // auf supervisor setzen
move.l a5,_rt_usp // rt_usp speichern
move.l _rt_ssp,a5 // rt_ssp holen
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr transferieren
move.l a5,usp // usp setzen
move.l 0xF0020000,a5 // vector holen: intack routine
add.l _rt_vbr,a5 // virtuelle VBR des Systems
move.l (a5),12(a7) // hier gehts weiter
movem.l (a7),d0/a5 // register zurück
addq.l #8,a7
move.b #6,2(a7) // intmaske setzen
rte // und weg
sev_sup6:
move.l 12(a7),-(a5) // pc transferieren
move.l 8(a7),-(a5) // sr,vec
bset #5,2(a5) // auf super setzen
move.l a5,usp // usp setzen
move.l 0xF0020000,a5 // vector holen: intack routine
add.l _rt_vbr,a5 // virtuelle VBR des Systems
move.l (a5),12(a7) // hier gehts weiter
movem.l (a7),d0/a5 // register zurück
rts
.data .data
blinker:.long 0 blinker:.long 0
@@ -704,9 +792,6 @@ acsi_dma_end:
move.l (a7)+,d1 move.l (a7)+,d1
move.l (a7)+,a1 move.l (a7)+,a1
rts rts
#endif /* _NOT_USED_ */
/* /*
* irq 7 = pseudo bus error * irq 7 = pseudo bus error
*/ */
@@ -736,20 +821,40 @@ irq7:
* psc3 com PIC MCF * psc3 com PIC MCF
*/ */
handler_psc3: handler_psc3:
.extern _pic_interrupt_handler
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
lea -4 * 4(sp),sp // save gcc scratch registers lea -20(a7),a7
movem.l d0-d1/a0-a1,(sp) movem.l d0-d2/a0/a3,(a7)
lea MCF_PSC3_PSCRB_8BIT,a3
move.b (a3),d1
cmp.b #2,d1 // anforderung rtc daten?
bne psc3_fertig
jsr _pic_interrupt_handler // call high level interrupt handler lea MCF_PSC0_PSCTB_8BIT,a0 // ++ vr
mchar move.l,'\P,'\I,'C,' ,(a0)
mchar move.l,'I,'N,'T,'\ ,(a0)
mchar move.l,'R,'T,'C,'!,(a0)
mchar move.l,0x0d,0x0a,0,0,(a0)
movem.l (sp),d0-d1/a0-a1 // restore registers lea 0xffff8961,a0
rte lea MCF_PSC3_PSCTB_8BIT,a3
clr.l d1
moveq #64,d2
move.b #0x82,(a3) // header: rtcd mcf->pic
loop_sr2:
move.b d1,(a0)
move.b 2(a0),d0
move.b d0,(a3)
addq.l #1,d1
cmp.b d1,d2
bne loop_sr2
psc3_fertig:
movem.l (a7),d0-d2/a0/a3 // restore saved registers
lea 20(a7),a7
RTE
/* /*
* general purpose timer 0 (GPT0): video change, later also others. GPT0 is used as * general purpose timer 0 (GPT0): video change, later also others. GPT0 is used as
* input trigger. It is connected to the TIN0 signal of the FPGA which triggers it everytime * input trigger. It is connected to the TIN0 signal of the FPGA and triggers everytime
* vbasehi is written to, i.e. when the video base address gets changed * vbasehi is written to, i.e. when the video base address gets changed
*/ */
handler_gpt0: handler_gpt0:
@@ -763,12 +868,11 @@ handler_gpt0:
blt video_chg_end // yes, do nothing blt video_chg_end // yes, do nothing
cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped
// to 60d00000 (FPGA video memory) // to 60d00000 (FPGA video memory)
blt sca_other blt sca_other //
lea MCF_SLT0_SCNT,a0 lea MCF_SLT0_SCNT,a0
move.l (a0),_video_sbt // save time move.l (a0),_video_sbt // save time
bra video_chg_end
// FIXME: don't we need to get out here? // FIXME: don't we need to get out here?
sca_other: sca_other:
@@ -797,6 +901,38 @@ video_copy_data:
add.l #0x60000000,a1 add.l #0x60000000,a1
move.l #0x10000,d4 // whole page move.l #0x10000,d4 // whole page
#ifndef _DO_CPU_COPY
// experiment: do video page copy using Coldfire DMA
lea -15 * 4(sp),sp
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
clr.l -(sp) // no special functions
move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp)
mov3q #7,-(sp) // highest DMA priority
move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA
move.l #1,-(sp) // copy 4 bytes at a time
move.l #0x100000,-(sp) // copy 1 Megabyte
move.l #4,-(sp) // destination increment
move.l a1,-(sp) // destination adress
move.l #4,-(sp) // source increment
move.l a0,-(sp) // source adress
move.l #1,-(sp) // channel 1
jsr _MCD_startDma
.wait_dma_finished:
clr.l -(sp)
jsr _MCD_dmaStatus
addq.l #4,sp
tst.l d0
cmp.l #6,d0
bne .wait_dma_finished
movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers
lea 15 * 4(sp),sp // adjust stack
#else
video_copy_data_loop: video_copy_data_loop:
move.l (a0)+,(a1)+ // copy video page contents to real screen move.l (a0)+,(a1)+ // copy video page contents to real screen
move.l (a0)+,(a1)+ move.l (a0)+,(a1)+
@@ -804,6 +940,7 @@ video_copy_data_loop:
move.l (a0)+,(a1)+ move.l (a0)+,(a1)+
subq.l #1,d4 subq.l #1,d4
bne video_copy_data_loop bne video_copy_data_loop
#endif
// eintrag suchen // eintrag suchen
move.l d0,MCF_MMU_MMUAR // adress move.l d0,MCF_MMU_MMUAR // adress
@@ -822,7 +959,6 @@ video_copy_data_loop:
move.l d1,MCF_MMU_MMUDR move.l d1,MCF_MMU_MMUDR
move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data
nop nop
video_chg_2page: video_chg_2page:
// test of adjacent page is needed also // test of adjacent page is needed also
move.l d3,d0 move.l d3,d0

View File

@@ -33,10 +33,16 @@
#define FPGA_DATA0 (1 << 3) #define FPGA_DATA0 (1 << 3)
#define FPGA_CONF_DONE (1 << 5) #define FPGA_CONF_DONE (1 << 5)
extern uint8_t _FPGA_FLASH_DATA[]; extern uint8_t _FPGA_CONFIG[];
#define FPGA_FLASH_DATA &_FPGA_FLASH_DATA[0] #define FPGA_FLASH_DATA &_FPGA_CONFIG[0]
extern uint8_t _FPGA_FLASH_DATA_SIZE[]; extern uint8_t _FPGA_CONFIG_SIZE[];
#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_FLASH_DATA_SIZE[0]) #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;
void config_gpio_for_fpga_config(void) void config_gpio_for_fpga_config(void)
{ {
@@ -78,7 +84,15 @@ bool init_fpga(void)
volatile int32_t time, start, end; volatile int32_t time, start, end;
int i; int i;
xprintf("FPGA load config... "); 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; start = MCF_SLT0_SCNT;
config_gpio_for_fpga_config(); config_gpio_for_fpga_config();

571
sys/mmu.c
View File

@@ -24,6 +24,26 @@
* Copyright 2013 M. Froeschle * Copyright 2013 M. Froeschle
*/ */
#define ACR_BA(x) ((x) & 0xffff0000)
#define ACR_ADMSK(x) (((x) & 0xffff) << 16)
#define ACR_E(x) (((x) & 1) << 15)
#define ACR_S(x) (((x) & 3) << 13)
#define ACR_S_USERMODE 0
#define ACR_S_SUPERVISOR_MODE 1
#define ACR_S_ALL 2
#define ACR_AMM(x) (((x) & 1) << 10)
#define ACR_CM(x) (((x) & 3) << 5)
#define ACR_CM_CACHEABLE_WT 0x0
#define ACR_CM_CACHEABLE_CB 0x1
#define ACR_CM_CACHE_INH_PRECISE 0x2
#define ACR_CM_CACHE_INH_IMPRECISE 0x3
#define ACR_SP(x) (((x) & 1) << 3)
#define ACR_W(x) (((x) & 1) << 2)
#include <stdint.h> #include <stdint.h>
#include "bas_printf.h" #include "bas_printf.h"
#include "bas_types.h" #include "bas_types.h"
@@ -42,12 +62,12 @@
#error "unknown machine!" #error "unknown machine!"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
#define DBG_MMU //#define DEBUG_MMU
#ifdef DBG_MMU #ifdef DEBUG_MMU
#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg);} while(0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg);} while(0)
#else #else
#define dbg(format, arg...) do {;} while (0) #define dbg(format, arg...) do {;} while (0)
#endif /* DBG_MMU */ #endif /* DEBUG_MMU */
/* /*
* set ASID register * set ASID register
@@ -169,356 +189,257 @@ inline uint32_t set_mmubar(uint32_t value)
return ret; return ret;
} }
/*
* TODO: this would be nicer in an include file
*/
extern uint8_t _SYS_SRAM[];
#define SYS_SRAM_ADDRESS ((uint32_t) &_SYS_SRAM[0])
extern uint8_t _SYS_SRAM_SIZE[];
extern uint8_t _FASTRAM_END[];
struct mmu_mapping
{
uint32_t phys;
uint32_t virt;
uint32_t length;
uint32_t pagesize;
struct map_flags flags;
};
static struct mmu_mapping locked_map[] =
{
{
/* Falcon video memory. Needs special care */
0x60d00000,
0xd00000,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, SCA_PAGE_ID, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
};
static int num_locked_mmu_maps = sizeof(locked_map) / sizeof(struct mmu_mapping);
static struct mmu_mapping memory_map[] =
{
/* map OS system vectors supervisor-protected */
{
0,
0,
0x800,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
0x800,
0x800,
0x800,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* when the first 4k are filled with 1k pages, we can switch to 8k pages */
0x1000,
0x1000,
0xff000,
MMU_PAGE_SIZE_8K,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* arrived at a 1Meg border, we can switch to 1Meg pages */
0x100000,
0x100000,
0xc00000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
/* Falcon video ram left out intentionally here (see above) */
{
/* ROM */
0xe00000,
0xe00000,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_EXECUTE },
},
{
/* FASTRAM */
0x1000000,
0x1000000,
(uint32_t) _FASTRAM_END - 0x1000000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* MBAR */
MBAR_ADDRESS,
MBAR_ADDRESS,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* RAMBAR0 */
RAMBAR0_ADDRESS,
RAMBAR0_ADDRESS,
(uint32_t) _RAMBAR0_SIZE,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* RAMBAR1 */
RAMBAR1_ADDRESS,
RAMBAR1_ADDRESS,
(uint32_t) _RAMBAR1_SIZE,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* SYSTEM SRAM */
SYS_SRAM_ADDRESS,
SYS_SRAM_ADDRESS,
(uint32_t) _SYS_SRAM_SIZE,
MMU_PAGE_SIZE_8K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* Firebee FPGA registers */
(uint32_t) 0xf0000000,
(uint32_t) 0xf0000000,
(uint32_t) 0x08000000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* Falcon I/O registers */
(uint32_t) 0xfff00000,
(uint32_t) 0xfff00000,
(uint32_t) 0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* the same, but different virtual address */
(uint32_t) 0x00f00000,
(uint32_t) 0xfff00000,
(uint32_t) 0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* PCI memory */
(uint32_t) PCI_MEMORY_OFFSET,
(uint32_t) PCI_MEMORY_OFFSET,
(uint32_t) PCI_MEMORY_SIZE,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* PCI I/O */
(uint32_t) PCI_IO_OFFSET,
(uint32_t) PCI_IO_OFFSET,
(uint32_t) PCI_IO_SIZE,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
}
};
static int num_mmu_maps = sizeof(memory_map) / sizeof(struct mmu_mapping);
static struct mmu_mapping *lookup_mapping(uint32_t virt)
{
int i;
/*
* dumb, for now
*/
for (i = 0; i < num_mmu_maps; i++)
{
if (virt >= memory_map[i].virt && virt <= memory_map[i].virt + memory_map[i].length - 1)
return &memory_map[i];
}
return NULL;
}
void mmu_init(void) void mmu_init(void)
{ {
extern uint8_t _MMUBAR[]; extern uint8_t _MMUBAR[];
uint32_t MMUBAR = (uint32_t) &_MMUBAR[0]; uint32_t MMUBAR = (uint32_t) &_MMUBAR[0];
int i; 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_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */
/*
* need to set data ACRs in a way that supervisor access to all memory regions
* becomes possible. Otherways it might be that the supervisor stack ends up in an unmapped
* region when further MMU TLB entries force a page steal. This would lead to a double
* fault since the CPU wouldn't be able to push its exception stack frame during an access
* exception
*/
/* set data access attributes in ACR0 and ACR1 */ /* set data access attributes in ACR0 and ACR1 */
set_acr0(ACR_W(0) | /* read and write accesses permitted */
set_acr0(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ ACR_SP(0) | /* supervisor and user mode access permitted */
ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* cache inhibit, precise */
ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ ACR_AMM(0) | /* control region > 16 MB */
ACR_ADDRESS_MASK_MODE(1) | /* region 13 MByte */ ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */
ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */
ACR_E(1) | /* enable ACR */ ACR_E(1) | /* enable ACR */
ACR_ADMSK(0x0a) | /* cover 12 MByte from 0x0 */ #if defined(MACHINE_FIREBEE)
ACR_BA(0)); /* start from 0x0 */ ACR_ADMSK(0x7f) | /* cover 2GB area from 0x80000000 to 0xffffffff */
ACR_BA(0x80000000)); /* (equals area from 3 to 4 GB */
#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(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */ // set_acr1(0x601fc000);
ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */ set_acr1(ACR_W(0) |
ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */ ACR_SP(0) |
ACR_ADDRESS_MASK_MODE(0) | /* region > 16 MByte */ ACR_CM(0) |
ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */ #if defined(MACHINE_FIREBEE)
ACR_E(1) | /* enable ACR */ ACR_CM(ACR_CM_CACHEABLE_WT) | /* video RAM on the Firebee */
ACR_ADMSK(0x1f) | /* cover 495 MByte from 0x1000000 */ #elif defined(MACHINE_M5484LITE)
ACR_BA(0x01000000)); /* all Fast RAM */ 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
* set instruction access attributes in ACR2 and ACR3. This is the same as above, basically: #error unknown machine!
* enable supervisor access to all SDRAM #endif /* MACHINE_FIREBEE */
*/ ACR_AMM(0) |
ACR_S(ACR_S_ALL) |
set_acr2(ACR_WRITE_PROTECT(0) |
ACR_SUPERVISOR_PROTECT(0) |
ACR_CACHE_MODE(CACHE_WRITETHROUGH) |
ACR_ADDRESS_MASK_MODE(1) |
ACR_S(ACR_S_SUPERVISOR_MODE) |
ACR_E(1) |
ACR_ADMSK(0x0c) |
ACR_BA(0x0));
set_acr3(ACR_WRITE_PROTECT(0) |
ACR_SUPERVISOR_PROTECT(0) |
ACR_CACHE_MODE(CACHE_WRITETHROUGH) |
ACR_ADDRESS_MASK_MODE(0) |
ACR_S(ACR_S_SUPERVISOR_MODE) |
ACR_E(1) | ACR_E(1) |
ACR_ADMSK(0x1f) | ACR_ADMSK(0x1f) |
ACR_BA(0x0f)); ACR_BA(0x60000000));
/* set instruction access attributes in ACR2 and ACR3 */
//set_acr2(0xe007c400);
set_acr2(ACR_W(0) |
ACR_SP(0) |
ACR_CM(0) |
ACR_CM(ACR_CM_CACHEABLE_WT) |
ACR_AMM(1) |
ACR_S(ACR_S_ALL) |
ACR_E(1) |
ACR_ADMSK(0x7) |
ACR_BA(0xe0000000));
/* disable ACR3 */
set_acr3(0x0);
set_mmubar(MMUBAR + 1); /* set and enable MMUBAR */ set_mmubar(MMUBAR + 1); /* set and enable MMUBAR */
/* clear all MMU TLB entries */ /* clear all MMU TLB entries */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA; MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA;
/* map locked TLB entries */ /* create locked TLB entries */
for (i = 0; i < num_locked_mmu_maps; i++)
{
mmu_map_page(locked_map[i].virt, locked_map[i].phys, locked_map->pagesize, locked_map->flags);
if (locked_map[i].flags.page_id == SCA_PAGE_ID) /*
{ * 0x0000'0000 - 0x000F'FFFF (first MB of physical memory) locked virtual = physical
video_tlb = 0x2000; */
video_sbt = 0x0; MCF_MMU_MMUTR = 0x0 | /* virtual address */
} MCF_MMU_MMUTR_SG | /* shared global */
} MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = 0x0 | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x1) | /* cacheable, copyback */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
/*
* 0x00d0'0000 - 0x00df'ffff (last megabyte of ST RAM = Falcon video memory) locked ID = 6
* 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) |
#endif /* MACHINE_FIREBEE */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
#if defined(MACHINE_FIREBEE)
/* map FPGA video memory for FireBee only */
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 */
/* caveat: can't be supervisor protected since TOS puts the application stack there! */
//MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#if defined(MACHINE_FIREBEE)
video_tlb = 0x2000; /* set page as video page */
video_sbt = 0x0; /* clear time */
#endif /* MACHINE_FIREBEE */
/*
* Make the TOS (in SDRAM) read-only
* This maps virtual 0x00e0'0000 - 0x00ef'ffff to the same virtual address
*/
MCF_MMU_MMUTR = TOS | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = TOS | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x1) | /* cachable copyback */
MCF_MMU_MMUDR_R | /* read access enable */
//MCF_MMU_MMUDR_W | /* write access enable (FIXME: for now) */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#if MACHINE_FIREBEE
/*
* Map FireBee I/O area (0xfff0'0000 - 0xffff'ffff physical) to the Falcon-compatible I/O
* area (0x00f0'0000 - 0x00ff'ffff virtual) for the FireBee
*/
MCF_MMU_MMUTR = 0x00f00000 | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = 0xfff00000 | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x2) | /* nocache precise */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#endif /* MACHINE_FIREBEE */
/*
* Map (locked) the second last MB of physical SDRAM (this is where BaS .data and .bss reside) to the same
* virtual address. This is also used when BaS is in RAM
*/
MCF_MMU_MMUTR = (SDRAM_START + SDRAM_SIZE - 0x00200000) | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (SDRAM_START + SDRAM_SIZE - 0x00200000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x0) | /* cacheable writethrough */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
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.
*/
MCF_MMU_MMUTR = (SDRAM_START + SDRAM_SIZE - 0x00100000) | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (SDRAM_START + SDRAM_SIZE - 0x00100000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x2) | /* nocache precise */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
//MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
} }
/* void mmutr_miss(uint32_t address)
* handle an access error
* upper level routine called from access_exception inside exceptions.S
*/
bool access_exception(uint32_t pc, uint32_t format_status)
{ {
int fault_status; dbg("MMU TLB MISS at 0x%08x\r\n", address);
uint32_t fault_address; flush_and_invalidate_caches();
uint32_t mmu_status;
/* switch (address)
* extract fault status from format_status exception stack field
*/
fault_status = format_status & 0xc030000;
mmu_status = MCF_MMU_MMUSR;
/*
* determine if access fault was caused by a TLB miss
*/
switch (fault_status)
{ {
case 0x4010000: /* TLB miss on opword of instruction fetch */ case keyctl:
case 0x4020000: /* TLB miss on extension word of instruction fetch */ case keybd:
//fault_address = pc; /* do something to emulate the IKBD access */
//break; dbg("IKBD access\r\n");
case 0x8020000: /* TLB miss on data write */ break;
case 0xc020000: /* TLB miss on data read or read-modify-write */
fault_address = MCF_MMU_MMUAR; case midictl:
/* case midi:
* the following line must stay commented or we risk a double fault (debugging /* do something to emulate MIDI access */
* output requiring itself a page mapping): dbg("MIDI ACIA access\r\n");
*/
// dbg("access fault - TLB miss at %p. Fault status = 0x0%x\r\n", pc, fault_status);
break; break;
default: default:
return false; /* add missed page to TLB */
} MCF_MMU_MMUTR = (address & 0xfff00000) | /* virtual aligned to 1M */
if (mmu_status & MCF_MMU_MMUSR_HIT) /* did the last fault hit in TLB? */
{
/*
* if yes, then we already mapped that page during a previous turn and this is in fact a bus error
*/
return false;
}
else
{
struct mmu_mapping *map;
if ((map = lookup_mapping(fault_address)) != NULL)
{
uint32_t mask;
switch (map->pagesize)
{
case MMU_PAGE_SIZE_1M:
mask = ~(0x100000 - 1);
break;
case MMU_PAGE_SIZE_4K:
mask = ~(0x1000 - 1);
break;
case MMU_PAGE_SIZE_8K:
mask = ~(0x2000 - 1);
break;
case MMU_PAGE_SIZE_1K:
mask = ~(0x400 - 1);
break;
}
mmu_map_page(fault_address & mask, fault_address & mask, map->pagesize, map->flags);
return true;
}
}
return false;
}
void mmu_map_page(uint32_t virt, uint32_t phys, uint32_t map_size, struct map_flags flags)
{
/*
* add page to TLB
*/
MCF_MMU_MMUTR = virt | /* virtual address */
MCF_MMU_MMUTR_ID(flags.page_id) |
MCF_MMU_MMUTR_SG | /* shared global */ MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */ MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = phys | /* physical address */ MCF_MMU_MMUDR = (address & 0xfff00000) | /* physical aligned to 1M */
MCF_MMU_MMUDR_SZ(map_size) | /* 1 MB page size */ MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(flags.cache_mode) | MCF_MMU_MMUDR_CM(0x1) | /* cacheable copyback */
(flags.access & ACCESS_READ ? MCF_MMU_MMUDR_R : 0) | /* read access enable */ MCF_MMU_MMUDR_R | /* read access enable */
(flags.access & ACCESS_WRITE ? MCF_MMU_MMUDR_W : 0) | /* write access enable */ MCF_MMU_MMUDR_W | /* write access enable */
(flags.access & ACCESS_EXECUTE ? MCF_MMU_MMUDR_X : 0); /* execute access enable */ MCF_MMU_MMUDR_X; /* execute access enable */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */ MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */ MCF_MMU_MMUOR_UAA; /* update allocation address field */
@@ -526,7 +447,7 @@ void mmu_map_page(uint32_t virt, uint32_t phys, uint32_t map_size, struct map_fl
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */ MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */ MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */ MCF_MMU_MMUOR_UAA; /* update allocation address field */
dbg("mapped virt=%p to phys=%p\r\n", virt, phys); }
} }

View File

@@ -18,7 +18,7 @@
#define DBG_MODES #define DBG_MODES
#ifdef DBG_MODES #ifdef DBG_MODES
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_MODES */ #endif /* DBG_MODES */

View File

@@ -7,11 +7,10 @@
* option any later version. See doc/license.txt for details. * option any later version. See doc/license.txt for details.
*/ */
#include "config.h" #include "bas_types.h"
#include "portab.h"
#include "font.h" #include "font.h"
static const UWORD off_table[] = static const uint16_t off_table[] =
{ {
0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038, 0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038,
0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078, 0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078,
@@ -48,7 +47,7 @@ static const UWORD off_table[] =
0x0800, 0x0800,
}; };
static const UWORD dat_table[] = static const uint16_t dat_table[] =
{ {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1104, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1104,

View File

@@ -11,7 +11,12 @@
* option any later version. See doc/license.txt for details. * option any later version. See doc/license.txt for details.
*/ */
#define DBG_VIDEL 0 #define DBG_VIDEL
#ifdef DBG_VIDEL
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_VIDEL */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@@ -332,11 +337,14 @@ const VMODE_ENTRY *lookup_videl_mode(int16_t mode,int16_t monitor)
{ {
const VMODE_ENTRY *vmode_init_table, *p; const VMODE_ENTRY *vmode_init_table, *p;
if (mode&VIDEL_VGA) { if (mode&VIDEL_VGA)
{
vmode_init_table = vga_init_table; vmode_init_table = vga_init_table;
/* ignore bits that don't affect initialisation data */ /* ignore bits that don't affect initialisation data */
mode &= ~(VIDEL_VERTICAL|VIDEL_PAL); mode &= ~(VIDEL_VERTICAL|VIDEL_PAL);
} else { }
else
{
vmode_init_table = nonvga_init_table; vmode_init_table = nonvga_init_table;
} }
@@ -372,11 +380,14 @@ static int16_t determine_vctl(int16_t mode,int16_t monitor)
{ {
int16_t vctl; int16_t vctl;
if (mode&VIDEL_VGA) { if (mode & VIDEL_VGA)
{
vctl = (mode & VIDEL_80COL) ? 0x08 : 0x04; vctl = (mode & VIDEL_80COL) ? 0x08 : 0x04;
if (mode & VIDEL_VERTICAL) if (mode & VIDEL_VERTICAL)
vctl |= 0x01; vctl |= 0x01;
} else { }
else
{
vctl = (mode & VIDEL_80COL) ? 0x04 : 0x00; vctl = (mode & VIDEL_80COL) ? 0x04 : 0x00;
if (mode & VIDEL_VERTICAL) if (mode & VIDEL_VERTICAL)
vctl |= 0x02; vctl |= 0x02;
@@ -385,7 +396,8 @@ static int16_t determine_vctl(int16_t mode,int16_t monitor)
if (!(mode & VIDEL_COMPAT)) if (!(mode & VIDEL_COMPAT))
return vctl; return vctl;
switch(mode&VIDEL_BPPMASK) { switch (mode & VIDEL_BPPMASK)
{
case VIDEL_1BPP: case VIDEL_1BPP:
if (!(mode & VIDEL_VGA) && (monitor == MON_MONO)) if (!(mode & VIDEL_VGA) && (monitor == MON_MONO))
vctl = 0x08; vctl = 0x08;
@@ -414,8 +426,11 @@ static int16_t determine_regc0(int16_t mode,int16_t monitor)
return (monitor == MON_TV) ? 0x0183 : 0x0181; return (monitor == MON_TV) ? 0x0183 : 0x0181;
/* handle ST-compatible modes */ /* handle ST-compatible modes */
if ((mode&(VIDEL_80COL|VIDEL_BPPMASK)) == (VIDEL_80COL|VIDEL_1BPP)) { /* 80-column, 2-colour */ if ((mode & (VIDEL_80COL | VIDEL_BPPMASK)) == (VIDEL_80COL | VIDEL_1BPP))
switch(monitor) { {
/* 80-column, 2-colour */
switch(monitor)
{
case MON_MONO: case MON_MONO:
return 0x0080; return 0x0080;
case MON_TV: case MON_TV:
@@ -476,7 +491,9 @@ static int set_videl_vga(int16_t mode)
videlword(0xc0) = determine_regc0(mode,monitor); videlword(0xc0) = determine_regc0(mode,monitor);
videlword(0x66) = 0x0000; /* clear SPSHIFT */ videlword(0x66) = 0x0000; /* clear SPSHIFT */
switch(mode&VIDEL_BPPMASK) { /* set SPSHIFT / ST shift */ switch(mode & VIDEL_BPPMASK)
{
/* set SPSHIFT / ST shift */
case VIDEL_1BPP: /* 2 colours (mono) */ case VIDEL_1BPP: /* 2 colours (mono) */
if (monitor == MON_MONO) if (monitor == MON_MONO)
videlregs[0x60] = 0x02; videlregs[0x60] = 0x02;
@@ -518,8 +535,8 @@ int16_t vsetmode(int16_t mode)
if (mode == -1) if (mode == -1)
return current_video_mode; return current_video_mode;
#if DBG_VIDEL #ifdef DBG_VIDEL
kprintf("vsetmode(0x%04x)\n", mode); xprintf("vsetmode(0x%04x)\n", mode);
#endif #endif
if (set_videl_vga(mode) < 0) /* invalid mode */ if (set_videl_vga(mode) < 0) /* invalid mode */
@@ -577,13 +594,17 @@ int32_t vgetsize(int16_t mode)
monitor = vmontype(); monitor = vmontype();
mode &= VIDEL_VALID; /* ignore invalid bits */ mode &= VIDEL_VALID; /* ignore invalid bits */
if ((mode&VIDEL_BPPMASK) > VIDEL_TRUECOLOR) { /* fixup invalid bpp */ if ((mode & VIDEL_BPPMASK) > VIDEL_TRUECOLOR)
{
/* fixup invalid bpp */
mode &= ~VIDEL_BPPMASK; mode &= ~VIDEL_BPPMASK;
mode |= VIDEL_TRUECOLOR; mode |= VIDEL_TRUECOLOR;
} }
p = lookup_videl_mode(mode, monitor); p = lookup_videl_mode(mode, monitor);
if (!p) { /* invalid mode */ if (!p)
{
/* invalid mode */
if (mode & VIDEL_COMPAT) if (mode & VIDEL_COMPAT)
return ST_VRAM_SIZE; return ST_VRAM_SIZE;
mode &= ~(VIDEL_OVERSCAN|VIDEL_PAL);/* ignore less-important bits */ mode &= ~(VIDEL_OVERSCAN|VIDEL_PAL);/* ignore less-important bits */
@@ -606,15 +627,18 @@ int32_t vgetsize(int16_t mode)
* convert from Falcon palette format to STe palette format * convert from Falcon palette format to STe palette format
*/ */
#define falc2ste(a) ((((a) >> 1) & 0x08) | (((a) >> 5) & 0x07)) #define falc2ste(a) ((((a) >> 1) & 0x08) | (((a) >> 5) & 0x07))
static void convert2ste(int16_t *ste,int32_t *falcon) static void convert2ste(int16_t *ste,int32_t *falcon)
{ {
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
int i; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
{
u.l = *falcon++; u.l = *falcon++;
*ste++ = (falc2ste(u.b[0]) << 8) | (falc2ste(u.b[1]) << 4) | falc2ste(u.b[3]); *ste++ = (falc2ste(u.b[0]) << 8) | (falc2ste(u.b[1]) << 4) | falc2ste(u.b[3]);
} }
@@ -655,7 +679,8 @@ static int use_ste_palette(int16_t videomode)
int16_t vsetrgb(int16_t index,int16_t count, int32_t *rgb) int16_t vsetrgb(int16_t index,int16_t count, int32_t *rgb)
{ {
int32_t *shadow, *source; int32_t *shadow, *source;
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
@@ -708,7 +733,8 @@ int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb)
int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb) int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb)
{ {
int32_t *shadow; int32_t *shadow;
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
@@ -722,7 +748,8 @@ int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb)
return -1; /* Generic error */ return -1; /* Generic error */
shadow = falcon_shadow_palette + index; shadow = falcon_shadow_palette + index;
while(count--) { while (count--)
{
u.l = *shadow++; u.l = *shadow++;
u.b[2] = u.b[1]; /* shift R & G right*/ u.b[2] = u.b[1]; /* shift R & G right*/
u.b[1] = u.b[0]; u.b[1] = u.b[0];