public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] add access to AMD secure silicon area
@ 2002-10-03  8:16 Clive Davies
  2002-10-15 10:09 ` David Woodhouse
  0 siblings, 1 reply; 6+ messages in thread
From: Clive Davies @ 2002-10-03  8:16 UTC (permalink / raw)
  To: linux-mtd

[-- Attachment #1: Type: text/plain, Size: 167 bytes --]

This patch makes the secure silicon (secsi) area available in some AMD flash 
devices available for reading via the read_user_prot_reg/read_fact_prot_reg 
functions.


[-- Attachment #2: patch --]
[-- Type: text/x-diff, Size: 4309 bytes --]

Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.58
diff -u -p -r1.58 cfi_cmdset_0002.c
--- cfi_cmdset_0002.c	13 Sep 2002 14:37:35 -0000	1.58
+++ cfi_cmdset_0002.c	25 Sep 2002 10:17:09 -0000
@@ -36,6 +36,8 @@ static int cfi_amdstd_erase_varsize(stru
 static void cfi_amdstd_sync (struct mtd_info *);
 static int cfi_amdstd_suspend (struct mtd_info *);
 static void cfi_amdstd_resume (struct mtd_info *);
+static int cfi_amdstd_secsi_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_amdstd_secsi_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 
 static void cfi_amdstd_destroy(struct mtd_info *);
 
@@ -75,7 +77,7 @@ struct mtd_info *cfi_cmdset_0002(struct 
 		cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
 		cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
 		cfi->mfr = cfi_read_query(map, base);
-		cfi->id = cfi_read_query(map, base + ofs_factor);
+		cfi->id = cfi_read_query(map, base + ofs_factor);    
 
 		/* Wheee. Bring me the head of someone at AMD. */
 #ifdef AMD_BOOTLOC_BUG
@@ -246,6 +248,8 @@ static struct mtd_info *cfi_amdstd_setup
 		cfi->fast_prog = 0;
 	}
 		
+	mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
+	mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
 	mtd->sync = cfi_amdstd_sync;
 	mtd->suspend = cfi_amdstd_suspend;
 	mtd->resume = cfi_amdstd_resume;
@@ -324,6 +328,117 @@ static int cfi_amdstd_read (struct mtd_i
 			thislen = len;
 
 		ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
+		if (ret)
+			break;
+
+		*retlen += thislen;
+		len -= thislen;
+		buf += thislen;
+
+		ofs = 0;
+		chipnum++;
+	}
+	return ret;
+}
+
+static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long timeo = jiffies + HZ;
+	struct cfi_private *cfi = map->fldrv_priv;
+
+ retry:
+	cfi_spin_lock(chip->mutex);
+
+	if (chip->state != FL_READY){
+#if 0
+	        printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
+#endif
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		add_wait_queue(&chip->wq, &wait);
+                
+		cfi_spin_unlock(chip->mutex);
+
+		schedule();
+		remove_wait_queue(&chip->wq, &wait);
+#if 0
+		if(signal_pending(current))
+			return -EINTR;
+#endif
+		timeo = jiffies + HZ;
+
+		goto retry;
+	}	
+
+	adr += chip->start;
+
+	chip->state = FL_READY;
+	
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	
+	map->copy_from(map, buf, adr, len);
+
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	
+	wake_up(&chip->wq);
+	cfi_spin_unlock(chip->mutex);
+
+	return 0;
+}
+
+static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long ofs;
+	int chipnum;
+	int ret = 0;
+
+        /* does this chip even have a secsi area? */
+	if(cfi->mfr!=1)
+		return -EINVAL;
+	switch(cfi->id){
+	case 0x50:
+	case 0x53:
+	case 0x55:
+	case 0x56:
+	case 0x5C:
+	case 0x5F:
+		break;
+	default:
+		return -EINVAL;
+	}
+	
+        /* yes, it does... */
+
+
+
+	/* ofs: offset within the first chip that the first read should start */
+
+	/* 8 secsi bytes per chip */
+	chipnum=from>>3;
+	ofs=from & 7;
+
+
+	*retlen = 0;
+
+	while (len) {
+		unsigned long thislen;
+
+		if (chipnum >= cfi->numchips)
+			break;
+
+		if ((len + ofs -1) >> 3)
+			thislen = (1<<3) - ofs;
+		else
+			thislen = len;
+
+		ret = do_read_secsi_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
 		if (ret)
 			break;
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-10-15 13:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-03  8:16 [PATCH] add access to AMD secure silicon area Clive Davies
2002-10-15 10:09 ` David Woodhouse
2002-10-15 10:25   ` Clive Davies
2002-10-15 10:36     ` David Woodhouse
2002-10-15 13:21       ` Clive Davies
2002-10-15 13:24         ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox