diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README | 10 | ||||
-rw-r--r-- | board/freescale/p2041rdb/p2041rdb.c | 25 | ||||
-rw-r--r-- | common/cmd_bdinfo.c | 1 | ||||
-rw-r--r-- | common/exports.c | 1 | ||||
-rw-r--r-- | common/miiphyutil.c | 8 | ||||
-rw-r--r-- | drivers/tpm/Makefile | 43 | ||||
-rw-r--r-- | drivers/tpm/generic_lpc_tpm.c | 495 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 109 | ||||
-rw-r--r-- | include/miiphy.h | 12 | ||||
-rw-r--r-- | include/tpm.h | 71 | ||||
-rw-r--r-- | lib/qsort.c | 1 |
12 files changed, 703 insertions, 76 deletions
@@ -277,6 +277,9 @@ LIBS += arch/powerpc/cpu/mpc8xxx/lib8xxx.o endif LIBS += drivers/rtc/librtc.o LIBS += drivers/serial/libserial.o +ifeq ($(CONFIG_GENERIC_LPC_TPM),y) +LIBS += drivers/tpm/libtpm.o +endif LIBS += drivers/twserial/libtws.o LIBS += drivers/usb/eth/libusb_eth.o LIBS += drivers/usb/gadget/libusb_gadget.o @@ -1072,6 +1072,16 @@ The following options need to be configured: CONFIG_SH_ETHER_CACHE_WRITEBACK If this option is set, the driver enables cache flush. +- TPM Support: + CONFIG_GENERIC_LPC_TPM + Support for generic parallel port TPM devices. Only one device + per system is supported at this time. + + CONFIG_TPM_TIS_BASE_ADDRESS + Base address where the generic TPM device is mapped + to. Contemporary x86 systems usually map it at + 0xfed40000. + - USB Support: At the moment only the UHCI host controller is supported (PIP405, MIP405, MPC5200); define diff --git a/board/freescale/p2041rdb/p2041rdb.c b/board/freescale/p2041rdb/p2041rdb.c index 6461bd7..1f6a34b 100644 --- a/board/freescale/p2041rdb/p2041rdb.c +++ b/board/freescale/p2041rdb/p2041rdb.c @@ -83,10 +83,12 @@ int checkboard(void) puts("SERDES Reference Clocks: "); sw = in_8(&CPLD_SW(2)) >> 2; for (i = 0; i < 2; i++) { - static const char * const freq[] = {"0", "100", "125"}; + static const char * const freq[][3] = {{"0", "100", "125"}, + {"100", "156.25", "125"} + }; unsigned int clock = (sw >> (2 * i)) & 3; - printf("Bank%u=%sMhz ", i+1, freq[clock]); + printf("Bank%u=%sMhz ", i+1, freq[i][clock]); } puts("\n"); @@ -166,22 +168,25 @@ int misc_init_r(void) u32 actual[NUM_SRDS_BANKS]; unsigned int i; u8 sw; + static const int freq[][3] = { + {0, SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_125}, + {SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_156_25, + SRDS_PLLCR0_RFCK_SEL_125} + }; sw = in_8(&CPLD_SW(2)) >> 2; for (i = 0; i < NUM_SRDS_BANKS; i++) { unsigned int clock = (sw >> (2 * i)) & 3; - switch (clock) { - case 1: - actual[i] = SRDS_PLLCR0_RFCK_SEL_100; - break; - case 2: - actual[i] = SRDS_PLLCR0_RFCK_SEL_125; - break; - default: + if (clock == 0x3) { printf("Warning: SDREFCLK%u switch setting of '11' is " "unsupported\n", i + 1); break; } + if (i == 0 && clock == 0) + puts("Warning: SDREFCLK1 switch setting of" + "'00' is unsupported\n"); + else + actual[i] = freq[i][clock]; } for (i = 0; i < NUM_SRDS_BANKS; i++) { diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 73c03a8..67cb0da 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -36,6 +36,7 @@ static void print_num(const char *name, ulong value) printf("%-12s= 0x%08lX\n", name, value); } +__maybe_unused static void print_eth(int idx) { char name[10], *val; diff --git a/common/exports.c b/common/exports.c index 717e4af..b97ca48 100644 --- a/common/exports.c +++ b/common/exports.c @@ -1,5 +1,6 @@ #include <common.h> #include <exports.h> +#include <spi.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 88747b8..2cc23b4 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -106,9 +106,9 @@ static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad, */ void miiphy_register(const char *name, int (*read)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short *value), + unsigned char reg, unsigned short *value), int (*write)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short value)) + unsigned char reg, unsigned short value)) { struct mii_dev *new_dev; struct legacy_mii_dev *ldev; @@ -287,7 +287,7 @@ static struct mii_dev *miiphy_get_active_dev(const char *devname) * Returns: * 0 on success */ -int miiphy_read(const char *devname, unsigned char addr, unsigned short reg, +int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) { struct mii_dev *bus; @@ -315,7 +315,7 @@ int miiphy_read(const char *devname, unsigned char addr, unsigned short reg, * Returns: * 0 on success */ -int miiphy_write(const char *devname, unsigned char addr, unsigned short reg, +int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) { struct mii_dev *bus; diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile new file mode 100644 index 0000000..be11c8b --- /dev/null +++ b/drivers/tpm/Makefile @@ -0,0 +1,43 @@ +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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 2 of +# the License, or (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libtpm.o + +COBJS-$(CONFIG_GENERIC_LPC_TPM) = generic_lpc_tpm.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/tpm/generic_lpc_tpm.c b/drivers/tpm/generic_lpc_tpm.c new file mode 100644 index 0000000..6c494eb --- /dev/null +++ b/drivers/tpm/generic_lpc_tpm.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 2 of + * the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * The code in this file is based on the article "Writing a TPM Device Driver" + * published on http://ptgmedia.pearsoncmg.com. + * + * One principal difference is that in the simplest config the other than 0 + * TPM localities do not get mapped by some devices (for instance, by Infineon + * slb9635), so this driver provides access to locality 0 only. + */ + +#include <common.h> +#include <asm/io.h> +#include <tpm.h> + +#define PREFIX "lpc_tpm: " + +struct tpm_locality { + u32 access; + u8 padding0[4]; + u32 int_enable; + u8 vector; + u8 padding1[3]; + u32 int_status; + u32 int_capability; + u32 tpm_status; + u8 padding2[8]; + u8 data; + u8 padding3[3803]; + u32 did_vid; + u8 rid; + u8 padding4[251]; +}; + +/* + * This pointer refers to the TPM chip, 5 of its localities are mapped as an + * array. + */ +#define TPM_TOTAL_LOCALITIES 5 +static struct tpm_locality *lpc_tpm_dev = + (struct tpm_locality *)CONFIG_TPM_TIS_BASE_ADDRESS; + +/* Some registers' bit field definitions */ +#define TIS_STS_VALID (1 << 7) /* 0x80 */ +#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */ +#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */ +#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */ +#define TIS_STS_EXPECT (1 << 3) /* 0x08 */ +#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */ + +#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */ +#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */ +#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */ +#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */ +#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */ +#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */ +#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */ + +#define TIS_STS_BURST_COUNT_MASK (0xffff) +#define TIS_STS_BURST_COUNT_SHIFT (8) + +/* + * Error value returned if a tpm register does not enter the expected state + * after continuous polling. No actual TPM register reading ever returns -1, + * so this value is a safe error indication to be mixed with possible status + * register values. + */ +#define TPM_TIMEOUT_ERR (-1) + +/* Error value returned on various TPM driver errors. */ +#define TPM_DRIVER_ERR (1) + + /* 1 second is plenty for anything TPM does. */ +#define MAX_DELAY_US (1000 * 1000) + +/* Retrieve burst count value out of the status register contents. */ +static u16 burst_count(u32 status) +{ + return (status >> TIS_STS_BURST_COUNT_SHIFT) & TIS_STS_BURST_COUNT_MASK; +} + +/* + * Structures defined below allow creating descriptions of TPM vendor/device + * ID information for run time discovery. The only device the system knows + * about at this time is Infineon slb9635. + */ +struct device_name { + u16 dev_id; + const char * const dev_name; +}; + +struct vendor_name { + u16 vendor_id; + const char *vendor_name; + const struct device_name *dev_names; +}; + +static const struct device_name infineon_devices[] = { + {0xb, "SLB9635 TT 1.2"}, + {0} +}; + +static const struct vendor_name vendor_names[] = { + {0x15d1, "Infineon", infineon_devices}, +}; + +/* + * Cached vendor/device ID pair to indicate that the device has been already + * discovered. + */ +static u32 vendor_dev_id; + +/* TPM access wrappers to support tracing */ +static u8 tpm_read_byte(const u8 *ptr) +{ + u8 ret = readb(ptr); + debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n", + (u32)ptr - (u32)lpc_tpm_dev, ret); + return ret; +} + +static u32 tpm_read_word(const u32 *ptr) +{ + u32 ret = readl(ptr); + debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n", + (u32)ptr - (u32)lpc_tpm_dev, ret); + return ret; +} + +static void tpm_write_byte(u8 value, u8 *ptr) +{ + debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n", + (u32)ptr - (u32)lpc_tpm_dev, value); + writeb(value, ptr); +} + +static void tpm_write_word(u32 value, u32 *ptr) +{ + debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n", + (u32)ptr - (u32)lpc_tpm_dev, value); + writel(value, ptr); +} + +/* + * tis_wait_reg() + * + * Wait for at least a second for a register to change its state to match the + * expected state. Normally the transition happens within microseconds. + * + * @reg - pointer to the TPM register + * @mask - bitmask for the bitfield(s) to watch + * @expected - value the field(s) are supposed to be set to + * + * Returns the register contents in case the expected value was found in the + * appropriate register bits, or TPM_TIMEOUT_ERR on timeout. + */ +static u32 tis_wait_reg(u32 *reg, u8 mask, u8 expected) +{ + u32 time_us = MAX_DELAY_US; + + while (time_us > 0) { + u32 value = tpm_read_word(reg); + if ((value & mask) == expected) + return value; + udelay(1); /* 1 us */ + time_us--; + } + return TPM_TIMEOUT_ERR; +} + +/* + * Probe the TPM device and try determining its manufacturer/device name. + * + * Returns 0 on success (the device is found or was found during an earlier + * invocation) or TPM_DRIVER_ERR if the device is not found. + */ +int tis_init(void) +{ + u32 didvid = tpm_read_word(&lpc_tpm_dev[0].did_vid); + int i; + const char *device_name = "unknown"; + const char *vendor_name = device_name; + u16 vid, did; + + if (vendor_dev_id) + return 0; /* Already probed. */ + + if (!didvid || (didvid == 0xffffffff)) { + printf("%s: No TPM device found\n", __func__); + return TPM_DRIVER_ERR; + } + + vendor_dev_id = didvid; + + vid = didvid & 0xffff; + did = (didvid >> 16) & 0xffff; + for (i = 0; i < ARRAY_SIZE(vendor_names); i++) { + int j = 0; + u16 known_did; + + if (vid == vendor_names[i].vendor_id) + vendor_name = vendor_names[i].vendor_name; + + while ((known_did = vendor_names[i].dev_names[j].dev_id) != 0) { + if (known_did == did) { + device_name = + vendor_names[i].dev_names[j].dev_name; + break; + } + j++; + } + break; + } + + printf("Found TPM %s by %s\n", device_name, vendor_name); + return 0; +} + +/* + * tis_senddata() + * + * send the passed in data to the TPM device. + * + * @data - address of the data to send, byte by byte + * @len - length of the data to send + * + * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does + * not accept the entire command). + */ +static u32 tis_senddata(const u8 * const data, u32 len) +{ + u32 offset = 0; + u16 burst = 0; + u32 max_cycles = 0; + u8 locality = 0; + u32 value; + + value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status, + TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY); + if (value == TPM_TIMEOUT_ERR) { + printf("%s:%d - failed to get 'command_ready' status\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + burst = burst_count(value); + + while (1) { + unsigned count; + + /* Wait till the device is ready to accept more data. */ + while (!burst) { + if (max_cycles++ == MAX_DELAY_US) { + printf("%s:%d failed to feed %d bytes of %d\n", + __FILE__, __LINE__, len - offset, len); + return TPM_DRIVER_ERR; + } + udelay(1); + burst = burst_count(tpm_read_word(&lpc_tpm_dev + [locality].tpm_status)); + } + + max_cycles = 0; + + /* + * Calculate number of bytes the TPM is ready to accept in one + * shot. + * + * We want to send the last byte outside of the loop (hence + * the -1 below) to make sure that the 'expected' status bit + * changes to zero exactly after the last byte is fed into the + * FIFO. + */ + count = min(burst, len - offset - 1); + while (count--) + tpm_write_byte(data[offset++], + &lpc_tpm_dev[locality].data); + + value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status, + TIS_STS_VALID, TIS_STS_VALID); + + if ((value == TPM_TIMEOUT_ERR) || !(value & TIS_STS_EXPECT)) { + printf("%s:%d TPM command feed overflow\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + + burst = burst_count(value); + if ((offset == (len - 1)) && burst) { + /* + * We need to be able to send the last byte to the + * device, so burst size must be nonzero before we + * break out. + */ + break; + } + } + + /* Send the last byte. */ + tpm_write_byte(data[offset++], &lpc_tpm_dev[locality].data); + /* + * Verify that TPM does not expect any more data as part of this + * command. + */ + value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status, + TIS_STS_VALID, TIS_STS_VALID); + if ((value == TPM_TIMEOUT_ERR) || (value & TIS_STS_EXPECT)) { + printf("%s:%d unexpected TPM status 0x%x\n", + __FILE__, __LINE__, value); + return TPM_DRIVER_ERR; + } + + /* OK, sitting pretty, let's start the command execution. */ + tpm_write_word(TIS_STS_TPM_GO, &lpc_tpm_dev[locality].tpm_status); + return 0; +} + +/* + * tis_readresponse() + * + * read the TPM device response after a command was issued. + * + * @buffer - address where to read the response, byte by byte. + * @len - pointer to the size of buffer + * + * On success stores the number of received bytes to len and returns 0. On + * errors (misformatted TPM data or synchronization problems) returns + * TPM_DRIVER_ERR. + */ +static u32 tis_readresponse(u8 *buffer, u32 *len) +{ + u16 burst; + u32 value; + u32 offset = 0; + u8 locality = 0; + const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID; + u32 expected_count = *len; + int max_cycles = 0; + + /* Wait for the TPM to process the command. */ + value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status, + has_data, has_data); + if (value == TPM_TIMEOUT_ERR) { + printf("%s:%d failed processing command\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + + do { + while ((burst = burst_count(value)) == 0) { + if (max_cycles++ == MAX_DELAY_US) { + printf("%s:%d TPM stuck on read\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + udelay(1); + value = tpm_read_word(&lpc_tpm_dev + [locality].tpm_status); + } + + max_cycles = 0; + + while (burst-- && (offset < expected_count)) { + buffer[offset++] = tpm_read_byte(&lpc_tpm_dev + [locality].data); + + if (offset == 6) { + /* + * We got the first six bytes of the reply, + * let's figure out how many bytes to expect + * total - it is stored as a 4 byte number in + * network order, starting with offset 2 into + * the body of the reply. + */ + u32 real_length; + memcpy(&real_length, + buffer + 2, + sizeof(real_length)); + expected_count = be32_to_cpu(real_length); + + if ((expected_count < offset) || + (expected_count > *len)) { + printf("%s:%d bad response size %d\n", + __FILE__, __LINE__, + expected_count); + return TPM_DRIVER_ERR; + } + } + } + + /* Wait for the next portion. */ + value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status, + TIS_STS_VALID, TIS_STS_VALID); + if (value == TPM_TIMEOUT_ERR) { + printf("%s:%d failed to read response\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + + if (offset == expected_count) + break; /* We got all we needed. */ + + } while ((value & has_data) == has_data); + + /* + * Make sure we indeed read all there was. The TIS_STS_VALID bit is + * known to be set. + */ + if (value & TIS_STS_DATA_AVAILABLE) { + printf("%s:%d wrong receive status %x\n", + __FILE__, __LINE__, value); + return TPM_DRIVER_ERR; + } + + /* Tell the TPM that we are done. */ + tpm_write_word(TIS_STS_COMMAND_READY, &lpc_tpm_dev + [locality].tpm_status); + *len = offset; + return 0; +} + +int tis_open(void) +{ + u8 locality = 0; /* we use locality zero for everything. */ + + if (tis_close()) + return TPM_DRIVER_ERR; + + /* now request access to locality. */ + tpm_write_word(TIS_ACCESS_REQUEST_USE, &lpc_tpm_dev[locality].access); + + /* did we get a lock? */ + if (tis_wait_reg(&lpc_tpm_dev[locality].access, + TIS_ACCESS_ACTIVE_LOCALITY, + TIS_ACCESS_ACTIVE_LOCALITY) == TPM_TIMEOUT_ERR) { + printf("%s:%d - failed to lock locality %d\n", + __FILE__, __LINE__, locality); + return TPM_DRIVER_ERR; + } + + tpm_write_word(TIS_STS_COMMAND_READY, + &lpc_tpm_dev[locality].tpm_status); + return 0; +} + +int tis_close(void) +{ + u8 locality = 0; + + if (tpm_read_word(&lpc_tpm_dev[locality].access) & + TIS_ACCESS_ACTIVE_LOCALITY) { + tpm_write_word(TIS_ACCESS_ACTIVE_LOCALITY, + &lpc_tpm_dev[locality].access); + + if (tis_wait_reg(&lpc_tpm_dev[locality].access, + TIS_ACCESS_ACTIVE_LOCALITY, 0) == + TPM_TIMEOUT_ERR) { + printf("%s:%d - failed to release locality %d\n", + __FILE__, __LINE__, locality); + return TPM_DRIVER_ERR; + } + } + return 0; +} + +int tis_sendrecv(const u8 *sendbuf, size_t send_size, + u8 *recvbuf, size_t *recv_len) +{ + if (tis_senddata(sendbuf, send_size)) { + printf("%s:%d failed sending data to TPM\n", + __FILE__, __LINE__); + return TPM_DRIVER_ERR; + } + + return tis_readresponse(recvbuf, recv_len); +} diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 480df64..9be6166 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -242,8 +242,9 @@ #define CURSOR_SET #endif -#ifdef CONFIG_CONSOLE_CURSOR -#ifdef CURSOR_ON +#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR) +#if defined(CURSOR_ON) || \ + (defined(CONFIG_CONSOLE_CURSOR) && defined(CONFIG_VIDEO_SW_CURSOR)) #error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \ or CONFIG_VIDEO_HW_CURSOR can be defined #endif @@ -251,27 +252,18 @@ void console_cursor(int state); #define CURSOR_ON console_cursor(1) #define CURSOR_OFF console_cursor(0) -#define CURSOR_SET +#define CURSOR_SET video_set_cursor() +#endif /* CONFIG_CONSOLE_CURSOR || CONFIG_VIDEO_SW_CURSOR */ + +#ifdef CONFIG_CONSOLE_CURSOR +#ifndef CONFIG_CONSOLE_TIME +#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME +#endif #ifndef CONFIG_I8042_KBD #warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c #endif -#else -#ifdef CONFIG_CONSOLE_TIME -#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME -#endif #endif /* CONFIG_CONSOLE_CURSOR */ -#ifdef CONFIG_VIDEO_SW_CURSOR -#ifdef CURSOR_ON -#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \ - or CONFIG_VIDEO_HW_CURSOR can be defined -#endif -#define CURSOR_ON -#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\ - console_row * VIDEO_FONT_HEIGHT, ' ') -#define CURSOR_SET video_set_cursor() -#endif /* CONFIG_VIDEO_SW_CURSOR */ - #ifdef CONFIG_VIDEO_HW_CURSOR #ifdef CURSOR_ON @@ -376,6 +368,10 @@ static void *video_console_address; /* console buffer start address */ static int video_logo_height = VIDEO_LOGO_HEIGHT; +static int cursor_state; +static int old_col; +static int old_row; + static int console_col; /* cursor col */ static int console_row; /* cursor row */ @@ -435,6 +431,22 @@ static const int video_font_draw_table32[16][4] = { }; +static void video_invertchar(int xx, int yy) +{ + int firstx = xx * VIDEO_PIXEL_SIZE; + int lastx = (xx + VIDEO_FONT_WIDTH) * VIDEO_PIXEL_SIZE; + int firsty = yy * VIDEO_LINE_LEN; + int lasty = (yy + VIDEO_FONT_HEIGHT) * VIDEO_LINE_LEN; + int x, y; + for (y = firsty; y < lasty; y += VIDEO_LINE_LEN) { + for (x = firstx; x < lastx; x++) { + u8 *dest = (u8 *)(video_fb_address) + x + y; + *dest = ~*dest; + } + } +} + + static void video_drawchars(int xx, int yy, unsigned char *s, int count) { u8 *cdat, *dest, *dest0; @@ -610,27 +622,15 @@ static void video_putchar(int xx, int yy, unsigned char c) #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR) static void video_set_cursor(void) { - /* swap drawing colors */ - eorx = fgx; - fgx = bgx; - bgx = eorx; - eorx = fgx ^ bgx; - /* draw cursor */ - video_putchar(console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, ' '); - /* restore drawing colors */ - eorx = fgx; - fgx = bgx; - bgx = eorx; - eorx = fgx ^ bgx; + if (cursor_state) + console_cursor(0); + console_cursor(1); } -#endif -#ifdef CONFIG_CONSOLE_CURSOR + + void console_cursor(int state) { - static int last_state = 0; - #ifdef CONFIG_CONSOLE_TIME struct rtc_time tm; char info[16]; @@ -652,17 +652,22 @@ void console_cursor(int state) } #endif - if (state && (last_state != state)) { - video_set_cursor(); - } - - if (!state && (last_state != state)) { - /* clear cursor */ - video_putchar(console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, ' '); + if (cursor_state != state) { + if (cursor_state) { + /* turn off the cursor */ + video_invertchar(old_col * VIDEO_FONT_WIDTH, + old_row * VIDEO_FONT_HEIGHT + + video_logo_height); + } else { + /* turn off the cursor and record where it is */ + video_invertchar(console_col * VIDEO_FONT_WIDTH, + console_row * VIDEO_FONT_HEIGHT + + video_logo_height); + old_col = console_col; + old_row = console_row; + } + cursor_state = state; } - - last_state = state; } #endif @@ -729,19 +734,11 @@ static void console_back(void) if (console_row < 0) console_row = 0; } - video_putchar(console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, ' '); + CURSOR_SET; } static void console_newline(void) { - /* Check if last character in the line was just drawn. If so, cursor was - overwriten and need not to be cleared. Cursor clearing without this - check causes overwriting the 1st character of the line if line lenght - is >= CONSOLE_COLS - */ - if (console_col < CONSOLE_COLS) - CURSOR_OFF; console_row++; console_col = 0; @@ -757,7 +754,6 @@ static void console_newline(void) static void console_cr(void) { - CURSOR_OFF; console_col = 0; } @@ -765,6 +761,8 @@ void video_putc(const char c) { static int nl = 1; + CURSOR_OFF; + switch (c) { case 13: /* back to first column */ console_cr(); @@ -777,7 +775,6 @@ void video_putc(const char c) break; case 9: /* tab 8 */ - CURSOR_OFF; console_col |= 0x0008; console_col &= ~0x0007; diff --git a/include/miiphy.h b/include/miiphy.h index 7ce6d14..7e70cf8 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -42,14 +42,14 @@ struct legacy_mii_dev { int (*read)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short *value); + unsigned char reg, unsigned short *value); int (*write)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short value); + unsigned char reg, unsigned short value); }; -int miiphy_read(const char *devname, unsigned char addr, unsigned short reg, +int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value); -int miiphy_write(const char *devname, unsigned char addr, unsigned short reg, +int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value); int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui, unsigned char *model, unsigned char *rev); @@ -65,9 +65,9 @@ void miiphy_init(void); void miiphy_register(const char *devname, int (*read)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short *value), + unsigned char reg, unsigned short *value), int (*write)(const char *devname, unsigned char addr, - unsigned short reg, unsigned short value)); + unsigned char reg, unsigned short value)); int miiphy_set_current_dev(const char *devname); const char *miiphy_get_current_dev(void); diff --git a/include/tpm.h b/include/tpm.h new file mode 100644 index 0000000..6b21e9c --- /dev/null +++ b/include/tpm.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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 2 of + * the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _INCLUDE_TPM_H_ +#define _INCLUDE_TPM_H_ + +#include <common.h> + +/* + * tis_init() + * + * Initialize the TPM device. Returns 0 on success or -1 on + * failure (in case device probing did not succeed). + */ +int tis_init(void); + +/* + * tis_open() + * + * Requests access to locality 0 for the caller. After all commands have been + * completed the caller is supposed to call tis_close(). + * + * Returns 0 on success, -1 on failure. + */ +int tis_open(void); + +/* + * tis_close() + * + * terminate the currect session with the TPM by releasing the locked + * locality. Returns 0 on success of -1 on failure (in case lock + * removal did not succeed). + */ +int tis_close(void); + +/* + * tis_sendrecv() + * + * Send the requested data to the TPM and then try to get its response + * + * @sendbuf - buffer of the data to send + * @send_size size of the data to send + * @recvbuf - memory to save the response to + * @recv_len - pointer to the size of the response buffer + * + * Returns 0 on success (and places the number of response bytes at recv_len) + * or -1 on failure. + */ +int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf, + size_t *recv_len); + +#endif /* _INCLUDE_TPM_H_ */ diff --git a/lib/qsort.c b/lib/qsort.c index 86c392c..5709884 100644 --- a/lib/qsort.c +++ b/lib/qsort.c @@ -16,6 +16,7 @@ * bcc and gcc. */ #include <linux/types.h> +#include <common.h> #include <exports.h> void qsort(void *base, |