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

* Re: [PATCH] add access to AMD secure silicon area
  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
  0 siblings, 1 reply; 6+ messages in thread
From: David Woodhouse @ 2002-10-15 10:09 UTC (permalink / raw)
  To: Clive Davies; +Cc: linux-mtd

cdavies@altera.com said:
> 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. 

+	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);

Is this always correct?

+        /* 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;

Er, is this information not available from the CFI info? I really want to 
avoid having stuff like this in the chip drivers.


--
dwmw2

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

* Re: [PATCH] add access to AMD secure silicon area
  2002-10-15 10:09 ` David Woodhouse
@ 2002-10-15 10:25   ` Clive Davies
  2002-10-15 10:36     ` David Woodhouse
  0 siblings, 1 reply; 6+ messages in thread
From: Clive Davies @ 2002-10-15 10:25 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd

>
> +	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);
>
> Is this always correct?

It should be, it matches the command sequence in the data sheet for the 
AM29DL322D/323D/324D devices. 

>
> +        /* 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;
>
> Er, is this information not available from the CFI info? I really want to
> avoid having stuff like this in the chip drivers.

Unfortunately not. There's no mention of it at all in the AMD primary vendor 
specific extended query table v1.1 which is used on these devices. I don't 
like this method either but in the absence of CFI info I don't have any 
better ideas.

Clive

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

* Re: [PATCH] add access to AMD secure silicon area
  2002-10-15 10:25   ` Clive Davies
@ 2002-10-15 10:36     ` David Woodhouse
  2002-10-15 13:21       ` Clive Davies
  0 siblings, 1 reply; 6+ messages in thread
From: David Woodhouse @ 2002-10-15 10:36 UTC (permalink / raw)
  To: Clive Davies; +Cc: linux-mtd

cdavies@altera.com said:
>  It should be, it matches the command sequence in the data sheet for
> the  AM29DL322D/323D/324D devices.  

And CFI_DEVICETYPE_X8 is always correct? No X16 devices?

>  Unfortunately not. There's no mention of it at all in the AMD primary
> vendor  specific extended query table v1.1 which is used on these
> devices. I don't  like this method either but in the absence of CFI
> info I don't have any  better ideas.

Argh. FFS. So AMD can't manage to get the fscking erasesize table correct 
in the CFI data, and they can't manage to add the appropriate fields to 
their own vendor-specific table to remove the need to keep the device ID 
tables which CFI was supposed to eliminate?

Would someone from AMD care to either contradict me or promise me 
faithfully that they've taken a baseball bat to whoever is responsible?

I suspect we need a new 'amd_is_bloody_stupid_probe' alongside jedec_probe 
and cfi_probe :)

--
dwmw2

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

* Re: [PATCH] add access to AMD secure silicon area
  2002-10-15 10:36     ` David Woodhouse
@ 2002-10-15 13:21       ` Clive Davies
  2002-10-15 13:24         ` David Woodhouse
  0 siblings, 1 reply; 6+ messages in thread
From: Clive Davies @ 2002-10-15 13:21 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-mtd

> And CFI_DEVICETYPE_X8 is always correct? No X16 devices?
>

Good point, how about ....

+       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, 
cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
+
+       map->copy_from(map, buf, adr, len);
+
+       cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, 
cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
+       cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, 
cfi->device_type, NULL);
+

instead?

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

* Re: [PATCH] add access to AMD secure silicon area
  2002-10-15 13:21       ` Clive Davies
@ 2002-10-15 13:24         ` David Woodhouse
  0 siblings, 0 replies; 6+ messages in thread
From: David Woodhouse @ 2002-10-15 13:24 UTC (permalink / raw)
  To: Clive Davies; +Cc: linux-mtd

cdavies@altera.com said:
> > And CFI_DEVICETYPE_X8 is always correct? No X16 devices?
> Good point, how about ....

Looks saner to me.


--
dwmw2

^ 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