diff options
Diffstat (limited to 'drivers')
30 files changed, 846 insertions, 284 deletions
diff --git a/drivers/bios_emulator/Makefile b/drivers/bios_emulator/Makefile index e56356e..2ba43ac 100644 --- a/drivers/bios_emulator/Makefile +++ b/drivers/bios_emulator/Makefile @@ -9,4 +9,4 @@ obj-y = atibios.o biosemu.o besys.o bios.o \ $(X86DIR)/debug.o ccflags-y := -I$(srctree)/$(src) -I$(srctree)/$(src)/include \ - -D__PPC__ -D__BIG_ENDIAN__ + $(if $(CONFIG_PPC),-D__PPC__ -D__BIG_ENDIAN__) diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 3b2ed6e..93b815c 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -46,8 +46,11 @@ * BIOS in u-boot. ****************************************************************************/ #include <common.h> -#include "biosemui.h" +#include <bios_emul.h> +#include <errno.h> #include <malloc.h> +#include <vbe.h> +#include "biosemui.h" /* Length of the BIOS image */ #define MAX_BIOSLEN (128 * 1024L) @@ -59,17 +62,54 @@ static u32 saveBaseAddress14; static u32 saveBaseAddress18; static u32 saveBaseAddress20; +static void atibios_set_vesa_mode(RMREGS *regs, int vesa_mode, + struct vbe_mode_info *mode_info) +{ + debug("VBE: Setting VESA mode %#04x\n", vesa_mode); + /* request linear framebuffer mode */ + vesa_mode |= (1 << 14); + /* request clearing of framebuffer */ + vesa_mode &= ~(1 << 15); + regs->e.eax = VESA_SET_MODE; + regs->e.ebx = vesa_mode; + BE_int86(0x10, regs, regs); + + int offset = 0x2000; + void *buffer = (void *)(M.mem_base + offset); + + u16 buffer_seg = (((unsigned long)offset) >> 4) & 0xff00; + u16 buffer_adr = ((unsigned long)offset) & 0xffff; + regs->e.eax = VESA_GET_MODE_INFO; + regs->e.ebx = 0; + regs->e.ecx = vesa_mode; + regs->e.edx = 0; + regs->e.esi = buffer_seg; + regs->e.edi = buffer_adr; + BE_int86(0x10, regs, regs); + memcpy(mode_info->mode_info_block, buffer, + sizeof(struct vbe_mode_info)); + mode_info->valid = true; + + vesa_mode |= (1 << 14); + /* request clearing of framebuffer */ + vesa_mode &= ~(1 << 15); + regs->e.eax = VESA_SET_MODE; + regs->e.ebx = vesa_mode; + BE_int86(0x10, regs, regs); +} + /**************************************************************************** PARAMETERS: pcidev - PCI device info for the video card on the bus to boot -VGAInfo - BIOS emulator VGA info structure +vga_info - BIOS emulator VGA info structure REMARKS: This function executes the BIOS POST code on the controller. We assume that at this stage the controller has its I/O and memory space enabled and that all other controllers are in a disabled state. ****************************************************************************/ -static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo) +static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info, + int vesa_mode, struct vbe_mode_info *mode_info) { RMREGS regs; RMSREGS sregs; @@ -84,13 +124,16 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo) ((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev); /*Setup the X86 emulator for the VGA BIOS*/ - BE_setVGA(VGAInfo); + BE_setVGA(vga_info); /*Execute the BIOS POST code*/ BE_callRealMode(0xC000, 0x0003, ®s, &sregs); /*Cleanup and exit*/ - BE_getVGA(VGAInfo); + BE_getVGA(vga_info); + + if (vesa_mode != -1) + atibios_set_vesa_mode(®s, vesa_mode, mode_info); } /**************************************************************************** @@ -244,60 +287,61 @@ REMARKS: Loads and POST's the display controllers BIOS, directly from the BIOS image we can extract over the PCI bus. ****************************************************************************/ -static int PCI_postController(pci_dev_t pcidev, BE_VGAInfo * VGAInfo) +static int PCI_postController(pci_dev_t pcidev, uchar *bios_rom, int bios_len, + BE_VGAInfo *vga_info, int vesa_mode, + struct vbe_mode_info *mode_info) { - u32 BIOSImageLen; - uchar *mappedBIOS; - uchar *copyOfBIOS; - - /*Allocate memory to store copy of BIOS from display controller*/ - if ((mappedBIOS = PCI_mapBIOSImage(pcidev)) == NULL) { - printf("videoboot: Video ROM failed to map!\n"); - return false; - } + u32 bios_image_len; + uchar *mapped_bios; + uchar *copy_of_bios; + + if (bios_rom) { + copy_of_bios = bios_rom; + bios_image_len = bios_len; + } else { + /* + * Allocate memory to store copy of BIOS from display + * controller + */ + mapped_bios = PCI_mapBIOSImage(pcidev); + if (mapped_bios == NULL) { + printf("videoboot: Video ROM failed to map!\n"); + return false; + } - BIOSImageLen = mappedBIOS[2] * 512; + bios_image_len = mapped_bios[2] * 512; - if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL) { - printf("videoboot: Out of memory!\n"); - return false; + copy_of_bios = malloc(bios_image_len); + if (copy_of_bios == NULL) { + printf("videoboot: Out of memory!\n"); + return false; + } + memcpy(copy_of_bios, mapped_bios, bios_image_len); + PCI_unmapBIOSImage(pcidev, mapped_bios); } - memcpy(copyOfBIOS, mappedBIOS, BIOSImageLen); - PCI_unmapBIOSImage(pcidev, mappedBIOS); - - /*Save information in VGAInfo structure*/ - VGAInfo->function = PCI_FUNC(pcidev); - VGAInfo->device = PCI_DEV(pcidev); - VGAInfo->bus = PCI_BUS(pcidev); - VGAInfo->pcidev = pcidev; - VGAInfo->BIOSImage = copyOfBIOS; - VGAInfo->BIOSImageLen = BIOSImageLen; + /*Save information in vga_info structure*/ + vga_info->function = PCI_FUNC(pcidev); + vga_info->device = PCI_DEV(pcidev); + vga_info->bus = PCI_BUS(pcidev); + vga_info->pcidev = pcidev; + vga_info->BIOSImage = copy_of_bios; + vga_info->BIOSImageLen = bios_image_len; /*Now execute the BIOS POST for the device*/ - if (copyOfBIOS[0] != 0x55 || copyOfBIOS[1] != 0xAA) { + if (copy_of_bios[0] != 0x55 || copy_of_bios[1] != 0xAA) { printf("videoboot: Video ROM image is invalid!\n"); return false; } - PCI_doBIOSPOST(pcidev, VGAInfo); + PCI_doBIOSPOST(pcidev, vga_info, vesa_mode, mode_info); /*Reset the size of the BIOS image to the final size*/ - VGAInfo->BIOSImageLen = copyOfBIOS[2] * 512; + vga_info->BIOSImageLen = copy_of_bios[2] * 512; return true; } -/**************************************************************************** -PARAMETERS: -pcidev - PCI device info for the video card on the bus to boot -pVGAInfo - Place to return VGA info structure is requested -cleanUp - true to clean up on exit, false to leave emulator active - -REMARKS: -Boots the PCI/AGP video card on the bus using the Video ROM BIOS image -and the X86 BIOS emulator module. -****************************************************************************/ -int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp) +int biosemu_setup(pci_dev_t pcidev, BE_VGAInfo **vga_infop) { BE_VGAInfo *VGAInfo; @@ -307,28 +351,70 @@ int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp) /*Initialise the x86 BIOS emulator*/ if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) { printf("videoboot: Out of memory!\n"); - return false; + return -ENOMEM; } memset(VGAInfo, 0, sizeof(*VGAInfo)); BE_init(0, 65536, VGAInfo, 0); + *vga_infop = VGAInfo; - /*Post all the display controller BIOS'es*/ - if (!PCI_postController(pcidev, VGAInfo)) - return false; + return 0; +} - /*Cleanup and exit the emulator if requested. If the BIOS emulator - is needed after booting the card, we will not call BE_exit and - leave it enabled for further use (ie: VESA driver etc). +void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void)) +{ + X86EMU_setupIntrFunc(intnum, (X86EMU_intrFuncs)int_func); +} + +int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len, + BE_VGAInfo *vga_info, int clean_up, int vesa_mode, + struct vbe_mode_info *mode_info) +{ + /*Post all the display controller BIOS'es*/ + if (!PCI_postController(pcidev, bios_rom, bios_len, vga_info, + vesa_mode, mode_info)) + return -EINVAL; + + /* + * Cleanup and exit the emulator if requested. If the BIOS emulator + * is needed after booting the card, we will not call BE_exit and + * leave it enabled for further use (ie: VESA driver etc). */ - if (cleanUp) { + if (clean_up) { BE_exit(); - if (VGAInfo->BIOSImage) - free(VGAInfo->BIOSImage); - free(VGAInfo); - VGAInfo = NULL; + if (vga_info->BIOSImage) + free(vga_info->BIOSImage); + free(vga_info); + vga_info = NULL; } - /*Return VGA info pointer if the caller requested it*/ + + return 0; +} + +/**************************************************************************** +PARAMETERS: +pcidev - PCI device info for the video card on the bus to boot +pVGAInfo - Place to return VGA info structure is requested +cleanUp - true to clean up on exit, false to leave emulator active + +REMARKS: +Boots the PCI/AGP video card on the bus using the Video ROM BIOS image +and the X86 BIOS emulator module. +****************************************************************************/ +int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int clean_up) +{ + BE_VGAInfo *VGAInfo; + int ret; + + ret = biosemu_setup(pcidev, &VGAInfo); + if (ret) + return false; + ret = biosemu_run(pcidev, NULL, 0, VGAInfo, clean_up, -1, NULL); + if (ret) + return false; + + /* Return VGA info pointer if the caller requested it*/ if (pVGAInfo) *pVGAInfo = VGAInfo; + return true; } diff --git a/drivers/bios_emulator/besys.c b/drivers/bios_emulator/besys.c index ad88a53..752a928 100644 --- a/drivers/bios_emulator/besys.c +++ b/drivers/bios_emulator/besys.c @@ -54,12 +54,20 @@ /*------------------------- Global Variables ------------------------------*/ -#ifndef __i386__ +#ifndef CONFIG_X86EMU_RAW_IO static char *BE_biosDate = "08/14/99"; static u8 BE_model = 0xFC; static u8 BE_submodel = 0x00; #endif +#undef DEBUG_IO_ACCESS + +#ifdef DEBUG_IO_ACCESS +#define debug_io(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define debug_io(x, b...) +#endif + /*----------------------------- Implementation ----------------------------*/ /**************************************************************************** @@ -80,38 +88,40 @@ static u8 *BE_memaddr(u32 addr) if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) { return (u8*)(_BE_env.biosmem_base + addr - 0xC0000); } else if (addr > _BE_env.biosmem_limit && addr < 0xD0000) { - DB(printf("BE_memaddr: address %#lx may be invalid!\n", addr);) - return M.mem_base; + DB(printf("BE_memaddr: address %#lx may be invalid!\n", + (ulong)addr);) + return (u8 *)M.mem_base; } else if (addr >= 0xA0000 && addr <= 0xBFFFF) { return (u8*)(_BE_env.busmem_base + addr - 0xA0000); } -#ifdef __i386__ +#ifdef CONFIG_X86EMU_RAW_IO else if (addr >= 0xD0000 && addr <= 0xFFFFF) { /* We map the real System BIOS directly on real PC's */ - DB(printf("BE_memaddr: System BIOS address %#lx\n", addr);) - return _BE_env.busmem_base + addr - 0xA0000; + DB(printf("BE_memaddr: System BIOS address %#lx\n", + (ulong)addr);) + return (u8 *)_BE_env.busmem_base + addr - 0xA0000; } #else else if (addr >= 0xFFFF5 && addr < 0xFFFFE) { /* Return a faked BIOS date string for non-x86 machines */ - DB(printf("BE_memaddr - Returning BIOS date\n");) + debug_io("BE_memaddr - Returning BIOS date\n"); return (u8 *)(BE_biosDate + addr - 0xFFFF5); } else if (addr == 0xFFFFE) { /* Return system model identifier for non-x86 machines */ - DB(printf("BE_memaddr - Returning model\n");) + debug_io("BE_memaddr - Returning model\n"); return &BE_model; } else if (addr == 0xFFFFF) { /* Return system submodel identifier for non-x86 machines */ - DB(printf("BE_memaddr - Returning submodel\n");) + debug_io("BE_memaddr - Returning submodel\n"); return &BE_submodel; } #endif else if (addr > M.mem_size - 1) { HALT_SYS(); - return M.mem_base; + return (u8 *)M.mem_base; } - return M.mem_base + addr; + return (u8 *)(M.mem_base + addr); } /**************************************************************************** @@ -230,7 +240,7 @@ void X86API BE_wrl(u32 addr, u32 val) } } -#if defined(DEBUG) || !defined(__i386__) +#if !defined(CONFIG_X86EMU_RAW_IO) /* For Non-Intel machines we may need to emulate some I/O port accesses that * the BIOS may try to access, such as the PCI config registers. @@ -258,6 +268,7 @@ static u8 VGA_inpb (const int port) { u8 val = 0xff; + debug_io("vga_inb.%04X -> ", (u16) port); switch (port) { case 0x3C0: /* 3C0 has funky characteristics because it can act as either @@ -560,7 +571,7 @@ u8 X86API BE_inb(X86EMU_pioAddr port) { u8 val = 0; -#if defined(DEBUG) || !defined(__i386__) +#if !defined(CONFIG_X86EMU_RAW_IO) if (IS_VGA_PORT(port)){ /*seems reading port 0x3c3 return the high 16 bit of io port*/ if(port == 0x3c3) @@ -581,7 +592,12 @@ u8 X86API BE_inb(X86EMU_pioAddr port) val = LOG_inpb(port); } else #endif + { + debug_io("inb.%04X -> ", (u16) port); val = LOG_inpb(port); + debug_io("%02X\n", val); + } + return val; } @@ -601,7 +617,7 @@ u16 X86API BE_inw(X86EMU_pioAddr port) { u16 val = 0; -#if defined(DEBUG) || !defined(__i386__) +#if !defined(CONFIG_X86EMU_RAW_IO) if (IS_PCI_PORT(port)) val = PCI_inp(port, REG_READ_WORD); else if (port < 0x100) { @@ -609,7 +625,12 @@ u16 X86API BE_inw(X86EMU_pioAddr port) val = LOG_inpw(port); } else #endif + { + debug_io("inw.%04X -> ", (u16) port); val = LOG_inpw(port); + debug_io("%04X\n", val); + } + return val; } @@ -629,14 +650,19 @@ u32 X86API BE_inl(X86EMU_pioAddr port) { u32 val = 0; -#if defined(DEBUG) || !defined(__i386__) +#if !defined(CONFIG_X86EMU_RAW_IO) if (IS_PCI_PORT(port)) val = PCI_inp(port, REG_READ_DWORD); else if (port < 0x100) { val = LOG_inpd(port); } else #endif + { + debug_io("inl.%04X -> ", (u16) port); val = LOG_inpd(port); + debug_io("%08X\n", val); + } + return val; } @@ -652,7 +678,7 @@ through to the real hardware if we don't need to special case it. ****************************************************************************/ void X86API BE_outb(X86EMU_pioAddr port, u8 val) { -#if defined(DEBUG) || !defined(__i386__) +#if !defined(CONFIG_X86EMU_RAW_IO) if (IS_VGA_PORT(port)) VGA_outpb(port, val); else if (IS_TIMER_PORT(port)) @@ -668,7 +694,11 @@ void X86API BE_outb(X86EMU_pioAddr port, u8 val) LOG_outpb(port, val); } else #endif + { + debug_io("outb.%04X <- %02X", (u16) port, val); LOG_outpb(port, val); + debug_io("\n"); + } } /**************************************************************************** @@ -683,19 +713,23 @@ through to the real hardware if we don't need to special case it. ****************************************************************************/ void X86API BE_outw(X86EMU_pioAddr port, u16 val) { -#if defined(DEBUG) || !defined(__i386__) - if (IS_VGA_PORT(port)) { - VGA_outpb(port, val); - VGA_outpb(port + 1, val >> 8); - } else if (IS_PCI_PORT(port)) - PCI_outp(port, val, REG_WRITE_WORD); - else if (port < 0x100) { - DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16) port, - val);) - LOG_outpw(port, val); - } else +#if !defined(CONFIG_X86EMU_RAW_IO) + if (IS_VGA_PORT(port)) { + VGA_outpb(port, val); + VGA_outpb(port + 1, val >> 8); + } else if (IS_PCI_PORT(port)) { + PCI_outp(port, val, REG_WRITE_WORD); + } else if (port < 0x100) { + DB(printf("WARN: MAybe INVALID outw.%04X <- %04X\n", (u16)port, + val);) + LOG_outpw(port, val); + } else #endif - LOG_outpw(port, val); + { + debug_io("outw.%04X <- %04X", (u16) port, val); + LOG_outpw(port, val); + debug_io("\n"); + } } /**************************************************************************** @@ -710,13 +744,17 @@ through to the real hardware if we don't need to special case it. ****************************************************************************/ void X86API BE_outl(X86EMU_pioAddr port, u32 val) { -#if defined(DEBUG) || !defined(__i386__) - if (IS_PCI_PORT(port)) +#if !defined(CONFIG_X86EMU_RAW_IO) + if (IS_PCI_PORT(port)) { PCI_outp(port, val, REG_WRITE_DWORD); - else if (port < 0x100) { + } else if (port < 0x100) { DB(printf("WARN: INVALID outl.%04X <- %08X\n", (u16) port,val);) LOG_outpd(port, val); } else #endif + { + debug_io("outl.%04X <- %08X", (u16) port, val); LOG_outpd(port, val); + debug_io("\n"); + } } diff --git a/drivers/bios_emulator/bios.c b/drivers/bios_emulator/bios.c index bcc192f..152d70a 100644 --- a/drivers/bios_emulator/bios.c +++ b/drivers/bios_emulator/bios.c @@ -84,14 +84,14 @@ static void X86API int42(int intno) PM_outpb(0x3c2, PM_inpb(0x3cc) & (u8) ~ 0x02); return; } -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG else { printf("int42: unknown function AH=0x12, BL=0x32, AL=%#02x\n", M.x86.R_AL); } #endif } -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG else { printf("int42: unknown function AH=%#02x, AL=%#02x, BL=%#02x\n", M.x86.R_AH, M.x86.R_AL, M.x86.R_BL); diff --git a/drivers/bios_emulator/biosemui.h b/drivers/bios_emulator/biosemui.h index 8c1f111..7853015 100644 --- a/drivers/bios_emulator/biosemui.h +++ b/drivers/bios_emulator/biosemui.h @@ -48,7 +48,7 @@ #include <asm/io.h> /*---------------------- Macros and type definitions ----------------------*/ -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG #define DB(x) x #else #define DB(x) do{}while(0); diff --git a/drivers/bios_emulator/include/biosemu.h b/drivers/bios_emulator/include/biosemu.h index e92e96e..124d79d 100644 --- a/drivers/bios_emulator/include/biosemu.h +++ b/drivers/bios_emulator/include/biosemu.h @@ -43,6 +43,8 @@ #ifndef __BIOSEMU_H #define __BIOSEMU_H +#include <bios_emul.h> + #ifdef __KERNEL__ #include "x86emu.h" #else @@ -55,57 +57,6 @@ #pragma pack(1) -#ifndef __KERNEL__ -/**************************************************************************** -REMARKS: -Data structure used to describe the details specific to a particular VGA -controller. This information is used to allow the VGA controller to be -swapped on the fly within the BIOS emulator. - -HEADER: -biosemu.h - -MEMBERS: -pciInfo - PCI device information block for the controller -BIOSImage - Pointer to a read/write copy of the BIOS image -BIOSImageLen - Length of the BIOS image -LowMem - Copy of key low memory areas -****************************************************************************/ -typedef struct { - PCIDeviceInfo *pciInfo; - void *BIOSImage; - ulong BIOSImageLen; - uchar LowMem[1536]; -} BE_VGAInfo; -#else -/**************************************************************************** -REMARKS: -Data structure used to describe the details for the BIOS emulator system -environment as used by the X86 emulator library. - -HEADER: -biosemu.h - -MEMBERS: -vgaInfo - VGA BIOS information structure -biosmem_base - Base of the BIOS image -biosmem_limit - Limit of the BIOS image -busmem_base - Base of the VGA bus memory -****************************************************************************/ -typedef struct { - int function; - int device; - int bus; - u32 VendorID; - u32 DeviceID; - pci_dev_t pcidev; - void *BIOSImage; - u32 BIOSImageLen; - u8 LowMem[1536]; -} BE_VGAInfo; - -#endif /* __KERNEL__ */ - #define CRT_C 24 /* 24 CRT Controller Registers */ #define ATT_C 21 /* 21 Attribute Controller Registers */ #define GRA_C 9 /* 9 Graphics Controller Registers */ diff --git a/drivers/bios_emulator/include/x86emu.h b/drivers/bios_emulator/include/x86emu.h index a70a768..b28cdc6 100644 --- a/drivers/bios_emulator/include/x86emu.h +++ b/drivers/bios_emulator/include/x86emu.h @@ -53,9 +53,9 @@ typedef u16 X86EMU_pioAddr; /*---------------------- Macros and type definitions ----------------------*/ -#if defined (CONFIG_ARM) +#if defined(CONFIG_ARM) #define GAS_LINE_COMMENT "@" -#elif defined(CONFIG_MIPS) || defined(CONFIG_PPC) +#elif defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_X86) #define GAS_LINE_COMMENT "#" #elif defined (CONFIG_SH) #define GAS_LINE_COMMENT "!" @@ -153,6 +153,7 @@ extern "C" { /* Use "C" linkage when in C++ mode */ void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs); void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs); void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]); + void X86EMU_setupIntrFunc(int intnum, X86EMU_intrFuncs func); void X86EMU_prepareForInt(int num); /* decode.c */ @@ -160,7 +161,7 @@ extern "C" { /* Use "C" linkage when in C++ mode */ void X86EMU_exec(void); void X86EMU_halt_sys(void); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG #define HALT_SYS() \ printf("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \ X86EMU_halt_sys() diff --git a/drivers/bios_emulator/include/x86emu/debug.h b/drivers/bios_emulator/include/x86emu/debug.h index 268c9d3..304b2bf 100644 --- a/drivers/bios_emulator/include/x86emu/debug.h +++ b/drivers/bios_emulator/include/x86emu/debug.h @@ -48,7 +48,7 @@ #define CHECK_MEM_ACCESS_F 0x4 /*using regular linear pointer */ #define CHECK_DATA_ACCESS_F 0x8 /*using segment:offset */ -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG # define CHECK_IP_FETCH() (M.x86.check & CHECK_IP_FETCH_F) # define CHECK_SP_ACCESS() (M.x86.check & CHECK_SP_ACCESS_F) # define CHECK_MEM_ACCESS() (M.x86.check & CHECK_MEM_ACCESS_F) @@ -60,7 +60,7 @@ # define CHECK_DATA_ACCESS() #endif -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG # define DEBUG_INSTRUMENT() (M.x86.debug & DEBUG_INSTRUMENT_F) # define DEBUG_DECODE() (M.x86.debug & DEBUG_DECODE_F) # define DEBUG_TRACE() (M.x86.debug & DEBUG_TRACE_F) @@ -99,7 +99,11 @@ # define DEBUG_DECODE_NOPRINT() 0 #endif -#ifdef DEBUG +# define ERR_PRINTF(x) printf(x) +# define ERR_PRINTF2(x, y) printf(x, y) + +#ifdef CONFIG_X86EMU_DEBUG103 + # define DECODE_PRINTF(x) if (DEBUG_DECODE()) \ x86emu_decode_printf(x) @@ -129,7 +133,7 @@ # define SAVE_IP_CS(x,y) #endif -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG #define TRACE_REGS() \ if (DEBUG_DISASSEMBLE()) { \ x86emu_just_disassemble(); \ @@ -140,7 +144,7 @@ # define TRACE_REGS() #endif -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG # define SINGLE_STEP() if (DEBUG_STEP()) x86emu_single_step() #else # define SINGLE_STEP() @@ -150,7 +154,7 @@ TRACE_REGS(); \ SINGLE_STEP() -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG # define START_OF_INSTR() # define END_OF_INSTR() EndOfTheInstructionProcedure: x86emu_end_instr(); # define END_OF_INSTR_NO_TRACE() x86emu_end_instr(); @@ -160,7 +164,7 @@ # define END_OF_INSTR_NO_TRACE() #endif -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG # define CALL_TRACE(u,v,w,x,s) \ if (DEBUG_TRACECALLREGS()) \ x86emu_dump_regs(); \ @@ -176,7 +180,7 @@ # define RETURN_TRACE(n,u,v) #endif -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG #define DB(x) x #else #define DB(x) diff --git a/drivers/bios_emulator/include/x86emu/regs.h b/drivers/bios_emulator/include/x86emu/regs.h index a7fedd2..2934129 100644 --- a/drivers/bios_emulator/include/x86emu/regs.h +++ b/drivers/bios_emulator/include/x86emu/regs.h @@ -282,7 +282,7 @@ typedef struct { u8 intno; volatile int intr; /* mask of pending interrupts */ int debug; -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG int check; u16 saved_ip; u16 saved_cs; diff --git a/drivers/bios_emulator/x86emu/debug.c b/drivers/bios_emulator/x86emu/debug.c index 2fa8050..27e90e4 100644 --- a/drivers/bios_emulator/x86emu/debug.c +++ b/drivers/bios_emulator/x86emu/debug.c @@ -44,7 +44,7 @@ /*----------------------------- Implementation ----------------------------*/ -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG static void print_encoded_bytes(u16 s, u16 o); static void print_decoded_instruction(void); @@ -211,9 +211,7 @@ void X86EMU_dump_memory(u16 seg, u16 off, u32 amt) u32 start = off & 0xfffffff0; u32 end = (off + 16) & 0xfffffff0; u32 i; - u32 current; - current = start; while (end <= off + amt) { printk("%04x:%04x ", seg, start); for (i = start; i < off; i++) @@ -229,7 +227,7 @@ void X86EMU_dump_memory(u16 seg, u16 off, u32 amt) void x86emu_single_step(void) { char s[1024]; - int ps[10]; + int ps[10]; int ntok; int cmd; int done; @@ -238,8 +236,6 @@ void x86emu_single_step(void) static int breakpoint; static int noDecode = 1; - char *p; - if (DEBUG_BREAK()) { if (M.x86.saved_ip != breakpoint) { return; @@ -255,6 +251,8 @@ void x86emu_single_step(void) offset = M.x86.saved_ip; while (!done) { printk("-"); + ps[1] = 0; /* Avoid dodgy compiler warnings */ + ps[2] = 0; cmd = x86emu_parse_line(s, ps, &ntok); switch (cmd) { case 'u': diff --git a/drivers/bios_emulator/x86emu/decode.c b/drivers/bios_emulator/x86emu/decode.c index a782b81..da44c3d 100644 --- a/drivers/bios_emulator/x86emu/decode.c +++ b/drivers/bios_emulator/x86emu/decode.c @@ -303,7 +303,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline! u8 fetch_data_byte( uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -322,7 +322,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline! u16 fetch_data_word( uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -341,7 +341,7 @@ NOTE: Do not inline this function as (*sys_rdX) is already inline! u32 fetch_data_long( uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -362,7 +362,7 @@ u8 fetch_data_byte_abs( uint segment, uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif @@ -383,7 +383,7 @@ u16 fetch_data_word_abs( uint segment, uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif @@ -404,7 +404,7 @@ u32 fetch_data_long_abs( uint segment, uint offset) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif @@ -426,7 +426,7 @@ void store_data_byte( uint offset, u8 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -448,7 +448,7 @@ void store_data_word( uint offset, u16 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -470,7 +470,7 @@ void store_data_long( uint offset, u32 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access((u16)get_data_segment(), offset); #endif @@ -493,7 +493,7 @@ void store_data_byte_abs( uint offset, u8 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif @@ -516,7 +516,7 @@ void store_data_word_abs( uint offset, u16 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif @@ -539,7 +539,7 @@ void store_data_long_abs( uint offset, u32 val) { -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (CHECK_DATA_ACCESS()) x86emu_check_data_access(segment, offset); #endif diff --git a/drivers/bios_emulator/x86emu/ops.c b/drivers/bios_emulator/x86emu/ops.c index f8e093d..2bb5e2d 100644 --- a/drivers/bios_emulator/x86emu/ops.c +++ b/drivers/bios_emulator/x86emu/ops.c @@ -79,7 +79,7 @@ /* constant arrays to do several instructions in just one function */ -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG static char *x86emu_GenOpName[8] = { "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"}; #endif @@ -160,7 +160,7 @@ static u32 (*opcD1_long_operation[])(u32 s, u8 d) = sar_long, }; -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG static char *opF6_names[8] = { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" }; @@ -179,7 +179,7 @@ void x86emuOp_illegal_op( { START_OF_INSTR(); if (M.x86.R_SP != 0) { - DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); + ERR_PRINTF("ILLEGAL X86 OPCODE\n"); TRACE_REGS(); DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP-1,op1)); @@ -1281,7 +1281,7 @@ void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -1359,7 +1359,7 @@ void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -1475,7 +1475,7 @@ void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -1551,7 +1551,7 @@ void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -2148,7 +2148,7 @@ void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("POP\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (rh != 0) { - DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); + ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); HALT_SYS(); } if (mod < 3) { @@ -3083,7 +3083,7 @@ void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3158,7 +3158,7 @@ void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3347,7 +3347,7 @@ void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("MOV\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (rh != 0) { - DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); + ERR_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); HALT_SYS(); } if (mod < 3) { @@ -3381,7 +3381,7 @@ void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("MOV\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (rh != 0) { - DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); + ERR_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); HALT_SYS(); } if (mod < 3) { @@ -3630,7 +3630,7 @@ void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3701,7 +3701,7 @@ void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3803,7 +3803,7 @@ void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3876,7 +3876,7 @@ void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -3968,7 +3968,7 @@ void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("AAM\n"); a = fetch_byte_imm(); /* this is a stupid encoding. */ if (a != 10) { - DECODE_PRINTF("ERROR DECODING AAM\n"); + ERR_PRINTF("ERROR DECODING AAM\n"); TRACE_REGS(); HALT_SYS(); } @@ -4443,7 +4443,7 @@ void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) test_byte(destval, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); HALT_SYS(); break; case 2: @@ -4490,7 +4490,7 @@ void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) test_byte(*destreg, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); HALT_SYS(); break; case 2: @@ -4559,7 +4559,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) test_long(destval, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); HALT_SYS(); break; case 2: @@ -4611,7 +4611,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) test_word(destval, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); HALT_SYS(); break; case 2: @@ -4666,7 +4666,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) test_long(*destreg, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); HALT_SYS(); break; case 2: @@ -4715,7 +4715,7 @@ void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) test_word(*destreg, srcval); break; case 1: - DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); + ERR_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); HALT_SYS(); break; case 2: @@ -4859,7 +4859,7 @@ void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) /* Yet another special case instruction. */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -4879,7 +4879,7 @@ void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) case 5: case 6: case 7: - DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); + ERR_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x\n", mod); HALT_SYS(); break; } @@ -4923,7 +4923,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) /* Yet another special case instruction. */ START_OF_INSTR(); FETCH_DECODE_MODRM(mod, rh, rl); -#ifdef DEBUG +#ifdef CONFIG_X86EMU_DEBUG if (DEBUG_DECODE()) { /* XXX DECODE_PRINTF may be changed to something more general, so that it is important to leave the strings @@ -4961,7 +4961,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("PUSH\t"); break; case 7: - DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); + ERR_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); HALT_SYS(); break; } @@ -5092,7 +5092,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) M.x86.R_IP = *destreg; break; case 3: /* jmp far ptr ... */ - DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); + ERR_PRINTF("OPERATION UNDEFINED 0XFF\n"); TRACE_AND_STEP(); HALT_SYS(); break; @@ -5104,7 +5104,7 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) M.x86.R_IP = (u16) (*destreg); break; case 5: /* jmp far ptr ... */ - DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); + ERR_PRINTF("OPERATION UNDEFINED 0XFF\n"); TRACE_AND_STEP(); HALT_SYS(); break; diff --git a/drivers/bios_emulator/x86emu/ops2.c b/drivers/bios_emulator/x86emu/ops2.c index 59dbb42..be4ef36 100644 --- a/drivers/bios_emulator/x86emu/ops2.c +++ b/drivers/bios_emulator/x86emu/ops2.c @@ -58,7 +58,7 @@ void x86emuOp2_illegal_op( u8 op2) { START_OF_INSTR(); - DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); + ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); TRACE_REGS(); printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP-2,op2); @@ -1089,7 +1089,7 @@ void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) DECODE_PRINTF("BTC\t"); break; default: - DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); + ERR_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); TRACE_REGS(); printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl); diff --git a/drivers/bios_emulator/x86emu/sys.c b/drivers/bios_emulator/x86emu/sys.c index 21f9730..0ba9c0c 100644 --- a/drivers/bios_emulator/x86emu/sys.c +++ b/drivers/bios_emulator/x86emu/sys.c @@ -273,6 +273,11 @@ void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs) sys_outl = funcs->outl; } +void X86EMU_setupIntrFunc(int intnum, X86EMU_intrFuncs func) +{ + _X86EMU_intrTab[intnum] = func; +} + /**************************************************************************** PARAMETERS: funcs - New interrupt vector table to make active diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 75c2c06..c242214 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,9 +1,16 @@ menu "NAND Device Support" +config SYS_NAND_SELF_INIT + bool + help + This option, if enabled, provides more flexible and linux-like + NAND initialization process. + if !SPL_BUILD config NAND_DENALI bool "Support Denali NAND controller" + select SYS_NAND_SELF_INIT help Enable support for the Denali NAND controller. diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 308b784..9e0429a 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -44,7 +44,7 @@ static int onfi_timing_mode = NAND_DEFAULT_TIMINGS; * this macro allows us to convert from an MTD structure to our own * device context (denali) structure. */ -#define mtd_to_denali(m) (((struct nand_chip *)mtd->priv)->priv) +#define mtd_to_denali(m) container_of(m->priv, struct denali_nand_info, nand) /* These constants are defined by the driver to enable common driver * configuration options. */ @@ -1144,70 +1144,128 @@ static void denali_hw_init(struct denali_nand_info *denali) static struct nand_ecclayout nand_oob; -static int denali_nand_init(struct nand_chip *nand) +static int denali_init(struct denali_nand_info *denali) { - struct denali_nand_info *denali; + int ret; - denali = malloc(sizeof(*denali)); - if (!denali) - return -ENOMEM; + denali_hw_init(denali); - nand->priv = denali; + denali->mtd->name = "denali-nand"; + denali->mtd->owner = THIS_MODULE; + denali->mtd->priv = &denali->nand; - denali->flash_reg = (void __iomem *)CONFIG_SYS_NAND_REGS_BASE; - denali->flash_mem = (void __iomem *)CONFIG_SYS_NAND_DATA_BASE; + /* register the driver with the NAND core subsystem */ + denali->nand.select_chip = denali_select_chip; + denali->nand.cmdfunc = denali_cmdfunc; + denali->nand.read_byte = denali_read_byte; + denali->nand.read_buf = denali_read_buf; + denali->nand.waitfunc = denali_waitfunc; + + /* + * scan for NAND devices attached to the controller + * this is the first stage in a two step process to register + * with the nand subsystem + */ + if (nand_scan_ident(denali->mtd, denali->max_banks, NULL)) { + ret = -ENXIO; + goto fail; + } #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT /* check whether flash got BBT table (located at end of flash). As we * use NAND_BBT_NO_OOB, the BBT page will start with * bbt_pattern. We will have mirror pattern too */ - nand->bbt_options |= NAND_BBT_USE_FLASH; + denali->nand.bbt_options |= NAND_BBT_USE_FLASH; /* * We are using main + spare with ECC support. As BBT need ECC support, * we need to ensure BBT code don't write to OOB for the BBT pattern. * All BBT info will be stored into data area with ECC support. */ - nand->bbt_options |= NAND_BBT_NO_OOB; + denali->nand.bbt_options |= NAND_BBT_NO_OOB; #endif - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = CONFIG_NAND_DENALI_ECC_SIZE; - nand->ecc.read_oob = denali_read_oob; - nand->ecc.write_oob = denali_write_oob; - nand->ecc.read_page = denali_read_page; - nand->ecc.read_page_raw = denali_read_page_raw; - nand->ecc.write_page = denali_write_page; - nand->ecc.write_page_raw = denali_write_page_raw; + denali->nand.ecc.mode = NAND_ECC_HW; + denali->nand.ecc.size = CONFIG_NAND_DENALI_ECC_SIZE; + /* * Tell driver the ecc strength. This register may be already set * correctly. So we read this value out. */ - nand->ecc.strength = readl(denali->flash_reg + ECC_CORRECTION); - switch (nand->ecc.size) { + denali->nand.ecc.strength = readl(denali->flash_reg + ECC_CORRECTION); + switch (denali->nand.ecc.size) { case 512: - nand->ecc.bytes = (nand->ecc.strength * 13 + 15) / 16 * 2; + denali->nand.ecc.bytes = + (denali->nand.ecc.strength * 13 + 15) / 16 * 2; break; case 1024: - nand->ecc.bytes = (nand->ecc.strength * 14 + 15) / 16 * 2; + denali->nand.ecc.bytes = + (denali->nand.ecc.strength * 14 + 15) / 16 * 2; break; default: pr_err("Unsupported ECC size\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } - nand_oob.eccbytes = nand->ecc.bytes; - nand->ecc.layout = &nand_oob; - - /* Set address of hardware control function */ - nand->cmdfunc = denali_cmdfunc; - nand->read_byte = denali_read_byte; - nand->read_buf = denali_read_buf; - nand->select_chip = denali_select_chip; - nand->waitfunc = denali_waitfunc; - denali_hw_init(denali); - return 0; + nand_oob.eccbytes = denali->nand.ecc.bytes; + denali->nand.ecc.layout = &nand_oob; + + writel(denali->mtd->erasesize / denali->mtd->writesize, + denali->flash_reg + PAGES_PER_BLOCK); + writel(denali->nand.options & NAND_BUSWIDTH_16 ? 1 : 0, + denali->flash_reg + DEVICE_WIDTH); + writel(denali->mtd->writesize, + denali->flash_reg + DEVICE_MAIN_AREA_SIZE); + writel(denali->mtd->oobsize, + denali->flash_reg + DEVICE_SPARE_AREA_SIZE); + if (readl(denali->flash_reg + DEVICES_CONNECTED) == 0) + writel(1, denali->flash_reg + DEVICES_CONNECTED); + + /* override the default operations */ + denali->nand.ecc.read_page = denali_read_page; + denali->nand.ecc.read_page_raw = denali_read_page_raw; + denali->nand.ecc.write_page = denali_write_page; + denali->nand.ecc.write_page_raw = denali_write_page_raw; + denali->nand.ecc.read_oob = denali_read_oob; + denali->nand.ecc.write_oob = denali_write_oob; + + if (nand_scan_tail(denali->mtd)) { + ret = -ENXIO; + goto fail; + } + + ret = nand_register(0); + +fail: + return ret; +} + +static int __board_nand_init(void) +{ + struct denali_nand_info *denali; + + denali = kzalloc(sizeof(*denali), GFP_KERNEL); + if (!denali) + return -ENOMEM; + + /* + * If CONFIG_SYS_NAND_SELF_INIT is defined, each driver is responsible + * for instantiating struct nand_chip, while drivers/mtd/nand/nand.c + * still provides a "struct mtd_info nand_info" instance. + */ + denali->mtd = &nand_info[0]; + + /* + * In the future, these base addresses should be taken from + * Device Tree or platform data. + */ + denali->flash_reg = (void __iomem *)CONFIG_SYS_NAND_REGS_BASE; + denali->flash_mem = (void __iomem *)CONFIG_SYS_NAND_DATA_BASE; + + return denali_init(denali); } -int board_nand_init(struct nand_chip *chip) +void board_nand_init(void) { - return denali_nand_init(chip); + if (__board_nand_init() < 0) + pr_warn("Failed to initialize Denali NAND controller.\n"); } diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 3277da7..a258df0 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -434,9 +434,8 @@ struct nand_buf { #define DT 3 struct denali_nand_info { - struct mtd_info mtd; - struct nand_chip *nand; - + struct mtd_info *mtd; + struct nand_chip nand; int flash_bank; /* currently selected chip */ int status; int platform; diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 0b6e7ee..70e780c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -634,6 +634,11 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, { struct nand_chip *chip = mtd->priv; + if (!(chip->options & NAND_BBT_SCANNED)) { + chip->scan_bbt(mtd); + chip->options |= NAND_BBT_SCANNED; + } + if (!chip->bbt) return chip->block_bad(mtd, ofs, getchip); @@ -4322,10 +4327,9 @@ int nand_scan_tail(struct mtd_info *mtd) /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) - return 0; + chip->options |= NAND_BBT_SCANNED; - /* Build bad block table */ - return chip->scan_bbt(mtd); + return 0; } EXPORT_SYMBOL(nand_scan_tail); diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c index db87d07..b3a2a60 100644 --- a/drivers/mtd/nand/s3c2410_nand.c +++ b/drivers/mtd/nand/s3c2410_nand.c @@ -38,10 +38,10 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) } #endif -static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl); @@ -67,35 +67,35 @@ static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) writeb(cmd, chip->IO_ADDR_W); } -static int s3c2410_dev_ready(struct mtd_info *mtd) +static int s3c24x0_dev_ready(struct mtd_info *mtd) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); debug("dev_ready\n"); return readl(&nand->nfstat) & 0x01; } #ifdef CONFIG_S3C2410_NAND_HWECC -void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) +void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); - debug("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); + debug("s3c24x0_nand_enable_hwecc(%p, %d)\n", mtd, mode); writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf); } -static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, +static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { - struct s3c2410_nand *nand = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand = s3c24x0_get_base_nand(); ecc_code[0] = readb(&nand->nfecc); ecc_code[1] = readb(&nand->nfecc + 1); ecc_code[2] = readb(&nand->nfecc + 2); - debug("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", - mtd , ecc_code[0], ecc_code[1], ecc_code[2]); + debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", + mtd , ecc_code[0], ecc_code[1], ecc_code[2]); return 0; } -static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, +static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { if (read_ecc[0] == calc_ecc[0] && @@ -103,7 +103,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, read_ecc[2] == calc_ecc[2]) return 0; - printf("s3c2410_nand_correct_data: not implemented\n"); + printf("s3c24x0_nand_correct_data: not implemented\n"); return -1; } #endif @@ -113,7 +113,7 @@ int board_nand_init(struct nand_chip *nand) u_int32_t cfg; u_int8_t tacls, twrph0, twrph1; struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); - struct s3c2410_nand *nand_reg = s3c2410_get_base_nand(); + struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand(); debug("board_nand_init()\n"); @@ -149,14 +149,14 @@ int board_nand_init(struct nand_chip *nand) #endif /* hwcontrol always must be implemented */ - nand->cmd_ctrl = s3c2410_hwcontrol; + nand->cmd_ctrl = s3c24x0_hwcontrol; - nand->dev_ready = s3c2410_dev_ready; + nand->dev_ready = s3c24x0_dev_ready; #ifdef CONFIG_S3C2410_NAND_HWECC - nand->ecc.hwctl = s3c2410_nand_enable_hwecc; - nand->ecc.calculate = s3c2410_nand_calculate_ecc; - nand->ecc.correct = s3c2410_nand_correct_data; + nand->ecc.hwctl = s3c24x0_nand_enable_hwecc; + nand->ecc.calculate = s3c24x0_nand_calculate_ecc; + nand->ecc.correct = s3c24x0_nand_correct_data; nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 7feb3a7..928d58b 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c @@ -611,6 +611,9 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr) vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT); } + /* Disable subpage writes as we do not provide ecc->hwctl */ + chip->options |= NAND_NO_SUBPAGE_WRITE; + chip->dev_ready = vf610_nfc_dev_ready; chip->cmdfunc = vf610_nfc_command; chip->read_byte = vf610_nfc_read_byte; diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index e73a498..55d6a9b 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -6,7 +6,7 @@ # obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o -obj-$(CONFIG_PCI) += pci.o pci_auto.o +obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o obj-$(CONFIG_PCI_MSC01) += pci_msc01.o diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7ee21d1..3daf73c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -366,9 +366,27 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, return phys_addr; } -/* - * - */ +void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, + u32 addr_and_ctrl) +{ + int bar; + + bar = PCI_BASE_ADDRESS_0 + barnum * 4; + pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl); +} + +u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum) +{ + u32 addr; + int bar; + + bar = PCI_BASE_ADDRESS_0 + barnum * 4; + pci_hose_read_config_dword(hose, dev, bar, &addr); + if (addr & PCI_BASE_ADDRESS_SPACE_IO) + return addr & PCI_BASE_ADDRESS_IO_MASK; + else + return addr & PCI_BASE_ADDRESS_MEM_MASK; +} int pci_hose_config_device(struct pci_controller *hose, pci_dev_t dev, diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c new file mode 100644 index 0000000..af6a3ae --- /dev/null +++ b/drivers/pci/pci_rom.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2014 Google, Inc + * + * From coreboot, originally based on the Linux kernel (drivers/pci/pci.c). + * + * Modifications are: + * Copyright (C) 2003-2004 Linux Networx + * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx) + * Copyright (C) 2003-2006 Ronald G. Minnich <rminnich@gmail.com> + * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov> + * Copyright (C) 2005-2006 Tyan + * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan) + * Copyright (C) 2005-2009 coresystems GmbH + * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH) + * + * PCI Bus Services, see include/linux/pci.h for further explanation. + * + * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter, + * David Mosberger-Tang + * + * Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <bios_emul.h> +#include <errno.h> +#include <malloc.h> +#include <pci.h> +#include <pci_rom.h> +#include <vbe.h> +#include <video_fb.h> + +#ifdef CONFIG_HAVE_ACPI_RESUME +#include <asm/acpi.h> +#endif + +__weak bool board_should_run_oprom(pci_dev_t dev) +{ + return true; +} + +static bool should_load_oprom(pci_dev_t dev) +{ +#ifdef CONFIG_HAVE_ACPI_RESUME + if (acpi_get_slp_type() == 3) + return false; +#endif + if (IS_ENABLED(CONFIG_ALWAYS_LOAD_OPROM)) + return 1; + if (board_should_run_oprom(dev)) + return 1; + + return 0; +} + +__weak uint32_t board_map_oprom_vendev(uint32_t vendev) +{ + return vendev; +} + +static int pci_rom_probe(pci_dev_t dev, uint class, + struct pci_rom_header **hdrp) +{ + struct pci_rom_header *rom_header; + struct pci_rom_data *rom_data; + u16 vendor, device; + u32 vendev; + u32 mapped_vendev; + u32 rom_address; + + pci_read_config_word(dev, PCI_VENDOR_ID, &vendor); + pci_read_config_word(dev, PCI_DEVICE_ID, &device); + vendev = vendor << 16 | device; + mapped_vendev = board_map_oprom_vendev(vendev); + if (vendev != mapped_vendev) + debug("Device ID mapped to %#08x\n", mapped_vendev); + +#ifdef CONFIG_X86_OPTION_ROM_ADDR + rom_address = CONFIG_X86_OPTION_ROM_ADDR; +#else + pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK); + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); + if (rom_address == 0x00000000 || rom_address == 0xffffffff) { + debug("%s: rom_address=%x\n", __func__, rom_address); + return -ENOENT; + } + + /* Enable expansion ROM address decoding. */ + pci_write_config_dword(dev, PCI_ROM_ADDRESS, + rom_address | PCI_ROM_ADDRESS_ENABLE); +#endif + debug("Option ROM address %x\n", rom_address); + rom_header = (struct pci_rom_header *)rom_address; + + debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", + le32_to_cpu(rom_header->signature), + rom_header->size * 512, le32_to_cpu(rom_header->data)); + + if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { + printf("Incorrect expansion ROM header signature %04x\n", + le32_to_cpu(rom_header->signature)); + return -EINVAL; + } + + rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data)); + + debug("PCI ROM image, vendor ID %04x, device ID %04x,\n", + rom_data->vendor, rom_data->device); + + /* If the device id is mapped, a mismatch is expected */ + if ((vendor != rom_data->vendor || device != rom_data->device) && + (vendev == mapped_vendev)) { + printf("ID mismatch: vendor ID %04x, device ID %04x\n", + rom_data->vendor, rom_data->device); + return -EPERM; + } + + debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n", + rom_data->class_hi, rom_data->class_lo, rom_data->type); + + if (class != ((rom_data->class_hi << 8) | rom_data->class_lo)) { + debug("Class Code mismatch ROM %08x, dev %08x\n", + (rom_data->class_hi << 8) | rom_data->class_lo, + class); + } + *hdrp = rom_header; + + return 0; +} + +int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, + struct pci_rom_header **ram_headerp) +{ + struct pci_rom_data *rom_data; + unsigned int rom_size; + unsigned int image_size = 0; + void *target; + + do { + /* Get next image, until we see an x86 version */ + rom_header = (struct pci_rom_header *)((void *)rom_header + + image_size); + + rom_data = (struct pci_rom_data *)((void *)rom_header + + le32_to_cpu(rom_header->data)); + + image_size = le32_to_cpu(rom_data->ilen) * 512; + } while ((rom_data->type != 0) && (rom_data->indicator != 0)); + + if (rom_data->type != 0) + return -EACCES; + + rom_size = rom_header->size * 512; + + target = (void *)PCI_VGA_RAM_IMAGE_START; + if (target != rom_header) { + debug("Copying VGA ROM Image from %p to %p, 0x%x bytes\n", + rom_header, target, rom_size); + memcpy(target, rom_header, rom_size); + if (memcmp(target, rom_header, rom_size)) { + printf("VGA ROM copy failed\n"); + return -EFAULT; + } + } + *ram_headerp = target; + + return 0; +} + +static struct vbe_mode_info mode_info; + +int vbe_get_video_info(struct graphic_device *gdev) +{ +#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE + struct vesa_mode_info *vesa = &mode_info.vesa; + + gdev->winSizeX = vesa->x_resolution; + gdev->winSizeY = vesa->y_resolution; + + gdev->plnSizeX = vesa->x_resolution; + gdev->plnSizeY = vesa->y_resolution; + + gdev->gdfBytesPP = vesa->bits_per_pixel / 8; + + switch (vesa->bits_per_pixel) { + case 24: + gdev->gdfIndex = GDF_32BIT_X888RGB; + break; + case 16: + gdev->gdfIndex = GDF_16BIT_565RGB; + break; + default: + gdev->gdfIndex = GDF__8BIT_INDEX; + break; + } + + gdev->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS; + gdev->pciBase = vesa->phys_base_ptr; + + gdev->frameAdrs = vesa->phys_base_ptr; + gdev->memSize = vesa->bytes_per_scanline * vesa->y_resolution; + + gdev->vprBase = vesa->phys_base_ptr; + gdev->cprBase = vesa->phys_base_ptr; + + return 0; +#else + return -ENOSYS; +#endif +} + +int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) +{ + struct pci_rom_header *rom, *ram; + int vesa_mode = -1; + uint16_t class; + int ret; + + /* Only execute VGA ROMs */ + pci_read_config_word(dev, PCI_CLASS_DEVICE, &class); + if ((class ^ PCI_CLASS_DISPLAY_VGA) & 0xff00) { + debug("%s: Class %#x, should be %#x\n", __func__, class, + PCI_CLASS_DISPLAY_VGA); + return -ENODEV; + } + + if (!should_load_oprom(dev)) + return -ENXIO; + + ret = pci_rom_probe(dev, class, &rom); + if (ret) + return ret; + + ret = pci_rom_load(class, rom, &ram); + if (ret) + return ret; + + if (!board_should_run_oprom(dev)) + return -ENXIO; + +#if defined(CONFIG_FRAMEBUFFER_SET_VESA_MODE) && \ + defined(CONFIG_FRAMEBUFFER_VESA_MODE) + vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE; +#endif + debug("Selected vesa mode %d\b", vesa_mode); + if (emulate) { +#ifdef CONFIG_BIOSEMU + BE_VGAInfo *info; + + ret = biosemu_setup(dev, &info); + if (ret) + return ret; + biosemu_set_interrupt_handler(0x15, int15_handler); + ret = biosemu_run(dev, (uchar *)ram, 1 << 16, info, true, + vesa_mode, &mode_info); + if (ret) + return ret; +#else + printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); + return -ENOSYS; +#endif + } else { +#ifdef CONFIG_X86 + bios_set_interrupt_handler(0x15, int15_handler); + + bios_run_on_x86(dev, (unsigned long)ram, vesa_mode, + &mode_info); +#else + printf("BIOS native execution is only available on x86\n"); + return -ENOSYS; +#endif + } + debug("Final vesa mode %d\n", mode_info.video_mode); + + return 0; +} diff --git a/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c index 21a2189..4cf2d83 100644 --- a/drivers/rtc/bfin_rtc.c +++ b/drivers/rtc/bfin_rtc.c @@ -27,7 +27,7 @@ #define NUM_SECS_IN_DAY DAYS_TO_SECS(1) /* Enable the RTC prescaler enable register */ -static void rtc_init(void) +void rtc_init(void) { if (!(bfin_read_RTC_PREN() & 0x1)) bfin_write_RTC_PREN(0x1); diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index f7cf106..39e6041 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -14,6 +14,7 @@ #include <common.h> #include <command.h> #include <rtc.h> +#include <version.h> #if defined(__I386__) || defined(CONFIG_MALTA) #include <asm/io.h> @@ -23,6 +24,9 @@ #if defined(CONFIG_CMD_DATE) +/* Set this to 1 to clear the CMOS RAM */ +#define CLEAR_CMOS 0 + static uchar rtc_read (uchar reg); static void rtc_write (uchar reg, uchar val); @@ -41,7 +45,14 @@ static void rtc_write (uchar reg, uchar val); #define RTC_CONFIG_B 0x0B #define RTC_CONFIG_C 0x0C #define RTC_CONFIG_D 0x0D +#define RTC_REG_SIZE 0x80 + +#define RTC_CONFIG_A_REF_CLCK_32KHZ (1 << 5) +#define RTC_CONFIG_A_RATE_1024HZ 6 +#define RTC_CONFIG_B_24H (1 << 1) + +#define RTC_CONFIG_D_VALID_RAM_AND_TIME 0x80 /* ------------------------------------------------------------------------- */ @@ -128,25 +139,49 @@ void rtc_reset (void) */ static uchar rtc_read (uchar reg) { - return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg)); + return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg); } static void rtc_write (uchar reg, uchar val) { - out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val); + out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val); } #else static uchar rtc_read (uchar reg) { out8(RTC_PORT_MC146818,reg); - return(in8(RTC_PORT_MC146818+1)); + return in8(RTC_PORT_MC146818 + 1); } static void rtc_write (uchar reg, uchar val) { out8(RTC_PORT_MC146818,reg); - out8(RTC_PORT_MC146818+1,val); + out8(RTC_PORT_MC146818+1, val); } #endif +void rtc_init(void) +{ +#if CLEAR_CMOS + int i; + + rtc_write(RTC_SECONDS_ALARM, 0); + rtc_write(RTC_MINUTES_ALARM, 0); + rtc_write(RTC_HOURS_ALARM, 0); + for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++) + rtc_write(i, 0); + printf("RTC: zeroing CMOS RAM\n"); +#endif + + /* Setup the real time clock */ + rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H); + /* Setup the frequency it operates at */ + rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | + RTC_CONFIG_A_RATE_1024HZ); + /* Ensure all reserved bits are 0 in register D */ + rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); + + /* Clear any pending interrupts */ + rtc_read(RTC_CONFIG_C); +} #endif diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index 6046efb..e8a1608 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -11,6 +11,7 @@ #include <dm/device.h> #include <dm/platform_data/serial-uniphier.h> #include <serial.h> +#include <fdtdec.h> #define UART_REG(x) \ u8 x; \ @@ -113,19 +114,21 @@ static int uniphier_serial_remove(struct udevice *dev) } #ifdef CONFIG_OF_CONTROL -static const struct udevice_id uniphier_uart_of_match = { - { .compatible = "panasonic,uniphier-uart"}, +static const struct udevice_id uniphier_uart_of_match[] = { + { .compatible = "panasonic,uniphier-uart" }, {}, }; static int uniphier_serial_ofdata_to_platdata(struct udevice *dev) { - /* - * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com) - * - * Implement conversion code from DTB to platform data - * when supporting CONFIG_OF_CONTROL on UniPhir platform. - */ + struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); + DECLARE_GLOBAL_DATA_PTR; + + plat->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg"); + plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", 0); + + return 0; } #endif diff --git a/drivers/usb/host/ehci-uniphier.c b/drivers/usb/host/ehci-uniphier.c index 77f6c9d..32a4375 100644 --- a/drivers/usb/host/ehci-uniphier.c +++ b/drivers/usb/host/ehci-uniphier.c @@ -6,10 +6,43 @@ */ #include <common.h> +#include <linux/err.h> #include <usb.h> #include <asm/arch/ehci-uniphier.h> #include "ehci.h" +#ifdef CONFIG_OF_CONTROL +#include <fdtdec.h> +DECLARE_GLOBAL_DATA_PTR; + +#define FDT gd->fdt_blob +#define COMPAT "panasonic,uniphier-ehci" + +static int get_uniphier_ehci_base(int index, struct ehci_hccr **base) +{ + int offset; + + for (offset = fdt_node_offset_by_compatible(FDT, 0, COMPAT); + offset >= 0; + offset = fdt_node_offset_by_compatible(FDT, offset, COMPAT)) { + if (index == 0) { + *base = (struct ehci_hccr *) + fdtdec_get_addr(FDT, offset, "reg"); + return 0; + } + index--; + } + + return -ENODEV; /* not found */ +} +#else +static int get_uniphier_ehci_base(int index, struct ehci_hccr **base) +{ + *base = (struct ehci_hccr *)uniphier_ehci_platdata[index].base; + return 0; +} +#endif + /* * Create the appropriate control structures to manage * a new EHCI host controller. @@ -17,12 +50,15 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { + int ret; struct ehci_hccr *cr; struct ehci_hcor *or; uniphier_ehci_reset(index, 0); - cr = (struct ehci_hccr *)(uniphier_ehci_platdata[index].base); + ret = get_uniphier_ehci_base(index, &cr); + if (ret < 0) + return ret; or = (void *)cr + HC_LENGTH(ehci_readl(&cr->cr_capbase)); *hccr = cr; diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7301be3..00b563f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o obj-$(CONFIG_VIDEO_TEGRA) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o +obj-$(CONFIG_VIDEO_X86) += x86_fb.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o obj-$(CONFIG_VIDEO_PARADE) += parade.o diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c index 618f5d9..5748951 100644 --- a/drivers/video/ati_radeon_fb.c +++ b/drivers/video/ati_radeon_fb.c @@ -19,6 +19,7 @@ #include <common.h> #include <command.h> +#include <bios_emul.h> #include <pci.h> #include <asm/processor.h> #include <asm/errno.h> @@ -544,7 +545,6 @@ void radeon_setmode_9200(int vesa_idx, int bpp) } #include "../bios_emulator/include/biosemu.h" -extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp); int radeon_probe(struct radeonfb_info *rinfo) { diff --git a/drivers/video/x86_fb.c b/drivers/video/x86_fb.c new file mode 100644 index 0000000..8743a8c --- /dev/null +++ b/drivers/video/x86_fb.c @@ -0,0 +1,37 @@ +/* + * + * Vesa frame buffer driver for x86 + * + * Copyright (C) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <video_fb.h> +#include <vbe.h> +#include "videomodes.h" + +/* + * The Graphic Device + */ +GraphicDevice ctfb; + +void *video_hw_init(void) +{ + GraphicDevice *gdev = &ctfb; + int bits_per_pixel; + + printf("Video: "); + if (vbe_get_video_info(gdev)) { + printf("No video mode configured\n"); + return NULL; + } + + bits_per_pixel = gdev->gdfBytesPP * 8; + sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, + bits_per_pixel); + printf("%s\n", gdev->modeIdent); + + return (void *)gdev; +} |